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