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 "irplib_utils.h"
00037 #include "irplib_pfits.h"
00038
00039 #include <cpl.h>
00040
00041 #include <assert.h>
00042 #include <string.h>
00043 #include <sys/types.h>
00044 #include <regex.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
00119
00120 double irplib_pfits_get_double_macro(const cpl_propertylist * self,
00121 const char * key,
00122 const char * function,
00123 const char * file,
00124 unsigned line)
00125 {
00126 double value;
00127 cpl_errorstate prestate = cpl_errorstate_get();
00128
00129 value = cpl_propertylist_get_double(self, key);
00130
00131 if (cpl_errorstate_is_equal(prestate)) {
00132 cpl_msg_debug(function, "FITS card '%s' [double]: %g", key, value);
00133 } else {
00134
00135 (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
00136 line, "Missing FITS card "
00137 " [double]: '%s' ", key);
00138 }
00139
00140 return value;
00141 }
00142
00143
00144
00145
00156
00157 int irplib_pfits_get_int_macro(const cpl_propertylist * self,
00158 const char * key, const char * function,
00159 const char * file, unsigned line)
00160 {
00161 int value;
00162 cpl_errorstate prestate = cpl_errorstate_get();
00163
00164 value = cpl_propertylist_get_int(self, key);
00165
00166 if (cpl_errorstate_is_equal(prestate)) {
00167 cpl_msg_debug(function, "FITS card '%s' [int]: %d", key, value);
00168 } else {
00169
00170 (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
00171 line, "Missing FITS card "
00172 " [int]: '%s' ", key);
00173 }
00174
00175 return value;
00176 }
00177
00178
00179
00190
00191 const char * irplib_pfits_get_string_macro(const cpl_propertylist * self,
00192 const char * key,
00193 const char * function,
00194 const char * file,
00195 unsigned line)
00196 {
00197 const char * value;
00198 cpl_errorstate prestate = cpl_errorstate_get();
00199
00200 value = cpl_propertylist_get_string(self, key);
00201
00202 if (cpl_errorstate_is_equal(prestate)) {
00203 cpl_msg_debug(function, "FITS card '%s' [string]: %s", key, value);
00204 } else {
00205
00206 (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
00207 line, "Missing FITS card "
00208 " [string]: '%s' ", key);
00209 }
00210
00211 return value;
00212 }
00213
00214
00215
00216
00217
00224
00225 cpl_error_code irplib_dfs_check_framelist_tag(const irplib_framelist * self,
00226 const char* (*pfind)(const char *,
00227 const char *,
00228 const char *))
00229 {
00230
00231 int i;
00232
00233 if (cpl_error_get_code()) return cpl_error_get_code();
00234
00235 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00236 cpl_ensure_code(pfind != NULL, CPL_ERROR_NULL_INPUT);
00237
00238 for (i = 0; i < irplib_framelist_get_size(self); i++) {
00239 const cpl_frame * frame = irplib_framelist_get_const(self, i);
00240 const cpl_propertylist * plist
00241 = irplib_framelist_get_propertylist_const(self, i);
00242
00243 cpl_ensure_code(frame != NULL, cpl_error_get_code());
00244 cpl_ensure_code(plist != NULL, cpl_error_get_code());
00245
00246 cpl_ensure_code(!irplib_dfs_check_frame_tag(frame, plist, pfind),
00247 cpl_error_get_code());
00248 }
00249
00250 return cpl_error_get_code();
00251
00252 }
00253
00254
00255
00266
00267 int irplib_dfs_find_words(const char * words, const char * format, ...)
00268 {
00269
00270 regex_t re;
00271 va_list ap;
00272 int error, status;
00273
00274
00275 if (cpl_error_get_code()) return -1;
00276
00277 cpl_ensure(words != NULL, CPL_ERROR_NULL_INPUT, -2);
00278 cpl_ensure(format != NULL, CPL_ERROR_NULL_INPUT, -3);
00279
00280
00281 error = regcomp(&re, "^ *%s( +%s)* *$", REG_EXTENDED | REG_NOSUB);
00282
00283
00284 cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, -4);
00285
00286 status = regexec(&re, format, (size_t)0, NULL, 0);
00287
00288 regfree(&re);
00289
00290 if (status != 0) {
00291 cpl_msg_error(cpl_func, "Regexp counter must consist of space-separated"
00292 " %%s, not: %s", format);
00293 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, -5);
00294 }
00295
00296 va_start(ap, format);
00297
00298
00299 for (; format != NULL; format = strchr(++format, '%')) {
00300
00301 const char * regexp = va_arg(ap, const char *);
00302
00303 if (regexp == NULL) {
00304 va_end(ap);
00305 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, -6);
00306 }
00307
00308 error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
00309
00310 if (error) {
00311 va_end(ap);
00312 cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, -7);
00313 }
00314
00315 status = regexec(&re, words, (size_t)0, NULL, 0);
00316
00317 regfree(&re);
00318
00319 if (status != 0) break;
00320
00321 }
00322
00323 va_end(ap);
00324
00325 return format == NULL ? 0 : 1;
00326
00327 }
00328
00329
00337
00338 cpl_error_code irplib_pfits_set_airmass(cpl_propertylist * self,
00339 const irplib_framelist * rawframes)
00340 {
00341
00342 char * newcomment = NULL;
00343 const int nframes = irplib_framelist_get_size(rawframes);
00344 int iframe;
00345 int nmass = 0;
00346 double astart0 = -1.0;
00347 double aend0 = -1.0;
00348 double airmass = 0.0;
00349 cpl_errorstate prestate = cpl_errorstate_get();
00350
00351 skip_if(0);
00352 skip_if(self == NULL);
00353
00354 for (iframe = 0; iframe < nframes; iframe++) {
00355 const cpl_propertylist * plist
00356 = irplib_framelist_get_propertylist_const(rawframes, iframe);
00357 double astart = DBL_MAX;
00358 double aend = DBL_MAX;
00359 double airmi;
00360
00361 if (!cpl_errorstate_is_equal(prestate)) {
00362 irplib_error_recover(prestate, "No propertylist found for frame %d:",
00363 iframe);
00364 continue;
00365 }
00366
00367 if (iframe == 0) {
00368 astart = irplib_pfits_get_double(plist, "ESO TEL AIRM START");
00369 if (cpl_errorstate_is_equal(prestate)) {
00370 astart0 = astart;
00371 aend = irplib_pfits_get_double(plist, "ESO TEL AIRM END");
00372 }
00373 } else {
00374 aend = irplib_pfits_get_double(plist, "ESO TEL AIRM END");
00375 if (cpl_errorstate_is_equal(prestate)) {
00376 if (iframe == nframes - 1) aend0 = aend;
00377 astart = irplib_pfits_get_double(plist, "ESO TEL AIRM START");
00378 }
00379 }
00380
00381 if (cpl_errorstate_is_equal(prestate)) {
00382 airmi = 0.5 * (astart + aend);
00383 } else {
00384 const char * filename = cpl_frame_get_filename(
00385 irplib_framelist_get_const(rawframes, iframe));
00386 irplib_error_recover(prestate, "Could not get FITS key from %s",
00387 filename);
00388
00389 airmi = irplib_pfits_get_double(plist, "AIRMASS");
00390
00391 if (!cpl_errorstate_is_equal(prestate)) {
00392 irplib_error_recover(prestate, "Could not get FITS key from %s",
00393 filename);
00394 continue;
00395 }
00396 }
00397
00398 airmass += airmi;
00399 nmass++;
00400 }
00401
00402 bug_if(0);
00403
00404 if (nmass == 0 && astart0 > 0.0 && aend0 > 0.0) {
00405 airmass = 0.5 * (astart0 + aend0);
00406 nmass = 1;
00407 }
00408 if (nmass > 0) {
00409 const char * key = "AIRMASS";
00410 const char * comment = cpl_propertylist_get_comment(self, key);
00411
00412 cpl_errorstate_set(prestate);
00413
00414 airmass /= (double)nmass;
00415
00416 bug_if(cpl_propertylist_update_double(self, key, airmass));
00417
00418 if (comment == NULL) {
00419 bug_if(cpl_propertylist_set_comment(self, key, "Averaged air mass "
00420 "(Recalculated)"));
00421 } else {
00422 newcomment = cpl_sprintf("%s (Recalculated)",
00423 comment);
00424 bug_if(cpl_propertylist_set_comment(self, key, newcomment));
00425 }
00426
00427 }
00428
00429 end_skip;
00430
00431 cpl_free(newcomment);
00432
00433 return cpl_error_get_code();
00434
00435 }
00436
00440
00448
00449 static cpl_error_code irplib_dfs_check_frame_tag(const cpl_frame * self,
00450 const cpl_propertylist * plist,
00451 const char* (*pfind)
00452 (const char *,
00453 const char *,
00454 const char *))
00455 {
00456
00457 const char * file;
00458 const char * tag;
00459 const char * catg;
00460 const char * type;
00461 const char * tech;
00462 cpl_errorstate prestate = cpl_errorstate_get();
00463
00464
00465 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00466
00467 file = cpl_frame_get_filename(self);
00468
00469 cpl_ensure_code(file != NULL, cpl_error_get_code());
00470
00471 tag = cpl_frame_get_tag(self);
00472
00473 cpl_ensure_code(tag != NULL, cpl_error_get_code());
00474
00475 catg = irplib_pfits_get_dpr_catg(plist);
00476 type = irplib_pfits_get_dpr_type(plist);
00477 tech = irplib_pfits_get_dpr_tech(plist);
00478
00479 if (!cpl_errorstate_is_equal(prestate)) {
00480 if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
00481 cpl_msg_warning(cpl_func, "File %s has missing or incomplete DPR "
00482 "triplet", file);
00483 cpl_errorstate_dump(prestate, CPL_FALSE, NULL);
00484 }
00485 cpl_errorstate_set(prestate);
00486 } else {
00487 const char * docatg;
00488
00489 cpl_ensure_code(pfind != NULL, CPL_ERROR_NULL_INPUT);
00490
00491 docatg = (*pfind)(catg, type, tech);
00492
00493 if (docatg == NULL) {
00494 if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00495 cpl_msg_warning(cpl_func, "File %s has tag %s but unknown DPR "
00496 "triplet: (CATG;TYPE;TECH)=(%s;%s;%s)", file, tag,
00497 catg, type, tech);
00498 } else if (strcmp(tag, docatg) != 0) {
00499 if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00500 cpl_msg_warning(cpl_func, "File %s has tag %s but DPR triplet of "
00501 "%s: (CATG;TYPE;TECH)=(%s;%s;%s)", file, tag,
00502 docatg, catg, type, tech);
00503 }
00504 }
00505
00506 return CPL_ERROR_NONE;
00507
00508 }
00509
00510