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 #include <fors_dfs.h>
00033
00034 #include <fors_utils.h>
00035 #include <fors_image.h>
00036 #include <fors_pfits.h>
00037
00038 #include <cpl.h>
00039
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <ctype.h>
00043 #include <stdbool.h>
00044 #include <string.h>
00045 #include <unistd.h>
00046
00047
00054
00055
00058 #define WCS_KEYS "^((CRVAL|CRPIX|CTYPE|CDELT)[0-9]|RADECSYS|CD[0-9]_[0-9])$"
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 static char *strlower(char *s)
00070 {
00071
00072 char *t = s;
00073
00074 while (*t) {
00075 *t = tolower(*t);
00076 t++;
00077 }
00078
00079 return s;
00080
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 char *dfs_generate_filename(const char *category)
00106 {
00107 char *filename = cpl_calloc(strlen(category) + 6, sizeof(char));
00108
00109 strlower(strcpy(filename, category));
00110 strcat(filename, ".fits");
00111
00112 return filename;
00113 }
00114
00115
00116
00117 char *dfs_generate_filename_tfits(const char *category)
00118 {
00119
00120
00121
00122 char *filename = cpl_calloc(strlen(category) + 6, sizeof(char));
00123
00124 strlower(strcpy(filename, category));
00125
00126
00127
00128
00129 strcat(filename, ".fits");
00130
00131 return filename;
00132 }
00133
00134
00145
00146 static void
00147 errorstate_dump_one(unsigned self, unsigned first, unsigned last)
00148 {
00149
00150 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
00151 const unsigned newest = is_reverse ? first : last;
00152 const unsigned oldest = is_reverse ? last : first;
00153 const char * revmsg = is_reverse ? " in reverse order" : "";
00154
00155
00156
00157
00158
00159 if (newest == 0) {
00160 cpl_msg_info(cpl_func, "No error(s) to dump");
00161
00162 } else {
00163
00164
00165 if (self == first) {
00166 if (oldest == 1) {
00167 cpl_msg_debug(cpl_func, "Dumping all %u error(s)%s:", newest,
00168 revmsg);
00169 } else {
00170 cpl_msg_error(cpl_func, "Dumping the %u most recent error(s) "
00171 "out of a total of %u errors%s:",
00172 newest - oldest + 1, newest, revmsg);
00173 }
00174 }
00175
00176 const char *message_from_cpl = cpl_error_get_message();
00177
00178 if (message_from_cpl == NULL) {
00179
00180 cpl_msg_error(cpl_func, "Unspecified error");
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 while (*message_from_cpl != '\0' && *message_from_cpl != ':') {
00190 message_from_cpl += 1;
00191 }
00192
00193 if (*message_from_cpl != '\0') {
00194 message_from_cpl += 1;
00195
00196 if (*message_from_cpl == ' ') message_from_cpl++;
00197
00198 if (*message_from_cpl != '\0') {
00199
00200 cpl_msg_error(cpl_func, "%s [%s]", message_from_cpl,
00201 cpl_error_get_where());
00202 }
00203 else {
00204 cpl_msg_error(cpl_func, "%s [%s]",
00205 cpl_error_get_message(), cpl_error_get_where());
00206 }
00207 }
00208 else {
00209
00210 cpl_msg_error(cpl_func, "%s [%s]",
00211 cpl_error_get_message(), cpl_error_get_where());
00212 }
00213 }
00214
00215 return;
00216 }
00217
00218
00219
00229
00230 void fors_begin(cpl_frameset *frames,
00231 const char *description_short)
00232 {
00233 cpl_msg_info(cpl_func, "%s", PACKAGE_STRING);
00234 cpl_msg_info(cpl_func, "%s", description_short);
00235
00236 fors_dfs_set_groups(frames);
00237 cpl_msg_info(cpl_func, "Input frame%s:",
00238 cpl_frameset_get_size(frames) != 1 ? "s" : "");
00239 fors_frameset_print(frames);
00240
00241 return;
00242 }
00243
00244
00257
00258 int fors_end(const cpl_frameset *frames, cpl_errorstate before_exec)
00259 {
00260 if (cpl_error_get_code() == CPL_ERROR_NONE) {
00261
00262 const cpl_frame *f;
00263
00264 cpl_msg_info(cpl_func, "Product frame%s:",
00265 cpl_frameset_get_size(frames) != 1 ? "s" : "");
00266
00267 for (f = cpl_frameset_get_first_const(frames);
00268 f != NULL;
00269 f = cpl_frameset_get_next_const(frames)) {
00270 if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_PRODUCT) {
00271 fors_frame_print(f);
00272 }
00273 }
00274
00275
00276
00277 return 0;
00278 }
00279 else {
00280
00281 cpl_errorstate_dump(before_exec, CPL_FALSE, errorstate_dump_one);
00282
00283 return 1;
00284 }
00285 }
00286
00287 #undef cleanup
00288 #define cleanup
00289
00294
00295 void
00296 fors_dfs_set_groups(cpl_frameset * set)
00297 {
00298 cpl_frame *f;
00299
00300 assure( set != NULL, return, NULL );
00301
00302 for (f = cpl_frameset_get_first(set);
00303 f != NULL;
00304 f = cpl_frameset_get_next(set)) {
00305
00306 const char *tag = cpl_frame_get_tag(f);
00307
00308 if (tag != NULL) {
00309 if (strcmp(tag, BIAS ) == 0 ||
00310 strcmp(tag, DARK ) == 0 ||
00311 strcmp(tag, SCREEN_FLAT_IMG ) == 0 ||
00312 strcmp(tag, SKY_FLAT_IMG ) == 0 ||
00313 strcmp(tag, STANDARD_IMG ) == 0 ||
00314 strcmp(tag, "LAMP_PMOS" ) == 0 ||
00315 strcmp(tag, "SCREEN_FLAT_PMOS") == 0 ||
00316 strcmp(tag, "STANDARD_PMOS" ) == 0 ||
00317 strcmp(tag, "SCIENCE_PMOS" ) == 0 ||
00318 strcmp(tag, SCIENCE_IMG ) == 0 ) {
00319 cpl_frame_set_group(f, CPL_FRAME_GROUP_RAW);
00320 }
00321 else if (strcmp(tag, MASTER_BIAS ) == 0 ||
00322 strcmp(tag, MASTER_DARK ) == 0 ||
00323 strcmp(tag, MASTER_SCREEN_FLAT_IMG ) == 0 ||
00324 strcmp(tag, MASTER_SKY_FLAT_IMG ) == 0 ||
00325 strcmp(tag, ALIGNED_PHOT ) == 0 ||
00326 strcmp(tag, "MASTER_NORM_FLAT_PMOS" ) == 0 ||
00327 strcmp(tag, "DISP_COEFF_PMOS" ) == 0 ||
00328 strcmp(tag, "CURV_COEFF_PMOS" ) == 0 ||
00329 strcmp(tag, "SLIT_LOCATION_PMOS" ) == 0 ||
00330
00331 strcmp(tag, FLX_STD_IMG ) == 0 ||
00332 strcmp(tag, "MASTER_LINECAT" ) == 0 ||
00333 strcmp(tag, "MASTER_DISTORTION_TABLE" ) == 0 ||
00334 strcmp(tag, "RETARDER_WAVEPLATE_CHROMATISM") == 0 ||
00335 strcmp(tag, "GRISM_TABLE" ) == 0 ||
00336 strcmp(tag, "STD_PMOS_TABLE" ) == 0 ||
00337 strcmp(tag, PHOT_TABLE ) == 0) {
00338 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
00339 }
00340 else {
00341 cpl_msg_warning(cpl_func, "Unrecognized frame tag: '%s'",
00342 tag);
00343 }
00344 }
00345 }
00346
00347 return;
00348 }
00349
00350
00351 #undef cleanup
00352 #define cleanup
00353
00361
00362 const char *
00363 fors_dfs_pipeline_version(const cpl_propertylist *header,
00364 const char **instrument_version)
00365 {
00366 const char *instrume = NULL;
00367
00368 instrume = cpl_propertylist_get_string(header,
00369 FORS_PFITS_INSTRUME);
00370 assure( !cpl_error_get_code(), return NULL,
00371 "Missing keyword %s in input header", FORS_PFITS_INSTRUME);
00372
00373 assure( strlen(instrume) >= 5, return NULL,
00374 "%s keyword must be 'fors1' or 'fors2', not '%s'",
00375 FORS_PFITS_INSTRUME, instrume);
00376
00377 assure( instrume[4] == '1' || instrume[4] == '2', return NULL,
00378 "Unrecognized %s: %s", FORS_PFITS_INSTRUME, instrume);
00379
00380 if (instrument_version != NULL) {
00381 *instrument_version = cpl_sprintf("%s", instrume);
00382 }
00383
00384 return cpl_sprintf("fors%c/%s", instrume[4], VERSION);
00385 }
00386
00387
00409
00410 int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name,
00411 const cpl_table *defaults)
00412 {
00413 const char *func = "dfs_get_parameter_int";
00414
00415 const char *alias;
00416 cpl_parameter *param;
00417
00418
00419 if (parlist == NULL) {
00420 cpl_msg_error(func, "Missing input parameter list");
00421 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00422 return 0;
00423 }
00424
00425 if (name == NULL) {
00426 cpl_msg_error(func, "Missing input parameter name");
00427 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00428 return 0;
00429 }
00430
00431 param = cpl_parameterlist_find(parlist, name);
00432
00433 if (param == NULL) {
00434 cpl_msg_error(func, "Wrong parameter name: %s", name);
00435 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00436 return 0;
00437 }
00438
00439 if (cpl_parameter_get_type(param) != CPL_TYPE_INT) {
00440 cpl_msg_error(func, "Unexpected type for parameter "
00441 "\"%s\": it should be integer", name);
00442 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00443 return 0;
00444 }
00445
00446 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00447
00448
00449 if (defaults &&
00450 cpl_parameter_get_default_int(param) == cpl_parameter_get_int(param)) {
00451
00452 if (cpl_table_has_column(defaults, alias)) {
00453 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00454 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00455 "column \"%s\": it should be integer", alias);
00456 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00457 return 0;
00458 }
00459 if (cpl_table_is_valid(defaults, alias, 0)) {
00460 cpl_parameter_set_int(param, cpl_table_get_int(defaults,
00461 alias, 0, NULL));
00462 }
00463 else {
00464 cpl_msg_error(func, "Invalid parameter value in table "
00465 "column \"%s\"", alias);
00466 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00467 return 0;
00468 }
00469 }
00470 else {
00471 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00472 "- using recipe default", alias);
00473 }
00474 }
00475
00476 cpl_msg_info(func, "%s:", alias);
00477 cpl_msg_info(func, "%s: %d",
00478 cpl_parameter_get_help(param), cpl_parameter_get_int(param));
00479
00480 return cpl_parameter_get_int(param);
00481
00482 }
00483
00484
00506
00507 double dfs_get_parameter_double(cpl_parameterlist *parlist,
00508 const char *name, const cpl_table *defaults)
00509 {
00510 const char *func = "dfs_get_parameter_double";
00511
00512 const char *alias;
00513 cpl_parameter *param;
00514
00515
00516 if (parlist == NULL) {
00517 cpl_msg_error(func, "Missing input parameter list");
00518 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00519 return 0;
00520 }
00521
00522 if (name == NULL) {
00523 cpl_msg_error(func, "Missing input parameter name");
00524 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00525 return 0;
00526 }
00527
00528 param = cpl_parameterlist_find(parlist, name);
00529
00530 if (param == NULL) {
00531 cpl_msg_error(func, "Wrong parameter name: %s", name);
00532 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00533 return 0;
00534 }
00535
00536 if (cpl_parameter_get_type(param) != CPL_TYPE_DOUBLE) {
00537 cpl_msg_error(func, "Unexpected type for parameter "
00538 "\"%s\": it should be double", name);
00539 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00540 return 0;
00541 }
00542
00543 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00544
00545
00546 if (defaults &&
00547 cpl_parameter_get_default_double(param) ==
00548 cpl_parameter_get_double(param)) {
00549
00550 if (cpl_table_has_column(defaults, alias)) {
00551 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_DOUBLE) {
00552 cpl_msg_error(func, "Unexpected type for GRISM_TABL "
00553 "column \"%s\": it should be double", alias);
00554 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00555 return 0;
00556 }
00557 if (cpl_table_is_valid(defaults, alias, 0)) {
00558 cpl_parameter_set_double(param, cpl_table_get_double(defaults,
00559 alias, 0, NULL));
00560 }
00561 else {
00562 cpl_msg_error(func, "Invalid parameter value in table "
00563 "column \"%s\"", alias);
00564 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00565 return 0;
00566 }
00567 }
00568 else {
00569 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00570 "- using recipe default", alias);
00571 }
00572 }
00573
00574 cpl_msg_info(func, "%s:", alias);
00575 cpl_msg_info(func, "%s: %f",
00576 cpl_parameter_get_help(param), cpl_parameter_get_double(param));
00577
00578 return cpl_parameter_get_double(param);
00579
00580 }
00581
00582
00604
00605 const char *dfs_get_parameter_string(cpl_parameterlist *parlist,
00606 const char *name,
00607 const cpl_table *defaults)
00608 {
00609 const char *func = "dfs_get_parameter_string";
00610
00611 const char *alias;
00612 cpl_parameter *param;
00613
00614
00615 if (parlist == NULL) {
00616 cpl_msg_error(func, "Missing input parameter list");
00617 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00618 return 0;
00619 }
00620
00621 if (name == NULL) {
00622 cpl_msg_error(func, "Missing input parameter name");
00623 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00624 return 0;
00625 }
00626
00627 param = cpl_parameterlist_find(parlist, name);
00628
00629 if (param == NULL) {
00630 cpl_msg_error(func, "Wrong parameter name: %s", name);
00631 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00632 return 0;
00633 }
00634
00635 if (cpl_parameter_get_type(param) != CPL_TYPE_STRING) {
00636 cpl_msg_error(func, "Unexpected type for parameter "
00637 "\"%s\": it should be string", name);
00638 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00639 return 0;
00640 }
00641
00642 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00643
00644
00645 if (defaults &&
00646 strcmp(cpl_parameter_get_default_string(param),
00647 cpl_parameter_get_string(param)) == 0) {
00648
00649 if (cpl_table_has_column(defaults, alias)) {
00650 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_STRING) {
00651 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00652 "column \"%s\": it should be string", alias);
00653 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00654 return 0;
00655 }
00656 if (cpl_table_is_valid(defaults, alias, 0)) {
00657 cpl_parameter_set_string(param, cpl_table_get_string(defaults,
00658 alias, 0));
00659 }
00660 else {
00661 cpl_msg_error(func, "Invalid parameter value in table "
00662 "column \"%s\"", alias);
00663 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00664 return 0;
00665 }
00666 }
00667 else {
00668 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00669 "- using recipe default", alias);
00670 }
00671 }
00672
00673 cpl_msg_info(func, "%s:", alias);
00674 cpl_msg_info(func, "%s: %s", cpl_parameter_get_help(param),
00675 cpl_parameter_get_string(param));
00676
00677 return cpl_parameter_get_string(param);
00678
00679 }
00680
00681
00703
00704 int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name,
00705 const cpl_table *defaults)
00706 {
00707 const char *func = "dfs_get_parameter_bool";
00708
00709 const char *alias;
00710 cpl_parameter *param;
00711 int value;
00712
00713
00714 if (parlist == NULL) {
00715 cpl_msg_error(func, "Missing input parameter list");
00716 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00717 return 0;
00718 }
00719
00720 if (name == NULL) {
00721 cpl_msg_error(func, "Missing input parameter name");
00722 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00723 return 0;
00724 }
00725
00726 param = cpl_parameterlist_find(parlist, name);
00727
00728 if (param == NULL) {
00729 cpl_msg_error(func, "Wrong parameter name: %s", name);
00730 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00731 return 0;
00732 }
00733
00734 if (cpl_parameter_get_type(param) != CPL_TYPE_BOOL) {
00735 cpl_msg_error(func, "Unexpected type for parameter "
00736 "\"%s\": it should be boolean", name);
00737 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00738 return 0;
00739 }
00740
00741 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00742
00743
00744 if (defaults &&
00745 cpl_parameter_get_default_bool(param) ==
00746 cpl_parameter_get_bool(param)) {
00747
00748 if (cpl_table_has_column(defaults, alias)) {
00749 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00750 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00751 "column \"%s\": it should be integer", alias);
00752 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00753 return 0;
00754 }
00755 if (cpl_table_is_valid(defaults, alias, 0)) {
00756 value = cpl_table_get_int(defaults, alias, 0, NULL);
00757 if (value < 0 || value > 1) {
00758 cpl_msg_error(func, "Illegal parameter value in table "
00759 "column \"%s\": it should be either 0 or 1",
00760 alias);
00761 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00762 return 0;
00763 }
00764 cpl_parameter_set_bool(param, value);
00765 }
00766 else {
00767 cpl_msg_error(func, "Invalid parameter value in table "
00768 "column \"%s\"", alias);
00769 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00770 return 0;
00771 }
00772 }
00773 else {
00774 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00775 "- using recipe default", alias);
00776 }
00777 }
00778
00779 value = cpl_parameter_get_bool(param);
00780
00781 if (value) {
00782 cpl_msg_info(func, "%s:", alias);
00783 cpl_msg_info(func, "%s: TRUE", cpl_parameter_get_help(param));
00784 }
00785 else {
00786 cpl_msg_info(func, "%s:", alias);
00787 cpl_msg_info(func, "%s: FALSE", cpl_parameter_get_help(param));
00788 }
00789
00790 return value;
00791
00792 }
00793
00794
00798
00799 int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
00800 {
00801 return dfs_get_parameter_bool((cpl_parameterlist *)parlist, name, NULL);
00802 }
00803
00804
00808
00809 int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
00810 {
00811 return dfs_get_parameter_int((cpl_parameterlist *)parlist, name, NULL);
00812 }
00813
00814
00818
00819 double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
00820 {
00821 return dfs_get_parameter_double((cpl_parameterlist *)parlist, name, NULL);
00822 }
00823
00824
00828
00829 const char *dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
00830 {
00831 return dfs_get_parameter_string((cpl_parameterlist *)parlist, name, NULL);
00832 }
00833
00834
00862
00863 cpl_image *dfs_load_image(cpl_frameset *frameset, const char *category,
00864 cpl_type type, int ext, int calib)
00865 {
00866 const char *func = "dfs_load_image";
00867
00868 cpl_frame *frame = NULL;
00869 cpl_image *image = NULL;
00870
00871
00872 frame = cpl_frameset_find(frameset, category);
00873
00874 if (frame) {
00875 image = cpl_image_load(cpl_frame_get_filename(frame), type, 0, ext);
00876 if (image == NULL) {
00877 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00878 cpl_msg_error(func, "Cannot load image %s",
00879 cpl_frame_get_filename(frame));
00880 }
00881 else {
00882 if (calib)
00883 cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
00884 else
00885 cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
00886 }
00887 }
00888
00889 return image;
00890 }
00891
00892
00918
00919 cpl_table *dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
00920 {
00921 const char *func = "dfs_load_table";
00922
00923 cpl_frame *frame = NULL;
00924 cpl_table *table = NULL;
00925
00926
00927 frame = cpl_frameset_find(frameset, category);
00928
00929 if (frame) {
00930 table = cpl_table_load(cpl_frame_get_filename(frame), ext, 1);
00931 if (table == NULL) {
00932 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00933 cpl_msg_error(func, "Cannot load table %s",
00934 cpl_frame_get_filename(frame));
00935 }
00936 else
00937 cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
00938 }
00939
00940 return table;
00941 }
00942
00943
00968
00969 cpl_propertylist *dfs_load_header(cpl_frameset *frameset,
00970 const char *category, int ext)
00971 {
00972 const char *func = "dfs_load_header";
00973
00974 cpl_frame *frame = NULL;
00975 cpl_propertylist *plist = NULL;
00976
00977
00978 frame = cpl_frameset_find(frameset, category);
00979
00980 if (frame) {
00981 plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext);
00982 if (plist == NULL) {
00983 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00984 cpl_msg_error(func, "Cannot load header from %s",
00985 cpl_frame_get_filename(frame));
00986 }
00987 }
00988
00989 return plist;
00990 }
00991
00992
00999
01000 static void
01001 dfs_save(cpl_frameset *frameset, const void *object, cpl_frame_type type,
01002 const char *category, cpl_propertylist *header,
01003 const cpl_parameterlist *parlist, const char *recipename,
01004 const cpl_frame *raw_frame)
01005 {
01006 char *filename;
01007 cpl_frame *frame;
01008 cpl_propertylist *plist;
01009 const char *version = NULL;
01010 cpl_propertylist *raw_header = NULL;
01011
01012
01013 if (category == NULL || frameset == NULL || object == NULL ||
01014 raw_frame == NULL) {
01015 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01016 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
01017 return;
01018 }
01019
01020 if (type == CPL_FRAME_TYPE_IMAGE) {
01021 cpl_msg_debug(cpl_func, "Saving %s image to disk...", category);
01022 }
01023 else {
01024 cpl_msg_debug(cpl_func, "Saving %s table to disk...", category);
01025 }
01026
01027
01028 {
01029 const char *raw_filename =
01030 cpl_frame_get_filename(raw_frame);
01031
01032 raw_header = cpl_propertylist_load(raw_filename, 0);
01033 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01034 cpl_msg_error(cpl_func, "Could not read %s primary header", raw_filename);
01035 return;
01036 }
01037
01038 version = fors_dfs_pipeline_version(raw_header, NULL);
01039 cpl_propertylist_delete(raw_header);
01040
01041 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01042 cpl_msg_error(cpl_func, "Could not identify instrument version from %s header",
01043 raw_filename);
01044 return;
01045 }
01046 }
01047
01048 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01049
01050 strlower(strcpy(filename, category));
01051 strcat(filename, ".fits");
01052
01053 frame = cpl_frame_new();
01054
01055 cpl_frame_set_filename(frame, filename);
01056 cpl_frame_set_tag(frame, category);
01057 cpl_frame_set_type(frame, type);
01058 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01059 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01060 if (cpl_error_get_code()) {
01061 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01062 cpl_msg_error(cpl_func, "Cannot initialise the product frame");
01063 cpl_frame_delete(frame);
01064 cpl_free(filename);
01065 cpl_free((void *)version);
01066 return;
01067 }
01068
01069
01070
01071
01072
01073
01074 if (header == NULL)
01075 plist = cpl_propertylist_new();
01076 else
01077 plist = header;
01078
01079 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
01080 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01081 recipename, version, "PRO-1.15", NULL)) {
01082 #else
01083 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01084 recipename, version, "PRO-1.15")) {
01085 #endif
01086 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01087 cpl_msg_error(cpl_func, "Problem with product %s FITS header definition",
01088 category);
01089 if (header == NULL)
01090 cpl_propertylist_delete(plist);
01091 cpl_frame_delete(frame);
01092 cpl_free(filename);
01093 cpl_free((void *)version);
01094 return;
01095 }
01096
01097 cpl_free((void *)version);
01098
01099
01100
01101
01102
01103
01104 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01105 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01106 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01107 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01108
01109
01110
01111
01112
01113 if (type == CPL_FRAME_TYPE_IMAGE) {
01114 fors_image_save((fors_image *)object, plist, filename);
01115 }
01116 else {
01117 cpl_table_save((cpl_table *)object,
01118 plist, NULL, filename, CPL_IO_DEFAULT);
01119 }
01120
01121 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01122 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01123 cpl_msg_error(cpl_func, "Cannot save product %s to disk", filename);
01124 if (header == NULL)
01125 cpl_propertylist_delete(plist);
01126 cpl_frame_delete(frame);
01127 cpl_free(filename);
01128 return;
01129 }
01130
01131 if (header == NULL)
01132 cpl_propertylist_delete(plist);
01133
01134 cpl_free(filename);
01135
01136 cpl_frameset_insert(frameset, frame);
01137
01138 return;
01139 }
01140
01141
01162
01163 void
01164 fors_dfs_save_image(cpl_frameset *frameset, const fors_image *image,
01165 const char *category, cpl_propertylist *header,
01166 const cpl_parameterlist *parlist, const char *recipename,
01167 const cpl_frame *raw_frame)
01168 {
01169 dfs_save(frameset, image, CPL_FRAME_TYPE_IMAGE,
01170 category, header,
01171 parlist, recipename,
01172 raw_frame);
01173 }
01174
01175 #undef cleanup
01176 #define cleanup \
01177 do { \
01178 cpl_propertylist_delete(wcs_header); \
01179 } while (0)
01180
01185 void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame,
01186 const fors_setting *setting)
01187 {
01188 bool invert = false;
01189 int extension = 0;
01190
01191 cpl_propertylist *wcs_header =
01192 cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
01193 extension, WCS_KEYS, invert);
01194
01195 cpl_propertylist_copy_property_regexp(header, wcs_header, ".*", invert);
01196
01197 double crpix1 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX1);
01198
01199 assure( !cpl_error_get_code(), return,
01200 "Could not read %s from %s", FORS_PFITS_CRPIX1,
01201 cpl_frame_get_filename(frame));
01202
01203 double crpix2 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX2);
01204
01205 assure( !cpl_error_get_code(), return,
01206 "Could not read %s from %s", FORS_PFITS_CRPIX2,
01207 cpl_frame_get_filename(frame));
01208
01209 cpl_propertylist_update_double(header, FORS_PFITS_CRPIX1,
01210 crpix1 - setting->prescan_x);
01211
01212 cpl_propertylist_update_double(header, FORS_PFITS_CRPIX2,
01213 crpix2 - setting->prescan_y);
01214
01215
01216 cleanup;
01217 return;
01218 }
01219
01220
01221 #undef cleanup
01222 #define cleanup \
01223 do { \
01224 cpl_propertylist_delete(time_header); \
01225 } while (0)
01226
01238
01239 void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame,
01240 double exptime)
01241 {
01242 bool invert = false;
01243 int extension = 0;
01244
01245 cpl_propertylist *time_header = NULL;
01246
01247 if (frame) {
01248
01249 time_header =
01250 cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
01251 extension, "EXPTIME", invert);
01252
01253 if (time_header) {
01254 cpl_propertylist_copy_property_regexp(header,
01255 time_header, ".*", invert);
01256 }
01257 else {
01258 cpl_error_reset();
01259 }
01260 }
01261 else {
01262 while (cpl_propertylist_erase(header, "EXPTIME"));
01263 cpl_propertylist_update_double(header, "EXPTIME", exptime);
01264 }
01265
01266 cleanup;
01267 return;
01268 }
01269
01270
01277
01278 void
01279 fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
01280 const char *category, cpl_propertylist *header,
01281 const cpl_parameterlist *parlist, const char *recipename,
01282 const cpl_frame *raw_frame)
01283 {
01284 dfs_save(frameset, table, CPL_FRAME_TYPE_TABLE,
01285 category, header,
01286 parlist, recipename,
01287 raw_frame);
01288 }
01289
01290
01322
01323 int dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
01324 const char *category, cpl_propertylist *header,
01325 const cpl_parameterlist *parlist, const char *recipename,
01326 const char *version)
01327 {
01328 const char *func = "dfs_save_image";
01329
01330 char *filename;
01331 cpl_frame *frame;
01332 cpl_propertylist *plist;
01333
01334
01335 if (category == NULL || frameset == NULL || image == NULL) {
01336 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01337 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01338 return -1;
01339 }
01340
01341 cpl_msg_info(func, "Saving %s image to disk...", category);
01342
01343 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01344
01345 strlower(strcpy(filename, category));
01346 strcat(filename, ".fits");
01347
01348 frame = cpl_frame_new();
01349
01350 cpl_frame_set_filename(frame, filename);
01351 cpl_frame_set_tag(frame, category);
01352 cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE);
01353 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01354 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01355 if (cpl_error_get_code()) {
01356 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01357 cpl_msg_error(func, "Cannot initialise the product frame");
01358 cpl_frame_delete(frame);
01359 cpl_free(filename);
01360 return -1;
01361 }
01362
01363
01364
01365
01366
01367
01368 if (header == NULL)
01369 plist = cpl_propertylist_new();
01370 else
01371 plist = header;
01372
01373 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
01374 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01375 recipename, version, "PRO-1.15", NULL)) {
01376 #else
01377 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01378 recipename, version, "PRO-1.15")) {
01379 #endif
01380 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01381 cpl_msg_error(func, "Problem with product %s FITS header definition",
01382 category);
01383 if (header == NULL)
01384 cpl_propertylist_delete(plist);
01385 cpl_frame_delete(frame);
01386 cpl_free(filename);
01387 return -1;
01388 }
01389
01390
01391
01392
01393
01394
01395 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01396 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01397 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01398 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01399
01400
01401
01402
01403
01404 if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist,
01405 CPL_IO_DEFAULT)) {
01406 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01407 cpl_msg_error(func, "Cannot save product %s to disk", filename);
01408 if (header == NULL)
01409 cpl_propertylist_delete(plist);
01410 cpl_frame_delete(frame);
01411 cpl_free(filename);
01412 return -1;
01413 }
01414
01415 if (header == NULL)
01416 cpl_propertylist_delete(plist);
01417
01418 cpl_free(filename);
01419
01420 cpl_frameset_insert(frameset, frame);
01421
01422 return 0;
01423 }
01424
01425
01457
01458 int dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
01459 const char *category, cpl_propertylist *header,
01460 const cpl_parameterlist *parlist, const char *recipename,
01461 const char *version)
01462 {
01463 const char *func = "dfs_save_table";
01464
01465 char *filename;
01466 cpl_frame *frame;
01467 cpl_propertylist *plist;
01468
01469
01470 if (category == NULL || frameset == NULL || table == NULL) {
01471 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01472 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01473 return -1;
01474 }
01475
01476 cpl_msg_info(func, "Saving %s table to disk...", category);
01477
01478
01479
01480
01481 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01482
01483 strlower(strcpy(filename, category));
01484
01485
01486
01487
01488 strcat(filename, ".fits");
01489
01490 frame = cpl_frame_new();
01491
01492 cpl_frame_set_filename(frame, filename);
01493 cpl_frame_set_tag(frame, category);
01494 cpl_frame_set_type(frame, CPL_FRAME_TYPE_TABLE);
01495 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01496 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01497 if (cpl_error_get_code()) {
01498 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01499 cpl_msg_error(func, "Cannot initialise the product frame");
01500 cpl_frame_delete(frame);
01501 cpl_free(filename);
01502 return -1;
01503 }
01504
01505
01506
01507
01508
01509
01510 if (header == NULL)
01511 plist = cpl_propertylist_new();
01512 else
01513 plist = header;
01514
01515 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
01516 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01517 recipename, version, "PRO-1.15", NULL)) {
01518 #else
01519 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01520 recipename, version, "PRO-1.15")) {
01521 #endif
01522 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01523 cpl_msg_error(func, "Problem with product %s FITS header definition",
01524 category);
01525 if (header == NULL)
01526 cpl_propertylist_delete(plist);
01527 cpl_frame_delete(frame);
01528 cpl_free(filename);
01529 return -1;
01530 }
01531
01532
01533
01534
01535
01536
01537 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01538 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01539 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01540 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01541
01542
01543
01544
01545
01546
01547 if (cpl_table_save(table, plist, NULL, filename, CPL_IO_DEFAULT)) {
01548 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01549 cpl_msg_error(func, "Cannot save product %s to disk", filename);
01550 if (header == NULL)
01551 cpl_propertylist_delete(plist);
01552 cpl_frame_delete(frame);
01553 cpl_free(filename);
01554 return -1;
01555 }
01556
01557 if (header == NULL)
01558 cpl_propertylist_delete(plist);
01559 cpl_free(filename);
01560
01561 cpl_frameset_insert(frameset, frame);
01562
01563 return 0;
01564 }
01565
01566
01576
01577 int dfs_files_dont_exist(cpl_frameset *frameset)
01578 {
01579 const char *func = "dfs_files_dont_exist";
01580 cpl_frame *frame;
01581
01582
01583 if (frameset == NULL) {
01584 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01585 return 1;
01586 }
01587
01588 if (cpl_frameset_is_empty(frameset)) {
01589 return 0;
01590 }
01591
01592 frame = cpl_frameset_get_first(frameset);
01593
01594 while (frame) {
01595 if (access(cpl_frame_get_filename(frame), F_OK)) {
01596 cpl_msg_error(func, "File %s (%s) was not found",
01597 cpl_frame_get_filename(frame),
01598 cpl_frame_get_tag(frame));
01599 cpl_error_set(func, CPL_ERROR_FILE_NOT_FOUND);
01600 }
01601
01602 frame = cpl_frameset_get_next(frameset);
01603 }
01604
01605 if (cpl_error_get_code())
01606 return 1;
01607
01608 return 0;
01609 }
01610
01611
01628
01629 int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
01630 {
01631 const char *func = "dfs_equal_keyword";
01632
01633 cpl_frame *frame;
01634 cpl_propertylist *reference;
01635 cpl_type rtype;
01636 cpl_type type;
01637 const char *rstring;
01638 const char *string;
01639 int rintero;
01640 int intero;
01641 int found;
01642
01643
01644 if (frameset == NULL || keyword == NULL) {
01645 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01646 return 0;
01647 }
01648
01649 if (cpl_frameset_is_empty(frameset)) {
01650 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
01651 return 0;
01652 }
01653
01654 frame = cpl_frameset_get_first(frameset);
01655
01656 found = 0;
01657
01658 while (frame) {
01659
01660 reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01661 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01662 cpl_error_reset();
01663 frame = cpl_frameset_get_next(frameset);
01664 continue;
01665 }
01666
01667 if (cpl_propertylist_has(reference, keyword)) {
01668 rtype = cpl_propertylist_get_type(reference, keyword);
01669
01670 if (rtype == CPL_TYPE_STRING) {
01671 found = 1;
01672 rstring = cpl_strdup(cpl_propertylist_get_string(reference,
01673 keyword));
01674 cpl_propertylist_delete(reference);
01675 break;
01676 }
01677
01678 if (rtype == CPL_TYPE_INT) {
01679 found = 1;
01680 rintero = cpl_propertylist_get_int(reference, keyword);
01681 cpl_propertylist_delete(reference);
01682 break;
01683 }
01684
01685 cpl_propertylist_delete(reference);
01686 return 0;
01687 }
01688
01689 cpl_propertylist_delete(reference);
01690
01691 frame = cpl_frameset_get_next(frameset);
01692 }
01693
01694
01695 if (!found)
01696 return 1;
01697
01698 frame = cpl_frameset_get_first(frameset);
01699
01700 while (frame) {
01701
01702 reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01703 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01704 cpl_error_reset();
01705 frame = cpl_frameset_get_next(frameset);
01706 continue;
01707 }
01708
01709 if (cpl_propertylist_has(reference, keyword)) {
01710
01711 type = cpl_propertylist_get_type(reference, keyword);
01712
01713 if (rtype != type) {
01714 cpl_propertylist_delete(reference);
01715 return 0;
01716 }
01717
01718 if (rtype == CPL_TYPE_STRING) {
01719 string = cpl_propertylist_get_string(reference,
01720 keyword);
01721 if (strncmp(rstring, string, 15)) {
01722 cpl_propertylist_delete(reference);
01723 return 0;
01724 }
01725 }
01726
01727 if (rtype == CPL_TYPE_INT) {
01728 intero = cpl_propertylist_get_int(reference, keyword);
01729 if (rintero - intero) {
01730 cpl_propertylist_delete(reference);
01731 return 0;
01732 }
01733 }
01734 }
01735
01736 cpl_propertylist_delete(reference);
01737
01738 frame = cpl_frameset_get_next(frameset);
01739 }
01740
01741 if (rtype == CPL_TYPE_STRING)
01742 cpl_free((void *)rstring);
01743
01744 return 1;
01745
01746 }
01747
01757 cpl_error_code dfs_save_table_ext(cpl_table * table,
01758 const char * tag,
01759 cpl_propertylist * extheader)
01760 {
01761 char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
01762 cpl_propertylist * header;
01763
01764 if (extheader) {
01765 header = cpl_propertylist_duplicate(extheader);
01766
01767 cpl_propertylist_erase_regexp(header,
01768 "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
01769 } else {
01770 header = NULL;
01771 }
01772
01773 strlower(strcpy(filename, tag));
01774 strcat(filename, ".fits");
01775
01776 if (cpl_table_save(table, NULL, header, filename, CPL_IO_EXTEND)) {
01777 cpl_free(filename);
01778 cpl_ensure_code(0, CPL_ERROR_FILE_IO);
01779 }
01780
01781 cpl_propertylist_delete(header);
01782 cpl_free(filename);
01783
01784 return CPL_ERROR_NONE;
01785 }
01786
01796 cpl_error_code dfs_save_image_ext(cpl_image * image,
01797 const char * tag,
01798 cpl_propertylist * extheader)
01799 {
01800 char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
01801
01802 cpl_propertylist * header;
01803
01804 if (extheader) {
01805 header = cpl_propertylist_duplicate(extheader);
01806
01807 cpl_propertylist_erase_regexp(header,
01808 "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
01809 } else {
01810 header = NULL;
01811 }
01812
01813 strlower(strcpy(filename, tag));
01814 strcat(filename, ".fits");
01815
01816 if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT,
01817 header, CPL_IO_EXTEND)) {
01818 cpl_free(filename);
01819 cpl_ensure_code(0, CPL_ERROR_FILE_IO);
01820 }
01821
01822 cpl_propertylist_delete(header);
01823 cpl_free(filename);
01824
01825 return CPL_ERROR_NONE;
01826 }
01827
01839 cpl_error_code dfs_save_image_null(cpl_frameset * frameset,
01840 cpl_parameterlist * parlist,
01841 const char * tag,
01842 const char * recipename,
01843 const char * version)
01844 {
01845 const char * regexp = "ESO DET OUT1 OVSCX|"
01846 "ESO DET OUT1 PRSCX|"
01847 "ESO DET OUT1 OVSCY|"
01848 "ESO DET OUT1 PRSCY";
01849
01850 char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
01851
01852 cpl_error_code error;
01853
01854 cpl_propertylist * pro = cpl_propertylist_new();
01855
01856 cpl_propertylist_append_string(pro, "ESO PRO CATG", tag);
01857
01858 strlower(strcpy(filename, tag));
01859 strcat(filename, ".fits");
01860
01861 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
01862 error = cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, NULL,
01863 CPL_BPP_IEEE_FLOAT, recipename, pro,
01864 regexp, version, filename);
01865 #else
01866 error = cpl_dfs_save_image(frameset, parlist, frameset, NULL,
01867 CPL_BPP_IEEE_FLOAT, recipename, tag,
01868 NULL, regexp, version, filename);
01869 #endif
01870
01871 cpl_free(filename);
01872 cpl_propertylist_delete(pro);
01873
01874 return error;
01875 }