|
KMOS Pipeline Reference Manual
1.1.1
|
00001 /* $Id: kmo_reconstruct.c,v 1.42 2013/04/18 12:55:54 aagudo Exp $ 00002 * 00003 * This file is part of the KMOS Pipeline 00004 * Copyright (C) 2002,2003 European Southern Observatory 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 */ 00020 00021 /* 00022 * $Author: aagudo $ 00023 * $Date: 2013/04/18 12:55:54 $ 00024 * $Revision: 1.42 $ 00025 * $Name: HEAD $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 * Includes 00034 *----------------------------------------------------------------------------*/ 00035 00036 #include <string.h> 00037 #include <math.h> 00038 00039 #include <cpl.h> 00040 00041 #include "kmo_utils.h" 00042 #include "kmo_functions.h" 00043 #include "kmo_priv_reconstruct.h" 00044 #include "kmo_priv_functions.h" 00045 #include "kmo_cpl_extensions.h" 00046 #include "kmo_dfs.h" 00047 #include "kmo_error.h" 00048 #include "kmo_utils.h" 00049 #include "kmo_constants.h" 00050 #include "kmo_debug.h" 00051 00052 /*----------------------------------------------------------------------------- 00053 * Functions prototypes 00054 *----------------------------------------------------------------------------*/ 00055 00056 static int kmo_reconstruct_create(cpl_plugin *); 00057 static int kmo_reconstruct_exec(cpl_plugin *); 00058 static int kmo_reconstruct_destroy(cpl_plugin *); 00059 static int kmo_reconstruct(cpl_parameterlist *, cpl_frameset *); 00060 00061 /*----------------------------------------------------------------------------- 00062 * Static variables 00063 *----------------------------------------------------------------------------*/ 00064 00065 static char kmo_reconstruct_description[] = 00066 "Data with or without noise is reconstructed into a cube using the calibration\n" 00067 "frames XCAL, YCAL and LCAL. XCAL and YCAL are generated using recipe kmo_flat,\n" 00068 "LCAL is generated using recipe kmo_wave_cal.\n" 00069 "The input data can contain noise extensions and will be reconstructed into\n" 00070 "additional extensions.\n" 00071 "\n" 00072 "BASIC PARAMETERS:\n" 00073 "-----------------\n" 00074 "--imethod\n" 00075 "The interpolation method used for reconstruction.\n" 00076 "\n" 00077 "--detimg\n" 00078 "Specify if the resampled image of the input frame should be generated. There-\n" 00079 "fore all slitlets of all IFUs are aligned one next to the other. This frame\n" 00080 "serves for quality control. One can immediately see if the reconstruction was\n" 00081 "successful.\n" 00082 "\n" 00083 "--file_extension" 00084 "Set this parameter to TRUE if the EXPTIME keyword should be appended to\n" 00085 "the output filenames.\n" 00086 "\n" 00087 "ADVANCED PARAMETERS\n" 00088 "-------------------\n" 00089 "--flux\n" 00090 "Specify if flux conservation should be applied.\n" 00091 "\n" 00092 "--neighborhoodRange\n" 00093 "Defines the range to search for neighbors during reconstruction\n" 00094 "\n" 00095 "--b_samples\n" 00096 "The number of samples in spectral direction for the reconstructed cube. Ideal-\n" 00097 "ly this number should be greater than 2048, the detector size.\n" 00098 "\n" 00099 "--b_start\n" 00100 "--b_end\n" 00101 "Used to define manually the start and end wavelength for the reconstructed\n" 00102 "cube. By default the internally defined values are used.\n" 00103 "\n" 00104 "--file_extension" 00105 "Set to TRUE if OBS_ID (from input frame header) should be appended to the\n" 00106 "output frame.\n" 00107 "\n" 00108 "-------------------------------------------------------------------------------\n" 00109 " Input files:\n" 00110 "\n" 00111 " DO KMOS \n" 00112 " category Type Explanation Required #Frames\n" 00113 " -------- ----- ----------- -------- -------\n" 00114 " DARK or RAW/F2D data with Y 1 \n" 00115 " FLAT_ON or RAW/F2D or without noise \n" 00116 " ARC_ON or RAW/F2D \n" 00117 " OBJECT or RAW \n" 00118 " STD or RAW \n" 00119 " SCIENCE RAW \n" 00120 " XCAL F2D x-direction calib. frame Y 1 \n" 00121 " YCAL F2D y-direction calib. frame Y 1 \n" 00122 " LCAL F2D Wavelength calib. frame Y 1 \n" 00123 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00124 "\n" 00125 " Output files:\n" 00126 "\n" 00127 " DO KMOS\n" 00128 " category Type Explanation\n" 00129 " -------- ----- -----------\n" 00130 " CUBE_DARK or F3I Reconstructed cube \n" 00131 " CUBE_FLAT or RAW/F2D with or without noise\n" 00132 " CUBE_ARC or \n" 00133 " CUBE_OBJECT or \n" 00134 " CUBE_STD or \n" 00135 " CUBE_SCIENCE \n" 00136 "-------------------------------------------------------------------------------\n" 00137 "\n"; 00138 00139 /*----------------------------------------------------------------------------- 00140 * Functions code 00141 *----------------------------------------------------------------------------*/ 00142 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_reconstruct", 00169 "Performs the cube reconstruction " 00170 "using different interpolation methods.", 00171 kmo_reconstruct_description, 00172 "Alex Agudo Berbel", 00173 "agudo@mpe.mpg.de", 00174 kmos_get_license(), 00175 kmo_reconstruct_create, 00176 kmo_reconstruct_exec, 00177 kmo_reconstruct_destroy); 00178 00179 cpl_pluginlist_append(list, plugin); 00180 00181 return 0; 00182 } 00183 00191 static int kmo_reconstruct_create(cpl_plugin *plugin) 00192 { 00193 cpl_recipe *recipe; 00194 cpl_parameter *p; 00195 00196 /* Check that the plugin is part of a valid recipe */ 00197 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00198 recipe = (cpl_recipe *)plugin; 00199 else 00200 return -1; 00201 00202 /* Create the parameters list in the cpl_recipe object */ 00203 recipe->parameters = cpl_parameterlist_new(); 00204 00205 /* Fill the parameters list */ 00206 /* --imethod */ 00207 p = cpl_parameter_new_value("kmos.kmo_reconstruct.imethod", 00208 CPL_TYPE_STRING, 00209 "Method to use for interpolation. " 00210 "[\"NN\" (nearest neighbour), " 00211 "\"lwNN\" (linear weighted nearest neighbor), " 00212 "\"swNN\" (square weighted nearest neighbor), " 00213 "\"MS\" (Modified Shepard's method)" 00214 "\"CS\" (Cubic spline)]", 00215 "kmos.kmo_reconstruct", 00216 "CS"); 00217 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00218 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00219 cpl_parameterlist_append(recipe->parameters, p); 00220 00221 /* --neighborhoodRange */ 00222 p = cpl_parameter_new_value("kmos.kmo_reconstruct.neighborhoodRange", 00223 CPL_TYPE_DOUBLE, 00224 "Defines the range to search for neighbors. " 00225 "in pixels", 00226 "kmos.kmo_reconstruct", 00227 1.001); 00228 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00229 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00230 cpl_parameterlist_append(recipe->parameters, p); 00231 00232 /* --flux */ 00233 p = cpl_parameter_new_value("kmos.kmo_reconstruct.flux", 00234 CPL_TYPE_BOOL, 00235 "TRUE: Apply flux conservation. FALSE: otherwise", 00236 "kmos.kmo_reconstruct", 00237 FALSE); 00238 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00239 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00240 cpl_parameterlist_append(recipe->parameters, p); 00241 00242 /* --detectorimage */ 00243 p = cpl_parameter_new_value("kmos.kmo_reconstruct.detectorimage", 00244 CPL_TYPE_BOOL, 00245 "TRUE: if resampled detector frame should be " 00246 "created, FALSE: otherwise", 00247 "kmos.kmo_reconstruct", 00248 FALSE); 00249 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detimg"); 00250 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00251 cpl_parameterlist_append(recipe->parameters, p); 00252 00253 /* --file_extension */ 00254 p = cpl_parameter_new_value("kmos.kmo_reconstruct.file_extension", 00255 CPL_TYPE_BOOL, 00256 "TRUE: if OBS_ID keyword should be appended to " 00257 "output frames, FALSE: otherwise", 00258 "kmos.kmo_reconstruct", 00259 FALSE); 00260 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "file_extension"); 00261 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00262 cpl_parameterlist_append(recipe->parameters, p); 00263 00264 /* --pix_scale */ 00265 p = cpl_parameter_new_value("kmos.kmo_reconstruct.pix_scale", 00266 CPL_TYPE_DOUBLE, 00267 "Change the pixel scale [arcsec]. " 00268 "Default of 0.2\" results into cubes of 14x14pix, " 00269 "a scale of 0.1\" results into cubes of 28x28pix, " 00270 "etc.", 00271 "kmos.kmo_reconstruct", 00272 0.2); 00273 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pix_scale"); 00274 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00275 cpl_parameterlist_append(recipe->parameters, p); 00276 00277 /* --dev_flip */ 00278 p = cpl_parameter_new_value("kmos.kmo_reconstruct.dev_flip", 00279 CPL_TYPE_BOOL, 00280 "INTENDED FOR PIPELINE DEVELOPERS ONLY: " 00281 "Set this parameter to TRUE if the wavelengths " 00282 "are ascending on the detector from bottom to " 00283 "top (only for old simulation data).", 00284 "kmos.kmo_reconstruct", 00285 FALSE); 00286 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dev_flip"); 00287 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00288 cpl_parameterlist_append(recipe->parameters, p); 00289 00290 // add parameters for band-definition 00291 kmo_band_pars_create(recipe->parameters, 00292 "kmos.kmo_reconstruct"); 00293 00294 return 0; 00295 } 00296 00302 static int kmo_reconstruct_exec(cpl_plugin *plugin) 00303 { 00304 cpl_recipe *recipe; 00305 00306 /* Get the recipe out of the plugin */ 00307 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00308 recipe = (cpl_recipe *)plugin; 00309 else return -1; 00310 00311 return kmo_reconstruct(recipe->parameters, recipe->frames); 00312 } 00313 00319 static int kmo_reconstruct_destroy(cpl_plugin *plugin) 00320 { 00321 cpl_recipe *recipe; 00322 00323 /* Get the recipe out of the plugin */ 00324 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00325 recipe = (cpl_recipe *)plugin; 00326 else return -1 ; 00327 00328 cpl_parameterlist_delete(recipe->parameters); 00329 return 0 ; 00330 } 00331 00346 static int kmo_reconstruct(cpl_parameterlist *parlist, cpl_frameset *frameset) 00347 { 00348 int ret_val = 0, 00349 nr_devices = 0, 00350 i = 0, 00351 j = 0, 00352 flux = FALSE, 00353 background = FALSE, 00354 index = 0, 00355 detectorimage = 0, 00356 *bounds = NULL, 00357 ifu_nr = 0, 00358 obs_id = 0, 00359 file_extension = FALSE, 00360 dev_flip = FALSE, 00361 detImgCube = FALSE; 00362 float *pdet_img_data = NULL, 00363 *pdet_img_noise = NULL, 00364 *slice = NULL; 00365 double neighborhoodRange = 1.001, 00366 pix_scale = 0.0; 00367 00368 const char *imethod = NULL, 00369 *input_frame_name = NULL, 00370 *output_frame_name = NULL, 00371 *filter_id = NULL, 00372 *filter_id_tmp = NULL; 00373 char *keyword = NULL, 00374 *filename_cube = NULL, 00375 *filename_img = NULL, 00376 // *fn_lut = NULL, 00377 *suffix = NULL, 00378 *obs_suffix = NULL, 00379 *my_filter_id = NULL, 00380 *extname = NULL; 00381 cpl_image *lcal = NULL, 00382 *det_img_data[KMOS_NR_DETECTORS], 00383 *det_img_noise[KMOS_NR_DETECTORS]; 00384 cpl_imagelist *cube_data = NULL, 00385 *cube_noise = NULL; 00386 cpl_frame *rec_frame = NULL, 00387 *xcal_frame = NULL, 00388 *ycal_frame = NULL, 00389 *lcal_frame = NULL; 00390 cpl_propertylist *main_header = NULL, 00391 *sub_header = NULL, 00392 *sub_header_orig = NULL, 00393 *actual_sub_header = NULL, 00394 *tmp_header = NULL; 00395 cpl_table *band_table = NULL; 00396 gridDefinition gd; 00397 main_fits_desc desc1, 00398 desc2; 00399 00400 for (int i=0; i<KMOS_NR_DETECTORS; i++) { 00401 det_img_data[i] = NULL; 00402 det_img_noise[i] = NULL; 00403 } 00404 00405 KMO_TRY 00406 { 00407 kmo_init_fits_desc(&desc1); 00408 kmo_init_fits_desc(&desc2); 00409 00410 // --- check input --- 00411 KMO_TRY_ASSURE((parlist != NULL) && 00412 (frameset != NULL), 00413 CPL_ERROR_NULL_INPUT, 00414 "Not all input data is provided!"); 00415 00416 KMO_TRY_ASSURE((cpl_frameset_count_tags(frameset, DARK) == 1) || 00417 (cpl_frameset_count_tags(frameset, FLAT_ON) == 1) || 00418 (cpl_frameset_count_tags(frameset, ARC_ON) == 1) || 00419 (cpl_frameset_count_tags(frameset, OBJECT) == 1) || 00420 (cpl_frameset_count_tags(frameset, STD) == 1) || 00421 (cpl_frameset_count_tags(frameset, SCIENCE) == 1), 00422 CPL_ERROR_NULL_INPUT, 00423 "A data frame (DARK, FLAT_ON, ARC_ON, OBJECT, STD or SCIENCE) must " 00424 "be provided!"); 00425 00426 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00427 CPL_ERROR_FILE_NOT_FOUND, 00428 "XCAL frame missing in frameset!!"); 00429 00430 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00431 CPL_ERROR_FILE_NOT_FOUND, 00432 "YCAL frame missing in frameset!!"); 00433 00434 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00435 CPL_ERROR_FILE_NOT_FOUND, 00436 "LCAL frame missing in frameset!!"); 00437 00438 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00439 CPL_ERROR_FILE_NOT_FOUND, 00440 "WAVE_BAND frame missing in frameset!!"); 00441 00442 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_reconstruct") == 1, 00443 CPL_ERROR_ILLEGAL_INPUT, 00444 "Cannot identify RAW and CALIB frames!"); 00445 00446 // --- get parameters --- 00447 cpl_msg_info("", "--- Parameter setup for kmo_reconstruct ---"); 00448 00449 KMO_TRY_EXIT_IF_NULL( 00450 imethod = kmo_dfs_get_parameter_string(parlist, 00451 "kmos.kmo_reconstruct.imethod")); 00452 00453 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00454 (strcmp(imethod, "lwNN") == 0) || 00455 (strcmp(imethod, "swNN") == 0) || 00456 (strcmp(imethod, "MS") == 0) || 00457 (strcmp(imethod, "CS") == 0), 00458 CPL_ERROR_ILLEGAL_INPUT, 00459 "imethod must be either \"NN\", \"lwNN\", " 00460 "\"swNN\", \"MS\" or \"CS\"!"); 00461 00462 KMO_TRY_EXIT_IF_ERROR( 00463 kmo_dfs_print_parameter_help(parlist, 00464 "kmos.kmo_reconstruct.imethod")); 00465 00466 flux = kmo_dfs_get_parameter_bool(parlist, 00467 "kmos.kmo_reconstruct.flux"); 00468 00469 KMO_TRY_ASSURE((flux == 0) || 00470 (flux == 1), 00471 CPL_ERROR_ILLEGAL_INPUT, 00472 "flux must be either FALSE or TRUE!"); 00473 00474 KMO_TRY_EXIT_IF_ERROR( 00475 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.flux")); 00476 00477 detectorimage = kmo_dfs_get_parameter_bool(parlist, 00478 "kmos.kmo_reconstruct.detectorimage"); 00479 00480 KMO_TRY_ASSURE((detectorimage == 0) || 00481 (detectorimage == 1), 00482 CPL_ERROR_ILLEGAL_INPUT, 00483 "detectorimage must be either 0 or 1 !"); 00484 00485 KMO_TRY_EXIT_IF_ERROR( 00486 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.detectorimage")); 00487 00488 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00489 "kmos.kmo_reconstruct.neighborhoodRange"); 00490 KMO_TRY_CHECK_ERROR_STATE(); 00491 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00492 CPL_ERROR_ILLEGAL_INPUT, 00493 "neighborhoodRange must be greater than 0.0"); 00494 KMO_TRY_EXIT_IF_ERROR( 00495 kmo_dfs_print_parameter_help(parlist, 00496 "kmos.kmo_reconstruct.neighborhoodRange")); 00497 00498 kmo_band_pars_load(parlist, "kmos.kmo_reconstruct"); 00499 00500 file_extension = kmo_dfs_get_parameter_bool(parlist, 00501 "kmos.kmo_reconstruct.file_extension"); 00502 KMO_TRY_CHECK_ERROR_STATE(); 00503 KMO_TRY_EXIT_IF_ERROR( 00504 kmo_dfs_print_parameter_help(parlist, 00505 "kmos.kmo_reconstruct.file_extension")); 00506 00507 pix_scale = kmo_dfs_get_parameter_double(parlist, 00508 "kmos.kmo_reconstruct.pix_scale"); 00509 KMO_TRY_CHECK_ERROR_STATE(); 00510 KMO_TRY_EXIT_IF_ERROR( 00511 kmo_dfs_print_parameter_help(parlist, 00512 "kmos.kmo_reconstruct.pix_scale")); 00513 KMO_TRY_ASSURE((pix_scale >= 0.01) && 00514 (pix_scale <= 0.4), 00515 CPL_ERROR_ILLEGAL_INPUT, 00516 "pix_scale must be between 0.01 and 0.4 (results in cubes " 00517 "with 7x7 to 280x280 pixels)!"); 00518 00519 dev_flip = kmo_dfs_get_parameter_bool(parlist, 00520 "kmos.kmo_reconstruct.dev_flip"); 00521 KMO_TRY_CHECK_ERROR_STATE(); 00522 KMO_TRY_EXIT_IF_ERROR( 00523 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_reconstruct.dev_flip")); 00524 KMO_TRY_ASSURE((dev_flip == TRUE) || 00525 (dev_flip == FALSE), 00526 CPL_ERROR_ILLEGAL_INPUT, 00527 "dev_flip must be TRUE or FALSE!"); 00528 00529 00530 cpl_msg_info("", "-------------------------------------------"); 00531 00532 // load descriptor and header of data frame to reconstruct 00533 if (cpl_frameset_count_tags(frameset, DARK) == 1) { 00534 input_frame_name = DARK; 00535 output_frame_name = CUBE_DARK; 00536 } else if (cpl_frameset_count_tags(frameset, FLAT_ON) == 1) { 00537 input_frame_name = FLAT_ON; 00538 output_frame_name = CUBE_FLAT; 00539 } else if (cpl_frameset_count_tags(frameset, ARC_ON) == 1) { 00540 input_frame_name = ARC_ON; 00541 output_frame_name = CUBE_ARC; 00542 } else if (cpl_frameset_count_tags(frameset, OBJECT) == 1) { 00543 input_frame_name = OBJECT; 00544 output_frame_name = CUBE_OBJECT; 00545 } else if (cpl_frameset_count_tags(frameset, STD) == 1) { 00546 input_frame_name = STD; 00547 output_frame_name = CUBE_STD; 00548 } else if (cpl_frameset_count_tags(frameset, SCIENCE) == 1) { 00549 input_frame_name = SCIENCE; 00550 output_frame_name = CUBE_SCIENCE; 00551 } 00552 00553 // assure that filters, grating and rotation offsets match for 00554 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 00555 // frames) 00556 // check if filter_id and grating_id match for all detectors 00557 KMO_TRY_EXIT_IF_ERROR( 00558 kmo_check_frame_setup(frameset, XCAL, YCAL, 00559 TRUE, FALSE, TRUE)); 00560 KMO_TRY_EXIT_IF_ERROR( 00561 kmo_check_frame_setup(frameset, XCAL, LCAL, 00562 TRUE, FALSE, TRUE)); 00563 00564 // This check doesn't make sense here since OCS.ROT.NAANGLE is compared. 00565 // When creating the calibration files the RAW exposures needn't have been 00566 // provided in the same order 00567 // KMO_TRY_EXIT_IF_ERROR( 00568 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00569 // KMO_TRY_EXIT_IF_ERROR( 00570 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00571 00572 if (cpl_frameset_count_tags(frameset, DARK) != 1) { 00573 00574 // check if filters, gratings and rotator offset match 00575 // (except for DARK frames) 00576 KMO_TRY_EXIT_IF_ERROR( 00577 kmo_check_frame_setup(frameset, XCAL, input_frame_name, 00578 TRUE, FALSE, FALSE)); 00579 /* 00580 // check if rotator offset don't differ to much 00581 cpl_frame *f1 = NULL, *f2 = NULL; 00582 cpl_propertylist *h1 = NULL, *h2 = NULL; 00583 char *kw = NULL; 00584 double tmp_dbl1 = 0.0, tmp_dbl2 = 0.0; 00585 00586 KMO_TRY_EXIT_IF_NULL( 00587 f1 = kmo_dfs_get_frame(frameset, XCAL)); 00588 00589 KMO_TRY_EXIT_IF_NULL( 00590 f2 = kmo_dfs_get_frame(frameset, input_frame_name)); 00591 h1 = kmclipm_propertylist_load(cpl_frame_get_filename(f1), 0); 00592 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00593 cpl_msg_error("","File not found: %s!", 00594 cpl_frame_get_filename(f1)); 00595 KMO_TRY_CHECK_ERROR_STATE(); 00596 } 00597 00598 h2 = kmclipm_propertylist_load(cpl_frame_get_filename(f2), 0); 00599 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00600 cpl_msg_error("","File not found: %s!", 00601 cpl_frame_get_filename(f2)); 00602 KMO_TRY_CHECK_ERROR_STATE(); 00603 } 00604 KMO_TRY_EXIT_IF_NULL( 00605 kw = cpl_sprintf("%s", ROTANGLE)); 00606 tmp_dbl1 = cpl_propertylist_get_double(h1, kw); 00607 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00608 KMO_TRY_ASSURE(1 == 0, 00609 CPL_ERROR_ILLEGAL_INPUT, 00610 "keyword \n%s\n of frame %s is missing!", 00611 keyword, XCAL); 00612 } 00613 00614 tmp_dbl2 = cpl_propertylist_get_double(h2, kw); 00615 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00616 KMO_TRY_ASSURE(1 == 0, 00617 CPL_ERROR_ILLEGAL_INPUT, 00618 "keyword \n%s\n of frame %s is missing!", 00619 keyword, input_frame_name); 00620 } 00621 00622 // strip angles below 0 deg and above 360 deg 00623 kmclipm_strip_angle(&tmp_dbl1); 00624 kmclipm_strip_angle(&tmp_dbl2); 00625 00626 if (fabs(tmp_dbl1 - tmp_dbl2) > 30.) { 00627 if ((fabs(tmp_dbl1) < 0.001) && (tmp_dbl2>330) && (tmp_dbl2<360)) { 00628 // singularity! 00629 // we have rot=0 for XCAL and rot>330 | rot<360 for input frame 00630 } else { 00631 cpl_msg_warning("","The angle of the calibration files (%g deg) " 00632 "and the angle of the frame to reconstruct" 00633 " (%g deg) differ by %g deg! Think about using " 00634 "calibration files matching better the actual " 00635 "rotator offset (ESO OCS ROT NAANGLE)", 00636 tmp_dbl1, tmp_dbl2, 00637 fabs(tmp_dbl1 - tmp_dbl2)); 00638 } 00639 } 00640 00641 cpl_propertylist_delete(h1); h1 = NULL; 00642 cpl_propertylist_delete(h2); h2 = NULL; 00643 cpl_free(kw); kw = NULL; 00644 */ 00645 } 00646 00647 KMO_TRY_EXIT_IF_NULL( 00648 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 00649 KMO_TRY_EXIT_IF_NULL( 00650 rec_frame = kmo_dfs_get_frame(frameset, input_frame_name)); 00651 KMO_TRY_EXIT_IF_NULL( 00652 suffix = kmo_dfs_get_suffix(rec_frame, TRUE, TRUE)); 00653 00654 KMO_TRY_EXIT_IF_ERROR( 00655 kmo_check_frame_setup_md5_xycal(frameset)); 00656 KMO_TRY_EXIT_IF_ERROR( 00657 kmo_check_frame_setup_md5(frameset)); 00658 00659 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00660 cpl_msg_info("", "(grating 1, 2 & 3, rotation angle)"); 00661 cpl_msg_info("", "-------------------------------------------"); 00662 00663 00664 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(rec_frame)); 00665 KMO_TRY_CHECK_ERROR_STATE(); 00666 00667 KMO_TRY_ASSURE(((desc1.nr_ext == KMOS_NR_DETECTORS) || 00668 ((desc1.nr_ext == 2*KMOS_NR_DETECTORS))) && 00669 (desc1.ex_badpix == FALSE) && 00670 ((desc1.fits_type == raw_fits) || 00671 (desc1.fits_type == f2d_fits)) && 00672 (desc1.frame_type == detector_frame), 00673 CPL_ERROR_ILLEGAL_INPUT, 00674 "The frame to reconstruct isn't in the correct format!!!" 00675 "Exactly 3 frames, or 6 with noise are expected!"); 00676 00677 if (!desc1.ex_noise) { 00678 nr_devices = desc1.nr_ext; 00679 } else { 00680 nr_devices = desc1.nr_ext / 2; 00681 } 00682 00683 // compare descriptor of XCAL and data frame to reconstruct 00684 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 00685 KMO_TRY_CHECK_ERROR_STATE(); 00686 00687 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00688 (desc1.ex_badpix == desc2.ex_badpix) && 00689 (desc1.frame_type == desc2.frame_type), 00690 CPL_ERROR_ILLEGAL_INPUT, 00691 "XCAL isn't in the correct format!!!"); 00692 00693 kmo_free_fits_desc(&desc2); 00694 00695 // compare descriptor of YCAL and data frame to reconstruct 00696 kmo_init_fits_desc(&desc2); 00697 00698 KMO_TRY_EXIT_IF_NULL( 00699 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 00700 00701 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 00702 KMO_TRY_CHECK_ERROR_STATE(); 00703 00704 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00705 (desc1.ex_badpix == desc2.ex_badpix) && 00706 (desc1.frame_type == desc2.frame_type), 00707 CPL_ERROR_ILLEGAL_INPUT, 00708 "YCAL isn't in the correct format!!!"); 00709 00710 kmo_free_fits_desc(&desc2); 00711 00712 // compare descriptor of LCAL and data frame to reconstruct 00713 kmo_init_fits_desc(&desc2); 00714 00715 KMO_TRY_EXIT_IF_NULL( 00716 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00717 00718 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 00719 KMO_TRY_CHECK_ERROR_STATE(); 00720 00721 KMO_TRY_ASSURE((desc2.nr_ext % 3 == 0) && 00722 (desc1.ex_badpix == desc2.ex_badpix) && 00723 (desc1.frame_type == desc2.frame_type), 00724 CPL_ERROR_ILLEGAL_INPUT, 00725 "LCAL isn't in the correct format!!!"); 00726 00727 kmo_free_fits_desc(&desc2); 00728 00729 // 00730 // --- load, update & save primary header --- 00731 // 00732 KMO_TRY_EXIT_IF_NULL( 00733 main_header = kmo_dfs_load_primary_header(frameset, 00734 input_frame_name)); 00735 00736 KMO_TRY_EXIT_IF_NULL( 00737 tmp_header = kmo_dfs_load_primary_header(frameset, LCAL)); 00738 00739 // assert that filters have correct IDs and that all detectors of all 00740 // input frames have the same filter set 00741 for (i = 1; i <= nr_devices; i++) { 00742 // ESO INS FILTi ID 00743 KMO_TRY_EXIT_IF_NULL( 00744 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, i, 00745 IFU_FILTID_POSTFIX)); 00746 00747 KMO_TRY_EXIT_IF_NULL( 00748 filter_id = cpl_propertylist_get_string(tmp_header, keyword)); 00749 00750 KMO_TRY_ASSURE((strcmp(filter_id, "IZ") == 0) || 00751 (strcmp(filter_id, "YJ") == 0) || 00752 (strcmp(filter_id, "H") == 0) || 00753 (strcmp(filter_id, "K") == 0) || 00754 (strcmp(filter_id, "HK") == 0), 00755 CPL_ERROR_ILLEGAL_INPUT, 00756 "Filter ID in primary header of LCAL frame must " 00757 "be either \"IZ\", \"YJ\", \"H\", \"K\" or " 00758 "\"HK\" !"); 00759 00760 if (strcmp(input_frame_name, DARK) != 0) { 00761 // dark needn't to be taken with filter! 00762 00763 KMO_TRY_EXIT_IF_NULL( 00764 filter_id_tmp = cpl_propertylist_get_string(main_header, 00765 keyword)); 00766 KMO_TRY_ASSURE(strcmp(filter_id, filter_id_tmp) == 0, 00767 CPL_ERROR_ILLEGAL_INPUT, 00768 "Filter IDs must be the same for LCAL frame and " 00769 "the frame to reconstruct!" 00770 "Detector No.: %d\nLCAL: %s\n%s: %s\n", 00771 i, filter_id, input_frame_name, filter_id_tmp); 00772 } 00773 cpl_free(keyword); keyword = NULL; 00774 } 00775 KMO_TRY_EXIT_IF_NULL( 00776 my_filter_id = cpl_strdup(filter_id)); 00777 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00778 00779 obs_id = cpl_propertylist_get_int(main_header, OBS_ID); 00780 KMO_TRY_CHECK_ERROR_STATE(); 00781 00782 KMO_TRY_EXIT_IF_NULL( 00783 filename_cube = cpl_sprintf("%s", output_frame_name)); 00784 KMO_TRY_EXIT_IF_NULL( 00785 filename_img = cpl_sprintf("%s", DET_IMG_REC)); 00786 if (file_extension) { 00787 KMO_TRY_EXIT_IF_NULL( 00788 obs_suffix = cpl_sprintf("%s%d", "_", obs_id)); 00789 } else { 00790 KMO_TRY_EXIT_IF_NULL( 00791 obs_suffix = cpl_sprintf("%s", "")); 00792 } 00793 00794 KMO_TRY_EXIT_IF_ERROR( 00795 kmo_dfs_save_main_header(frameset, filename_cube, obs_suffix, 00796 rec_frame, NULL, parlist, cpl_func)); 00797 00798 // setup grid definition, wavelength start and end points will be set 00799 // in the detector loop 00800 KMO_TRY_EXIT_IF_ERROR( 00801 kmclipm_setup_grid(&gd, imethod, neighborhoodRange)); 00802 00803 00804 // adapt pixel range if desired 00805 if (fabs(pix_scale*1000-KMOS_PIXEL_RESOLUTION) > 0.001) { 00806 int pixNewX = 0, 00807 pixNewY = 0; 00808 double deltaNewX = 0., 00809 deltaNewY = 0.; 00810 00811 pix_scale *=1000; 00812 00813 // calculate temporary (eventually fractional) pixel scale 00814 double pixNewTmp = KMOS_SLITLET_X*KMOS_PIXEL_RESOLUTION/pix_scale; 00815 deltaNewX = KMOS_SLITLET_X*KMOS_PIXEL_RESOLUTION/pixNewTmp; 00816 00817 // calculate integer pixel scale 00818 pixNewX = floor(pixNewTmp+.5); 00819 deltaNewX = 14*200/pixNewX; 00820 00821 // calculate final pixel scale in x and y 00822 pixNewX = floor(KMOS_SLITLET_X*KMOS_PIXEL_RESOLUTION/pix_scale+.5); 00823 pixNewY = floor(KMOS_SLITLET_Y*KMOS_PIXEL_RESOLUTION/pix_scale+.5); 00824 deltaNewX = KMOS_SLITLET_X*KMOS_PIXEL_RESOLUTION/pixNewX; 00825 deltaNewY = KMOS_SLITLET_Y*KMOS_PIXEL_RESOLUTION/pixNewY; 00826 00827 cpl_msg_info("", "Pixel resolution has been changed from 0.2\" to %g\"", deltaNewX/1000); 00828 if (fabs(pixNewTmp-pixNewX) > 0.0001) { 00829 cpl_msg_info("", "(%g\" would have resulted in cubes with %g pixels...)", pix_scale/1000, pixNewTmp); 00830 } 00831 cpl_msg_info("", " Created cubes will have %dx%d pixels, instead the standard 14x14 pixels", pixNewX, pixNewY); 00832 00833 gd.x.delta = deltaNewX; 00834 gd.y.delta = deltaNewY; 00835 gd.x.dim = pixNewX; 00836 gd.y.dim = pixNewY; 00837 } 00838 00839 KMO_TRY_EXIT_IF_NULL( 00840 tmp_header = kmo_dfs_load_primary_header(frameset, XCAL)); 00841 00842 KMO_TRY_EXIT_IF_NULL( 00843 bounds = kmclipm_extract_bounds(tmp_header)); 00844 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00845 00846 if (detectorimage == TRUE) { 00847 KMO_TRY_EXIT_IF_ERROR( 00848 kmo_dfs_save_main_header(frameset, filename_img, obs_suffix, 00849 rec_frame, NULL, parlist, cpl_func)); 00850 } 00851 00852 /* loop through all detectors */ 00853 for (i = 1; i <= nr_devices; i++) { 00854 cpl_msg_info("","Processing detector No. %d", i); 00855 00856 // load lcal 00857 // extract LCAL image close to ROTANGLE 0. assuming that the wavelength range 00858 // doesn't differ too much with different ROTANGLEs. 00859 double rotangle_found; 00860 KMO_TRY_EXIT_IF_NULL( 00861 lcal = kmo_dfs_load_cal_image(frameset, LCAL, i, FALSE, 0., 00862 FALSE, NULL, &rotangle_found)); 00863 00864 char *tmp_band_method = getenv("KMO_BAND_METHOD"); 00865 int band_method = 0; 00866 if (tmp_band_method != NULL) { 00867 band_method = atoi(tmp_band_method); 00868 } 00869 00870 KMO_TRY_EXIT_IF_NULL( 00871 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, FALSE)); 00872 00873 KMO_TRY_EXIT_IF_ERROR( 00874 kmclipm_setup_grid_band_lcal(&gd, lcal, my_filter_id, 00875 band_method, band_table)); 00876 cpl_table_delete(band_table); band_table = NULL; 00877 00878 cpl_image_delete(lcal); lcal = NULL; 00879 00880 if (detectorimage == TRUE) { 00881 KMO_TRY_EXIT_IF_NULL( 00882 det_img_data[i-1] = cpl_image_new(gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR, 00883 gd.l.dim, CPL_TYPE_FLOAT)); 00884 KMO_TRY_EXIT_IF_NULL( 00885 pdet_img_data = cpl_image_get_data_float(det_img_data[i-1])); 00886 00887 KMO_TRY_EXIT_IF_NULL( 00888 det_img_noise[i-1] = cpl_image_new(gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR, 00889 gd.l.dim, CPL_TYPE_FLOAT)); 00890 KMO_TRY_EXIT_IF_NULL( 00891 pdet_img_noise = cpl_image_get_data_float(det_img_noise[i-1])); 00892 } 00893 00894 00895 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 00896 /* update sub-header */ 00897 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 00898 00899 /* load raw image and sub-header*/ 00900 KMO_TRY_EXIT_IF_NULL( 00901 sub_header = kmo_dfs_load_sub_header(frameset, input_frame_name, 00902 i, FALSE)); 00903 KMO_TRY_EXIT_IF_NULL( 00904 sub_header_orig = cpl_propertylist_duplicate(sub_header)); 00905 00906 // check if IFU is valid according to main header keywords & 00907 // calibration files 00908 00909 if (getenv("KMOS_RECONSTRUCT_ALL") == NULL) { 00910 KMO_TRY_EXIT_IF_NULL( 00911 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, 00912 IFU_VALID_POSTFIX)); 00913 KMO_TRY_CHECK_ERROR_STATE(); 00914 cpl_propertylist_get_string(main_header, keyword); 00915 cpl_free(keyword); keyword = NULL; 00916 } else { 00917 // if KMOS_RECONSTRUCT_ALL is set all IFUs should be 00918 // reconstructed 00919 cpl_propertylist_get_string(main_header, "ggg"); 00920 } 00921 00922 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 00923 (bounds[2*(ifu_nr-1)] != -1) && 00924 (bounds[2*(ifu_nr-1)+1] != -1)) 00925 { 00926 cpl_error_reset(); 00927 // IFU is valid 00928 actual_sub_header = sub_header; 00929 00930 // calculate WCS 00931 KMO_TRY_EXIT_IF_ERROR( 00932 kmo_calc_wcs(main_header, actual_sub_header, ifu_nr, 00933 gd.l.start, gd.l.delta)); 00934 00935 // reconstruct data and noise (if available) 00936 if (j == 0) { 00937 sat_mode_msg = FALSE; 00938 } else { 00939 sat_mode_msg = TRUE; 00940 } 00941 KMO_TRY_EXIT_IF_ERROR( 00942 kmo_reconstruct_sci(ifu_nr, 00943 bounds[2*(ifu_nr-1)], 00944 bounds[2*(ifu_nr-1)+1], 00945 rec_frame, 00946 input_frame_name, 00947 NULL, 00948 NULL, 00949 NULL, 00950 xcal_frame, 00951 ycal_frame, 00952 lcal_frame, 00953 &gd, 00954 &cube_data, 00955 &cube_noise, 00956 flux, 00957 background)); 00958 } else { 00959 // IFU is invalid 00960 actual_sub_header = sub_header_orig; 00961 cpl_error_reset(); 00962 } // if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) .. 00963 00964 if (detectorimage) { 00965 if (cube_data != NULL) { 00966 for (int l=0; l<gd.l.dim; l++) { 00967 KMO_TRY_EXIT_IF_NULL( 00968 slice = cpl_image_get_data_float(cpl_imagelist_get(cube_data, l))); 00969 for (int y=0; y<gd.y.dim; y++) { 00970 for (int x=0; x<gd.x.dim; x++) { 00971 int ix = x + 00972 y * gd.x.dim + 00973 j * gd.x.dim*gd.y.dim + //IFU offset 00974 l * gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR; 00975 pdet_img_data[ix] = slice[x + y*gd.x.dim]; 00976 } 00977 } 00978 } 00979 } 00980 if (cube_noise != NULL) { 00981 if (detectorimage) { 00982 detImgCube = TRUE; 00983 } 00984 for (int l=0; l<gd.l.dim; l++) { 00985 KMO_TRY_EXIT_IF_NULL( 00986 slice = cpl_image_get_data_float(cpl_imagelist_get(cube_noise, l))); 00987 for (int y=0; y<gd.y.dim; y++) { 00988 for (int x=0; x<gd.x.dim; x++) { 00989 int ix = x + 00990 y * gd.x.dim + 00991 j * gd.x.dim*gd.y.dim + //IFU offset 00992 l * gd.x.dim*gd.y.dim*KMOS_IFUS_PER_DETECTOR; 00993 pdet_img_noise[ix] = slice[x + y*gd.x.dim]; 00994 } 00995 } 00996 } 00997 } 00998 } 00999 01000 // save output 01001 KMO_TRY_EXIT_IF_NULL( 01002 extname = kmo_extname_creator(ifu_frame, ifu_nr, 01003 EXT_DATA)); 01004 01005 KMO_TRY_EXIT_IF_ERROR( 01006 kmclipm_update_property_string(actual_sub_header, 01007 EXTNAME, 01008 extname, 01009 "FITS extension name")); 01010 01011 cpl_free(extname); extname = NULL; 01012 01013 KMO_TRY_EXIT_IF_ERROR( 01014 kmo_dfs_save_cube(cube_data, filename_cube, obs_suffix, 01015 actual_sub_header, 0./0.)); 01016 01017 if (cube_noise != NULL) { 01018 KMO_TRY_EXIT_IF_NULL( 01019 extname = kmo_extname_creator(ifu_frame, ifu_nr, 01020 EXT_NOISE)); 01021 01022 KMO_TRY_EXIT_IF_ERROR( 01023 kmclipm_update_property_string(actual_sub_header, 01024 EXTNAME, 01025 extname, 01026 "FITS extension name")); 01027 01028 cpl_free(extname); extname = NULL; 01029 01030 KMO_TRY_EXIT_IF_ERROR( 01031 kmo_dfs_save_cube(cube_noise, filename_cube, obs_suffix, 01032 actual_sub_header, 0./0.)); 01033 } 01034 01035 cpl_imagelist_delete(cube_data); cube_data = NULL; 01036 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01037 cpl_propertylist_delete(sub_header); sub_header = NULL; 01038 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01039 } // for j IFUs 01040 01041 if (detectorimage) { 01042 index = kmo_identify_index(cpl_frame_get_filename(rec_frame), 01043 i, FALSE); 01044 KMO_TRY_CHECK_ERROR_STATE(); 01045 01046 KMO_TRY_EXIT_IF_NULL( 01047 tmp_header = kmclipm_propertylist_load( 01048 cpl_frame_get_filename(rec_frame), index)); 01049 KMO_TRY_EXIT_IF_ERROR( 01050 kmo_save_det_img_ext(det_img_data[i-1], gd, i, filename_img, 01051 obs_suffix, tmp_header, dev_flip, FALSE)); 01052 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01053 01054 if (detImgCube) { 01055 if (desc1.ex_noise) { 01056 index = kmo_identify_index(cpl_frame_get_filename(rec_frame), 01057 i, TRUE); 01058 KMO_TRY_CHECK_ERROR_STATE(); 01059 } else { 01060 // use same index as for data frame, since input frame 01061 // has just 3 extensions 01062 } 01063 KMO_TRY_EXIT_IF_NULL( 01064 tmp_header = kmclipm_propertylist_load( 01065 cpl_frame_get_filename(rec_frame), index)); 01066 KMO_TRY_EXIT_IF_ERROR( 01067 kmo_save_det_img_ext(det_img_noise[i-1], gd, i, filename_img, 01068 obs_suffix, tmp_header, dev_flip, TRUE)); 01069 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01070 } 01071 } 01072 01073 // free memory 01074 cpl_imagelist_delete(cube_data); cube_data = NULL; 01075 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01076 cpl_propertylist_delete(sub_header); sub_header = NULL; 01077 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01078 } // for i devices 01079 } 01080 KMO_CATCH 01081 { 01082 KMO_CATCH_MSG(); 01083 ret_val = -1; 01084 } 01085 01086 kmo_free_fits_desc(&desc1); 01087 kmo_free_fits_desc(&desc2); 01088 for (int i=0; i<KMOS_NR_DETECTORS; i++) { 01089 cpl_image_delete(det_img_data[i]); det_img_data[i] = NULL; 01090 cpl_image_delete(det_img_noise[i]); det_img_noise[i] = NULL; 01091 } 01092 cpl_free(my_filter_id); my_filter_id = NULL; 01093 cpl_free(bounds); bounds = NULL; 01094 cpl_propertylist_delete(main_header); main_header = NULL; 01095 cpl_propertylist_delete(sub_header); sub_header = NULL; 01096 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01097 cpl_imagelist_delete(cube_data); cube_data = NULL; 01098 cpl_imagelist_delete(cube_noise); cube_noise = NULL; 01099 cpl_free(obs_suffix); obs_suffix = NULL; 01100 cpl_free(suffix); suffix = NULL; 01101 cpl_free(filename_img); filename_img = NULL; 01102 cpl_free(filename_cube); filename_cube = NULL; 01103 sat_mode_msg = FALSE; 01104 01105 return ret_val; 01106 } 01107
1.7.6.1