|
KMOS Pipeline Reference Manual
1.3.1
|
00001 /* 00002 * This file is part of the KMOS Pipeline 00003 * Copyright (C) 2002,2003 European Southern Observatory 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 */ 00019 00020 #ifdef HAVE_CONFIG_H 00021 #include <config.h> 00022 #endif 00023 00024 /*----------------------------------------------------------------------------- 00025 * Includes 00026 *----------------------------------------------------------------------------*/ 00027 00028 #include <string.h> 00029 #include <math.h> 00030 00031 #ifdef __USE_XOPEN2K 00032 #include <stdlib.h> 00033 #define GGG 00034 #else 00035 #define __USE_XOPEN2K /* to get the definition for setenv in stdlib.h */ 00036 #include <stdlib.h> 00037 #undef __USE_XOPEN2K 00038 #endif 00039 00040 #include <cpl.h> 00041 00042 #include "kmo_utils.h" 00043 #include "kmo_functions.h" 00044 #include "kmo_priv_wave_cal.h" 00045 #include "kmo_priv_functions.h" 00046 #include "kmo_cpl_extensions.h" 00047 #include "kmo_dfs.h" 00048 #include "kmo_error.h" 00049 #include "kmo_constants.h" 00050 #include "kmo_debug.h" 00051 00052 /*----------------------------------------------------------------------------- 00053 * Functions prototypes 00054 *----------------------------------------------------------------------------*/ 00055 00056 static int kmo_wave_cal_create(cpl_plugin *); 00057 static int kmo_wave_cal_exec(cpl_plugin *); 00058 static int kmo_wave_cal_destroy(cpl_plugin *); 00059 static int kmo_wave_cal(cpl_parameterlist *, cpl_frameset *); 00060 00061 /*----------------------------------------------------------------------------- 00062 * Static variables 00063 *----------------------------------------------------------------------------*/ 00064 00065 static char kmo_wave_cal_description[] = 00066 "This recipe creates the wavelength calibration frame needed for all three\n" 00067 "detectors. It must be called after the kmo_flat recipe, which generates the\n" 00068 "two spatial calibration frames needed in this recipe. As input a lamp-on \n" 00069 "frame, a lamp-off frame, the spatial calibration frames and the list with \n" 00070 "the reference arclines are required.\n" 00071 "An additional output frame is the resampled image of the reconstructed arc\n" 00072 "frame. All slitlets of all IFUs are aligned one next to the other. This \n" 00073 "frame serves for quality control. One can immediately see if the \n" 00074 "calibration was successful.\n" 00075 "The lists of reference arclines are supposed to contain the lines for both\n" 00076 "available calibration arc-lamps, i.e. Argon and Neon. The list is supposed\n" 00077 "to be a F2L KMOS FITS file with three columns:\n" 00078 "\t1. Reference wavelength\n" 00079 "\t2. Relative strength\n" 00080 "\t3. String either containing “Ar” or “Ne”\n" 00081 "The recipe extracts, based on the header keywords, either the applying\n" 00082 "argon and/or neon emission lines. Below are the plots of the emission lines\n" 00083 "for both argon and neon. The marked lines are the ones used for wavelength \n" 00084 "calibration.\n" 00085 "\n" 00086 "Furthermore frames can be provided for several rotator angles. In this case\n" 00087 "the resulting calibration frames for each detector are repeatedly saved as \n" 00088 "extension for every angle.\n" 00089 "\n" 00090 "BASIC PARAMETERS:\n" 00091 "-----------------\n" 00092 "--order\n" 00093 "The polynomial order to use for the fit of the wavelength solution.\n" 00094 "0: (default) The appropriate order is choosen automatically depending on\n" 00095 "the waveband (4 for IZ band, 5 for HK, 6 for the others)\n" 00096 "\n" 00097 "ADVANCED PARAMETERS\n" 00098 "-------------------\n" 00099 "--b_samples\n" 00100 "The number of samples in spectral direction for the reconstructed cube.\n" 00101 "Ideally this number should be greater than 2048, the detector size.\n" 00102 "\n" 00103 "--b_start\n" 00104 "--b_end\n" 00105 "Used to define manually the start and end wavelength for the reconstructed\n" 00106 "cube. By default the internally defined values are used.\n" 00107 "\n" 00108 "--suppress_extension\n" 00109 "If set to TRUE, the arbitrary filename extensions are supressed. If\n" 00110 "multiple products with the same category are produced, they will be numered\n" 00111 "consecutively starting from 0.\n" 00112 "\n" 00113 "----------------------------------------------------------------------------\n" 00114 "Input files:\n" 00115 "\n" 00116 " DO category Type Explanation Required #Frames\n" 00117 " ----------- ----- ----------- -------- -------\n" 00118 " ARC_ON RAW Arclamp-on exposure Y >=1\n" 00119 " ARC_OFF RAW Arclamp-off exposure Y 1\n" 00120 " XCAL F2D x calibration frame Y 1\n" 00121 " YCAL F2D y calibration frame Y 1\n" 00122 " ARC_LIST F2L List of arclines Y 1\n" 00123 " FLAT_EDGE F2L Fitted edge parameters Y 1\n" 00124 " REF_LINES F2L Reference line table Y 1\n" 00125 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1\n" 00126 "\n" 00127 "Output files:\n" 00128 "\n" 00129 " DO category Type Explanation\n" 00130 " ----------- ----- -----------\n" 00131 " LCAL F2D Wavelength calibration frame\n" 00132 " (3 Extensions)\n" 00133 " DET_IMG_WAVE F2D reconstructed arclamp-on exposure\n" 00134 " (4 extensions: 3 detector images + \n" 00135 " the arclines list table)\n" 00136 "----------------------------------------------------------------------------\n" 00137 "\n"; 00138 00139 /*----------------------------------------------------------------------------- 00140 * Functions code 00141 *----------------------------------------------------------------------------*/ 00142 00149 /*----------------------------------------------------------------------------*/ 00158 /*----------------------------------------------------------------------------*/ 00159 int cpl_plugin_get_info(cpl_pluginlist *list) 00160 { 00161 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00162 cpl_plugin *plugin = &recipe->interface; 00163 00164 cpl_plugin_init(plugin, 00165 CPL_PLUGIN_API, 00166 KMOS_BINARY_VERSION, 00167 CPL_PLUGIN_TYPE_RECIPE, 00168 "kmo_wave_cal", 00169 "Create a calibration frame encoding the spectral position " 00170 "(i.e. wavelength) of each pixel on the detector.", 00171 kmo_wave_cal_description, 00172 "Alex Agudo Berbel", 00173 "usd-help@eso.org", 00174 kmos_get_license(), 00175 kmo_wave_cal_create, 00176 kmo_wave_cal_exec, 00177 kmo_wave_cal_destroy); 00178 cpl_pluginlist_append(list, plugin); 00179 00180 return 0; 00181 } 00182 00183 /*----------------------------------------------------------------------------*/ 00191 /*----------------------------------------------------------------------------*/ 00192 static int kmo_wave_cal_create(cpl_plugin *plugin) 00193 { 00194 cpl_recipe *recipe; 00195 cpl_parameter *p; 00196 00197 // Check that the plugin is part of a valid recipe 00198 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00199 recipe = (cpl_recipe *)plugin; 00200 else 00201 return -1; 00202 00203 // Create the parameters list in the cpl_recipe object 00204 recipe->parameters = cpl_parameterlist_new(); 00205 00206 // Fill the parameters list 00207 p = cpl_parameter_new_value("kmos.kmo_wave_cal.order", CPL_TYPE_INT, 00208 "The fitting polynomial order used for the wavelength solution. " 00209 "By default, 4 for IZ band, 5 for HK, 6 for the others", 00210 "kmos.kmo_wave_cal", 0); 00211 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "order"); 00212 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00213 cpl_parameterlist_append(recipe->parameters, p); 00214 00215 /* --suppress_extension */ 00216 p = cpl_parameter_new_value("kmos.kmo_wave_cal.suppress_extension", 00217 CPL_TYPE_BOOL, "Suppress arbitrary filename extension", 00218 "kmos.kmo_wave_cal", FALSE); 00219 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00220 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00221 cpl_parameterlist_append(recipe->parameters, p); 00222 00223 // add parameters for band-definition 00224 kmo_band_pars_create(recipe->parameters, "kmos.kmo_wave_cal"); 00225 00226 return 0; 00227 } 00228 00229 /*----------------------------------------------------------------------------*/ 00235 /*----------------------------------------------------------------------------*/ 00236 static int kmo_wave_cal_exec(cpl_plugin *plugin) 00237 { 00238 cpl_recipe *recipe; 00239 00240 // Get the recipe out of the plugin 00241 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00242 recipe = (cpl_recipe *)plugin; 00243 else return -1; 00244 00245 return kmo_wave_cal(recipe->parameters, recipe->frames); 00246 } 00247 00248 /*----------------------------------------------------------------------------*/ 00254 /*----------------------------------------------------------------------------*/ 00255 static int kmo_wave_cal_destroy(cpl_plugin *plugin) 00256 { 00257 cpl_recipe *recipe; 00258 00259 // Get the recipe out of the plugin 00260 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00261 recipe = (cpl_recipe *)plugin; 00262 else return -1 ; 00263 00264 cpl_parameterlist_delete(recipe->parameters); 00265 return 0 ; 00266 } 00267 00268 /*----------------------------------------------------------------------------*/ 00283 /*----------------------------------------------------------------------------*/ 00284 static int kmo_wave_cal(cpl_parameterlist *parlist, cpl_frameset *frameset) 00285 { 00286 cpl_image *det_lamp_on = NULL, 00287 *det_lamp_on_copy = NULL, 00288 *det_lamp_off = NULL, 00289 *bad_pix_mask = NULL, 00290 *xcal = NULL, 00291 *ycal = NULL, 00292 *lcal = NULL; 00293 00294 cpl_image **stored_lcal = NULL, 00295 **stored_det_img = NULL; 00296 00297 cpl_frame *frame = NULL; 00298 cpl_frameset ** angle_frameset = NULL; 00299 00300 int ret_val = 0, 00301 nr_devices = 0, 00302 nr_angles = 0, 00303 nx = 0, 00304 ny = 0, 00305 nz = 0, 00306 *stored_qc_arc_sat = NULL, 00307 fit_order_par = 0, 00308 fit_order = 0, 00309 ndit = 0, 00310 suppress_extension = FALSE, 00311 line_estimate_method = 2, 00312 nr_sat = 0, 00313 i = 0, j = 0, a = 0, ax = 0, x = 0, y = 0; 00314 float *pbad_pix_mask = NULL; 00315 double exptime = 0.0, 00316 gain = 0.0, 00317 *stored_qc_ar_eff = NULL, 00318 *stored_qc_ne_eff = NULL, 00319 angle_found = 0.0; 00320 00321 cpl_table *arclines = NULL, 00322 *reflines = NULL, 00323 ***edge_table = NULL; 00324 00325 cpl_propertylist *main_header = NULL, 00326 **stored_sub_headers_lcal = NULL, 00327 **stored_sub_headers_det_img = NULL, 00328 *qc_header = NULL, 00329 *tmp_header = NULL, 00330 *header = NULL; 00331 00332 cpl_array **unused_ifus_before = NULL, 00333 **unused_ifus_after = NULL; 00334 00335 cpl_bivector *lines = NULL; 00336 00337 main_fits_desc desc1, 00338 desc2; 00339 00340 char *extname = NULL, 00341 filename_lcal[256], 00342 filename_det_img[256], 00343 *suffix = NULL, 00344 *fn_suffix = NULL, 00345 tmpstr[256], 00346 **filter_ids = NULL, 00347 *readmode = NULL, 00348 *str_line_estimate_method = NULL, 00349 *last_env = NULL; 00350 00351 const char *tmp_str = NULL; 00352 00353 cpl_error_code err = CPL_ERROR_NONE; 00354 00355 enum lampConfiguration lamp_config; 00356 00357 KMO_TRY 00358 { 00359 kmo_init_fits_desc(&desc1); 00360 kmo_init_fits_desc(&desc2); 00361 00362 str_line_estimate_method = getenv("KMO_WAVE_LINE_ESTIMATE"); 00363 if (str_line_estimate_method != NULL) { 00364 line_estimate_method = atoi(str_line_estimate_method); 00365 } 00366 cpl_msg_debug(__func__, "Line estimation method: %d\n", 00367 line_estimate_method); 00368 00369 /* Check inputs */ 00370 KMO_TRY_ASSURE((parlist != NULL) && (frameset != NULL), 00371 CPL_ERROR_NULL_INPUT, "Not all input data is provided!"); 00372 00373 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, ARC_ON) >= 1, 00374 CPL_ERROR_NULL_INPUT, "At least 1 ARC_ON frame is required!"); 00375 00376 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, ARC_OFF) >= 1, 00377 CPL_ERROR_NULL_INPUT, "Exactly 1 ARC_OFF frame is required!"); 00378 00379 if (cpl_frameset_count_tags(frameset, ARC_OFF) > 1) { 00380 cpl_msg_warning(__func__, 00381 "Only 1 ARC_OFF frame required. Frame #1 will be used"); 00382 } 00383 00384 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00385 CPL_ERROR_FILE_NOT_FOUND, "Exactly 1 XCAL frame is required!"); 00386 00387 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00388 CPL_ERROR_FILE_NOT_FOUND, "Exactly 1 YCAL frame is required!"); 00389 00390 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, ARC_LIST) == 1, 00391 CPL_ERROR_FILE_NOT_FOUND, "Exactly 1 ARC_LIST is required!"); 00392 00393 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, FLAT_EDGE) == 1, 00394 CPL_ERROR_FILE_NOT_FOUND, "Exactly 1 FLAT_EDGE is required!"); 00395 00396 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00397 CPL_ERROR_FILE_NOT_FOUND, "Exactly 1 WAVE_BAND is required!"); 00398 00399 if (line_estimate_method == 2) { 00400 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, REF_LINES) == 1, 00401 CPL_ERROR_FILE_NOT_FOUND, "Exactly 1 REF_LINES required!"); 00402 } 00403 00404 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_wave_cal") == 1, 00405 CPL_ERROR_ILLEGAL_INPUT, 00406 "Cannot identify RAW and CALIB frames!"); 00407 00408 /* Get Parameters */ 00409 cpl_msg_info(__func__, "--- Parameter setup for kmo_wave_cal ------"); 00410 00411 fit_order_par = kmo_dfs_get_parameter_int(parlist, 00412 "kmos.kmo_wave_cal.order"); 00413 KMO_TRY_CHECK_ERROR_STATE(); 00414 KMO_TRY_EXIT_IF_ERROR( 00415 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_wave_cal.order")); 00416 KMO_TRY_ASSURE((fit_order_par >= 0) && (fit_order_par <= 7), 00417 CPL_ERROR_ILLEGAL_INPUT, "order must be between 1 and 7"); 00418 00419 suppress_extension = kmo_dfs_get_parameter_bool(parlist, 00420 "kmos.kmo_wave_cal.suppress_extension"); 00421 KMO_TRY_CHECK_ERROR_STATE(); 00422 KMO_TRY_EXIT_IF_ERROR( 00423 kmo_dfs_print_parameter_help(parlist, 00424 "kmos.kmo_wave_cal.suppress_extension")); 00425 00426 KMO_TRY_ASSURE((suppress_extension == TRUE) || 00427 (suppress_extension == FALSE), CPL_ERROR_ILLEGAL_INPUT, 00428 "suppress_extension must be TRUE or FALSE!"); 00429 00430 kmo_band_pars_load(parlist, "kmos.kmo_wave_cal"); 00431 00432 cpl_msg_info(__func__, "-------------------------------------------"); 00433 00434 /* check EXPTIME, NDIT, READMODE and lamps */ 00435 /* check ARC_OFF */ 00436 KMO_TRY_EXIT_IF_NULL(frame = kmo_dfs_get_frame(frameset, ARC_OFF)); 00437 00438 main_header=kmclipm_propertylist_load(cpl_frame_get_filename(frame), 0); 00439 00440 ndit = cpl_propertylist_get_int(main_header, NDIT); 00441 KMO_TRY_CHECK_ERROR_STATE("NDIT keyword in main header missing"); 00442 00443 exptime = cpl_propertylist_get_double(main_header, EXPTIME); 00444 KMO_TRY_CHECK_ERROR_STATE("EXPTIME keyword in main header missing"); 00445 00446 readmode = cpl_strdup(cpl_propertylist_get_string(main_header, 00447 READMODE)); 00448 KMO_TRY_CHECK_ERROR_STATE("ESO DET READ CURNAME missing from header"); 00449 00450 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(frame)); 00451 KMO_TRY_CHECK_ERROR_STATE_MSG("ARC_OFF frame has wrong format"); 00452 00453 KMO_TRY_ASSURE(desc1.fits_type == raw_fits, CPL_ERROR_ILLEGAL_INPUT, 00454 "ARC_OFF frame type is wrong (%s must be raw)", 00455 cpl_frame_get_filename(frame)); 00456 00457 nx = desc1.naxis1; 00458 ny = desc1.naxis2; 00459 nz = desc1.naxis3; 00460 nr_devices = desc1.nr_ext; 00461 00462 /* assure that flat lamps are off */ 00463 KMO_TRY_ASSURE((kmo_check_lamp(main_header, INS_LAMP3_ST) == FALSE) && 00464 (kmo_check_lamp(main_header, INS_LAMP4_ST) == FALSE), 00465 CPL_ERROR_ILLEGAL_INPUT,"Flat lamps must be switched off (%s)!", 00466 cpl_frame_get_filename(frame)); 00467 00468 /* check if arc lamps are off (or at least blocked by filter wheel) */ 00469 if ((kmo_check_lamp(main_header, INS_LAMP1_ST) == TRUE) || 00470 (kmo_check_lamp(main_header, INS_LAMP2_ST) == TRUE)) { 00471 if (!(strcmp(cpl_propertylist_get_string(main_header, 00472 "ESO INS FILT1 ID"), "Block") == 0) || 00473 !(strcmp(cpl_propertylist_get_string(main_header, 00474 "ESO INS FILT3 ID"), "Block") == 0) || 00475 !(strcmp(cpl_propertylist_get_string(main_header, 00476 "ESO INS FILT3 ID"), "Block") == 0)) { 00477 cpl_msg_warning(__func__, 00478 "At least one arc lamp is on! Check if the lamps are blocked!"); 00479 } 00480 } 00481 cpl_propertylist_delete(main_header); main_header = NULL; 00482 00483 /* check REF_LINES */ 00484 if (line_estimate_method == 2) { 00485 KMO_TRY_EXIT_IF_NULL(frame=kmo_dfs_get_frame(frameset, REF_LINES)); 00486 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(frame)); 00487 KMO_TRY_CHECK_ERROR_STATE_MSG("REF_LINES frame has wrong format"); 00488 00489 KMO_TRY_ASSURE(desc2.fits_type == f2l_fits, CPL_ERROR_ILLEGAL_INPUT, 00490 "REF_LINES frame hasn't correct frame type " 00491 "(%s must be a F2L frame)!", 00492 cpl_frame_get_filename(frame)); 00493 kmo_free_fits_desc(&desc2); 00494 } 00495 00496 /* check ARC_ON */ 00497 KMO_TRY_EXIT_IF_NULL(frame = kmo_dfs_get_frame(frameset, ARC_ON)); 00498 00499 while (frame != NULL) { 00500 main_header = kmclipm_propertylist_load( 00501 cpl_frame_get_filename(frame), 0); 00502 00503 KMO_TRY_ASSURE(cpl_propertylist_get_int(main_header, NDIT) == ndit, 00504 CPL_ERROR_ILLEGAL_INPUT, 00505 "NDIT varies: (is %d and %d).", 00506 cpl_propertylist_get_int(main_header, NDIT), ndit); 00507 00508 KMO_TRY_ASSURE( 00509 cpl_propertylist_get_double(main_header, EXPTIME)==exptime, 00510 CPL_ERROR_ILLEGAL_INPUT, 00511 "EXPTIME varies: (is %g and %g).", 00512 cpl_propertylist_get_double(main_header, EXPTIME), exptime); 00513 00514 KMO_TRY_ASSURE( 00515 strcmp(cpl_propertylist_get_string(main_header, READMODE), 00516 readmode) == 0, CPL_ERROR_ILLEGAL_INPUT, 00517 "ESO DET READ CURNAME varies: (is %s and %s).", 00518 cpl_propertylist_get_string(main_header, READMODE), 00519 readmode); 00520 00521 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(frame)); 00522 KMO_TRY_CHECK_ERROR_STATE_MSG("ARC_ON frame wrong format"); 00523 00524 KMO_TRY_ASSURE(desc2.fits_type == raw_fits, CPL_ERROR_ILLEGAL_INPUT, 00525 "ARC_ON frame wrong data type (%s must be a raw)", 00526 cpl_frame_get_filename(frame)); 00527 00528 KMO_TRY_ASSURE((desc2.naxis1 == nx) && (desc2.naxis2 == ny) && 00529 (desc2.naxis3 == nz), CPL_ERROR_ILLEGAL_INPUT, 00530 "ARC_ON has wrong dimensions (x,y): (%d,%d) vs (%d,%d)", 00531 desc2.naxis1, desc2.naxis2, nx, ny); 00532 00533 // assure that flat lamp is off (LAMP3 and 4) 00534 // and that either arc lamp is on (LAMP1 and 2) 00535 KMO_TRY_ASSURE( 00536 ((kmo_check_lamp(main_header, INS_LAMP1_ST) == TRUE) || 00537 (kmo_check_lamp(main_header, INS_LAMP2_ST) == TRUE)) && 00538 (kmo_check_lamp(main_header, INS_LAMP3_ST) == FALSE) && 00539 (kmo_check_lamp(main_header, INS_LAMP4_ST) == FALSE), 00540 CPL_ERROR_ILLEGAL_INPUT, 00541 "Lamp1 or 2 must be on, 3 and 4 must be off for ARC_ON"); 00542 00543 frame = kmo_dfs_get_frame(frameset, NULL); 00544 KMO_TRY_CHECK_ERROR_STATE(); 00545 00546 kmo_free_fits_desc(&desc2); 00547 kmo_init_fits_desc(&desc2); 00548 cpl_propertylist_delete(main_header); main_header = NULL; 00549 } 00550 00551 // load first ARC_ON main header 00552 KMO_TRY_EXIT_IF_NULL(frame = kmo_dfs_get_frame(frameset, ARC_ON)); 00553 KMO_TRY_EXIT_IF_NULL(main_header = 00554 kmclipm_propertylist_load(cpl_frame_get_filename(frame), 0)); 00555 00556 // check FLAT_EDGE 00557 KMO_TRY_EXIT_IF_NULL(frame = kmo_dfs_get_frame(frameset, FLAT_EDGE)); 00558 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(frame)); 00559 KMO_TRY_CHECK_ERROR_STATE(); 00560 KMO_TRY_ASSURE((desc2.nr_ext % 24==0) && (desc2.fits_type == f2l_fits), 00561 CPL_ERROR_ILLEGAL_INPUT, "FLAT_EDGE has a wrong format."); 00562 00563 kmo_free_fits_desc(&desc2); 00564 kmo_init_fits_desc(&desc2); 00565 00566 // ------------ check filter_id, grating_id and rotator offset --------- 00567 // assure that filters, grating and rotation offsets match for 00568 // ARC_ON, XCAL and YCAL 00569 // check if filter_id, grating_id and rotator offset match for all 00570 // detectors 00571 KMO_TRY_EXIT_IF_ERROR( 00572 kmo_check_frame_setup(frameset, ARC_ON, XCAL,TRUE,FALSE,FALSE)); 00573 KMO_TRY_EXIT_IF_ERROR( 00574 kmo_check_frame_setup(frameset, ARC_ON, YCAL, TRUE, FALSE, FALSE)); 00575 00576 KMO_TRY_EXIT_IF_ERROR(kmo_check_frame_setup_md5_xycal(frameset)); 00577 00578 strcpy(filename_lcal, LCAL); 00579 strcpy(filename_det_img, DET_IMG_WAVE); 00580 00581 KMO_TRY_EXIT_IF_NULL(frame = kmo_dfs_get_frame(frameset, XCAL)); 00582 KMO_TRY_EXIT_IF_NULL(suffix = kmo_dfs_get_suffix(frame, TRUE, FALSE)); 00583 00584 cpl_msg_info(__func__, "Detected instrument setup: %s", suffix+1); 00585 cpl_msg_info(__func__, "(grating 1, 2 & 3)"); 00586 00587 // setup lamp config 00588 if ((kmo_check_lamp(main_header, INS_LAMP1_ST) == TRUE) && 00589 (kmo_check_lamp(main_header, INS_LAMP2_ST) == FALSE)) { 00590 lamp_config = ARGON; 00591 strcpy(tmpstr, "Argon"); 00592 } else if ((kmo_check_lamp(main_header, INS_LAMP1_ST) == FALSE) && 00593 (kmo_check_lamp(main_header, INS_LAMP2_ST) == TRUE)) { 00594 lamp_config = NEON; 00595 strcpy(tmpstr, "Neon"); 00596 } else if ((kmo_check_lamp(main_header, INS_LAMP1_ST) == TRUE) && 00597 (kmo_check_lamp(main_header, INS_LAMP2_ST) == TRUE)) { 00598 lamp_config = ARGON_NEON; 00599 strcpy(tmpstr, "Argon + Neon"); 00600 } 00601 00602 cpl_msg_info(__func__, "Detected arc lamp configuration: %s", tmpstr); 00603 00604 /* assert that filter and grating match for each detector */ 00605 /* filter/grating can be different for each detector */ 00606 KMO_TRY_EXIT_IF_NULL( 00607 filter_ids = kmo_get_filter_setup(main_header, nr_devices, TRUE)); 00608 00609 /* scan for rotator angles */ 00610 #define ANGLE_DIM 360 00611 int rotang_found[ANGLE_DIM]; 00612 int rotang_cnt[ANGLE_DIM]; 00613 for (i = 0; i < ANGLE_DIM; i++) { 00614 rotang_found[i] = 0; 00615 rotang_cnt[i] = 0; 00616 } 00617 KMO_TRY_EXIT_IF_NULL(frame = kmo_dfs_get_frame(frameset, ARC_ON)); 00618 while (frame != NULL) { 00619 header = kmclipm_propertylist_load(cpl_frame_get_filename(frame),0); 00620 if (cpl_propertylist_has(header, ROTANGLE)) { 00621 int rot_angle = (int)rint(cpl_propertylist_get_double( 00622 header, ROTANGLE)); 00623 if (rot_angle < 0) rot_angle += 360; 00624 if (rot_angle < 360 && rot_angle >= 0) rotang_cnt[rot_angle]++; 00625 } else { 00626 cpl_msg_warning(__func__,"File %s has no keyword \"ROTANGLE\"", 00627 cpl_frame_get_filename(frame)); 00628 } 00629 00630 cpl_propertylist_delete(header); header = NULL; 00631 frame = kmo_dfs_get_frame(frameset, NULL); 00632 KMO_TRY_CHECK_ERROR_STATE(); 00633 } 00634 for (ax = 0; ax < ANGLE_DIM; ax++) { 00635 if (rotang_cnt[ax] != 0) { 00636 if (rotang_cnt[ax] == 1 ) { 00637 cpl_msg_info(__func__, 00638 "Found %d frame with rotator angle %d", 00639 rotang_cnt[ax],ax); 00640 } else { 00641 cpl_msg_warning(__func__, 00642 "Found %d frames with rotator angle %d but only one will be used", 00643 rotang_cnt[ax],ax); 00644 } 00645 rotang_found[nr_angles] = ax; 00646 nr_angles++; 00647 } 00648 } 00649 00650 KMO_TRY_EXIT_IF_NULL(angle_frameset = (cpl_frameset **)cpl_malloc( 00651 nr_angles * sizeof(cpl_frameset*))); 00652 for (i = 0; i < nr_angles; i++) { 00653 angle_frameset[i] = cpl_frameset_new(); 00654 } 00655 00656 KMO_TRY_EXIT_IF_NULL(frame = kmo_dfs_get_frame(frameset, ARC_ON)); 00657 while (frame != NULL) { 00658 header=kmclipm_propertylist_load(cpl_frame_get_filename(frame), 0); 00659 if (cpl_propertylist_has(header, ROTANGLE)) { 00660 int rot_angle = (int)rint(cpl_propertylist_get_double(header, 00661 ROTANGLE)); 00662 if (rot_angle < 0) rot_angle += 360; 00663 int ix = -1; 00664 for (ix = 0; ix<nr_angles; ix++) { 00665 if (rotang_found[ix] == rot_angle) { 00666 break; 00667 } 00668 } 00669 if (ix<nr_angles) { 00670 KMO_TRY_EXIT_IF_ERROR( 00671 cpl_frameset_insert(angle_frameset[ix], 00672 cpl_frame_duplicate(frame))); 00673 } 00674 } 00675 00676 cpl_propertylist_delete(header); header = NULL; 00677 frame = kmo_dfs_get_frame(frameset, NULL); 00678 KMO_TRY_CHECK_ERROR_STATE(); 00679 } 00680 00681 /* allocate temporary memory */ 00682 /* allocate here a edge table structure for all detectors */ 00683 KMO_TRY_EXIT_IF_NULL(edge_table = (cpl_table***)cpl_calloc(nr_devices, 00684 sizeof(cpl_table**))); 00685 for (i = 0; i < nr_devices; i++) { 00686 KMO_TRY_EXIT_IF_NULL( 00687 edge_table[i] = (cpl_table**)cpl_calloc(KMOS_IFUS_PER_DETECTOR, 00688 sizeof(cpl_table*))); 00689 } 00690 00691 /* the frames have to be stored temporarily because the QC params */ 00692 /* for the main header are calculated per detector. So they can be */ 00693 /* stored only when all detectors are processed */ 00694 KMO_TRY_EXIT_IF_NULL(stored_lcal = (cpl_image**)cpl_calloc( 00695 nr_devices * nr_angles, sizeof(cpl_image*))); 00696 KMO_TRY_EXIT_IF_NULL(stored_det_img = (cpl_image**)cpl_calloc( 00697 nr_devices * nr_angles, sizeof(cpl_image*))); 00698 KMO_TRY_EXIT_IF_NULL(stored_sub_headers_lcal = (cpl_propertylist**) 00699 cpl_calloc(nr_devices * nr_angles, sizeof(cpl_propertylist*))); 00700 KMO_TRY_EXIT_IF_NULL(stored_sub_headers_det_img = (cpl_propertylist**) 00701 cpl_calloc(nr_devices * nr_angles, sizeof(cpl_propertylist*))); 00702 KMO_TRY_EXIT_IF_NULL(stored_qc_arc_sat = (int*)cpl_calloc(nr_devices, 00703 nr_angles * sizeof(int))); 00704 KMO_TRY_EXIT_IF_NULL(stored_qc_ar_eff = (double*)cpl_calloc(nr_devices, 00705 nr_angles * sizeof(double))); 00706 KMO_TRY_EXIT_IF_NULL(stored_qc_ne_eff = (double*)cpl_calloc(nr_devices, 00707 nr_angles * sizeof(double))); 00708 00709 /* process data */ 00710 /* load arclines and reference lines */ 00711 KMO_TRY_EXIT_IF_NULL(frame = kmo_dfs_get_frame(frameset, ARC_LIST)); 00712 00713 /* check if ARC_LIST is the filter_id-one */ 00714 KMO_TRY_EXIT_IF_NULL(tmp_header = kmclipm_propertylist_load( 00715 cpl_frame_get_filename(frame), 0)); 00716 KMO_TRY_EXIT_IF_NULL( 00717 tmp_str = cpl_propertylist_get_string(tmp_header, FILT_ID)); 00718 KMO_TRY_ASSURE(strcmp(filter_ids[0], tmp_str) == 0, 00719 CPL_ERROR_ILLEGAL_INPUT, 00720 "ARC_LIST model must have keyword %s = %s", 00721 FILT_ID, filter_ids[0]); 00722 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00723 00724 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(frame)); 00725 KMO_TRY_CHECK_ERROR_STATE(); 00726 00727 KMO_TRY_ASSURE((desc2.nr_ext == 1) && (desc2.fits_type == f2l_fits), 00728 CPL_ERROR_ILLEGAL_INPUT, "ARC_LIST has wrong format"); 00729 kmo_free_fits_desc(&desc2); 00730 kmo_init_fits_desc(&desc2); 00731 00732 KMO_TRY_EXIT_IF_NULL( 00733 arclines = kmo_dfs_load_table(frameset, ARC_LIST, 1, 0)); 00734 00735 KMO_TRY_EXIT_IF_NULL(lines = kmo_get_lines(arclines, lamp_config)); 00736 00737 cpl_msg_info(__func__, 00738 "Nr. of lines in arclist for this configuration: %lld", 00739 cpl_bivector_get_size(lines)); 00740 00741 if (line_estimate_method == 2) { 00742 KMO_TRY_EXIT_IF_NULL( 00743 reflines = kmo_dfs_load_table(frameset, REF_LINES, 1, 0)); 00744 } 00745 00746 /* check which IFUs are active for all FLAT frames */ 00747 KMO_TRY_EXIT_IF_NULL( 00748 unused_ifus_before = kmo_get_unused_ifus(frameset, 0, 0)); 00749 00750 KMO_TRY_EXIT_IF_NULL( 00751 unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before)); 00752 00753 kmo_print_unused_ifus(unused_ifus_before, FALSE); 00754 00755 /* make sure no reconstruction lookup table (LUT) is used */ 00756 if (getenv("KMCLIPM_PRIV_RECONSTRUCT_LUT_MODE") != NULL) { 00757 last_env = getenv("KMCLIPM_PRIV_RECONSTRUCT_LUT_MODE"); 00758 } 00759 setenv("KMCLIPM_PRIV_RECONSTRUCT_LUT_MODE","NONE",1); 00760 00761 /* Loop all Rotator Angles and Detectors */ 00762 for (a = 0; a < nr_angles; a++) { 00763 cpl_msg_info(__func__, "Processing rotator angle %d -> %d degree", 00764 a, rotang_found[a]); 00765 cpl_msg_indent_more(); 00766 for (i = 1; i <= nr_devices; i++) { 00767 cpl_msg_info(__func__,"Processing detector No. %d", i); 00768 cpl_msg_indent_more(); 00769 00770 /* Load edge parameters */ 00771 KMO_TRY_EXIT_IF_NULL(frame=kmo_dfs_get_frame(frameset, 00772 FLAT_EDGE)); 00773 00774 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 00775 edge_table[i-1][j] = kmclipm_cal_table_load( 00776 cpl_frame_get_filename(frame), 00777 (i-1) * KMOS_IFUS_PER_DETECTOR + j + 1, 00778 rotang_found[a], 0, &angle_found); 00779 00780 /* IFU is inactive: proceed */ 00781 if (cpl_error_get_code() == CPL_ERROR_ILLEGAL_INPUT) { 00782 cpl_error_reset(); 00783 } 00784 } 00785 00786 if (fit_order_par == 0) { 00787 /* set default fit orders for the different bands */ 00788 if ((strcmp(filter_ids[i-1], "H") == 0) || 00789 (strcmp(filter_ids[i-1], "K") == 0) || 00790 (strcmp(filter_ids[i-1], "YJ") == 0)) 00791 { 00792 fit_order = 6; 00793 } else if (strcmp(filter_ids[i-1], "IZ") == 0) { 00794 fit_order = 4; 00795 } else if (strcmp(filter_ids[i-1], "HK") == 0) { 00796 fit_order = 5; 00797 } 00798 cpl_msg_info(__func__, 00799 "Order of wavelength spectrum fit for %s-band: %d", 00800 filter_ids[i-1], fit_order); 00801 } else { 00802 fit_order = fit_order_par; 00803 } 00804 00805 /* lamp_on */ 00806 KMO_TRY_EXIT_IF_NULL( 00807 frame = kmo_dfs_get_frame(angle_frameset[a], ARC_ON)); 00808 00809 /* if sat_mode is set to TRUE here, then the calc. of the */ 00810 /* saturated pixels has to be updated like in kmo_flat-recipe */ 00811 KMO_TRY_EXIT_IF_NULL(det_lamp_on = kmo_dfs_load_image_frame( 00812 frame, i, FALSE, TRUE, &nr_sat)); 00813 00814 int sx = a * nr_devices + (i - 1); 00815 00816 /* count saturated pixels for each detector */ 00817 if (strcmp(cpl_propertylist_get_string(main_header, 00818 READMODE), "Nondest") == 0) { 00819 /* NDR: non-destructive readout mode */ 00820 stored_qc_arc_sat[sx] = nr_sat; 00821 } else { 00822 /* normal readout mode */ 00823 stored_qc_arc_sat[sx] = kmo_image_get_saturated( 00824 det_lamp_on, KMO_FLAT_SATURATED); 00825 } 00826 KMO_TRY_CHECK_ERROR_STATE(); 00827 00828 KMO_TRY_EXIT_IF_NULL( 00829 det_lamp_on_copy = cpl_image_duplicate(det_lamp_on)); 00830 00831 // lamp_off 00832 KMO_TRY_EXIT_IF_NULL( 00833 frame = kmo_dfs_get_frame(frameset, ARC_OFF)); 00834 00835 KMO_TRY_EXIT_IF_NULL( 00836 det_lamp_off = kmo_dfs_load_image_frame(frame, i, FALSE, 00837 FALSE, NULL)); 00838 00839 /* process imagelist */ 00840 KMO_TRY_CHECK_ERROR_STATE(); 00841 00842 /* subtract lamp_off from lamp_on */ 00843 KMO_TRY_EXIT_IF_ERROR( 00844 cpl_image_subtract(det_lamp_on, det_lamp_off)); 00845 00846 /* load flat calibration frames */ 00847 KMO_TRY_EXIT_IF_NULL( 00848 xcal = kmo_dfs_load_cal_image(frameset, XCAL, i, 0, 00849 (double)rotang_found[a], FALSE, NULL, &angle_found, -1, 00850 0, 0)); 00851 00852 KMO_TRY_EXIT_IF_NULL( 00853 ycal = kmo_dfs_load_cal_image(frameset, YCAL, i, 0, 00854 (double)rotang_found[a], FALSE, NULL, &angle_found, -1, 00855 0, 0)); 00856 00857 /* load bad pixel mask from XCAL and set NaNs to 0 */ 00858 /* and all other values to 1 */ 00859 KMO_TRY_EXIT_IF_NULL(bad_pix_mask = cpl_image_duplicate(xcal)); 00860 00861 KMO_TRY_EXIT_IF_NULL( 00862 pbad_pix_mask = cpl_image_get_data_float(bad_pix_mask)); 00863 for (x = 0; x < nx; x++) { 00864 for (y = 0; y < ny; y++) { 00865 if (isnan(pbad_pix_mask[x+nx*y])) { 00866 pbad_pix_mask[x+nx*y] = 0.; 00867 } else { 00868 pbad_pix_mask[x+nx*y] = 1.; 00869 } 00870 } 00871 } 00872 00873 /* ---------------------------- */ 00874 /* CALCULATE SPECTRAL CURVATURE */ 00875 /* ---------------------------- */ 00876 err = kmo_calc_wave_calib(det_lamp_on, bad_pix_mask, xcal, 00877 ycal, filter_ids[i-1], lamp_config, i, 00878 unused_ifus_after[i-1], edge_table[i-1], lines, 00879 reflines, -1.0, &lcal, &(stored_qc_ar_eff[sx]), 00880 &(stored_qc_ne_eff[sx]), FALSE, fit_order, 00881 line_estimate_method); 00882 00883 if (err == CPL_ERROR_NONE) { 00884 /* Update QC parameters */ 00885 if (stored_qc_ar_eff[sx] != -1.0) 00886 stored_qc_ar_eff[sx] /= exptime; 00887 if (stored_qc_ne_eff[sx] != -1.0) 00888 stored_qc_ne_eff[sx] /= exptime; 00889 00890 /* Apply the badpixel mask to the produced frame */ 00891 KMO_TRY_EXIT_IF_ERROR( 00892 cpl_image_multiply(lcal, bad_pix_mask)); 00893 KMO_TRY_EXIT_IF_ERROR( 00894 kmo_image_reject_from_mask(lcal, bad_pix_mask)); 00895 00896 /* Store Result frame */ 00897 stored_lcal[sx] = lcal; 00898 } else if (err == CPL_ERROR_UNSPECIFIED) { 00899 /* All IFUs seem to be deactivated */ 00900 /* Continue processing - just save empty frame */ 00901 cpl_error_reset(); 00902 stored_lcal[sx] = cpl_image_new(nx, ny, CPL_TYPE_FLOAT); 00903 kmo_image_fill(stored_lcal[sx], 0.0); 00904 } else { 00905 cpl_error_reset(); 00906 cpl_msg_warning(__func__, 00907 "Couldn't identify any line - Check the line list"); 00908 cpl_msg_warning(__func__, 00909 "Band defined in header of detector %d: %s", 00910 i, filter_ids[i-1]); 00911 cpl_msg_warning(__func__, "Arc line file defined: %s", 00912 cpl_frame_get_filename(kmo_dfs_get_frame(frameset, 00913 ARC_LIST))); 00914 } 00915 00916 /* -------------------------------------------- */ 00917 /* CREATE RECONSTRUCTED AND RESAMPLED ARC FRAME */ 00918 /* -------------------------------------------- */ 00919 stored_det_img[sx] = kmo_reconstructed_arc_image(frameset, 00920 det_lamp_on_copy, det_lamp_off, xcal, ycal, 00921 stored_lcal[sx], unused_ifus_after[i-1], FALSE, i, 00922 suffix, filter_ids[i-1], lamp_config, &qc_header); 00923 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00924 /* couldn't reconstruct */ 00925 cpl_msg_error(__func__, 00926 "Couldn't reconstruct IFUs on detector %d", i); 00927 cpl_error_reset(); 00928 } 00929 00930 /* --------------------------------------- */ 00931 /* CREATE EXTENSION HEADER FOR THE PRODUCT */ 00932 /* --------------------------------------- */ 00933 KMO_TRY_EXIT_IF_NULL(stored_sub_headers_lcal[sx] = 00934 kmo_dfs_load_sub_header(frameset, ARC_ON, i, FALSE)); 00935 /* update EXTNAME */ 00936 KMO_TRY_EXIT_IF_NULL( 00937 extname = kmo_extname_creator(detector_frame, i, EXT_DATA)); 00938 KMO_TRY_EXIT_IF_ERROR( 00939 kmclipm_update_property_string(stored_sub_headers_lcal[sx], 00940 EXTNAME, extname, "FITS extension name")); 00941 cpl_free(extname); extname = NULL; 00942 00943 KMO_TRY_EXIT_IF_ERROR( 00944 kmclipm_update_property_int(stored_sub_headers_lcal[sx], 00945 EXTVER, sx+1, "FITS extension ver")); 00946 00947 // add first QC parameters 00948 KMO_TRY_EXIT_IF_ERROR( 00949 kmclipm_update_property_int(stored_sub_headers_lcal[sx], 00950 QC_ARC_SAT, stored_qc_arc_sat[sx], 00951 "[] nr. saturated pixels of arc exp.")); 00952 00953 gain = kmo_dfs_get_property_double(stored_sub_headers_lcal[sx], 00954 GAIN); 00955 KMO_TRY_CHECK_ERROR_STATE_MSG("GAIN is missing in header"); 00956 00957 if (stored_qc_ar_eff[sx] != -1.0) { 00958 KMO_TRY_EXIT_IF_ERROR(kmclipm_update_property_double( 00959 stored_sub_headers_lcal[sx], QC_ARC_AR_EFF, 00960 stored_qc_ar_eff[sx]/gain, 00961 "[e-/s] Argon lamp efficiency")); 00962 } 00963 00964 if (stored_qc_ne_eff[sx] != -1.0) { 00965 KMO_TRY_EXIT_IF_ERROR(kmclipm_update_property_double( 00966 stored_sub_headers_lcal[sx], QC_ARC_NE_EFF, 00967 stored_qc_ne_eff[sx]/gain, 00968 "[e-/s] Neon lamp efficiency")); 00969 } 00970 00971 KMO_TRY_EXIT_IF_ERROR( 00972 kmclipm_update_property_double(stored_sub_headers_lcal[sx], 00973 CAL_ROTANGLE, ((double) rotang_found[a]), 00974 "[deg] Rotator relative to nasmyth")); 00975 00976 /* append QC parameters */ 00977 KMO_TRY_EXIT_IF_ERROR(cpl_propertylist_append( 00978 stored_sub_headers_lcal[sx], qc_header)); 00979 cpl_propertylist_delete(qc_header); qc_header = NULL; 00980 00981 KMO_TRY_EXIT_IF_NULL( 00982 stored_sub_headers_det_img[sx]=cpl_propertylist_duplicate( 00983 stored_sub_headers_lcal[sx])); 00984 00985 cpl_propertylist_erase(stored_sub_headers_lcal[sx], CRVAL1); 00986 cpl_propertylist_erase(stored_sub_headers_lcal[sx], CRVAL2); 00987 cpl_propertylist_erase(stored_sub_headers_lcal[sx], CTYPE1); 00988 cpl_propertylist_erase(stored_sub_headers_lcal[sx], CTYPE2); 00989 cpl_propertylist_erase(stored_sub_headers_lcal[sx], CDELT1); 00990 cpl_propertylist_erase(stored_sub_headers_lcal[sx], CDELT2); 00991 00992 /* free memory */ 00993 cpl_image_delete(det_lamp_on); det_lamp_on = NULL; 00994 cpl_image_delete(det_lamp_on_copy); det_lamp_on_copy = NULL; 00995 cpl_image_delete(det_lamp_off); det_lamp_off = NULL; 00996 cpl_image_delete(bad_pix_mask); bad_pix_mask = NULL; 00997 cpl_image_delete(xcal); xcal = NULL; 00998 cpl_image_delete(ycal); ycal = NULL; 00999 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 01000 cpl_table_delete(edge_table[i-1][j]); 01001 edge_table[i-1][j] = NULL; 01002 } 01003 cpl_msg_indent_less(); 01004 } // for i devices 01005 cpl_msg_indent_less() ; 01006 } // for a angles 01007 01008 if (line_estimate_method == 2) { 01009 cpl_table_delete(reflines); reflines = NULL; 01010 } 01011 01012 /* QC parameters & saving */ 01013 cpl_msg_info(__func__, "Saving data..."); 01014 01015 /* load, update & save primary header */ 01016 if (!suppress_extension) { 01017 KMO_TRY_EXIT_IF_NULL(fn_suffix = cpl_sprintf("%s", suffix)); 01018 } else { 01019 KMO_TRY_EXIT_IF_NULL(fn_suffix = cpl_sprintf("%s", "")); 01020 } 01021 01022 /* update which IFUs are not used */ 01023 KMO_TRY_EXIT_IF_ERROR( 01024 kmo_set_unused_ifus(unused_ifus_after, main_header, 01025 "kmo_wave_cal")); 01026 01027 KMO_TRY_EXIT_IF_NULL(frame = kmo_dfs_get_frame(frameset, ARC_ON)); 01028 01029 KMO_TRY_EXIT_IF_ERROR( 01030 kmo_dfs_save_main_header(frameset, filename_lcal, fn_suffix, frame, 01031 main_header, parlist, cpl_func)); 01032 01033 KMO_TRY_EXIT_IF_ERROR( 01034 kmo_dfs_save_main_header(frameset, filename_det_img, fn_suffix, 01035 frame, main_header, parlist, cpl_func)); 01036 01037 cpl_propertylist_delete(main_header); main_header = NULL; 01038 01039 /* save sub-frames */ 01040 for (a = 0; a < nr_angles; a++) { 01041 for (i = 1; i <= nr_devices; i++) { 01042 int sx = a * nr_devices + (i - 1); 01043 /* save lcal-frame */ 01044 KMO_TRY_EXIT_IF_ERROR( 01045 kmo_dfs_save_image(stored_lcal[sx], filename_lcal, 01046 fn_suffix, stored_sub_headers_lcal[sx], 0./0.)); 01047 01048 /* save detector image */ 01049 KMO_TRY_EXIT_IF_ERROR( 01050 kmo_dfs_save_image(stored_det_img[sx], filename_det_img, 01051 fn_suffix, stored_sub_headers_det_img[sx], 0./0.)); 01052 } // for i = nr_devices 01053 } // for a angles 01054 01055 /* print which IFUs are not used */ 01056 kmo_print_unused_ifus(unused_ifus_after, TRUE); 01057 } 01058 KMO_CATCH 01059 { 01060 KMO_CATCH_MSG(); 01061 ret_val = -1; 01062 } 01063 01064 if (last_env != NULL) { 01065 setenv("KMCLIPM_PRIV_RECONSTRUCT_LUT_MODE",last_env,1); 01066 } else { 01067 unsetenv("KMCLIPM_PRIV_RECONSTRUCT_LUT_MODE"); 01068 } 01069 01070 kmo_free_fits_desc(&desc1); 01071 kmo_free_fits_desc(&desc2); 01072 if (unused_ifus_before != NULL) { 01073 kmo_free_unused_ifus(unused_ifus_before); unused_ifus_before = NULL; 01074 } 01075 if (unused_ifus_after != NULL) { 01076 kmo_free_unused_ifus(unused_ifus_after); unused_ifus_after = NULL; 01077 } 01078 cpl_propertylist_delete(main_header); main_header = NULL; 01079 cpl_image_delete(det_lamp_on); det_lamp_on = NULL; 01080 cpl_image_delete(det_lamp_off); det_lamp_off = NULL; 01081 cpl_image_delete(bad_pix_mask); bad_pix_mask = NULL; 01082 cpl_table_delete(arclines); arclines = NULL; 01083 cpl_table_delete(reflines); reflines = NULL; 01084 cpl_free(stored_qc_arc_sat); stored_qc_arc_sat = NULL; 01085 cpl_free(stored_qc_ar_eff); stored_qc_ar_eff = NULL; 01086 cpl_free(stored_qc_ne_eff); stored_qc_ne_eff = NULL; 01087 for (i = 0; i < nr_devices * nr_angles; i++) { 01088 cpl_image_delete(stored_lcal[i]); stored_lcal[i] = NULL; 01089 cpl_image_delete(stored_det_img[i]); stored_det_img[i] = NULL; 01090 cpl_propertylist_delete(stored_sub_headers_lcal[i]); 01091 stored_sub_headers_lcal[i] = NULL; 01092 cpl_propertylist_delete(stored_sub_headers_det_img[i]); 01093 stored_sub_headers_det_img[i] = NULL; 01094 } 01095 for (i = 0; i < nr_angles; i++) { 01096 cpl_frameset_delete(angle_frameset[i]); angle_frameset[i] = NULL; 01097 } 01098 if (filter_ids != NULL) { 01099 for (i = 0; i < nr_devices; i++) { 01100 cpl_free(filter_ids[i]); filter_ids[i] = NULL; 01101 01102 } 01103 cpl_free(filter_ids); filter_ids = NULL; 01104 } 01105 if (edge_table != NULL) { 01106 for (i = 0; i < nr_devices; i++) { 01107 cpl_free(edge_table[i]); edge_table[i] = NULL; 01108 } 01109 cpl_free(edge_table); edge_table = NULL; 01110 } 01111 01112 cpl_free(angle_frameset); angle_frameset = NULL; 01113 cpl_free(stored_lcal); stored_lcal = NULL; 01114 cpl_free(stored_det_img); stored_det_img = NULL; 01115 cpl_free(stored_sub_headers_lcal); stored_sub_headers_lcal = NULL; 01116 cpl_free(stored_sub_headers_det_img); stored_sub_headers_det_img = NULL; 01117 cpl_free(readmode); readmode = NULL; 01118 cpl_bivector_delete(lines); lines = NULL; 01119 cpl_free(suffix); suffix = NULL; 01120 cpl_free(fn_suffix); fn_suffix = NULL; 01121 01122 return ret_val; 01123 } 01124
1.7.6.1