00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <string.h>
00037 #include <sys/types.h>
00038 #include <regex.h>
00039
00040 #include <assert.h>
00041 #include <cpl.h>
00042
00043 #include "irplib_utils.h"
00044 #include "irplib_tools.h"
00045 #include "irplib_pfits.h"
00046
00047
00048
00049
00050
00051 static cpl_error_code irplib_dfs_check_frame_tag(const cpl_frame *,
00052 const cpl_propertylist *,
00053 const char* (*)
00054 (const char *,
00055 const char *,
00056 const char *));
00057
00058
00059
00064
00065
00068
00069
00070
00071
00072
00073
00079
00080 const char * irplib_pfits_get_dpr_catg(const cpl_propertylist * self)
00081 {
00082 return irplib_pfits_get_string(self, "ESO DPR CATG");
00083 }
00084
00085
00091
00092 const char * irplib_pfits_get_dpr_tech(const cpl_propertylist * self)
00093 {
00094 return irplib_pfits_get_string(self, "ESO DPR TECH");
00095 }
00096
00097
00103
00104 const char * irplib_pfits_get_dpr_type(const cpl_propertylist * self)
00105 {
00106 return irplib_pfits_get_string(self, "ESO DPR TYPE");
00107 }
00108
00109
00110
00121
00122 cpl_boolean irplib_pfits_get_bool_macro(const cpl_propertylist * self,
00123 const char * key, const char * function,
00124 const char * file, unsigned line)
00125 {
00126 cpl_boolean value;
00127 cpl_errorstate prestate = cpl_errorstate_get();
00128
00129 value = cpl_propertylist_get_bool(self, key);
00130
00131 if (cpl_errorstate_is_equal(prestate)) {
00132 cpl_msg_debug(function, "FITS card '%s' [bool]: %c", key,
00133 value ? 'T' : 'F');
00134 } else {
00135
00136 (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
00137 line, "Missing FITS card "
00138 " [bool]: '%s' ", key);
00139 }
00140
00141 return value;
00142 }
00143
00144
00155
00156 double irplib_pfits_get_double_macro(const cpl_propertylist * self,
00157 const char * key,
00158 const char * function,
00159 const char * file,
00160 unsigned line)
00161 {
00162 double value;
00163 cpl_errorstate prestate = cpl_errorstate_get();
00164
00165 value = cpl_propertylist_get_double(self, key);
00166
00167 if (cpl_errorstate_is_equal(prestate)) {
00168 cpl_msg_debug(function, "FITS card '%s' [double]: %g", key, value);
00169 } else {
00170
00171 (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
00172 line, "Missing FITS card "
00173 " [double]: '%s' ", key);
00174 }
00175
00176 return value;
00177 }
00178
00179
00180
00181
00192
00193 int irplib_pfits_get_int_macro(const cpl_propertylist * self,
00194 const char * key, const char * function,
00195 const char * file, unsigned line)
00196 {
00197 int value;
00198 cpl_errorstate prestate = cpl_errorstate_get();
00199
00200 value = cpl_propertylist_get_int(self, key);
00201
00202 if (cpl_errorstate_is_equal(prestate)) {
00203 cpl_msg_debug(function, "FITS card '%s' [int]: %d", key, value);
00204 } else {
00205
00206 (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
00207 line, "Missing FITS card "
00208 " [int]: '%s' ", key);
00209 }
00210
00211 return value;
00212 }
00213
00214
00215
00226
00227 const char * irplib_pfits_get_string_macro(const cpl_propertylist * self,
00228 const char * key,
00229 const char * function,
00230 const char * file,
00231 unsigned line)
00232 {
00233 const char * value;
00234 cpl_errorstate prestate = cpl_errorstate_get();
00235
00236 value = cpl_propertylist_get_string(self, key);
00237
00238 if (cpl_errorstate_is_equal(prestate)) {
00239 cpl_msg_debug(function, "FITS card '%s' [string]: %s", key, value);
00240 } else {
00241
00242 (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
00243 line, "Missing FITS card "
00244 " [string]: '%s' ", key);
00245 }
00246
00247 return value;
00248 }
00249
00250
00251
00252
00253
00260
00261 cpl_error_code irplib_dfs_check_framelist_tag(const irplib_framelist * self,
00262 const char* (*pfind)(const char *,
00263 const char *,
00264 const char *))
00265 {
00266
00267 int i;
00268
00269 if (cpl_error_get_code()) return cpl_error_get_code();
00270
00271 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00272 cpl_ensure_code(pfind != NULL, CPL_ERROR_NULL_INPUT);
00273
00274 for (i = 0; i < irplib_framelist_get_size(self); i++) {
00275 const cpl_frame * frame = irplib_framelist_get_const(self, i);
00276 const cpl_propertylist * plist
00277 = irplib_framelist_get_propertylist_const(self, i);
00278
00279 cpl_ensure_code(frame != NULL, cpl_error_get_code());
00280 cpl_ensure_code(plist != NULL, cpl_error_get_code());
00281
00282 cpl_ensure_code(!irplib_dfs_check_frame_tag(frame, plist, pfind),
00283 cpl_error_get_code());
00284 }
00285
00286 return cpl_error_get_code();
00287
00288 }
00289
00290
00291
00302
00303 int irplib_dfs_find_words(const char * words, const char * format, ...)
00304 {
00305
00306 regex_t re;
00307 va_list ap;
00308 int error, status;
00309
00310
00311 if (cpl_error_get_code()) return -1;
00312
00313 cpl_ensure(words != NULL, CPL_ERROR_NULL_INPUT, -2);
00314 cpl_ensure(format != NULL, CPL_ERROR_NULL_INPUT, -3);
00315
00316
00317 error = regcomp(&re, "^ *%s( +%s)* *$", REG_EXTENDED | REG_NOSUB);
00318
00319
00320 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, -4);
00321
00322 status = regexec(&re, format, (size_t)0, NULL, 0);
00323
00324 regfree(&re);
00325
00326 if (status != 0) {
00327 cpl_msg_error(cpl_func, "Regexp counter must consist of space-separated"
00328 " %%s, not: %s", format);
00329 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, -5);
00330 }
00331
00332 va_start(ap, format);
00333
00334
00335 for (; format != NULL; format = strchr(++format, '%')) {
00336
00337 const char * regexp = va_arg(ap, const char *);
00338
00339 if (regexp == NULL) {
00340 va_end(ap);
00341 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, -6);
00342 }
00343
00344 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
00345
00346 if (error) {
00347 va_end(ap);
00348 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, -7);
00349 }
00350
00351 status = regexec(&re, words, (size_t)0, NULL, 0);
00352
00353 regfree(&re);
00354
00355 if (status != 0) break;
00356
00357 }
00358
00359 va_end(ap);
00360
00361 return format == NULL ? 0 : 1;
00362
00363 }
00364
00365
00373
00374 cpl_error_code irplib_pfits_set_airmass(cpl_propertylist * self,
00375 const irplib_framelist * rawframes)
00376 {
00377
00378 char * newcomment = NULL;
00379 const int nframes = irplib_framelist_get_size(rawframes);
00380 int iframe;
00381 int nmass = 0;
00382 double astart0 = -1.0;
00383 double aend0 = -1.0;
00384 double airmass = 0.0;
00385 cpl_errorstate prestate = cpl_errorstate_get();
00386
00387 skip_if(0);
00388 skip_if(self == NULL);
00389
00390 for (iframe = 0; iframe < nframes; iframe++) {
00391 const cpl_propertylist * plist
00392 = irplib_framelist_get_propertylist_const(rawframes, iframe);
00393 double astart = DBL_MAX;
00394 double aend = DBL_MAX;
00395 double airmi;
00396
00397 if (!cpl_errorstate_is_equal(prestate)) {
00398 irplib_error_recover(prestate, "No propertylist found for frame %d:",
00399 iframe);
00400 continue;
00401 }
00402
00403 if (iframe == 0) {
00404 astart = irplib_pfits_get_double(plist, "ESO TEL AIRM START");
00405 if (cpl_errorstate_is_equal(prestate)) {
00406 astart0 = astart;
00407 aend = irplib_pfits_get_double(plist, "ESO TEL AIRM END");
00408 }
00409 } else {
00410 aend = irplib_pfits_get_double(plist, "ESO TEL AIRM END");
00411 if (cpl_errorstate_is_equal(prestate)) {
00412 if (iframe == nframes - 1) aend0 = aend;
00413 astart = irplib_pfits_get_double(plist, "ESO TEL AIRM START");
00414 }
00415 }
00416
00417 if (cpl_errorstate_is_equal(prestate)) {
00418 airmi = 0.5 * (astart + aend);
00419 } else {
00420 const char * filename = cpl_frame_get_filename(
00421 irplib_framelist_get_const(rawframes, iframe));
00422 irplib_error_recover(prestate, "Could not get FITS key from %s",
00423 filename);
00424
00425 airmi = irplib_pfits_get_double(plist, "AIRMASS");
00426
00427 if (!cpl_errorstate_is_equal(prestate)) {
00428 irplib_error_recover(prestate, "Could not get FITS key from %s",
00429 filename);
00430 continue;
00431 }
00432 }
00433
00434 airmass += airmi;
00435 nmass++;
00436 }
00437
00438 bug_if(0);
00439
00440 if (nmass == 0 && astart0 > 0.0 && aend0 > 0.0) {
00441 airmass = 0.5 * (astart0 + aend0);
00442 nmass = 1;
00443 }
00444 if (nmass > 0) {
00445 const char * key = "AIRMASS";
00446 const char * comment = cpl_propertylist_get_comment(self, key);
00447
00448 irplib_error_recover(prestate, "Could not get FITS key:");
00449
00450 airmass /= (double)nmass;
00451
00452 bug_if(cpl_propertylist_update_double(self, key, airmass));
00453
00454 if (comment == NULL) {
00455 bug_if(cpl_propertylist_set_comment(self, key, "Averaged air mass "
00456 "(Recalculated)"));
00457 } else {
00458 newcomment = cpl_sprintf("%s (Recalculated)",
00459 comment);
00460 bug_if(cpl_propertylist_set_comment(self, key, newcomment));
00461 }
00462
00463 }
00464
00465 end_skip;
00466
00467 cpl_free(newcomment);
00468
00469 return cpl_error_get_code();
00470
00471 }
00472
00476
00484
00485 static cpl_error_code irplib_dfs_check_frame_tag(const cpl_frame * self,
00486 const cpl_propertylist * plist,
00487 const char* (*pfind)
00488 (const char *,
00489 const char *,
00490 const char *))
00491 {
00492
00493 const char * file;
00494 const char * tag;
00495 const char * docatg;
00496 const char * catg;
00497 const char * type;
00498 const char * tech;
00499 cpl_errorstate prestate = cpl_errorstate_get();
00500
00501
00502 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00503
00504 file = cpl_frame_get_filename(self);
00505
00506 cpl_ensure_code(file != NULL, cpl_error_get_code());
00507
00508 tag = cpl_frame_get_tag(self);
00509
00510 cpl_ensure_code(tag != NULL, cpl_error_get_code());
00511
00512 catg = irplib_pfits_get_dpr_catg(plist);
00513 type = irplib_pfits_get_dpr_type(plist);
00514 tech = irplib_pfits_get_dpr_tech(plist);
00515
00516 if (!cpl_errorstate_is_equal(prestate)) {
00517 if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
00518 cpl_msg_warning(cpl_func, "File %s has missing or incomplete DPR "
00519 "triplet", file);
00520 cpl_errorstate_dump(prestate, CPL_FALSE, NULL);
00521 }
00522 cpl_errorstate_set(prestate);
00523 } else {
00524
00525 cpl_ensure_code(pfind != NULL, CPL_ERROR_NULL_INPUT);
00526
00527 docatg = (*pfind)(catg, type, tech);
00528
00529 if (docatg == NULL) {
00530 if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00531 cpl_msg_warning(cpl_func, "File %s has tag %s but unknown DPR "
00532 "triplet: (CATG;TYPE;TECH)=(%s;%s;%s)", file, tag,
00533 catg, type, tech);
00534 } else if (strcmp(tag, docatg) != 0) {
00535 if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00536 cpl_msg_warning(cpl_func, "File %s has tag %s but DPR triplet of "
00537 "%s: (CATG;TYPE;TECH)=(%s;%s;%s)", file, tag,
00538 docatg, catg, type, tech);
00539 }
00540 }
00541
00542 return CPL_ERROR_NONE;
00543
00544 }
00545
00546