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 char *dfs_generate_filename(const char *category)
00086 {
00087 char *filename = cpl_calloc(strlen(category) + 6, sizeof(char));
00088
00089 strlower(strcpy(filename, category));
00090 strcat(filename, ".fits");
00091
00092 return filename;
00093 }
00094
00095
00106
00107 static void
00108 errorstate_dump_one(unsigned self, unsigned first, unsigned last)
00109 {
00110
00111 const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
00112 const unsigned newest = is_reverse ? first : last;
00113 const unsigned oldest = is_reverse ? last : first;
00114 const char * revmsg = is_reverse ? " in reverse order" : "";
00115
00116
00117
00118
00119
00120 if (newest == 0) {
00121 cpl_msg_info(cpl_func, "No error(s) to dump");
00122
00123 } else {
00124
00125
00126 if (self == first) {
00127 if (oldest == 1) {
00128 cpl_msg_debug(cpl_func, "Dumping all %u error(s)%s:", newest,
00129 revmsg);
00130 } else {
00131 cpl_msg_error(cpl_func, "Dumping the %u most recent error(s) "
00132 "out of a total of %u errors%s:",
00133 newest - oldest + 1, newest, revmsg);
00134 }
00135 }
00136
00137 const char *message_from_cpl = cpl_error_get_message();
00138
00139 if (message_from_cpl == NULL) {
00140
00141 cpl_msg_error(cpl_func, "Unspecified error");
00142 }
00143
00144
00145
00146
00147
00148
00149
00150 while (*message_from_cpl != '\0' && *message_from_cpl != ':') {
00151 message_from_cpl += 1;
00152 }
00153
00154 if (*message_from_cpl != '\0') {
00155 message_from_cpl += 1;
00156
00157 if (*message_from_cpl == ' ') message_from_cpl++;
00158
00159 if (*message_from_cpl != '\0') {
00160
00161 cpl_msg_error(cpl_func, "%s [%s]", message_from_cpl,
00162 cpl_error_get_where());
00163 }
00164 else {
00165 cpl_msg_error(cpl_func, "%s [%s]",
00166 cpl_error_get_message(), cpl_error_get_where());
00167 }
00168 }
00169 else {
00170
00171 cpl_msg_error(cpl_func, "%s [%s]",
00172 cpl_error_get_message(), cpl_error_get_where());
00173 }
00174 }
00175
00176 return;
00177 }
00178
00179
00180
00190
00191 void fors_begin(cpl_frameset *frames,
00192 const char *description_short)
00193 {
00194 cpl_msg_info(cpl_func, "%s", PACKAGE_STRING);
00195 cpl_msg_info(cpl_func, "%s", description_short);
00196
00197 fors_dfs_set_groups(frames);
00198 cpl_msg_info(cpl_func, "Input frame%s:",
00199 cpl_frameset_get_size(frames) != 1 ? "s" : "");
00200 fors_frameset_print(frames);
00201
00202 return;
00203 }
00204
00205
00218
00219 int fors_end(const cpl_frameset *frames, cpl_errorstate before_exec)
00220 {
00221 if (cpl_error_get_code() == CPL_ERROR_NONE) {
00222
00223 const cpl_frame *f;
00224 int i_frame = 0;
00225
00226 cpl_msg_info(cpl_func, "Product frame%s:",
00227 cpl_frameset_get_size(frames) != 1 ? "s" : "");
00228
00229 for (i_frame = 0; i_frame < cpl_frameset_get_size(frames); ++i_frame) {
00230 f = cpl_frameset_get_position_const(frames, i_frame);
00231 if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_PRODUCT) {
00232 fors_frame_print(f);
00233 }
00234 }
00235
00236
00237
00238 return 0;
00239 }
00240 else {
00241
00242 cpl_errorstate_dump(before_exec, CPL_FALSE, errorstate_dump_one);
00243
00244 return 1;
00245 }
00246 }
00247
00248 #undef cleanup
00249 #define cleanup
00250
00255
00256 void
00257 fors_dfs_set_groups(cpl_frameset * set)
00258 {
00259 cpl_frame *f;
00260 int i_frame = 0;
00261
00262 assure( set != NULL, return, NULL );
00263
00264 for (i_frame = 0; i_frame < cpl_frameset_get_size(set); ++i_frame) {
00265
00266 f = cpl_frameset_get_position_const(set, i_frame);
00267
00268 const char *tag = cpl_frame_get_tag(f);
00269
00270 if (tag != NULL) {
00271 if (strcmp(tag, BIAS ) == 0 ||
00272 strcmp(tag, DARK ) == 0 ||
00273 strcmp(tag, SCREEN_FLAT_IMG ) == 0 ||
00274 strcmp(tag, SKY_FLAT_IMG ) == 0 ||
00275 strcmp(tag, STANDARD_IMG ) == 0 ||
00276 strcmp(tag, "LAMP_PMOS" ) == 0 ||
00277 strcmp(tag, "LAMP_MXU" ) == 0 ||
00278 strcmp(tag, "LAMP_MOS" ) == 0 ||
00279 strcmp(tag, "LAMP_LSS" ) == 0 ||
00280 strcmp(tag, "SCREEN_FLAT_PMOS") == 0 ||
00281 strcmp(tag, "STANDARD_PMOS" ) == 0 ||
00282 strcmp(tag, "SCIENCE_PMOS" ) == 0 ||
00283 strcmp(tag, "SCIENCE_MOS" ) == 0 ||
00284 strcmp(tag, "SCIENCE_MXU" ) == 0 ||
00285 strcmp(tag, "SCIENCE_LSS" ) == 0 ||
00286 strcmp(tag, "STANDARD_MOS" ) == 0 ||
00287 strcmp(tag, "STANDARD_MXU" ) == 0 ||
00288 strcmp(tag, "STANDARD_LSS" ) == 0 ||
00289 strcmp(tag, SCIENCE_IMG ) == 0 ||
00290 strcmp(tag, "SCREEN_FLAT_MXU" ) == 0 ||
00291 strcmp(tag, "SCREEN_FLAT_MOS" ) == 0 ||
00292 strcmp(tag, "SCREEN_FLAT_LSS" ) == 0 ) {
00293 cpl_frame_set_group(f, CPL_FRAME_GROUP_RAW);
00294 }
00295 else if (strcmp(tag, MASTER_BIAS ) == 0 ||
00296 strcmp(tag, MASTER_DARK ) == 0 ||
00297 strcmp(tag, MASTER_SCREEN_FLAT_IMG ) == 0 ||
00298 strcmp(tag, MASTER_SKY_FLAT_IMG ) == 0 ||
00299 strcmp(tag, ALIGNED_PHOT ) == 0 ||
00300 strcmp(tag, "MASTER_NORM_FLAT_PMOS" ) == 0 ||
00301 strcmp(tag, "DISP_COEFF_PMOS" ) == 0 ||
00302 strcmp(tag, "CURV_COEFF_PMOS" ) == 0 ||
00303 strcmp(tag, "SLIT_LOCATION_PMOS" ) == 0 ||
00304 strcmp(tag, "MASTER_NORM_FLAT_MOS" ) == 0 ||
00305 strcmp(tag, "MASTER_NORM_FLAT_MXU" ) == 0 ||
00306 strcmp(tag, "MASTER_NORM_FLAT_LSS" ) == 0 ||
00307 strcmp(tag, "MASTER_NORM_FLAT_LONG_MOS" ) == 0 ||
00308 strcmp(tag, "SLIT_LOCATION_MOS" ) == 0 ||
00309 strcmp(tag, "SLIT_LOCATION_MXU" ) == 0 ||
00310 strcmp(tag, "SLIT_LOCATION_LSS" ) == 0 ||
00311 strcmp(tag, "SLIT_LOCATION_LONG_MOS" ) == 0 ||
00312 strcmp(tag, "CURV_COEFF_MOS" ) == 0 ||
00313 strcmp(tag, "CURV_COEFF_MXU" ) == 0 ||
00314 strcmp(tag, "CURV_COEFF_LSS" ) == 0 ||
00315 strcmp(tag, "DISP_COEFF_MOS" ) == 0 ||
00316 strcmp(tag, "DISP_COEFF_MXU" ) == 0 ||
00317 strcmp(tag, "DISP_COEFF_LSS" ) == 0 ||
00318 strcmp(tag, "DISP_COEFF_LONG_MOS" ) == 0 ||
00319 strcmp(tag, "FLAT_SED_MOS" ) == 0 ||
00320 strcmp(tag, "FLAT_SED_MXU" ) == 0 ||
00321 strcmp(tag, "FLAT_SED_LSS" ) == 0 ||
00322 strcmp(tag, "FLAT_SED_LONG_MOS" ) == 0 ||
00323
00324 strcmp(tag, FLX_STD_IMG ) == 0 ||
00325 strcmp(tag, "EXTINCT_TABLE" ) == 0 ||
00326 strcmp(tag, "MASTER_LINECAT" ) == 0 ||
00327 strcmp(tag, "MASTER_DISTORTION_TABLE" ) == 0 ||
00328 strcmp(tag, "GLOBAL_DISTORTION_TABLE" ) == 0 ||
00329 strcmp(tag, "RETARDER_WAVEPLATE_CHROMATISM") == 0 ||
00330 strcmp(tag, "GRISM_TABLE" ) == 0 ||
00331 strcmp(tag, "STD_PMOS_TABLE" ) == 0 ||
00332 strcmp(tag, "TELLURIC_CONTAMINATION" ) == 0 ||
00333 strcmp(tag, "STD_FLUX_TABLE" ) == 0 ||
00334 strcmp(tag, "SPECPHOT_TABLE" ) == 0 ||
00335 strcmp(tag, PHOT_TABLE ) == 0) {
00336 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
00337 }
00338 else {
00339 cpl_msg_warning(cpl_func, "Unrecognized frame tag: '%s'",
00340 tag);
00341 }
00342 }
00343 }
00344
00345 return;
00346 }
00347
00348
00349 #undef cleanup
00350 #define cleanup
00351
00359
00360 const char *
00361 fors_dfs_pipeline_version(const cpl_propertylist *header,
00362 const char **instrument_version)
00363 {
00364 const char *instrume = NULL;
00365
00366 instrume = cpl_propertylist_get_string(header,
00367 FORS_PFITS_INSTRUME);
00368 assure( !cpl_error_get_code(), return NULL,
00369 "Missing keyword %s in input header", FORS_PFITS_INSTRUME);
00370
00371 assure( strlen(instrume) >= 5, return NULL,
00372 "%s keyword must be 'fors1' or 'fors2', not '%s'",
00373 FORS_PFITS_INSTRUME, instrume);
00374
00375 assure( instrume[4] == '1' || instrume[4] == '2', return NULL,
00376 "Unrecognized %s: %s", FORS_PFITS_INSTRUME, instrume);
00377
00378 if (instrument_version != NULL) {
00379 *instrument_version = cpl_sprintf("%s", instrume);
00380 }
00381
00382 return cpl_sprintf("fors%c/%s", instrume[4], PACKAGE_VERSION);
00383 }
00384
00385
00407
00408 int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name,
00409 const cpl_table *defaults)
00410 {
00411 const char *func = "dfs_get_parameter_int";
00412
00413 const char *alias;
00414 cpl_parameter *param;
00415
00416
00417 if (parlist == NULL) {
00418 cpl_msg_error(func, "Missing input parameter list");
00419 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00420 return 0;
00421 }
00422
00423 if (name == NULL) {
00424 cpl_msg_error(func, "Missing input parameter name");
00425 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00426 return 0;
00427 }
00428
00429 param = cpl_parameterlist_find(parlist, name);
00430
00431 if (param == NULL) {
00432 cpl_msg_error(func, "Wrong parameter name: %s", name);
00433 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00434 return 0;
00435 }
00436
00437 if (cpl_parameter_get_type(param) != CPL_TYPE_INT) {
00438 cpl_msg_error(func, "Unexpected type for parameter "
00439 "\"%s\": it should be integer", name);
00440 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00441 return 0;
00442 }
00443
00444 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00445
00446
00447 if (defaults &&
00448 cpl_parameter_get_default_int(param) == cpl_parameter_get_int(param)) {
00449
00450 if (cpl_table_has_column(defaults, alias)) {
00451 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00452 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00453 "column \"%s\": it should be integer", alias);
00454 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00455 return 0;
00456 }
00457 if (cpl_table_is_valid(defaults, alias, 0)) {
00458 cpl_parameter_set_int(param, cpl_table_get_int(defaults,
00459 alias, 0, NULL));
00460 }
00461 else {
00462 cpl_msg_error(func, "Invalid parameter value in table "
00463 "column \"%s\"", alias);
00464 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00465 return 0;
00466 }
00467 }
00468 else {
00469 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00470 "- using recipe default", alias);
00471 }
00472 }
00473
00474 cpl_msg_info(func, "%s: %d", alias, cpl_parameter_get_int(param));
00475
00476 return cpl_parameter_get_int(param);
00477
00478 }
00479
00480
00502
00503 double dfs_get_parameter_double(cpl_parameterlist *parlist,
00504 const char *name, const cpl_table *defaults)
00505 {
00506 const char *func = "dfs_get_parameter_double";
00507
00508 const char *alias;
00509 cpl_parameter *param;
00510
00511
00512 if (parlist == NULL) {
00513 cpl_msg_error(func, "Missing input parameter list");
00514 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00515 return 0;
00516 }
00517
00518 if (name == NULL) {
00519 cpl_msg_error(func, "Missing input parameter name");
00520 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00521 return 0;
00522 }
00523
00524 param = cpl_parameterlist_find(parlist, name);
00525
00526 if (param == NULL) {
00527 cpl_msg_error(func, "Wrong parameter name: %s", name);
00528 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00529 return 0;
00530 }
00531
00532 if (cpl_parameter_get_type(param) != CPL_TYPE_DOUBLE) {
00533 cpl_msg_error(func, "Unexpected type for parameter "
00534 "\"%s\": it should be double", name);
00535 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00536 return 0;
00537 }
00538
00539 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00540
00541
00542 if (defaults &&
00543 cpl_parameter_get_default_double(param) ==
00544 cpl_parameter_get_double(param)) {
00545
00546 if (cpl_table_has_column(defaults, alias)) {
00547 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_DOUBLE) {
00548 cpl_msg_error(func, "Unexpected type for GRISM_TABL "
00549 "column \"%s\": it should be double", alias);
00550 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00551 return 0;
00552 }
00553 if (cpl_table_is_valid(defaults, alias, 0)) {
00554 cpl_parameter_set_double(param, cpl_table_get_double(defaults,
00555 alias, 0, NULL));
00556 }
00557 else {
00558 cpl_msg_error(func, "Invalid parameter value in table "
00559 "column \"%s\"", alias);
00560 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00561 return 0;
00562 }
00563 }
00564 else {
00565 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00566 "- using recipe default", alias);
00567 }
00568 }
00569
00570 cpl_msg_info(func, "%s: %f", alias, cpl_parameter_get_double(param));
00571
00572 return cpl_parameter_get_double(param);
00573
00574 }
00575
00576
00598
00599 const char *dfs_get_parameter_string(cpl_parameterlist *parlist,
00600 const char *name,
00601 const cpl_table *defaults)
00602 {
00603 const char *func = "dfs_get_parameter_string";
00604
00605 const char *alias;
00606 cpl_parameter *param;
00607
00608
00609 if (parlist == NULL) {
00610 cpl_msg_error(func, "Missing input parameter list");
00611 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00612 return 0;
00613 }
00614
00615 if (name == NULL) {
00616 cpl_msg_error(func, "Missing input parameter name");
00617 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00618 return 0;
00619 }
00620
00621 param = cpl_parameterlist_find(parlist, name);
00622
00623 if (param == NULL) {
00624 cpl_msg_error(func, "Wrong parameter name: %s", name);
00625 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00626 return 0;
00627 }
00628
00629 if (cpl_parameter_get_type(param) != CPL_TYPE_STRING) {
00630 cpl_msg_error(func, "Unexpected type for parameter "
00631 "\"%s\": it should be string", name);
00632 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00633 return 0;
00634 }
00635
00636 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00637
00638
00639 if (defaults &&
00640 strcmp(cpl_parameter_get_default_string(param),
00641 cpl_parameter_get_string(param)) == 0) {
00642
00643 if (cpl_table_has_column(defaults, alias)) {
00644 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_STRING) {
00645 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00646 "column \"%s\": it should be string", alias);
00647 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00648 return 0;
00649 }
00650 if (cpl_table_is_valid(defaults, alias, 0)) {
00651 cpl_parameter_set_string(param, cpl_table_get_string(defaults,
00652 alias, 0));
00653 }
00654 else {
00655 cpl_msg_error(func, "Invalid parameter value in table "
00656 "column \"%s\"", alias);
00657 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00658 return 0;
00659 }
00660 }
00661 else {
00662 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00663 "- using recipe default", alias);
00664 }
00665 }
00666
00667 cpl_msg_info(func, "%s: %s", alias, cpl_parameter_get_string(param));
00668
00669 return cpl_parameter_get_string(param);
00670
00671 }
00672
00673
00695
00696 int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name,
00697 const cpl_table *defaults)
00698 {
00699 const char *func = "dfs_get_parameter_bool";
00700
00701 const char *alias;
00702 cpl_parameter *param;
00703 int value;
00704
00705
00706 if (parlist == NULL) {
00707 cpl_msg_error(func, "Missing input parameter list");
00708 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00709 return 0;
00710 }
00711
00712 if (name == NULL) {
00713 cpl_msg_error(func, "Missing input parameter name");
00714 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
00715 return 0;
00716 }
00717
00718 param = cpl_parameterlist_find(parlist, name);
00719
00720 if (param == NULL) {
00721 cpl_msg_error(func, "Wrong parameter name: %s", name);
00722 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
00723 return 0;
00724 }
00725
00726 if (cpl_parameter_get_type(param) != CPL_TYPE_BOOL) {
00727 cpl_msg_error(func, "Unexpected type for parameter "
00728 "\"%s\": it should be boolean", name);
00729 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00730 return 0;
00731 }
00732
00733 alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
00734
00735
00736 if (defaults &&
00737 cpl_parameter_get_default_bool(param) ==
00738 cpl_parameter_get_bool(param)) {
00739
00740 if (cpl_table_has_column(defaults, alias)) {
00741 if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
00742 cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
00743 "column \"%s\": it should be integer", alias);
00744 cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
00745 return 0;
00746 }
00747 if (cpl_table_is_valid(defaults, alias, 0)) {
00748 value = cpl_table_get_int(defaults, alias, 0, NULL);
00749 if (value < 0 || value > 1) {
00750 cpl_msg_error(func, "Illegal parameter value in table "
00751 "column \"%s\": it should be either 0 or 1",
00752 alias);
00753 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00754 return 0;
00755 }
00756 cpl_parameter_set_bool(param, value);
00757 }
00758 else {
00759 cpl_msg_error(func, "Invalid parameter value in table "
00760 "column \"%s\"", alias);
00761 cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
00762 return 0;
00763 }
00764 }
00765 else {
00766 cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
00767 "- using recipe default", alias);
00768 }
00769 }
00770
00771 value = cpl_parameter_get_bool(param);
00772
00773 if (value) {
00774 cpl_msg_info(func, "%s: TRUE", alias);
00775 }
00776 else {
00777 cpl_msg_info(func, "%s: FALSE", alias);
00778 }
00779
00780 return value;
00781
00782 }
00783
00784
00788
00789 int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
00790 {
00791 return dfs_get_parameter_bool((cpl_parameterlist *)parlist, name, NULL);
00792 }
00793
00794
00798
00799 int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
00800 {
00801 return dfs_get_parameter_int((cpl_parameterlist *)parlist, name, NULL);
00802 }
00803
00804
00808
00809 double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
00810 {
00811 return dfs_get_parameter_double((cpl_parameterlist *)parlist, name, NULL);
00812 }
00813
00814
00818
00819 const char *dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
00820 {
00821 return dfs_get_parameter_string((cpl_parameterlist *)parlist, name, NULL);
00822 }
00823
00824
00852
00853 cpl_image *dfs_load_image(cpl_frameset *frameset, const char *category,
00854 cpl_type type, int ext, int calib)
00855 {
00856 const char *func = "dfs_load_image";
00857
00858 cpl_frame *frame = NULL;
00859 cpl_image *image = NULL;
00860
00861
00862 frame = cpl_frameset_find(frameset, category);
00863
00864 if (frame) {
00865 image = cpl_image_load(cpl_frame_get_filename(frame), type, 0, ext);
00866 if (image == NULL) {
00867 cpl_msg_error(cpl_error_get_where(),"%s", cpl_error_get_message());
00868 cpl_msg_error(func, "Cannot load image %s",
00869 cpl_frame_get_filename(frame));
00870 }
00871 else {
00872 if (calib)
00873 cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
00874 else
00875 cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
00876 }
00877 }
00878
00879 return image;
00880 }
00881
00882
00908
00909 cpl_table *dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
00910 {
00911 const char *func = "dfs_load_table";
00912
00913 cpl_frame *frame = NULL;
00914 cpl_table *table = NULL;
00915
00916
00917 frame = cpl_frameset_find(frameset, category);
00918
00919 if (frame) {
00920 table = cpl_table_load(cpl_frame_get_filename(frame), ext, 1);
00921 if (table == NULL) {
00922 cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
00923 cpl_msg_error(func, "Cannot load table %s",
00924 cpl_frame_get_filename(frame));
00925 }
00926 }
00927
00928 return table;
00929 }
00930
00931
00956
00957 cpl_propertylist *dfs_load_header(cpl_frameset *frameset,
00958 const char *category, int ext)
00959 {
00960 const char *func = "dfs_load_header";
00961
00962 cpl_frame *frame = NULL;
00963 cpl_propertylist *plist = NULL;
00964
00965
00966 frame = cpl_frameset_find(frameset, category);
00967
00968 if (frame) {
00969 plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext);
00970 if (plist == NULL) {
00971 cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
00972 cpl_msg_error(func, "Cannot load header from %s",
00973 cpl_frame_get_filename(frame));
00974 }
00975 }
00976
00977 return plist;
00978 }
00979
00980
00987
00988 static void
00989 dfs_save(cpl_frameset *frameset, const void *object, fors_type type,
00990 const char *category, cpl_propertylist *header,
00991 cpl_propertylist *extra_header,
00992 const cpl_parameterlist *parlist, const char *recipename,
00993 const cpl_frame *inherit_frame)
00994 {
00995 char *filename;
00996 cpl_frame *frame;
00997 cpl_propertylist *plist;
00998 const char *version = NULL;
00999 cpl_propertylist *raw_header = NULL;
01000
01001
01002 if (category == NULL || frameset == NULL || object == NULL ||
01003 inherit_frame == NULL) {
01004 cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
01005 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
01006 return;
01007 }
01008
01009 if (type == FORS_TYPE_TABLE) {
01010 cpl_msg_debug(cpl_func, "Saving %s table to disk...", category);
01011 }
01012 else {
01013 cpl_msg_debug(cpl_func, "Saving %s image to disk...", category);
01014 }
01015
01016
01017 {
01018 const char *raw_filename =
01019 cpl_frame_get_filename(inherit_frame);
01020
01021 raw_header = cpl_propertylist_load(raw_filename, 0);
01022 if (raw_header == NULL) {
01023 cpl_msg_error(cpl_func, "Could not read %s primary header", raw_filename);
01024 return;
01025 }
01026
01027 version = fors_dfs_pipeline_version(raw_header, NULL);
01028 cpl_propertylist_delete(raw_header);
01029
01030 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01031 cpl_msg_error(cpl_func, "Could not identify instrument version from %s header",
01032 raw_filename);
01033 return;
01034 }
01035 }
01036
01037 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01038
01039 strlower(strcpy(filename, category));
01040 strcat(filename, ".fits");
01041
01042 frame = cpl_frame_new();
01043
01044 cpl_frame_set_filename(frame, filename);
01045 cpl_frame_set_tag(frame, category);
01046 cpl_frame_set_type(frame, CPL_FRAME_TYPE_ANY);
01047 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01048 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01049 if (cpl_error_get_code()) {
01050 cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
01051 cpl_msg_error(cpl_func, "Cannot initialise the product frame");
01052 cpl_frame_delete(frame);
01053 cpl_free(filename);
01054 cpl_free((void *)version);
01055 return;
01056 }
01057
01058
01059
01060
01061
01062
01063 if (header == NULL)
01064 plist = cpl_propertylist_new();
01065 else
01066 plist = cpl_propertylist_duplicate(header);
01067
01068 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01069 recipename, version, "PRO-1.15",
01070 inherit_frame)) {
01071 cpl_msg_error(cpl_func, "Error found in %s: %s",
01072 cpl_error_get_where(), cpl_error_get_message());
01073 cpl_msg_error(cpl_func, "Problem with product %s FITS header definition",
01074 category);
01075 cpl_propertylist_delete(plist);
01076 cpl_frame_delete(frame);
01077 cpl_free(filename);
01078 cpl_free((void *)version);
01079 return;
01080 }
01081
01082 cpl_free((void *)version);
01083
01084
01085
01086
01087
01088 if (type == FORS_TYPE_IMAGE_ERR) {
01089 fors_image_save((fors_image *)object, plist, extra_header, filename);
01090 }
01091 else if (type == FORS_TYPE_IMAGE) {
01092 cpl_image_save((cpl_image *)object, filename, CPL_BPP_IEEE_FLOAT, plist,
01093 CPL_IO_DEFAULT);
01094 }
01095 else {
01096 cpl_table_save((cpl_table *)object,
01097 plist, NULL, filename, CPL_IO_DEFAULT);
01098 }
01099
01100 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01101 cpl_msg_error(cpl_func, "Error found in %s: %s",
01102 cpl_error_get_where(), cpl_error_get_message());
01103 cpl_msg_error(cpl_func, "Cannot save product %s to disk", filename);
01104 cpl_propertylist_delete(plist);
01105 cpl_frame_delete(frame);
01106 cpl_free(filename);
01107 return;
01108 }
01109
01110 cpl_propertylist_delete(plist);
01111
01112 cpl_free(filename);
01113
01114 cpl_frameset_insert(frameset, frame);
01115
01116 return;
01117 }
01118
01119
01140
01141 void
01142 fors_dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
01143 const char *category, cpl_propertylist *header,
01144 const cpl_parameterlist *parlist, const char *recipename,
01145 const cpl_frame *inherit_frame)
01146 {
01147 dfs_save(frameset, image, FORS_TYPE_IMAGE,
01148 category, header, NULL,
01149 parlist, recipename,
01150 inherit_frame);
01151 }
01152
01153
01175
01176 void
01177 fors_dfs_save_image_mask(cpl_frameset *frameset, const cpl_image *image,
01178 const cpl_image *mask, const char *category,
01179 cpl_propertylist *header,
01180 const cpl_parameterlist *parlist, const char *recipename,
01181 const cpl_frame *inherit_frame)
01182 {
01183 char *filename;
01184 cpl_propertylist * extension_header;
01185
01186 dfs_save(frameset, image, FORS_TYPE_IMAGE,
01187 category, header, NULL,
01188 parlist, recipename,
01189 inherit_frame);
01190
01191 extension_header = cpl_propertylist_new();
01192 cpl_propertylist_append_string(extension_header,
01193 "EXTNAME", "IMAGE.BPM");
01194
01195 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01196
01197 strlower(strcpy(filename, category));
01198 strcat(filename, ".fits");
01199
01200 cpl_image_save(mask, filename, CPL_BPP_IEEE_FLOAT, extension_header,
01201 CPL_IO_EXTEND);
01202 cpl_propertylist_delete(extension_header);
01203 cpl_free(filename);
01204
01205 }
01206
01207
01228
01229 void
01230 fors_dfs_save_image_err(cpl_frameset *frameset, const fors_image *image,
01231 const char *category, cpl_propertylist *header,
01232 cpl_propertylist *err_header,
01233 const cpl_parameterlist *parlist, const char *recipename,
01234 const cpl_frame *inherit_frame)
01235 {
01236 dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
01237 category, header, err_header,
01238 parlist, recipename,
01239 inherit_frame);
01240 }
01241
01242
01265
01266 void
01267 fors_dfs_save_image_err_mask(cpl_frameset *frameset, const fors_image *image,
01268 const cpl_image *mask, const char *category,
01269 cpl_propertylist *header,
01270 const cpl_parameterlist *parlist, const char *recipename,
01271 const cpl_frame *inherit_frame)
01272 {
01273 char *filename;
01274 cpl_propertylist * extension_header;
01275
01276 dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
01277 category, header, NULL,
01278 parlist, recipename,
01279 inherit_frame);
01280
01281 extension_header = cpl_propertylist_new();
01282 cpl_propertylist_append_string(extension_header,
01283 "EXTNAME", "IMAGE.BPM");
01284
01285 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01286
01287 strlower(strcpy(filename, category));
01288 strcat(filename, ".fits");
01289
01290 cpl_image_save(mask, filename, CPL_BPP_IEEE_FLOAT, extension_header,
01291 CPL_IO_EXTEND);
01292 cpl_propertylist_delete(extension_header);
01293 cpl_free(filename);
01294 }
01295
01296 #undef cleanup
01297 #define cleanup \
01298 do { \
01299 cpl_propertylist_delete(wcs_header); \
01300 } while (0)
01301
01306 void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame,
01307 const fors_setting *setting)
01308 {
01309 bool invert = false;
01310 int extension = 0;
01311
01312 cpl_propertylist *wcs_header =
01313 cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
01314 extension, WCS_KEYS, invert);
01315
01316 cpl_propertylist_copy_property_regexp(header, wcs_header, ".*", invert);
01317
01318 double crpix1 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX1);
01319
01320 assure( !cpl_error_get_code(), return,
01321 "Could not read %s from %s", FORS_PFITS_CRPIX1,
01322 cpl_frame_get_filename(frame));
01323
01324 double crpix2 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX2);
01325
01326 assure( !cpl_error_get_code(), return,
01327 "Could not read %s from %s", FORS_PFITS_CRPIX2,
01328 cpl_frame_get_filename(frame));
01329
01330 cpl_propertylist_update_double(header, FORS_PFITS_CRPIX1,
01331 crpix1 - setting->prescan_x);
01332
01333 cpl_propertylist_update_double(header, FORS_PFITS_CRPIX2,
01334 crpix2 - setting->prescan_y);
01335
01336
01337 cleanup;
01338 return;
01339 }
01340
01341
01342 #undef cleanup
01343 #define cleanup \
01344 do { \
01345 cpl_propertylist_delete(time_header); \
01346 } while (0)
01347
01359
01360 void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame,
01361 double exptime)
01362 {
01363 bool invert = false;
01364 int extension = 0;
01365
01366 cpl_propertylist *time_header = NULL;
01367
01368 if (frame) {
01369
01370 time_header =
01371 cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
01372 extension, "EXPTIME", invert);
01373
01374 if (time_header) {
01375 cpl_propertylist_copy_property_regexp(header,
01376 time_header, ".*", invert);
01377 }
01378 else {
01379 cpl_error_reset();
01380 }
01381 }
01382 else {
01383 while (cpl_propertylist_erase(header, "EXPTIME"));
01384 cpl_propertylist_update_double(header, "EXPTIME", exptime);
01385 }
01386
01387 cleanup;
01388 return;
01389 }
01390
01391
01398
01399 void
01400 fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
01401 const char *category, cpl_propertylist *header,
01402 const cpl_parameterlist *parlist, const char *recipename,
01403 const cpl_frame *inherit_frame)
01404 {
01405 dfs_save(frameset, table, FORS_TYPE_TABLE,
01406 category, header, NULL,
01407 parlist, recipename,
01408 inherit_frame);
01409 }
01410
01411
01443
01444 int dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
01445 const char *category, cpl_propertylist *header,
01446 const cpl_parameterlist *parlist, const char *recipename,
01447 const char *version)
01448 {
01449 const char *func = "dfs_save_image";
01450
01451 char *filename;
01452 cpl_frame *frame;
01453 cpl_propertylist *plist;
01454
01455
01456 if (category == NULL || frameset == NULL || image == NULL) {
01457 cpl_msg_error(cpl_func, "Error found in %s: %s",
01458 cpl_error_get_where(), cpl_error_get_message());
01459 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01460 return -1;
01461 }
01462
01463 cpl_msg_info(func, "Saving %s image to disk...", category);
01464
01465 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01466
01467 strlower(strcpy(filename, category));
01468 strcat(filename, ".fits");
01469
01470 frame = cpl_frame_new();
01471
01472 cpl_frame_set_filename(frame, filename);
01473 cpl_frame_set_tag(frame, category);
01474 cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE);
01475 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01476 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01477 if (cpl_error_get_code()) {
01478 cpl_msg_error(cpl_func, "Error found in %s: %s",
01479 cpl_error_get_where(), cpl_error_get_message());
01480 cpl_msg_error(func, "Cannot initialise the product frame");
01481 cpl_frame_delete(frame);
01482 cpl_free(filename);
01483 return -1;
01484 }
01485
01486
01487
01488
01489
01490
01491 if (header == NULL)
01492 plist = cpl_propertylist_new();
01493 else
01494 plist = header;
01495
01496 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01497 recipename, version, "PRO-1.15", NULL)) {
01498 cpl_msg_error(cpl_func, "Error found in %s: %s",
01499 cpl_error_get_where(), cpl_error_get_message());
01500 cpl_msg_error(func, "Problem with product %s FITS header definition",
01501 category);
01502 if (header == NULL)
01503 cpl_propertylist_delete(plist);
01504 cpl_frame_delete(frame);
01505 cpl_free(filename);
01506 return -1;
01507 }
01508
01509
01510
01511
01512
01513 if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist,
01514 CPL_IO_DEFAULT)) {
01515 cpl_msg_error(cpl_func, "Error found in %s: %s",
01516 cpl_error_get_where(), cpl_error_get_message());
01517 cpl_msg_error(func, "Cannot save product %s to disk", filename);
01518 if (header == NULL)
01519 cpl_propertylist_delete(plist);
01520 cpl_frame_delete(frame);
01521 cpl_free(filename);
01522 return -1;
01523 }
01524
01525 if (header == NULL)
01526 cpl_propertylist_delete(plist);
01527
01528 cpl_free(filename);
01529
01530 cpl_frameset_insert(frameset, frame);
01531
01532 return 0;
01533 }
01534
01535
01567
01568 int dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
01569 const char *category, cpl_propertylist *header,
01570 const cpl_parameterlist *parlist, const char *recipename,
01571 const char *version)
01572 {
01573 const char *func = "dfs_save_table";
01574
01575 char *filename;
01576 cpl_frame *frame;
01577 cpl_propertylist *plist;
01578
01579
01580 if (category == NULL || frameset == NULL || table == NULL) {
01581 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01582 cpl_msg_error(cpl_func, "Error found in %s: %s",
01583 cpl_error_get_where(), cpl_error_get_message());
01584 return -1;
01585 }
01586
01587 cpl_msg_info(func, "Saving %s table to disk...", category);
01588
01589 filename = cpl_calloc(strlen(category) + 6, sizeof(char));
01590
01591 strlower(strcpy(filename, category));
01592
01593 strcat(filename, ".fits");
01594
01595 frame = cpl_frame_new();
01596
01597 cpl_frame_set_filename(frame, filename);
01598 cpl_frame_set_tag(frame, category);
01599 cpl_frame_set_type(frame, CPL_FRAME_TYPE_TABLE);
01600 cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
01601 cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
01602 if (cpl_error_get_code()) {
01603 cpl_msg_error(cpl_func, "Error found in %s: %s",
01604 cpl_error_get_where(), cpl_error_get_message());
01605 cpl_msg_error(func, "Cannot initialise the product frame");
01606 cpl_frame_delete(frame);
01607 cpl_free(filename);
01608 return -1;
01609 }
01610
01611
01612
01613
01614
01615
01616 if (header == NULL)
01617 plist = cpl_propertylist_new();
01618 else
01619 plist = header;
01620
01621 if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
01622 recipename, version, "PRO-1.15", NULL)) {
01623 cpl_msg_error(cpl_func, "Error found in %s: %s",
01624 cpl_error_get_where(), cpl_error_get_message());
01625 cpl_msg_error(func, "Problem with product %s FITS header definition",
01626 category);
01627 if (header == NULL)
01628 cpl_propertylist_delete(plist);
01629 cpl_frame_delete(frame);
01630 cpl_free(filename);
01631 return -1;
01632 }
01633
01634
01635
01636
01637
01638 if (cpl_table_save(table, plist, NULL, filename, CPL_IO_DEFAULT)) {
01639 cpl_msg_error(cpl_func, "Error found in %s: %s",
01640 cpl_error_get_where(), cpl_error_get_message());
01641 cpl_msg_error(func, "Cannot save product %s to disk", filename);
01642 if (header == NULL)
01643 cpl_propertylist_delete(plist);
01644 cpl_frame_delete(frame);
01645 cpl_free(filename);
01646 return -1;
01647 }
01648
01649 if (header == NULL)
01650 cpl_propertylist_delete(plist);
01651 cpl_free(filename);
01652
01653 cpl_frameset_insert(frameset, frame);
01654
01655 return 0;
01656 }
01657
01658
01675
01676 int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
01677 {
01678 const char *func = "dfs_equal_keyword";
01679
01680 cpl_frame *frame;
01681 cpl_propertylist *reference;
01682 cpl_type rtype;
01683 cpl_type type;
01684 const char *rstring;
01685 const char *string;
01686 int rintero;
01687 int intero;
01688 int found;
01689
01690
01691 if (frameset == NULL || keyword == NULL) {
01692 cpl_error_set(func, CPL_ERROR_NULL_INPUT);
01693 return 0;
01694 }
01695
01696 if (cpl_frameset_is_empty(frameset)) {
01697 cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
01698 return 0;
01699 }
01700
01701 frame = cpl_frameset_get_first(frameset);
01702
01703 found = 0;
01704
01705 while (frame) {
01706
01707 reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01708 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01709 cpl_error_reset();
01710 frame = cpl_frameset_get_next(frameset);
01711 continue;
01712 }
01713
01714 if (cpl_propertylist_has(reference, keyword)) {
01715 rtype = cpl_propertylist_get_type(reference, keyword);
01716
01717 if (rtype == CPL_TYPE_STRING) {
01718 found = 1;
01719 rstring = cpl_strdup(cpl_propertylist_get_string(reference,
01720 keyword));
01721 cpl_propertylist_delete(reference);
01722 break;
01723 }
01724
01725 if (rtype == CPL_TYPE_INT) {
01726 found = 1;
01727 rintero = cpl_propertylist_get_int(reference, keyword);
01728 cpl_propertylist_delete(reference);
01729 break;
01730 }
01731
01732 cpl_propertylist_delete(reference);
01733 return 0;
01734 }
01735
01736 cpl_propertylist_delete(reference);
01737
01738 frame = cpl_frameset_get_next(frameset);
01739 }
01740
01741
01742 if (!found)
01743 return 1;
01744
01745 frame = cpl_frameset_get_first(frameset);
01746
01747 while (frame) {
01748
01749 reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
01750 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
01751 cpl_error_reset();
01752 frame = cpl_frameset_get_next(frameset);
01753 continue;
01754 }
01755
01756 if (cpl_propertylist_has(reference, keyword)) {
01757
01758 type = cpl_propertylist_get_type(reference, keyword);
01759
01760 if (rtype != type) {
01761 cpl_propertylist_delete(reference);
01762 return 0;
01763 }
01764
01765 if (rtype == CPL_TYPE_STRING) {
01766 string = cpl_propertylist_get_string(reference,
01767 keyword);
01768 if (strncmp(rstring, string, 15)) {
01769 cpl_propertylist_delete(reference);
01770 return 0;
01771 }
01772 }
01773
01774 if (rtype == CPL_TYPE_INT) {
01775 intero = cpl_propertylist_get_int(reference, keyword);
01776 if (rintero - intero) {
01777 cpl_propertylist_delete(reference);
01778 return 0;
01779 }
01780 }
01781 }
01782
01783 cpl_propertylist_delete(reference);
01784
01785 frame = cpl_frameset_get_next(frameset);
01786 }
01787
01788 if (rtype == CPL_TYPE_STRING)
01789 cpl_free((void *)rstring);
01790
01791 return 1;
01792
01793 }
01794
01804 cpl_error_code dfs_save_table_ext(cpl_table * table,
01805 const char * tag,
01806 cpl_propertylist * extheader)
01807 {
01808 char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
01809 cpl_propertylist * header;
01810
01811 if (extheader) {
01812 header = cpl_propertylist_duplicate(extheader);
01813
01814 cpl_propertylist_erase_regexp(header,
01815 "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
01816 } else {
01817 header = NULL;
01818 }
01819
01820 strlower(strcpy(filename, tag));
01821 strcat(filename, ".fits");
01822
01823 if (cpl_table_save(table, NULL, header, filename, CPL_IO_EXTEND)) {
01824 cpl_free(filename);
01825 cpl_ensure_code(0, CPL_ERROR_FILE_IO);
01826 }
01827
01828 cpl_propertylist_delete(header);
01829 cpl_free(filename);
01830
01831 return CPL_ERROR_NONE;
01832 }
01833
01843 cpl_error_code dfs_save_image_ext(cpl_image * image,
01844 const char * tag,
01845 cpl_propertylist * extheader)
01846 {
01847 char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
01848
01849 cpl_propertylist * header;
01850
01851 if (extheader) {
01852 header = cpl_propertylist_duplicate(extheader);
01853
01854 cpl_propertylist_erase_regexp(header,
01855 "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
01856 } else {
01857 header = NULL;
01858 }
01859
01860 strlower(strcpy(filename, tag));
01861 strcat(filename, ".fits");
01862
01863 if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT,
01864 header, CPL_IO_EXTEND)) {
01865 cpl_free(filename);
01866 cpl_ensure_code(0, CPL_ERROR_FILE_IO);
01867 }
01868
01869 cpl_propertylist_delete(header);
01870 cpl_free(filename);
01871
01872 return CPL_ERROR_NONE;
01873 }
01874
01886 cpl_error_code dfs_save_image_null(cpl_frameset * frameset,
01887 cpl_parameterlist * parlist,
01888 const char * tag,
01889 const char * recipename,
01890 const char * version)
01891 {
01892
01893 char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
01894
01895 cpl_error_code error;
01896
01897 cpl_propertylist * pro = cpl_propertylist_new();
01898
01899 cpl_propertylist_append_string(pro, "ESO PRO CATG", tag);
01900
01901 strlower(strcpy(filename, tag));
01902 strcat(filename, ".fits");
01903
01904 error = cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, NULL,
01905 CPL_BPP_IEEE_FLOAT, recipename, pro,
01906 NULL, version, filename);
01907
01908 cpl_free(filename);
01909 cpl_propertylist_delete(pro);
01910
01911 return error;
01912 }
01913
01914