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
00056 #define WCS_KEYS "^((CRVAL|CRPIX|CTYPE)[0-9]|RADECSYS|CD[0-9]_[0-9])$"
00057
00058 static char *strlower(char *s)
00059 {
00060
00061 char *t = s;
00062
00063 while (*t) {
00064 *t = tolower(*t);
00065 t++;
00066 }
00067
00068 return s;
00069
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 char *dfs_generate_filename(const char *category)
00091 {
00092 char *filename = cpl_calloc(strlen(category) + 6, sizeof(char));
00093
00094 strlower(strcpy(filename, category));
00095 strcat(filename, ".fits");
00096
00097 return filename;
00098 }
00099
00100 char *dfs_generate_filename_tfits(const char *category)
00101 {
00102
00103
00104
00105 char *filename = cpl_calloc(strlen(category) + 6, sizeof(char));
00106
00107 strlower(strcpy(filename, category));
00108
00109
00110
00111
00112 strcat(filename, ".fits");
00113
00114 return filename;
00115 }
00116
00117
00118
00129
00130 static void
00131 errorstate_dump_one(unsigned self, unsigned first, unsigned last)
00132 {
00133
00134 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
00135 const unsigned newest = is_reverse ? first : last;
00136 const unsigned oldest = is_reverse ? last : first;
00137 const char * revmsg = is_reverse ? " in reverse order" : "";
00138
00139
00140
00141
00142
00143 if (newest == 0) {
00144 cpl_msg_info(cpl_func, "No error(s) to dump");
00145
00146 } else {
00147
00148
00149 if (self == first) {
00150 if (oldest == 1) {
00151 cpl_msg_debug(cpl_func, "Dumping all %u error(s)%s:", newest,
00152 revmsg);
00153 } else {
00154 cpl_msg_error(cpl_func, "Dumping the %u most recent error(s) "
00155 "out of a total of %u errors%s:",
00156 newest - oldest + 1, newest, revmsg);
00157 }
00158 }
00159
00160 const char *message_from_cpl = cpl_error_get_message();
00161
00162 if (message_from_cpl == NULL) {
00163
00164 cpl_msg_error(cpl_func, "Unspecified error");
00165 }
00166
00167
00168
00169
00170
00171
00172
00173 while (*message_from_cpl != '\0' && *message_from_cpl != ':') {
00174 message_from_cpl += 1;
00175 }
00176
00177 if (*message_from_cpl != '\0') {
00178 message_from_cpl += 1;
00179
00180 if (*message_from_cpl == ' ') message_from_cpl++;
00181
00182 if (*message_from_cpl != '\0') {
00183
00184 cpl_msg_error(cpl_func, "%s [%s]", message_from_cpl,
00185 cpl_error_get_where());
00186 }
00187 else {
00188 cpl_msg_error(cpl_func, "%s [%s]",
00189 cpl_error_get_message(), cpl_error_get_where());
00190 }
00191 }
00192 else {
00193
00194 cpl_msg_error(cpl_func, "%s [%s]",
00195 cpl_error_get_message(), cpl_error_get_where());
00196 }
00197 }
00198
00199 return;
00200 }
00201
00202
00203
00213
00214 void fors_begin(cpl_frameset *frames,
00215 const char *description_short)
00216 {
00217 cpl_msg_info(cpl_func, "%s", PACKAGE_STRING);
00218 cpl_msg_info(cpl_func, "%s", description_short);
00219
00220 fors_dfs_set_groups(frames);
00221 cpl_msg_info(cpl_func, "Input frame%s:",
00222 cpl_frameset_get_size(frames) != 1 ? "s" : "");
00223 fors_frameset_print(frames);
00224
00225 return;
00226 }
00227
00228
00241
00242 int fors_end(const cpl_frameset *frames, cpl_errorstate before_exec)
00243 {
00244 if (cpl_error_get_code() == CPL_ERROR_NONE) {
00245
00246 const cpl_frame *f;
00247
00248 cpl_msg_info(cpl_func, "Product frame%s:",
00249 cpl_frameset_get_size(frames) != 1 ? "s" : "");
00250
00251 for (f = cpl_frameset_get_first_const(frames);
00252 f != NULL;
00253 f = cpl_frameset_get_next_const(frames)) {
00254 if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_PRODUCT) {
00255 fors_frame_print(f);
00256 }
00257 }
00258
00259
00260
00261 return 0;
00262 }
00263 else {
00264
00265 cpl_errorstate_dump(before_exec, CPL_FALSE, errorstate_dump_one);
00266
00267 return 1;
00268 }
00269 }
00270
00271 #undef cleanup
00272 #define cleanup
00273
00278
00279 void
00280 fors_dfs_set_groups(cpl_frameset * set)
00281 {
00282 cpl_frame *f;
00283
00284 assure( set != NULL, return, NULL );
00285
00286 for (f = cpl_frameset_get_first(set);
00287 f != NULL;
00288 f = cpl_frameset_get_next(set)) {
00289
00290 const char *tag = cpl_frame_get_tag(f);
00291
00292 if (tag != NULL) {
00293 if (strcmp(tag, BIAS) == 0 ||
00294 strcmp(tag, DARK) == 0 ||
00295 strcmp(tag, SCREEN_FLAT_IMG) == 0 ||
00296 strcmp(tag, SKY_FLAT_IMG) == 0 ||
00297 strcmp(tag, STANDARD_IMG) == 0 ||
00298 strcmp(tag, SCIENCE_IMG) == 0) {
00299 cpl_frame_set_group(f, CPL_FRAME_GROUP_RAW);
00300 }
00301 else if (strcmp(tag, MASTER_BIAS ) == 0 ||
00302 strcmp(tag, MASTER_DARK ) == 0 ||
00303 strcmp(tag, MASTER_SCREEN_FLAT_IMG) == 0 ||
00304 strcmp(tag, MASTER_SKY_FLAT_IMG ) == 0 ||
00305 strcmp(tag, ALIGNED_PHOT ) == 0 ||
00306
00307 strcmp(tag, FLX_STD_IMG ) == 0 ||
00308 strcmp(tag, PHOT_TABLE ) == 0) {
00309 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
00310 }
00311 else {
00312 cpl_msg_warning(cpl_func, "Unrecognized frame tag: '%s'",
00313 tag);
00314 }
00315 }
00316 }
00317
00318 return;
00319 }
00320
00321 #undef cleanup
00322 #define cleanup
00323
00331 const char *
00332 fors_dfs_pipeline_version(const cpl_propertylist *header,
00333 const char **instrument_version)
00334 {
00335 const char *instrume = NULL;
00336
00337 instrume = cpl_propertylist_get_string(header,
00338 FORS_PFITS_INSTRUME);
00339 assure( !cpl_error_get_code(), return NULL,
00340 "Missing keyword %s in input header", FORS_PFITS_INSTRUME);
00341
00342 assure( strlen(instrume) >= 5, return NULL,
00343 "%s keyword must be 'fors1' or 'fors2', not '%s'",
00344 FORS_PFITS_INSTRUME, instrume);
00345
00346 assure( instrume[4] == '1' || instrume[4] == '2', return NULL,
00347 "Unrecognized %s: %s", FORS_PFITS_INSTRUME, instrume);
00348
00349 if (instrument_version != NULL) {
00350 *instrument_version = cpl_sprintf("%s", instrume);
00351 }
00352
00353 return cpl_sprintf("fors%c/%s", instrume[4], VERSION);
00354 }
00355
00356
00379 int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name,
00380 const cpl_table *defaults)
00381 {
00382 const char *func = "dfs_get_parameter_int";
00383
00384 const char *alias;
00385 cpl_parameter *param;
00386
00387
00388 if (parlist == NULL) {
00389 cpl_msg_error(func, "Missing input parameter list");
00390 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00391 return 0;
00392 }
00393
00394 if (name == NULL) {
00395 cpl_msg_error(func, "Missing input parameter name");
00396 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00397 return 0;
00398 }
00399
00400 param = cpl_parameterlist_find(parlist, name);
00401
00402 if (param == NULL) {
00403 cpl_msg_error(func, "Wrong parameter name: %s", name);
00404 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00405 return 0;
00406 }
00407
00408 if (cpl_parameter_get_type(param) != CPL_TYPE_INT) {
00409 cpl_msg_error(func, "Unexpected type for parameter "
00410 "\"%s\": it should be integer", name);
00411 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00412 return 0;
00413 }
00414
00415 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00416
00417 if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00418
00419 if (cpl_table_has_column(defaults, alias)) {
00420 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00421 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00422 "column \"%s\": it should be integer", alias);
00423 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00424 return 0;
00425 }
00426 if (cpl_table_is_valid(defaults, alias, 0)) {
00427 cpl_parameter_set_int(param, cpl_table_get_int(defaults,
00428 alias, 0, NULL));
00429 }
00430 else {
00431 cpl_msg_error(func, "Invalid parameter value in table "
00432 "column \"%s\"", alias);
00433 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00434 return 0;
00435 }
00436 }
00437 else {
00438 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00439 "- using recipe default", alias);
00440 }
00441 }
00442
00443 cpl_msg_info(func, "%s:", alias);
00444 cpl_msg_info(func, "%s: %d",
00445 cpl_parameter_get_help(param), cpl_parameter_get_int(param));
00446
00447 return cpl_parameter_get_int(param);
00448
00449 }
00450
00451
00474 double dfs_get_parameter_double(cpl_parameterlist *parlist,
00475 const char *name, const cpl_table *defaults)
00476 {
00477 const char *func = "dfs_get_parameter_double";
00478
00479 const char *alias;
00480 cpl_parameter *param;
00481
00482
00483 if (parlist == NULL) {
00484 cpl_msg_error(func, "Missing input parameter list");
00485 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00486 return 0;
00487 }
00488
00489 if (name == NULL) {
00490 cpl_msg_error(func, "Missing input parameter name");
00491 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00492 return 0;
00493 }
00494
00495 param = cpl_parameterlist_find(parlist, name);
00496
00497 if (param == NULL) {
00498 cpl_msg_error(func, "Wrong parameter name: %s", name);
00499 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00500 return 0;
00501 }
00502
00503 if (cpl_parameter_get_type(param) != CPL_TYPE_DOUBLE) {
00504 cpl_msg_error(func, "Unexpected type for parameter "
00505 "\"%s\": it should be double", name);
00506 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00507 return 0;
00508 }
00509
00510 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00511
00512 if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00513
00514 if (cpl_table_has_column(defaults, alias)) {
00515 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_DOUBLE) {
00516 cpl_msg_error(func, "Unexpected type for GRISM_TABL "
00517 "column \"%s\": it should be double", alias);
00518 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00519 return 0;
00520 }
00521 if (cpl_table_is_valid(defaults, alias, 0)) {
00522 cpl_parameter_set_double(param, cpl_table_get_double(defaults,
00523 alias, 0, NULL));
00524 }
00525 else {
00526 cpl_msg_error(func, "Invalid parameter value in table "
00527 "column \"%s\"", alias);
00528 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00529 return 0;
00530 }
00531 }
00532 else {
00533 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00534 "- using recipe default", alias);
00535 }
00536 }
00537
00538 cpl_msg_info(func, "%s:", alias);
00539 cpl_msg_info(func, "%s: %f",
00540 cpl_parameter_get_help(param), cpl_parameter_get_double(param));
00541
00542 return cpl_parameter_get_double(param);
00543
00544 }
00545
00546
00569 const char *dfs_get_parameter_string(cpl_parameterlist *parlist,
00570 const char *name,
00571 const cpl_table *defaults)
00572 {
00573 const char *func = "dfs_get_parameter_string";
00574
00575 const char *alias;
00576 cpl_parameter *param;
00577
00578
00579 if (parlist == NULL) {
00580 cpl_msg_error(func, "Missing input parameter list");
00581 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00582 return 0;
00583 }
00584
00585 if (name == NULL) {
00586 cpl_msg_error(func, "Missing input parameter name");
00587 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00588 return 0;
00589 }
00590
00591 param = cpl_parameterlist_find(parlist, name);
00592
00593 if (param == NULL) {
00594 cpl_msg_error(func, "Wrong parameter name: %s", name);
00595 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00596 return 0;
00597 }
00598
00599 if (cpl_parameter_get_type(param) != CPL_TYPE_STRING) {
00600 cpl_msg_error(func, "Unexpected type for parameter "
00601 "\"%s\": it should be string", name);
00602 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00603 return 0;
00604 }
00605
00606 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00607
00608 if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00609
00610 if (cpl_table_has_column(defaults, alias)) {
00611 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_STRING) {
00612 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00613 "column \"%s\": it should be string", alias);
00614 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00615 return 0;
00616 }
00617 if (cpl_table_is_valid(defaults, alias, 0)) {
00618 cpl_parameter_set_string(param, cpl_table_get_string(defaults,
00619 alias, 0));
00620 }
00621 else {
00622 cpl_msg_error(func, "Invalid parameter value in table "
00623 "column \"%s\"", alias);
00624 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00625 return 0;
00626 }
00627 }
00628 else {
00629 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00630 "- using recipe default", alias);
00631 }
00632 }
00633
00634 cpl_msg_info(func, "%s:", alias);
00635 cpl_msg_info(func, "%s: %s", cpl_parameter_get_help(param),
00636 cpl_parameter_get_string(param));
00637
00638 return cpl_parameter_get_string(param);
00639
00640 }
00641
00642
00665 int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name,
00666 const cpl_table *defaults)
00667 {
00668 const char *func = "dfs_get_parameter_bool";
00669
00670 const char *alias;
00671 cpl_parameter *param;
00672 int value;
00673
00674
00675 if (parlist == NULL) {
00676 cpl_msg_error(func, "Missing input parameter list");
00677 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00678 return 0;
00679 }
00680
00681 if (name == NULL) {
00682 cpl_msg_error(func, "Missing input parameter name");
00683 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00684 return 0;
00685 }
00686
00687 param = cpl_parameterlist_find(parlist, name);
00688
00689 if (param == NULL) {
00690 cpl_msg_error(func, "Wrong parameter name: %s", name);
00691 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00692 return 0;
00693 }
00694
00695 if (cpl_parameter_get_type(param) != CPL_TYPE_BOOL) {
00696 cpl_msg_error(func, "Unexpected type for parameter "
00697 "\"%s\": it should be boolean", name);
00698 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00699 return 0;
00700 }
00701
00702 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00703
00704 if (defaults && cpl_parameter_get_default_flag(param) == 0) {
00705
00706 if (cpl_table_has_column(defaults, alias)) {
00707 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00708 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00709 "column \"%s\": it should be integer", alias);
00710 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00711 return 0;
00712 }
00713 if (cpl_table_is_valid(defaults, alias, 0)) {
00714 value = cpl_table_get_int(defaults, alias, 0, NULL);
00715 if (value < 0 || value > 1) {
00716 cpl_msg_error(func, "Illegal parameter value in table "
00717 "column \"%s\": it should be either 0 or 1",
00718 alias);
00719 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00720 return 0;
00721 }
00722 cpl_parameter_set_bool(param, value);
00723 }
00724 else {
00725 cpl_msg_error(func, "Invalid parameter value in table "
00726 "column \"%s\"", alias);
00727 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00728 return 0;
00729 }
00730 }
00731 else {
00732 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00733 "- using recipe default", alias);
00734 }
00735 }
00736
00737 value = cpl_parameter_get_bool(param);
00738
00739 if (value) {
00740 cpl_msg_info(func, "%s:", alias);
00741 cpl_msg_info(func, "%s: TRUE", cpl_parameter_get_help(param));
00742 }
00743 else {
00744 cpl_msg_info(func, "%s:", alias);
00745 cpl_msg_info(func, "%s: FALSE", cpl_parameter_get_help(param));
00746 }
00747
00748 return value;
00749
00750 }
00751
00755 int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
00756 {
00757 return dfs_get_parameter_bool((cpl_parameterlist *)parlist, name, NULL);
00758 }
00759
00763 int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
00764 {
00765 return dfs_get_parameter_int((cpl_parameterlist *)parlist, name, NULL);
00766 }
00767
00771 double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
00772 {
00773 return dfs_get_parameter_double((cpl_parameterlist *)parlist, name, NULL);
00774 }
00775
00779 const char *dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
00780 {
00781 return dfs_get_parameter_string((cpl_parameterlist *)parlist, name, NULL);
00782 }
00783
00784
00813 cpl_image *dfs_load_image(cpl_frameset *frameset, const char *category,
00814 cpl_type type, int ext, int calib)
00815 {
00816 const char *func = "dfs_load_image";
00817
00818 cpl_frame *frame = NULL;
00819 cpl_image *image = NULL;
00820
00821
00822 frame = cpl_frameset_find(frameset, category);
00823
00824 if (frame) {
00825 image = cpl_image_load(cpl_frame_get_filename(frame), type, 0, ext);
00826 if (image == NULL) {
00827 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00828 cpl_msg_error(func, "Cannot load image %s",
00829 cpl_frame_get_filename(frame));
00830 }
00831 else {
00832 if (calib)
00833 cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
00834 else
00835 cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
00836 }
00837 }
00838
00839 return image;
00840 }
00841
00842
00869 cpl_table *dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
00870 {
00871 const char *func = "dfs_load_table";
00872
00873 cpl_frame *frame = NULL;
00874 cpl_table *table = NULL;
00875
00876
00877 frame = cpl_frameset_find(frameset, category);
00878
00879 if (frame) {
00880 table = cpl_table_load(cpl_frame_get_filename(frame), ext, 1);
00881 if (table == NULL) {
00882 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00883 cpl_msg_error(func, "Cannot load table %s",
00884 cpl_frame_get_filename(frame));
00885 }
00886 else
00887 cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
00888 }
00889
00890 return table;
00891 }
00892
00893
00919 cpl_propertylist *dfs_load_header(cpl_frameset *frameset,
00920 const char *category, int ext)
00921 {
00922 const char *func = "dfs_load_header";
00923
00924 cpl_frame *frame = NULL;
00925 cpl_propertylist *plist = NULL;
00926
00927
00928 frame = cpl_frameset_find(frameset, category);
00929
00930 if (frame) {
00931 plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext);
00932 if (plist == NULL) {
00933 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00934 cpl_msg_error(func, "Cannot load header from %s",
00935 cpl_frame_get_filename(frame));
00936 }
00937 }
00938
00939 return plist;
00940 }
00941
00942
00950 static void
00951 dfs_save(cpl_frameset *frameset, const void *object, cpl_frame_type type,
00952 const char *category, cpl_propertylist *header,
00953 const cpl_parameterlist *parlist, const char *recipename,
00954 const cpl_frame *raw_frame)
00955 {
00956 char *filename;
00957 cpl_frame *frame;
00958 cpl_propertylist *plist;
00959 const char *version = NULL;
00960 cpl_propertylist *raw_header = NULL;
00961
00962
00963 if (category == NULL || frameset == NULL || object == NULL ||
00964 raw_frame == NULL) {
00965 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00966 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
00967 return;
00968 }
00969
00970 if (type == CPL_FRAME_TYPE_IMAGE) {
00971 cpl_msg_debug(cpl_func, "Saving %s image to disk...", category);
00972 }
00973 else {
00974 cpl_msg_debug(cpl_func, "Saving %s table to disk...", category);
00975 }
00976
00977
00978 {
00979 const char *raw_filename =
00980 cpl_frame_get_filename(raw_frame);
00981
00982 raw_header = cpl_propertylist_load(raw_filename, 0);
00983 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00984 cpl_msg_error(cpl_func, "Could not read %s primary header", raw_filename);
00985 return;
00986 }
00987
00988 version = fors_dfs_pipeline_version(raw_header, NULL);
00989 cpl_propertylist_delete(raw_header);
00990
00991 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00992 cpl_msg_error(cpl_func, "Could not identify instrument version from %s header",
00993 raw_filename);
00994 return;
00995 }
00996 }
00997
00998 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
00999
01000 strlower(strcpy(filename, category));
01001 strcat(filename, ".fits");
01002
01003 frame = cpl_frame_new();
01004
01005 cpl_frame_set_filename(frame, filename);
01006 cpl_frame_set_tag(frame, category);
01007 cpl_frame_set_type(frame, type);
01008 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01009 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01010 if (cpl_error_get_code()) {
01011 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01012 cpl_msg_error(cpl_func, "Cannot initialise the product frame");
01013 cpl_frame_delete(frame);
01014 cpl_free(filename);
01015 cpl_free((void *)version);
01016 return;
01017 }
01018
01019
01020
01021
01022
01023
01024 if (header == NULL)
01025 plist = cpl_propertylist_new();
01026 else
01027 plist = header;
01028
01029 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01030 recipename, version, "PRO-1.15")) {
01031 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01032 cpl_msg_error(cpl_func, "Problem with product %s FITS header definition",
01033 category);
01034 if (header == NULL)
01035 cpl_propertylist_delete(plist);
01036 cpl_frame_delete(frame);
01037 cpl_free(filename);
01038 cpl_free((void *)version);
01039 return;
01040 }
01041
01042 cpl_free((void *)version);
01043
01044
01045
01046
01047
01048
01049 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01050 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01051 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01052 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01053
01054
01055
01056
01057
01058 if (type == CPL_FRAME_TYPE_IMAGE) {
01059 fors_image_save((fors_image *)object, plist, filename);
01060 }
01061 else {
01062 cpl_table_save((cpl_table *)object,
01063 plist, NULL, filename, CPL_IO_DEFAULT);
01064 }
01065
01066 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01067 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01068 cpl_msg_error(cpl_func, "Cannot save product %s to disk", filename);
01069 if (header == NULL)
01070 cpl_propertylist_delete(plist);
01071 cpl_frame_delete(frame);
01072 cpl_free(filename);
01073 return;
01074 }
01075
01076 if (header == NULL)
01077 cpl_propertylist_delete(plist);
01078
01079 cpl_free(filename);
01080
01081 cpl_frameset_insert(frameset, frame);
01082
01083 return;
01084 }
01085
01086
01107 void
01108 fors_dfs_save_image(cpl_frameset *frameset, const fors_image *image,
01109 const char *category, cpl_propertylist *header,
01110 const cpl_parameterlist *parlist, const char *recipename,
01111 const cpl_frame *raw_frame)
01112 {
01113 dfs_save(frameset, image, CPL_FRAME_TYPE_IMAGE,
01114 category, header,
01115 parlist, recipename,
01116 raw_frame);
01117 }
01118
01119 #undef cleanup
01120 #define cleanup \
01121 do { \
01122 cpl_propertylist_delete(wcs_header); \
01123 } while (0)
01124
01129 void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame,
01130 const fors_setting *setting)
01131 {
01132 bool invert = false;
01133 int extension = 0;
01134
01135 cpl_propertylist *wcs_header =
01136 cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
01137 extension, WCS_KEYS, invert);
01138
01139 cpl_propertylist_copy_property_regexp(header, wcs_header, ".*", invert);
01140
01141 double crpix1 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX1);
01142
01143 assure( !cpl_error_get_code(), return,
01144 "Could not read %s from %s", FORS_PFITS_CRPIX1,
01145 cpl_frame_get_filename(frame));
01146
01147 double crpix2 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX2);
01148
01149 assure( !cpl_error_get_code(), return,
01150 "Could not read %s from %s", FORS_PFITS_CRPIX2,
01151 cpl_frame_get_filename(frame));
01152
01153 cpl_propertylist_update_double(header, FORS_PFITS_CRPIX1,
01154 crpix1 - setting->prescan_x);
01155
01156 cpl_propertylist_update_double(header, FORS_PFITS_CRPIX2,
01157 crpix2 - setting->prescan_y);
01158
01159
01160 cleanup;
01161 return;
01162 }
01163
01164
01165 #undef cleanup
01166 #define cleanup \
01167 do { \
01168 cpl_propertylist_delete(time_header); \
01169 } while (0)
01170
01183 void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame,
01184 double exptime)
01185 {
01186 bool invert = false;
01187 int extension = 0;
01188
01189 cpl_propertylist *time_header = NULL;
01190
01191 if (frame) {
01192
01193 time_header =
01194 cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
01195 extension, "EXPTIME", invert);
01196
01197 if (time_header) {
01198 cpl_propertylist_copy_property_regexp(header,
01199 time_header, ".*", invert);
01200 }
01201 else {
01202 cpl_error_reset();
01203 }
01204 }
01205 else {
01206 while (cpl_propertylist_erase(header, "EXPTIME"));
01207 cpl_propertylist_update_double(header, "EXPTIME", exptime);
01208 }
01209
01210 cleanup;
01211 return;
01212 }
01213
01214
01222 void
01223 fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
01224 const char *category, cpl_propertylist *header,
01225 const cpl_parameterlist *parlist, const char *recipename,
01226 const cpl_frame *raw_frame)
01227 {
01228 dfs_save(frameset, table, CPL_FRAME_TYPE_TABLE,
01229 category, header,
01230 parlist, recipename,
01231 raw_frame);
01232 }
01233
01266 int dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
01267 const char *category, cpl_propertylist *header,
01268 const cpl_parameterlist *parlist, const char *recipename,
01269 const char *version)
01270 {
01271 const char *func = "dfs_save_image";
01272
01273 char *filename;
01274 cpl_frame *frame;
01275 cpl_propertylist *plist;
01276
01277
01278 if (category == NULL || frameset == NULL || image == NULL) {
01279 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01280 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01281 return -1;
01282 }
01283
01284 cpl_msg_info(func, "Saving %s image to disk...", category);
01285
01286 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01287
01288 strlower(strcpy(filename, category));
01289 strcat(filename, ".fits");
01290
01291 frame = cpl_frame_new();
01292
01293 cpl_frame_set_filename(frame, filename);
01294 cpl_frame_set_tag(frame, category);
01295 cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE);
01296 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01297 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01298 if (cpl_error_get_code()) {
01299 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01300 cpl_msg_error(func, "Cannot initialise the product frame");
01301 cpl_frame_delete(frame);
01302 cpl_free(filename);
01303 return -1;
01304 }
01305
01306
01307
01308
01309
01310
01311 if (header == NULL)
01312 plist = cpl_propertylist_new();
01313 else
01314 plist = header;
01315
01316 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01317 recipename, version, "PRO-1.15")) {
01318 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01319 cpl_msg_error(func, "Problem with product %s FITS header definition",
01320 category);
01321 if (header == NULL)
01322 cpl_propertylist_delete(plist);
01323 cpl_frame_delete(frame);
01324 cpl_free(filename);
01325 return -1;
01326 }
01327
01328
01329
01330
01331
01332
01333 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01334 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01335 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01336 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01337
01338
01339
01340
01341
01342 if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist,
01343 CPL_IO_DEFAULT)) {
01344 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01345 cpl_msg_error(func, "Cannot save product %s to disk", filename);
01346 if (header == NULL)
01347 cpl_propertylist_delete(plist);
01348 cpl_frame_delete(frame);
01349 cpl_free(filename);
01350 return -1;
01351 }
01352
01353 if (header == NULL)
01354 cpl_propertylist_delete(plist);
01355
01356 cpl_free(filename);
01357
01358 cpl_frameset_insert(frameset, frame);
01359
01360 return 0;
01361 }
01362
01363
01396 int dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
01397 const char *category, cpl_propertylist *header,
01398 const cpl_parameterlist *parlist, const char *recipename,
01399 const char *version)
01400 {
01401 const char *func = "dfs_save_table";
01402
01403 char *filename;
01404 cpl_frame *frame;
01405 cpl_propertylist *plist;
01406
01407
01408 if (category == NULL || frameset == NULL || table == NULL) {
01409 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01410 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01411 return -1;
01412 }
01413
01414 cpl_msg_info(func, "Saving %s table to disk...", category);
01415
01416
01417
01418
01419 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01420
01421 strlower(strcpy(filename, category));
01422
01423
01424
01425
01426 strcat(filename, ".fits");
01427
01428 frame = cpl_frame_new();
01429
01430 cpl_frame_set_filename(frame, filename);
01431 cpl_frame_set_tag(frame, category);
01432 cpl_frame_set_type(frame, CPL_FRAME_TYPE_TABLE);
01433 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01434 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01435 if (cpl_error_get_code()) {
01436 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01437 cpl_msg_error(func, "Cannot initialise the product frame");
01438 cpl_frame_delete(frame);
01439 cpl_free(filename);
01440 return -1;
01441 }
01442
01443
01444
01445
01446
01447
01448 if (header == NULL)
01449 plist = cpl_propertylist_new();
01450 else
01451 plist = header;
01452
01453 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01454 recipename, version, "PRO-1.15")) {
01455 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01456 cpl_msg_error(func, "Problem with product %s FITS header definition",
01457 category);
01458 if (header == NULL)
01459 cpl_propertylist_delete(plist);
01460 cpl_frame_delete(frame);
01461 cpl_free(filename);
01462 return -1;
01463 }
01464
01465
01466
01467
01468
01469
01470 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
01471 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
01472 cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
01473 cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
01474
01475
01476
01477
01478
01479 if (cpl_table_save(table, plist, NULL, filename, CPL_IO_DEFAULT)) {
01480 cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
01481 cpl_msg_error(func, "Cannot save product %s to disk", filename);
01482 if (header == NULL)
01483 cpl_propertylist_delete(plist);
01484 cpl_frame_delete(frame);
01485 cpl_free(filename);
01486 return -1;
01487 }
01488
01489 if (header == NULL)
01490 cpl_propertylist_delete(plist);
01491 cpl_free(filename);
01492
01493 cpl_frameset_insert(frameset, frame);
01494
01495 return 0;
01496 }
01497
01498
01509 int dfs_files_dont_exist(cpl_frameset *frameset)
01510 {
01511 const char *func = "dfs_files_dont_exist";
01512 cpl_frame *frame;
01513
01514
01515 if (frameset == NULL) {
01516 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01517 return 1;
01518 }
01519
01520 if (cpl_frameset_is_empty(frameset)) {
01521 return 0;
01522 }
01523
01524 frame = cpl_frameset_get_first(frameset);
01525
01526 while (frame) {
01527 if (access(cpl_frame_get_filename(frame), F_OK)) {
01528 cpl_msg_error(func, "File %s (%s) was not found",
01529 cpl_frame_get_filename(frame),
01530 cpl_frame_get_tag(frame));
01531 cpl_error_set(func, CPL_ERROR_FILE_NOT_FOUND);
01532 }
01533
01534 frame = cpl_frameset_get_next(frameset);
01535 }
01536
01537 if (cpl_error_get_code())
01538 return 1;
01539
01540 return 0;
01541 }
01542
01560 int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
01561 {
01562 const char *func = "dfs_equal_keyword";
01563
01564 cpl_frame *frame;
01565 cpl_propertylist *reference;
01566 cpl_type rtype;
01567 cpl_type type;
01568 const char *rstring;
01569 const char *string;
01570 int rintero;
01571 int intero;
01572 int found;
01573
01574
01575 if (frameset == NULL || keyword == NULL) {
01576 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01577 return 0;
01578 }
01579
01580 if (cpl_frameset_is_empty(frameset)) {
01581 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
01582 return 0;
01583 }
01584
01585 frame = cpl_frameset_get_first(frameset);
01586
01587 found = 0;
01588
01589 while (frame) {
01590
01591 reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01592 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01593 cpl_error_reset();
01594 frame = cpl_frameset_get_next(frameset);
01595 continue;
01596 }
01597
01598 if (cpl_propertylist_has(reference, keyword)) {
01599 rtype = cpl_propertylist_get_type(reference, keyword);
01600
01601 if (rtype == CPL_TYPE_STRING) {
01602 found = 1;
01603 rstring = cpl_strdup(cpl_propertylist_get_string(reference,
01604 keyword));
01605 cpl_propertylist_delete(reference);
01606 break;
01607 }
01608
01609 if (rtype == CPL_TYPE_INT) {
01610 found = 1;
01611 rintero = cpl_propertylist_get_int(reference, keyword);
01612 cpl_propertylist_delete(reference);
01613 break;
01614 }
01615
01616 cpl_propertylist_delete(reference);
01617 return 0;
01618 }
01619
01620 cpl_propertylist_delete(reference);
01621
01622 frame = cpl_frameset_get_next(frameset);
01623 }
01624
01625
01626 if (!found)
01627 return 1;
01628
01629 frame = cpl_frameset_get_first(frameset);
01630
01631 while (frame) {
01632
01633 reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01634 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01635 cpl_error_reset();
01636 frame = cpl_frameset_get_next(frameset);
01637 continue;
01638 }
01639
01640 if (cpl_propertylist_has(reference, keyword)) {
01641
01642 type = cpl_propertylist_get_type(reference, keyword);
01643
01644 if (rtype != type) {
01645 cpl_propertylist_delete(reference);
01646 return 0;
01647 }
01648
01649 if (rtype == CPL_TYPE_STRING) {
01650 string = cpl_propertylist_get_string(reference,
01651 keyword);
01652 if (strcmp(rstring, string)) {
01653 cpl_propertylist_delete(reference);
01654 return 0;
01655 }
01656 }
01657
01658 if (rtype == CPL_TYPE_INT) {
01659 intero = cpl_propertylist_get_int(reference, keyword);
01660 if (rintero - intero) {
01661 cpl_propertylist_delete(reference);
01662 return 0;
01663 }
01664 }
01665 }
01666
01667 cpl_propertylist_delete(reference);
01668
01669 frame = cpl_frameset_get_next(frameset);
01670 }
01671
01672 if (rtype == CPL_TYPE_STRING)
01673 cpl_free((void *)rstring);
01674
01675 return 1;
01676
01677 }
01678