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, SCIENCE_IMG) == 0) {
00315 cpl_frame_set_group(f, CPL_FRAME_GROUP_RAW);
00316 }
00317 else if (strcmp(tag, MASTER_BIAS ) == 0 ||
00318 strcmp(tag, MASTER_DARK ) == 0 ||
00319 strcmp(tag, MASTER_SCREEN_FLAT_IMG) == 0 ||
00320 strcmp(tag, MASTER_SKY_FLAT_IMG ) == 0 ||
00321 strcmp(tag, ALIGNED_PHOT ) == 0 ||
00322
00323 strcmp(tag, FLX_STD_IMG ) == 0 ||
00324 strcmp(tag, PHOT_TABLE ) == 0) {
00325 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
00326 }
00327 else {
00328 cpl_msg_warning(cpl_func, "Unrecognized frame tag: '%s'",
00329 tag);
00330 }
00331 }
00332 }
00333
00334 return;
00335 }
00336
00337
00338 #undef cleanup
00339 #define cleanup
00340
00348
00349 const char *
00350 fors_dfs_pipeline_version(const cpl_propertylist *header,
00351 const char **instrument_version)
00352 {
00353 const char *instrume = NULL;
00354
00355 instrume = cpl_propertylist_get_string(header,
00356 FORS_PFITS_INSTRUME);
00357 assure( !cpl_error_get_code(), return NULL,
00358 "Missing keyword %s in input header", FORS_PFITS_INSTRUME);
00359
00360 assure( strlen(instrume) >= 5, return NULL,
00361 "%s keyword must be 'fors1' or 'fors2', not '%s'",
00362 FORS_PFITS_INSTRUME, instrume);
00363
00364 assure( instrume[4] == '1' || instrume[4] == '2', return NULL,
00365 "Unrecognized %s: %s", FORS_PFITS_INSTRUME, instrume);
00366
00367 if (instrument_version != NULL) {
00368 *instrument_version = cpl_sprintf("%s", instrume);
00369 }
00370
00371 return cpl_sprintf("fors%c/%s", instrume[4], VERSION);
00372 }
00373
00374
00396
00397 int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name,
00398 const cpl_table *defaults)
00399 {
00400 const char *func = "dfs_get_parameter_int";
00401
00402 const char *alias;
00403 cpl_parameter *param;
00404
00405
00406 if (parlist == NULL) {
00407 cpl_msg_error(func, "Missing input parameter list");
00408 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00409 return 0;
00410 }
00411
00412 if (name == NULL) {
00413 cpl_msg_error(func, "Missing input parameter name");
00414 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00415 return 0;
00416 }
00417
00418 param = cpl_parameterlist_find(parlist, name);
00419
00420 if (param == NULL) {
00421 cpl_msg_error(func, "Wrong parameter name: %s", name);
00422 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00423 return 0;
00424 }
00425
00426 if (cpl_parameter_get_type(param) != CPL_TYPE_INT) {
00427 cpl_msg_error(func, "Unexpected type for parameter "
00428 "\"%s\": it should be integer", name);
00429 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00430 return 0;
00431 }
00432
00433 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00434
00435 if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00436
00437 if (cpl_table_has_column(defaults, alias)) {
00438 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00439 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00440 "column \"%s\": it should be integer", alias);
00441 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00442 return 0;
00443 }
00444 if (cpl_table_is_valid(defaults, alias, 0)) {
00445 cpl_parameter_set_int(param, cpl_table_get_int(defaults,
00446 alias, 0, NULL));
00447 }
00448 else {
00449 cpl_msg_error(func, "Invalid parameter value in table "
00450 "column \"%s\"", alias);
00451 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00452 return 0;
00453 }
00454 }
00455 else {
00456 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00457 "- using recipe default", alias);
00458 }
00459 }
00460
00461 cpl_msg_info(func, "%s:", alias);
00462 cpl_msg_info(func, "%s: %d",
00463 cpl_parameter_get_help(param), cpl_parameter_get_int(param));
00464
00465 return cpl_parameter_get_int(param);
00466
00467 }
00468
00469
00491
00492 double dfs_get_parameter_double(cpl_parameterlist *parlist,
00493 const char *name, const cpl_table *defaults)
00494 {
00495 const char *func = "dfs_get_parameter_double";
00496
00497 const char *alias;
00498 cpl_parameter *param;
00499
00500
00501 if (parlist == NULL) {
00502 cpl_msg_error(func, "Missing input parameter list");
00503 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00504 return 0;
00505 }
00506
00507 if (name == NULL) {
00508 cpl_msg_error(func, "Missing input parameter name");
00509 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00510 return 0;
00511 }
00512
00513 param = cpl_parameterlist_find(parlist, name);
00514
00515 if (param == NULL) {
00516 cpl_msg_error(func, "Wrong parameter name: %s", name);
00517 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00518 return 0;
00519 }
00520
00521 if (cpl_parameter_get_type(param) != CPL_TYPE_DOUBLE) {
00522 cpl_msg_error(func, "Unexpected type for parameter "
00523 "\"%s\": it should be double", name);
00524 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00525 return 0;
00526 }
00527
00528 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00529
00530 if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00531
00532 if (cpl_table_has_column(defaults, alias)) {
00533 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_DOUBLE) {
00534 cpl_msg_error(func, "Unexpected type for GRISM_TABL "
00535 "column \"%s\": it should be double", alias);
00536 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00537 return 0;
00538 }
00539 if (cpl_table_is_valid(defaults, alias, 0)) {
00540 cpl_parameter_set_double(param, cpl_table_get_double(defaults,
00541 alias, 0, NULL));
00542 }
00543 else {
00544 cpl_msg_error(func, "Invalid parameter value in table "
00545 "column \"%s\"", alias);
00546 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00547 return 0;
00548 }
00549 }
00550 else {
00551 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00552 "- using recipe default", alias);
00553 }
00554 }
00555
00556 cpl_msg_info(func, "%s:", alias);
00557 cpl_msg_info(func, "%s: %f",
00558 cpl_parameter_get_help(param), cpl_parameter_get_double(param));
00559
00560 return cpl_parameter_get_double(param);
00561
00562 }
00563
00564
00586
00587 const char *dfs_get_parameter_string(cpl_parameterlist *parlist,
00588 const char *name,
00589 const cpl_table *defaults)
00590 {
00591 const char *func = "dfs_get_parameter_string";
00592
00593 const char *alias;
00594 cpl_parameter *param;
00595
00596
00597 if (parlist == NULL) {
00598 cpl_msg_error(func, "Missing input parameter list");
00599 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00600 return 0;
00601 }
00602
00603 if (name == NULL) {
00604 cpl_msg_error(func, "Missing input parameter name");
00605 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00606 return 0;
00607 }
00608
00609 param = cpl_parameterlist_find(parlist, name);
00610
00611 if (param == NULL) {
00612 cpl_msg_error(func, "Wrong parameter name: %s", name);
00613 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00614 return 0;
00615 }
00616
00617 if (cpl_parameter_get_type(param) != CPL_TYPE_STRING) {
00618 cpl_msg_error(func, "Unexpected type for parameter "
00619 "\"%s\": it should be string", name);
00620 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00621 return 0;
00622 }
00623
00624 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00625
00626 if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00627
00628 if (cpl_table_has_column(defaults, alias)) {
00629 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_STRING) {
00630 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00631 "column \"%s\": it should be string", alias);
00632 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00633 return 0;
00634 }
00635 if (cpl_table_is_valid(defaults, alias, 0)) {
00636 cpl_parameter_set_string(param, cpl_table_get_string(defaults,
00637 alias, 0));
00638 }
00639 else {
00640 cpl_msg_error(func, "Invalid parameter value in table "
00641 "column \"%s\"", alias);
00642 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00643 return 0;
00644 }
00645 }
00646 else {
00647 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00648 "- using recipe default", alias);
00649 }
00650 }
00651
00652 cpl_msg_info(func, "%s:", alias);
00653 cpl_msg_info(func, "%s: %s", cpl_parameter_get_help(param),
00654 cpl_parameter_get_string(param));
00655
00656 return cpl_parameter_get_string(param);
00657
00658 }
00659
00660
00682
00683 int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name,
00684 const cpl_table *defaults)
00685 {
00686 const char *func = "dfs_get_parameter_bool";
00687
00688 const char *alias;
00689 cpl_parameter *param;
00690 int value;
00691
00692
00693 if (parlist == NULL) {
00694 cpl_msg_error(func, "Missing input parameter list");
00695 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00696 return 0;
00697 }
00698
00699 if (name == NULL) {
00700 cpl_msg_error(func, "Missing input parameter name");
00701 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00702 return 0;
00703 }
00704
00705 param = cpl_parameterlist_find(parlist, name);
00706
00707 if (param == NULL) {
00708 cpl_msg_error(func, "Wrong parameter name: %s", name);
00709 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00710 return 0;
00711 }
00712
00713 if (cpl_parameter_get_type(param) != CPL_TYPE_BOOL) {
00714 cpl_msg_error(func, "Unexpected type for parameter "
00715 "\"%s\": it should be boolean", name);
00716 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00717 return 0;
00718 }
00719
00720 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00721
00722 if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00723
00724 if (cpl_table_has_column(defaults, alias)) {
00725 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00726 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00727 "column \"%s\": it should be integer", alias);
00728 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00729 return 0;
00730 }
00731 if (cpl_table_is_valid(defaults, alias, 0)) {
00732 value = cpl_table_get_int(defaults, alias, 0, NULL);
00733 if (value < 0 || value > 1) {
00734 cpl_msg_error(func, "Illegal parameter value in table "
00735 "column \"%s\": it should be either 0 or 1",
00736 alias);
00737 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00738 return 0;
00739 }
00740 cpl_parameter_set_bool(param, value);
00741 }
00742 else {
00743 cpl_msg_error(func, "Invalid parameter value in table "
00744 "column \"%s\"", alias);
00745 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00746 return 0;
00747 }
00748 }
00749 else {
00750 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00751 "- using recipe default", alias);
00752 }
00753 }
00754
00755 value = cpl_parameter_get_bool(param);
00756
00757 if (value) {
00758 cpl_msg_info(func, "%s:", alias);
00759 cpl_msg_info(func, "%s: TRUE", cpl_parameter_get_help(param));
00760 }
00761 else {
00762 cpl_msg_info(func, "%s:", alias);
00763 cpl_msg_info(func, "%s: FALSE", cpl_parameter_get_help(param));
00764 }
00765
00766 return value;
00767
00768 }
00769
00770
00774
00775 int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
00776 {
00777 return dfs_get_parameter_bool((cpl_parameterlist *)parlist, name, NULL);
00778 }
00779
00780
00784
00785 int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
00786 {
00787 return dfs_get_parameter_int((cpl_parameterlist *)parlist, name, NULL);
00788 }
00789
00790
00794
00795 double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
00796 {
00797 return dfs_get_parameter_double((cpl_parameterlist *)parlist, name, NULL);
00798 }
00799
00800
00804
00805 const char *dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
00806 {
00807 return dfs_get_parameter_string((cpl_parameterlist *)parlist, name, NULL);
00808 }
00809
00810
00838
00839 cpl_image *dfs_load_image(cpl_frameset *frameset, const char *category,
00840 cpl_type type, int ext, int calib)
00841 {
00842 const char *func = "dfs_load_image";
00843
00844 cpl_frame *frame = NULL;
00845 cpl_image *image = NULL;
00846
00847
00848 frame = cpl_frameset_find(frameset, category);
00849
00850 if (frame) {
00851 image = cpl_image_load(cpl_frame_get_filename(frame), type, 0, ext);
00852 if (image == NULL) {
00853 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00854 cpl_msg_error(func, "Cannot load image %s",
00855 cpl_frame_get_filename(frame));
00856 }
00857 else {
00858 if (calib)
00859 cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
00860 else
00861 cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
00862 }
00863 }
00864
00865 return image;
00866 }
00867
00868
00894
00895 cpl_table *dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
00896 {
00897 const char *func = "dfs_load_table";
00898
00899 cpl_frame *frame = NULL;
00900 cpl_table *table = NULL;
00901
00902
00903 frame = cpl_frameset_find(frameset, category);
00904
00905 if (frame) {
00906 table = cpl_table_load(cpl_frame_get_filename(frame), ext, 1);
00907 if (table == NULL) {
00908 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00909 cpl_msg_error(func, "Cannot load table %s",
00910 cpl_frame_get_filename(frame));
00911 }
00912 else
00913 cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
00914 }
00915
00916 return table;
00917 }
00918
00919
00944
00945 cpl_propertylist *dfs_load_header(cpl_frameset *frameset,
00946 const char *category, int ext)
00947 {
00948 const char *func = "dfs_load_header";
00949
00950 cpl_frame *frame = NULL;
00951 cpl_propertylist *plist = NULL;
00952
00953
00954 frame = cpl_frameset_find(frameset, category);
00955
00956 if (frame) {
00957 plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext);
00958 if (plist == NULL) {
00959 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00960 cpl_msg_error(func, "Cannot load header from %s",
00961 cpl_frame_get_filename(frame));
00962 }
00963 }
00964
00965 return plist;
00966 }
00967
00968
00975
00976 static void
00977 dfs_save(cpl_frameset *frameset, const void *object, cpl_frame_type type,
00978 const char *category, cpl_propertylist *header,
00979 const cpl_parameterlist *parlist, const char *recipename,
00980 const cpl_frame *raw_frame)
00981 {
00982 char *filename;
00983 cpl_frame *frame;
00984 cpl_propertylist *plist;
00985 const char *version = NULL;
00986 cpl_propertylist *raw_header = NULL;
00987
00988
00989 if (category == NULL || frameset == NULL || object == NULL ||
00990 raw_frame == NULL) {
00991 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00992 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
00993 return;
00994 }
00995
00996 if (type == CPL_FRAME_TYPE_IMAGE) {
00997 cpl_msg_debug(cpl_func, "Saving %s image to disk...", category);
00998 }
00999 else {
01000 cpl_msg_debug(cpl_func, "Saving %s table to disk...", category);
01001 }
01002
01003
01004 {
01005 const char *raw_filename =
01006 cpl_frame_get_filename(raw_frame);
01007
01008 raw_header = cpl_propertylist_load(raw_filename, 0);
01009 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01010 cpl_msg_error(cpl_func, "Could not read %s primary header", raw_filename);
01011 return;
01012 }
01013
01014 version = fors_dfs_pipeline_version(raw_header, NULL);
01015 cpl_propertylist_delete(raw_header);
01016
01017 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01018 cpl_msg_error(cpl_func, "Could not identify instrument version from %s header",
01019 raw_filename);
01020 return;
01021 }
01022 }
01023
01024 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01025
01026 strlower(strcpy(filename, category));
01027 strcat(filename, ".fits");
01028
01029 frame = cpl_frame_new();
01030
01031 cpl_frame_set_filename(frame, filename);
01032 cpl_frame_set_tag(frame, category);
01033 cpl_frame_set_type(frame, type);
01034 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01035 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01036 if (cpl_error_get_code()) {
01037 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01038 cpl_msg_error(cpl_func, "Cannot initialise the product frame");
01039 cpl_frame_delete(frame);
01040 cpl_free(filename);
01041 cpl_free((void *)version);
01042 return;
01043 }
01044
01045
01046
01047
01048
01049
01050 if (header == NULL)
01051 plist = cpl_propertylist_new();
01052 else
01053 plist = header;
01054
01055 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
01056 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01057 recipename, version, "PRO-1.15", NULL)) {
01058 #else
01059 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01060 recipename, version, "PRO-1.15")) {
01061 #endif
01062 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01063 cpl_msg_error(cpl_func, "Problem with product %s FITS header definition",
01064 category);
01065 if (header == NULL)
01066 cpl_propertylist_delete(plist);
01067 cpl_frame_delete(frame);
01068 cpl_free(filename);
01069 cpl_free((void *)version);
01070 return;
01071 }
01072
01073 cpl_free((void *)version);
01074
01075
01076
01077
01078
01079
01080 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01081 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01082 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01083 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01084
01085
01086
01087
01088
01089 if (type == CPL_FRAME_TYPE_IMAGE) {
01090 fors_image_save((fors_image *)object, plist, filename);
01091 }
01092 else {
01093 cpl_table_save((cpl_table *)object,
01094 plist, NULL, filename, CPL_IO_DEFAULT);
01095 }
01096
01097 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01098 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01099 cpl_msg_error(cpl_func, "Cannot save product %s to disk", filename);
01100 if (header == NULL)
01101 cpl_propertylist_delete(plist);
01102 cpl_frame_delete(frame);
01103 cpl_free(filename);
01104 return;
01105 }
01106
01107 if (header == NULL)
01108 cpl_propertylist_delete(plist);
01109
01110 cpl_free(filename);
01111
01112 cpl_frameset_insert(frameset, frame);
01113
01114 return;
01115 }
01116
01117
01138
01139 void
01140 fors_dfs_save_image(cpl_frameset *frameset, const fors_image *image,
01141 const char *category, cpl_propertylist *header,
01142 const cpl_parameterlist *parlist, const char *recipename,
01143 const cpl_frame *raw_frame)
01144 {
01145 dfs_save(frameset, image, CPL_FRAME_TYPE_IMAGE,
01146 category, header,
01147 parlist, recipename,
01148 raw_frame);
01149 }
01150
01151 #undef cleanup
01152 #define cleanup \
01153 do { \
01154 cpl_propertylist_delete(wcs_header); \
01155 } while (0)
01156
01161 void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame,
01162 const fors_setting *setting)
01163 {
01164 bool invert = false;
01165 int extension = 0;
01166
01167 cpl_propertylist *wcs_header =
01168 cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
01169 extension, WCS_KEYS, invert);
01170
01171 cpl_propertylist_copy_property_regexp(header, wcs_header, ".*", invert);
01172
01173 double crpix1 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX1);
01174
01175 assure( !cpl_error_get_code(), return,
01176 "Could not read %s from %s", FORS_PFITS_CRPIX1,
01177 cpl_frame_get_filename(frame));
01178
01179 double crpix2 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX2);
01180
01181 assure( !cpl_error_get_code(), return,
01182 "Could not read %s from %s", FORS_PFITS_CRPIX2,
01183 cpl_frame_get_filename(frame));
01184
01185 cpl_propertylist_update_double(header, FORS_PFITS_CRPIX1,
01186 crpix1 - setting->prescan_x);
01187
01188 cpl_propertylist_update_double(header, FORS_PFITS_CRPIX2,
01189 crpix2 - setting->prescan_y);
01190
01191
01192 cleanup;
01193 return;
01194 }
01195
01196
01197 #undef cleanup
01198 #define cleanup \
01199 do { \
01200 cpl_propertylist_delete(time_header); \
01201 } while (0)
01202
01214
01215 void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame,
01216 double exptime)
01217 {
01218 bool invert = false;
01219 int extension = 0;
01220
01221 cpl_propertylist *time_header = NULL;
01222
01223 if (frame) {
01224
01225 time_header =
01226 cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
01227 extension, "EXPTIME", invert);
01228
01229 if (time_header) {
01230 cpl_propertylist_copy_property_regexp(header,
01231 time_header, ".*", invert);
01232 }
01233 else {
01234 cpl_error_reset();
01235 }
01236 }
01237 else {
01238 while (cpl_propertylist_erase(header, "EXPTIME"));
01239 cpl_propertylist_update_double(header, "EXPTIME", exptime);
01240 }
01241
01242 cleanup;
01243 return;
01244 }
01245
01246
01253
01254 void
01255 fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
01256 const char *category, cpl_propertylist *header,
01257 const cpl_parameterlist *parlist, const char *recipename,
01258 const cpl_frame *raw_frame)
01259 {
01260 dfs_save(frameset, table, CPL_FRAME_TYPE_TABLE,
01261 category, header,
01262 parlist, recipename,
01263 raw_frame);
01264 }
01265
01266
01298
01299 int dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
01300 const char *category, cpl_propertylist *header,
01301 const cpl_parameterlist *parlist, const char *recipename,
01302 const char *version)
01303 {
01304 const char *func = "dfs_save_image";
01305
01306 char *filename;
01307 cpl_frame *frame;
01308 cpl_propertylist *plist;
01309
01310
01311 if (category == NULL || frameset == NULL || image == NULL) {
01312 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01313 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01314 return -1;
01315 }
01316
01317 cpl_msg_info(func, "Saving %s image to disk...", category);
01318
01319 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01320
01321 strlower(strcpy(filename, category));
01322 strcat(filename, ".fits");
01323
01324 frame = cpl_frame_new();
01325
01326 cpl_frame_set_filename(frame, filename);
01327 cpl_frame_set_tag(frame, category);
01328 cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE);
01329 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01330 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01331 if (cpl_error_get_code()) {
01332 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01333 cpl_msg_error(func, "Cannot initialise the product frame");
01334 cpl_frame_delete(frame);
01335 cpl_free(filename);
01336 return -1;
01337 }
01338
01339
01340
01341
01342
01343
01344 if (header == NULL)
01345 plist = cpl_propertylist_new();
01346 else
01347 plist = header;
01348
01349 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
01350 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01351 recipename, version, "PRO-1.15", NULL)) {
01352 #else
01353 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01354 recipename, version, "PRO-1.15")) {
01355 #endif
01356 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01357 cpl_msg_error(func, "Problem with product %s FITS header definition",
01358 category);
01359 if (header == NULL)
01360 cpl_propertylist_delete(plist);
01361 cpl_frame_delete(frame);
01362 cpl_free(filename);
01363 return -1;
01364 }
01365
01366
01367
01368
01369
01370
01371 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01372 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01373 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01374 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01375
01376
01377
01378
01379
01380 if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist,
01381 CPL_IO_DEFAULT)) {
01382 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01383 cpl_msg_error(func, "Cannot save product %s to disk", filename);
01384 if (header == NULL)
01385 cpl_propertylist_delete(plist);
01386 cpl_frame_delete(frame);
01387 cpl_free(filename);
01388 return -1;
01389 }
01390
01391 if (header == NULL)
01392 cpl_propertylist_delete(plist);
01393
01394 cpl_free(filename);
01395
01396 cpl_frameset_insert(frameset, frame);
01397
01398 return 0;
01399 }
01400
01401
01433
01434 int dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
01435 const char *category, cpl_propertylist *header,
01436 const cpl_parameterlist *parlist, const char *recipename,
01437 const char *version)
01438 {
01439 const char *func = "dfs_save_table";
01440
01441 char *filename;
01442 cpl_frame *frame;
01443 cpl_propertylist *plist;
01444
01445
01446 if (category == NULL || frameset == NULL || table == NULL) {
01447 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01448 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01449 return -1;
01450 }
01451
01452 cpl_msg_info(func, "Saving %s table to disk...", category);
01453
01454
01455
01456
01457 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01458
01459 strlower(strcpy(filename, category));
01460
01461
01462
01463
01464 strcat(filename, ".fits");
01465
01466 frame = cpl_frame_new();
01467
01468 cpl_frame_set_filename(frame, filename);
01469 cpl_frame_set_tag(frame, category);
01470 cpl_frame_set_type(frame, CPL_FRAME_TYPE_TABLE);
01471 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01472 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01473 if (cpl_error_get_code()) {
01474 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01475 cpl_msg_error(func, "Cannot initialise the product frame");
01476 cpl_frame_delete(frame);
01477 cpl_free(filename);
01478 return -1;
01479 }
01480
01481
01482
01483
01484
01485
01486 if (header == NULL)
01487 plist = cpl_propertylist_new();
01488 else
01489 plist = header;
01490
01491 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
01492 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01493 recipename, version, "PRO-1.15", NULL)) {
01494 #else
01495 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01496 recipename, version, "PRO-1.15")) {
01497 #endif
01498 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01499 cpl_msg_error(func, "Problem with product %s FITS header definition",
01500 category);
01501 if (header == NULL)
01502 cpl_propertylist_delete(plist);
01503 cpl_frame_delete(frame);
01504 cpl_free(filename);
01505 return -1;
01506 }
01507
01508
01509
01510
01511
01512
01513 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01514 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01515 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01516 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01517
01518
01519
01520
01521
01522
01523 if (cpl_table_save(table, plist, NULL, filename, CPL_IO_DEFAULT)) {
01524 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01525 cpl_msg_error(func, "Cannot save product %s to disk", filename);
01526 if (header == NULL)
01527 cpl_propertylist_delete(plist);
01528 cpl_frame_delete(frame);
01529 cpl_free(filename);
01530 return -1;
01531 }
01532
01533 if (header == NULL)
01534 cpl_propertylist_delete(plist);
01535 cpl_free(filename);
01536
01537 cpl_frameset_insert(frameset, frame);
01538
01539 return 0;
01540 }
01541
01542
01552
01553 int dfs_files_dont_exist(cpl_frameset *frameset)
01554 {
01555 const char *func = "dfs_files_dont_exist";
01556 cpl_frame *frame;
01557
01558
01559 if (frameset == NULL) {
01560 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01561 return 1;
01562 }
01563
01564 if (cpl_frameset_is_empty(frameset)) {
01565 return 0;
01566 }
01567
01568 frame = cpl_frameset_get_first(frameset);
01569
01570 while (frame) {
01571 if (access(cpl_frame_get_filename(frame), F_OK)) {
01572 cpl_msg_error(func, "File %s (%s) was not found",
01573 cpl_frame_get_filename(frame),
01574 cpl_frame_get_tag(frame));
01575 cpl_error_set(func, CPL_ERROR_FILE_NOT_FOUND);
01576 }
01577
01578 frame = cpl_frameset_get_next(frameset);
01579 }
01580
01581 if (cpl_error_get_code())
01582 return 1;
01583
01584 return 0;
01585 }
01586
01587
01604
01605 int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
01606 {
01607 const char *func = "dfs_equal_keyword";
01608
01609 cpl_frame *frame;
01610 cpl_propertylist *reference;
01611 cpl_type rtype;
01612 cpl_type type;
01613 const char *rstring;
01614 const char *string;
01615 int rintero;
01616 int intero;
01617 int found;
01618
01619
01620 if (frameset == NULL || keyword == NULL) {
01621 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01622 return 0;
01623 }
01624
01625 if (cpl_frameset_is_empty(frameset)) {
01626 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
01627 return 0;
01628 }
01629
01630 frame = cpl_frameset_get_first(frameset);
01631
01632 found = 0;
01633
01634 while (frame) {
01635
01636 reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01637 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01638 cpl_error_reset();
01639 frame = cpl_frameset_get_next(frameset);
01640 continue;
01641 }
01642
01643 if (cpl_propertylist_has(reference, keyword)) {
01644 rtype = cpl_propertylist_get_type(reference, keyword);
01645
01646 if (rtype == CPL_TYPE_STRING) {
01647 found = 1;
01648 rstring = cpl_strdup(cpl_propertylist_get_string(reference,
01649 keyword));
01650 cpl_propertylist_delete(reference);
01651 break;
01652 }
01653
01654 if (rtype == CPL_TYPE_INT) {
01655 found = 1;
01656 rintero = cpl_propertylist_get_int(reference, keyword);
01657 cpl_propertylist_delete(reference);
01658 break;
01659 }
01660
01661 cpl_propertylist_delete(reference);
01662 return 0;
01663 }
01664
01665 cpl_propertylist_delete(reference);
01666
01667 frame = cpl_frameset_get_next(frameset);
01668 }
01669
01670
01671 if (!found)
01672 return 1;
01673
01674 frame = cpl_frameset_get_first(frameset);
01675
01676 while (frame) {
01677
01678 reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01679 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01680 cpl_error_reset();
01681 frame = cpl_frameset_get_next(frameset);
01682 continue;
01683 }
01684
01685 if (cpl_propertylist_has(reference, keyword)) {
01686
01687 type = cpl_propertylist_get_type(reference, keyword);
01688
01689 if (rtype != type) {
01690 cpl_propertylist_delete(reference);
01691 return 0;
01692 }
01693
01694 if (rtype == CPL_TYPE_STRING) {
01695 string = cpl_propertylist_get_string(reference,
01696 keyword);
01697 if (strcmp(rstring, string)) {
01698 cpl_propertylist_delete(reference);
01699 return 0;
01700 }
01701 }
01702
01703 if (rtype == CPL_TYPE_INT) {
01704 intero = cpl_propertylist_get_int(reference, keyword);
01705 if (rintero - intero) {
01706 cpl_propertylist_delete(reference);
01707 return 0;
01708 }
01709 }
01710 }
01711
01712 cpl_propertylist_delete(reference);
01713
01714 frame = cpl_frameset_get_next(frameset);
01715 }
01716
01717 if (rtype == CPL_TYPE_STRING)
01718 cpl_free((void *)rstring);
01719
01720 return 1;
01721
01722 }
01723
01733 cpl_error_code dfs_save_table_ext(cpl_table * table,
01734 const char * tag,
01735 cpl_propertylist * extheader)
01736 {
01737 char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
01738 cpl_propertylist * header;
01739
01740 if (extheader) {
01741 header = cpl_propertylist_duplicate(extheader);
01742
01743 cpl_propertylist_erase_regexp(header,
01744 "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
01745 } else {
01746 header = NULL;
01747 }
01748
01749 strlower(strcpy(filename, tag));
01750 strcat(filename, ".fits");
01751
01752 if (cpl_table_save(table, NULL, header, filename, CPL_IO_EXTEND)) {
01753 cpl_free(filename);
01754 cpl_ensure_code(0, CPL_ERROR_FILE_IO);
01755 }
01756
01757 cpl_propertylist_delete(header);
01758 cpl_free(filename);
01759
01760 return CPL_ERROR_NONE;
01761 }
01762
01772 cpl_error_code dfs_save_image_ext(cpl_image * image,
01773 const char * tag,
01774 cpl_propertylist * extheader)
01775 {
01776 char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
01777
01778 cpl_propertylist * header;
01779
01780 if (extheader) {
01781 header = cpl_propertylist_duplicate(extheader);
01782
01783 cpl_propertylist_erase_regexp(header,
01784 "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
01785 } else {
01786 header = NULL;
01787 }
01788
01789 strlower(strcpy(filename, tag));
01790 strcat(filename, ".fits");
01791
01792 if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT,
01793 header, CPL_IO_EXTEND)) {
01794 cpl_free(filename);
01795 cpl_ensure_code(0, CPL_ERROR_FILE_IO);
01796 }
01797
01798 cpl_propertylist_delete(header);
01799 cpl_free(filename);
01800
01801 return CPL_ERROR_NONE;
01802 }
01803
01815 cpl_error_code dfs_save_image_null(cpl_frameset * frameset,
01816 cpl_parameterlist * parlist,
01817 const char * tag,
01818 const char * recipename,
01819 const char * version)
01820 {
01821 const char * regexp = "ESO DET OUT1 OVSCX|"
01822 "ESO DET OUT1 PRSCX|"
01823 "ESO DET OUT1 OVSCY|"
01824 "ESO DET OUT1 PRSCY";
01825
01826 char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
01827
01828 cpl_error_code error;
01829
01830 cpl_propertylist * pro = cpl_propertylist_new();
01831
01832 cpl_propertylist_append_string(pro, "ESO PRO CATG", tag);
01833
01834 strlower(strcpy(filename, tag));
01835 strcat(filename, ".fits");
01836
01837 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
01838 error = cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, NULL,
01839 CPL_BPP_IEEE_FLOAT, recipename, pro,
01840 regexp, version, filename);
01841 #else
01842 error = cpl_dfs_save_image(frameset, parlist, frameset, NULL,
01843 CPL_BPP_IEEE_FLOAT, recipename, tag,
01844 NULL, regexp, version, filename);
01845 #endif
01846
01847 cpl_free(filename);
01848 cpl_propertylist_delete(pro);
01849
01850 return error;
01851 }