|
KMOS Pipeline Reference Manual
1.1.3
|
00001 /* $Id: kmo_multi_reconstruct.c,v 1.27 2013/05/07 08:36:03 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/05/07 08:36:03 $ 00024 * $Revision: 1.27 $ 00025 * $Name: HEAD $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 #include <string.h> 00033 #include <math.h> 00034 00035 #include <cpl.h> 00036 #include <cpl_wcs.h> 00037 00038 #include "kmo_debug.h" 00039 #include "kmo_utils.h" 00040 #include "kmo_dfs.h" 00041 #include "kmo_error.h" 00042 #include "kmo_priv_functions.h" 00043 #include "kmo_cpl_extensions.h" 00044 #include "kmo_constants.h" 00045 #include "kmo_priv_multi_reconstruct.h" 00046 #include "kmo_priv_reconstruct.h" 00047 00048 static int kmo_multi_reconstruct_create(cpl_plugin *); 00049 static int kmo_multi_reconstruct_exec(cpl_plugin *); 00050 static int kmo_multi_reconstruct_destroy(cpl_plugin *); 00051 static int kmo_multi_reconstruct(cpl_parameterlist *, cpl_frameset *); 00052 00053 static char kmo_multi_reconstruct_description[] = 00054 "This recipe shifts several exposures of an object and combines them. The diffe-\n" 00055 "rent methods to match the exposures are described below (--smethod parameter).\n" 00056 "The output cube is larger than the input cubes, according to the shifts to be\n" 00057 "applied. Additionally a border of NaN values is added. The WCS is the same as\n" 00058 "for the first exposure.\n" 00059 "For each spatial/spectral pixel a new value will be calculated (according the\n" 00060 "--cmethod parameter) and written into the output cube.\n" 00061 "Only exposures with equal orientation regarding the WCS can be combined (except\n" 00062 "-–smethod=”none”), north must point to the same direction. It is recommended to\n" 00063 "apply any rotation possibly after combining.\n" 00064 "The default mapping mode is done via the --name parameter, where the name of\n" 00065 "the object has to be provided. The recipe searches in all input data cubes IFUs\n" 00066 "pointing to that object.\n" 00067 "\n" 00068 "BASIC PARAMETERS:\n" 00069 "-----------------\n" 00070 "--name\n" 00071 "--ifus\n" 00072 "Since an object can be present only once per exposure and since it can be\n" 00073 "located in different IFUs for the existing exposures, there are two modes to\n" 00074 "identify the objects:\n" 00075 " * Combine by object names (default)\n" 00076 " In this case the object name must be provided via the --name parameter. The\n" 00077 " object name will be searched for in all primary headers of all provided frames\n" 00078 " in the keyword ESO OCS ARMx NAME.\n" 00079 "\n" 00080 " * Combine by index (advanced)\n" 00081 " In this case the --ifus parameter must be provided. The parameter must have\n" 00082 " the same number of entries as frames are provided, e.g. \"3;1;24\" for 3 expo-\n" 00083 " sures. The index doesn't reference the extension in the frame but the real\n" 00084 " index of the IFU as defined in the EXTNAME keyword (e.g. 'IFU.3.DATA').\n" 00085 "\n" 00086 "--smethod\n" 00087 "There are following sources to get the shift parameters from:\n" 00088 " * 'none' (default)\n" 00089 " The cubes are directly recombined, not shifting at all. The ouput frame will\n" 00090 " have the same dimensions as the input cubes.\n" 00091 " If the size differs a warning will be emitted and the cubes will be aligned\n" 00092 " to the lower left corner. If the orientation differs a warning will be emit-\n" 00093 " ted, but the cubes are combined anyway.\n" 00094 "\n" 00095 " * 'header'\n" 00096 " The shifts are calculated according to the WCS information stored in the\n" 00097 " header of every IFU. The output frame will get larger, except the object is\n" 00098 " at the exact same position for all exposures. The size of the exposures can\n" 00099 " differ, but the orientation must be the same for all exposures.\n" 00100 "\n" 00101 " * 'user'\n" 00102 " Read the shifts from a user specified file. The path of the file must be pro-\n" 00103 " vided using the --filename parameter. For every exposure (except the first one)\n" 00104 " two shift values are expected per line, they have to be separated with simple\n" 00105 " spaces. The values indicate pixel shifts and are referenced to the first\n" 00106 " frame. The 1st value is the shift in x-direction to the left, the 2nd the\n" 00107 " shift in y-direction upwards. The size of the exposures can differ, but the\n" 00108 " orientation must be the same for all exposures.\n" 00109 "\n" 00110 " * 'center'\n" 00111 " The shifts are calculated using a centering algorithm. The detector exposures\"" 00112 " will be reconstructed and the resulting data cubes will be collapsed to an image.\n" 00113 " A 2D profile of the image will be fitted to it to identify the centre. With \n" 00114 " the parameter --fmethod the function to fit can be provided. The size of the\n" 00115 " exposures can differ, but the orientation must be the same for all exposures.\n" 00116 "\n" 00117 "--fmethod\n" 00118 "The type of function that should be fitted spatially to the collapsed image.\n" 00119 "This fit is used to create a mask to extract the spectrum of the object. Valid\n" 00120 "values are “gauss” and “moffat”.\n" 00121 "\n" 00122 "ADVANCED PARAMETERS\n" 00123 "-------------------\n" 00124 "--b_samples\n" 00125 "The number of samples in spectral direction for the reconstructed cube. Ideal-\n" 00126 "ly this number should be greater than 2048, the detector size.\n" 00127 "\n" 00128 "--b_start\n" 00129 "--b_end\n" 00130 "Used to define manually the start and end wavelength for the reconstructed\n" 00131 "cube. By default the internally defined values are used.\n" 00132 "\n" 00133 "-------------------------------------------------------------------------------\n" 00134 " Input files:\n" 00135 "\n" 00136 " DO DO KMOS \n" 00137 " category group Type Explanation Required #Frames\n" 00138 " -------- ----- ----- ----------- -------- -------\n" 00139 " OBJECT or RAW The science frames Y >=2 \n" 00140 " STD RAW \n" 00141 " XCAL F2D x calibration frame Y 1 \n" 00142 " YCAL F2D y calibration frame Y 1 \n" 00143 " LCAL F2D Wavelength calib. frame Y 1 \n" 00144 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00145 "\n" 00146 " Output files:\n" 00147 "\n" 00148 " DO KMOS\n" 00149 " category Type Explanation\n" 00150 " -------- ----- -----------\n" 00151 " SCI_COMBINED F3I Combined cubes with noise\n" 00152 " SCI_RECONSTRUCTED F3I Reconstructed cube with noise\n" 00153 00154 00155 00156 " <none or any> - F3I data frame Y 2-n \n" 00157 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00158 "\n" 00159 " Output files:\n" 00160 "\n" 00161 " DO KMOS\n" 00162 " category Type Explanation\n" 00163 " -------- ----- -----------\n" 00164 " CUBE_MULTI_<name/ifu> F3I Combined data cube\n" 00165 "-------------------------------------------------------------------------------\n" 00166 "\n"; 00167 00184 int cpl_plugin_get_info(cpl_pluginlist *list) 00185 { 00186 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00187 cpl_plugin *plugin = &recipe->interface; 00188 00189 cpl_plugin_init(plugin, 00190 CPL_PLUGIN_API, 00191 KMOS_BINARY_VERSION, 00192 CPL_PLUGIN_TYPE_RECIPE, 00193 "kmo_multi_reconstruct", 00194 "Combine reconstructed cubes", 00195 kmo_multi_reconstruct_description, 00196 "Alex Agudo Berbel", 00197 "agudo@mpe.mpg.de", 00198 kmos_get_license(), 00199 kmo_multi_reconstruct_create, 00200 kmo_multi_reconstruct_exec, 00201 kmo_multi_reconstruct_destroy); 00202 00203 cpl_pluginlist_append(list, plugin); 00204 00205 return 0; 00206 } 00207 00215 static int kmo_multi_reconstruct_create(cpl_plugin *plugin) 00216 { 00217 cpl_recipe *recipe; 00218 cpl_parameter *p; 00219 00220 /* Check that the plugin is part of a valid recipe */ 00221 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00222 recipe = (cpl_recipe *)plugin; 00223 else 00224 return -1; 00225 00226 /* Create the parameters list in the cpl_recipe object */ 00227 recipe->parameters = cpl_parameterlist_new(); 00228 00229 /* Fill the parameters list */ 00230 /* --name */ 00231 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.name", 00232 CPL_TYPE_STRING, 00233 "Name of the object to combine.", 00234 "kmos.kmo_multi_reconstruct", 00235 ""); 00236 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00237 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00238 cpl_parameterlist_append(recipe->parameters, p); 00239 00240 /* --ifus */ 00241 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.ifus", 00242 CPL_TYPE_STRING, 00243 "The indices of the IFUs to combine. " 00244 "\"ifu1;ifu2;...\"", 00245 "kmos.kmo_multi_reconstruct", 00246 ""); 00247 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00248 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00249 cpl_parameterlist_append(recipe->parameters, p); 00250 00251 /* --size */ 00252 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.size", 00253 CPL_TYPE_STRING, 00254 "Spatial size of the output cube.", 00255 "kmos.kmo_multi_reconstruct", 00256 "max"); 00257 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "size"); 00258 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00259 cpl_parameterlist_append(recipe->parameters, p); 00260 00261 00262 /* --smethod shift method*/ 00263 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.smethod", 00264 CPL_TYPE_STRING, 00265 "The shifting method: " 00266 "'none': no shifting, combined directly " 00267 "(default), " 00268 "'header': shift according to WCS, " 00269 "'center': centering algorithm, " 00270 "'user': read shifts from file", 00271 "kmos.kmo_multi_reconstruct", 00272 "none"); 00273 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "smethod"); 00274 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00275 cpl_parameterlist_append(recipe->parameters, p); 00276 00277 /* --fmethod */ 00278 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.fmethod", 00279 CPL_TYPE_STRING, 00280 "The fitting method (applies only when " 00281 "method='center'): " 00282 "'gauss': fit a gauss function to collapsed " 00283 "image (default), " 00284 "'moffat': fit a moffat function to collapsed" 00285 " image", 00286 "kmos.kmo_combine", 00287 "gauss"); 00288 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00289 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00290 cpl_parameterlist_append(recipe->parameters, p); 00291 00292 /* --imethod interpolation method */ 00293 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.imethod", 00294 CPL_TYPE_STRING, 00295 "Method to use for interpolation. " 00296 "[\"NN\" (nearest neighbour), " 00297 "\"lwNN\" (linear weighted nearest neighbor), " 00298 "\"swNN\" (square weighted nearest neighbor), " 00299 "\"MS\" (Modified Shepard's method)" 00300 "\"CS\" (Cubic spline)]", 00301 "kmos.kmo_multi_reconstruct", 00302 "NN"); 00303 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00304 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00305 cpl_parameterlist_append(recipe->parameters, p); 00306 00307 /* --neighborhoodRange */ 00308 p = cpl_parameter_new_value("kmos.kmo_reconstruct.neighborhoodRange", 00309 CPL_TYPE_DOUBLE, 00310 "Defines the range to search for neighbors. " 00311 "in pixels", 00312 "kmos.kmo_reconstruct", 00313 1.001); 00314 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00315 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00316 cpl_parameterlist_append(recipe->parameters, p); 00317 00318 /* --filename */ 00319 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.filename", 00320 CPL_TYPE_STRING, 00321 "The path to the file with the shift vectors." 00322 "(Applies only to smethod='user')", 00323 "kmos.kmo_multi_reconstruct", 00324 ""); 00325 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filename"); 00326 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00327 cpl_parameterlist_append(recipe->parameters, p); 00328 00329 // add parameters for band-definition 00330 kmo_band_pars_create(recipe->parameters, 00331 "kmos.kmo_multi_reconstruct"); 00332 00333 return kmo_combine_pars_create(recipe->parameters, 00334 "kmos.kmo_multi_reconstruct", 00335 DEF_REJ_METHOD, 00336 FALSE); 00337 } 00338 00344 static int kmo_multi_reconstruct_exec(cpl_plugin *plugin) 00345 { 00346 cpl_recipe *recipe; 00347 00348 /* Get the recipe out of the plugin */ 00349 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00350 recipe = (cpl_recipe *)plugin; 00351 else return -1 ; 00352 00353 return kmo_multi_reconstruct(recipe->parameters, recipe->frames); 00354 } 00355 00361 static int kmo_multi_reconstruct_destroy(cpl_plugin *plugin) 00362 { 00363 cpl_recipe *recipe; 00364 00365 /* Get the recipe out of the plugin */ 00366 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00367 recipe = (cpl_recipe *)plugin; 00368 else return -1 ; 00369 00370 cpl_parameterlist_delete(recipe->parameters); 00371 return 0 ; 00372 } 00373 00374 //int kmo_tolerance_round(double x, double tol) 00375 //{ 00376 // int ret = 0; 00377 00378 // KMO_TRY 00379 // { 00380 // if (fabs(x - floor(x)) < tol) { 00381 // // value is slightly greater than the real int value 00382 // ret = floor(x); 00383 // } else { 00384 // if (fabs(x - floor(x+tol)) < tol) { 00385 // // value is slightly greater than the real int value 00386 // ret = floor(x+tol); 00387 // } else { 00388 // // error: sub pixel shift 00389 // KMO_TRY_ASSURE(1 == 0, 00390 // CPL_ERROR_ILLEGAL_INPUT, 00391 // "Please apply only whole pixel shifts here " 00392 // "and no subpixel shifts!"); 00393 // } 00394 // } 00395 // } 00396 // KMO_CATCH 00397 // { 00398 // KMO_CATCH_MSG(); 00399 00400 // ret = 0; 00401 // } 00402 00403 // return ret; 00404 //} 00405 00420 static int kmo_multi_reconstruct(cpl_parameterlist *parlist, cpl_frameset *frameset) 00421 { 00422 const char *smethod = NULL, 00423 *cmethod = NULL, 00424 *fmethod = NULL, 00425 *imethod = NULL, 00426 *filename = NULL, 00427 *ifus_txt = NULL, 00428 *name = NULL, 00429 *size = NULL, 00430 *filter_id = NULL; 00431 00432 char *tmp_str = NULL, 00433 *filename_output_cube = NULL, 00434 *extname = NULL, 00435 *keyword = NULL, 00436 *tmp_ocs = NULL; 00437 00438 cpl_imagelist **data_cube_list = NULL, 00439 **noise_cube_list = NULL, 00440 *cube_combined_data = NULL, 00441 *cube_combined_noise = NULL; 00442 00443 cpl_vector *ifus = NULL; 00444 00445 int ret_val = 0, 00446 nr_exposures = 0, 00447 device_nr = 0, 00448 citer = 0, 00449 cmin = 0, 00450 cmax = 0, 00451 nr_alloc = 0; 00452 00453 double neighborhoodRange = 1.001, 00454 cpos_rej = 0.0, 00455 cneg_rej = 0.0; 00456 00457 char **exposure_filename = NULL, 00458 **exposure_objectname = NULL; 00459 int *exposure_ifus = NULL, 00460 nr_object_frames = 0, 00461 nr_std_frames = 0; 00462 00463 double *xshifts = NULL, 00464 *yshifts = NULL, 00465 cd1_1 = 0.0, 00466 cd1_2 = 0.0, 00467 ang1 = 0.0, 00468 ang2 = 0.0, 00469 exposure_rotangle = 0.0; 00470 00471 cpl_propertylist *pl = NULL, 00472 *main_header = NULL, 00473 *ref_main_header = NULL, 00474 *ref_sub_header = NULL, 00475 *tmp_header = NULL, 00476 **header_data = NULL, 00477 **data_header_list = NULL, 00478 **noise_header_list = NULL; 00479 00480 cpl_frame *frame = NULL, 00481 *lcal_frame = NULL; 00482 00483 cpl_table *band_table = NULL; 00484 00485 cpl_image *lcalImg = NULL; 00486 00487 main_fits_desc desc; 00488 00489 cpl_frameset *exposures = NULL; 00490 00491 cpl_frame **empty_frames = NULL, 00492 *tmp_frame = NULL, 00493 *ref_frame = NULL; 00494 00495 gridDefinition gd; 00496 00497 KMO_TRY 00498 { 00499 /* --- check input --- */ 00500 KMO_TRY_ASSURE((parlist != NULL) && 00501 (frameset != NULL), 00502 CPL_ERROR_NULL_INPUT, 00503 "Not all input data is provided!"); 00504 00505 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_multi_reconstruct") == 1, 00506 CPL_ERROR_ILLEGAL_INPUT, 00507 "Cannot identify RAW and CALIB frames!"); 00508 00509 KMO_TRY_ASSURE(! ((cpl_frameset_count_tags(frameset, XCAL) == 0) && 00510 (cpl_frameset_count_tags(frameset, YCAL) == 0) && 00511 (cpl_frameset_count_tags(frameset, LCAL) == 0) && 00512 (cpl_frameset_count_tags(frameset, WAVE_BAND) == 0)), 00513 CPL_ERROR_FILE_NOT_FOUND, 00514 "XCAL, YCAL, LCAL or WAVE_BAND frames missing in " 00515 "frameset!!"); 00516 00517 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00518 CPL_ERROR_FILE_NOT_FOUND, 00519 "Exactly one XCAL frame is expected in frameset!"); 00520 00521 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00522 CPL_ERROR_FILE_NOT_FOUND, 00523 "Exactly one YCAL frame is expected in frameset!"); 00524 00525 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00526 CPL_ERROR_FILE_NOT_FOUND, 00527 "Exactly one LCAL frame is expected in frameset!"); 00528 00529 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00530 CPL_ERROR_FILE_NOT_FOUND, 00531 "Exactly one WAVE_BAND frame is expected in frameset!"); 00532 00533 // assert that at least two OBJECT or STD frames are available and create 00534 // intermediate frameset just with these science frames 00535 nr_object_frames = cpl_frameset_count_tags(frameset, OBJECT); 00536 nr_std_frames = cpl_frameset_count_tags(frameset, STD); 00537 KMO_TRY_CHECK_ERROR_STATE(); 00538 nr_exposures = nr_object_frames + nr_std_frames; 00539 00540 KMO_TRY_ASSURE(((nr_object_frames > 1) && (nr_std_frames == 0)) || 00541 ((nr_object_frames == 0) && (nr_std_frames > 1)), 00542 CPL_ERROR_ILLEGAL_INPUT, 00543 "OBJECT and STD frames mustn't be intermixed and at " 00544 "least two frames (OBJECT or STD) must be provided " 00545 "to combine!"); 00546 KMO_TRY_EXIT_IF_NULL( 00547 exposures = cpl_frameset_new()); 00548 if (nr_object_frames > 1) { 00549 KMO_TRY_EXIT_IF_NULL( 00550 tmp_frame = kmo_dfs_get_frame(frameset, OBJECT)); 00551 } else { 00552 KMO_TRY_EXIT_IF_NULL( 00553 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00554 } 00555 00556 for (int i = 0; i < nr_exposures; i++) { 00557 KMO_TRY_EXIT_IF_ERROR( 00558 cpl_frameset_insert(exposures, cpl_frame_duplicate(tmp_frame))); 00559 KMO_TRY_CHECK_ERROR_STATE(); 00560 00561 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 00562 } 00563 00564 cpl_msg_info("", "--- Parameter setup for kmo_multi_reconstruct -------"); 00565 00566 KMO_TRY_EXIT_IF_NULL( 00567 imethod = kmo_dfs_get_parameter_string(parlist, 00568 "kmos.kmo_multi_reconstruct.imethod")); 00569 00570 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00571 (strcmp(imethod, "lwNN") == 0) || 00572 (strcmp(imethod, "swNN") == 0) || 00573 (strcmp(imethod, "MS") == 0) || 00574 (strcmp(imethod, "CS") == 0), 00575 CPL_ERROR_ILLEGAL_INPUT, 00576 "imethod must be either \"NN\", \"lwNN\", " 00577 "\"swNN\", \"MS\" or \"CS\"!"); 00578 00579 KMO_TRY_EXIT_IF_ERROR( 00580 kmo_dfs_print_parameter_help(parlist, 00581 "kmos.kmo_multi_reconstruct.imethod")); 00582 00583 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00584 "kmos.kmo_reconstruct.neighborhoodRange"); 00585 KMO_TRY_CHECK_ERROR_STATE(); 00586 00587 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00588 CPL_ERROR_ILLEGAL_INPUT, 00589 "neighborhoodRange must be greater than 0.0"); 00590 00591 KMO_TRY_EXIT_IF_ERROR( 00592 kmo_dfs_print_parameter_help(parlist, 00593 "kmos.kmo_reconstruct.neighborhoodRange")); 00594 00595 KMO_TRY_EXIT_IF_NULL( 00596 size = kmo_dfs_get_parameter_string(parlist, 00597 "kmos.kmo_multi_reconstruct.size")); 00598 00599 KMO_TRY_EXIT_IF_NULL( 00600 smethod = kmo_dfs_get_parameter_string(parlist, 00601 "kmos.kmo_multi_reconstruct.smethod")); 00602 00603 KMO_TRY_EXIT_IF_NULL( 00604 fmethod = kmo_dfs_get_parameter_string(parlist, 00605 "kmos.kmo_multi_reconstruct.fmethod")); 00606 00607 KMO_TRY_ASSURE((strcmp(size, "max") == 0) || 00608 (strcmp(size, "std") == 0), 00609 CPL_ERROR_ILLEGAL_INPUT, 00610 "Following output cube size specifications are available: " 00611 "'std' or 'max'"); 00612 00613 00614 KMO_TRY_ASSURE((strcmp(smethod, "none") == 0) || 00615 (strcmp(smethod, "header") == 0) || 00616 (strcmp(smethod, "center") == 0) || 00617 (strcmp(smethod, "user") == 0), 00618 CPL_ERROR_ILLEGAL_INPUT, 00619 "Following shift methods are available : 'none', " 00620 "'header', 'center' or 'user'"); 00621 00622 if (strcmp(smethod, "user") == 0) { 00623 filename = kmo_dfs_get_parameter_string(parlist, 00624 "kmos.kmo_multi_reconstruct.filename"); 00625 KMO_TRY_CHECK_ERROR_STATE(); 00626 00627 KMO_TRY_ASSURE(strcmp(filename, "") != 0, 00628 CPL_ERROR_ILLEGAL_INPUT, 00629 "path of file with shift information must be " 00630 "provided!"); 00631 00632 KMO_TRY_EXIT_IF_ERROR( 00633 kmo_dfs_print_parameter_help(parlist, 00634 "kmos.kmo_multi_reconstruct.filename")); 00635 } 00636 00637 KMO_TRY_EXIT_IF_ERROR( 00638 kmo_dfs_print_parameter_help(parlist, 00639 "kmos.kmo_multi_reconstruct.smethod")); 00640 00641 ifus_txt = kmo_dfs_get_parameter_string(parlist, 00642 "kmos.kmo_multi_reconstruct.ifus"); 00643 KMO_TRY_CHECK_ERROR_STATE(); 00644 00645 name = kmo_dfs_get_parameter_string(parlist, 00646 "kmos.kmo_multi_reconstruct.name"); 00647 KMO_TRY_CHECK_ERROR_STATE(); 00648 00649 if (strcmp(ifus_txt, "") != 0) { 00650 KMO_TRY_ASSURE(strcmp(name, "") == 0, 00651 CPL_ERROR_ILLEGAL_INPUT, 00652 "name parameter must be NULL if IFU indices are " 00653 "provided!"); 00654 00655 KMO_TRY_EXIT_IF_NULL( 00656 ifus = kmo_identify_values(ifus_txt)); 00657 00658 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_exposures, 00659 CPL_ERROR_ILLEGAL_INPUT, 00660 "ifus parameter must have the same number of values " 00661 "than frames provided ) (%lld!=%d)", 00662 cpl_vector_get_size(ifus), nr_exposures); 00663 00664 for (int i = 0; i < nr_exposures; i++) { 00665 KMO_TRY_ASSURE((cpl_vector_get(ifus, i) > 0.5 && 00666 cpl_vector_get(ifus, i) < 24.5 ), 00667 CPL_ERROR_ILLEGAL_INPUT, 00668 "IFU numbers must be in the range 1..24"); 00669 } 00670 } 00671 00672 if (strcmp(name, "") != 0) { 00673 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, 00674 CPL_ERROR_ILLEGAL_INPUT, 00675 "ifus parameter must be NULL if name is provided!"); 00676 } 00677 00678 KMO_TRY_ASSURE((strcmp(name, "") != 0) || (strcmp(ifus_txt, "") != 0), 00679 CPL_ERROR_ILLEGAL_INPUT, 00680 "Either the name of the object or the numbers of the " 00681 "IFUs to combine must be provided (--name or --ifus " 00682 "parameters)"); 00683 00684 KMO_TRY_EXIT_IF_ERROR( 00685 kmo_dfs_print_parameter_help(parlist, 00686 "kmos.kmo_multi_reconstruct.ifus")); 00687 00688 KMO_TRY_EXIT_IF_ERROR( 00689 kmo_dfs_print_parameter_help(parlist, 00690 "kmos.kmo_multi_reconstruct.name")); 00691 00692 KMO_TRY_EXIT_IF_ERROR( 00693 kmo_combine_pars_load(parlist, 00694 "kmos.kmo_multi_reconstruct", 00695 &cmethod, 00696 &cpos_rej, 00697 &cneg_rej, 00698 &citer, 00699 &cmin, 00700 &cmax, 00701 FALSE)); 00702 00703 kmo_band_pars_load(parlist, "kmos.kmo_multi_reconstruct"); 00704 00705 cpl_msg_info("", "-------------------------------------------"); 00706 00707 // assure that filters and grating match for 00708 // XCAL, YCAL, LCAL and for data frames to reconstruct 00709 KMO_TRY_EXIT_IF_ERROR( 00710 kmo_check_frameset_setup(frameset, XCAL, 00711 TRUE, FALSE, FALSE)); 00712 KMO_TRY_EXIT_IF_ERROR( 00713 kmo_check_frameset_setup(frameset, YCAL, 00714 TRUE, FALSE, FALSE)); 00715 KMO_TRY_EXIT_IF_ERROR( 00716 kmo_check_frameset_setup(frameset, LCAL, 00717 TRUE, FALSE, FALSE)); 00718 KMO_TRY_EXIT_IF_ERROR( 00719 kmo_check_frame_setup(frameset, XCAL, YCAL, 00720 TRUE, FALSE, TRUE)); 00721 KMO_TRY_EXIT_IF_ERROR( 00722 kmo_check_frame_setup(frameset, XCAL, LCAL, 00723 TRUE, FALSE, TRUE)); 00724 if (nr_object_frames > 1) { 00725 KMO_TRY_EXIT_IF_ERROR( 00726 kmo_check_frameset_setup(frameset, OBJECT, 00727 TRUE, FALSE, FALSE)); 00728 KMO_TRY_EXIT_IF_ERROR( 00729 kmo_check_frame_setup(frameset, XCAL, OBJECT, 00730 TRUE, FALSE, TRUE)); 00731 } else { 00732 KMO_TRY_EXIT_IF_ERROR( 00733 kmo_check_frameset_setup(frameset, STD, 00734 TRUE, FALSE, FALSE)); 00735 KMO_TRY_EXIT_IF_ERROR( 00736 kmo_check_frame_setup(frameset, XCAL, STD, 00737 TRUE, FALSE, TRUE)); 00738 } 00739 00740 KMO_TRY_EXIT_IF_ERROR( 00741 kmo_check_frame_setup_md5_xycal(frameset)); 00742 KMO_TRY_EXIT_IF_ERROR( 00743 kmo_check_frame_setup_md5(frameset)); 00744 00745 // KMO_TRY_EXIT_IF_ERROR( 00746 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00747 // KMO_TRY_EXIT_IF_ERROR( 00748 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00749 00750 00751 nr_alloc = nr_exposures; 00752 KMO_TRY_EXIT_IF_NULL( 00753 exposure_filename = cpl_malloc(nr_alloc * sizeof(char *))); 00754 KMO_TRY_EXIT_IF_NULL( 00755 exposure_objectname = cpl_malloc(nr_alloc * sizeof(char *))); 00756 KMO_TRY_EXIT_IF_NULL( 00757 exposure_ifus = cpl_malloc(nr_alloc * sizeof(int))); 00758 00759 // check exposure frames 00760 for (int i = 0; i < nr_exposures; i++) { 00761 KMO_TRY_EXIT_IF_NULL( 00762 tmp_str = cpl_sprintf("%d", i)); 00763 00764 KMO_TRY_EXIT_IF_NULL( 00765 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00766 cpl_free(tmp_str); 00767 00768 KMO_TRY_EXIT_IF_NULL( 00769 exposure_filename[i] = (char*)cpl_frame_get_filename(frame)); 00770 00771 kmo_init_fits_desc(&desc); 00772 00773 desc = kmo_identify_fits_header(exposure_filename[i]); 00774 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to " 00775 "be in KMOS-format!"); 00776 00777 KMO_TRY_ASSURE(((desc.nr_ext == KMOS_NR_DETECTORS) || 00778 ((desc.nr_ext == 2*KMOS_NR_DETECTORS))) && 00779 (desc.ex_badpix == FALSE) && 00780 ((desc.fits_type == raw_fits) || 00781 (desc.fits_type == f2d_fits)) && 00782 (desc.frame_type == detector_frame), 00783 CPL_ERROR_ILLEGAL_INPUT, 00784 "The frame to reconstruct isn't in the correct " 00785 "format!!!"); 00786 kmo_free_fits_desc(&desc); 00787 } 00788 00789 // select IFU for each exposure 00790 KMO_TRY_EXIT_IF_NULL( 00791 empty_frames = cpl_malloc(nr_alloc * sizeof(cpl_frame *))); 00792 int found=0; 00793 for (int i = 0; i < nr_exposures; i++) { 00794 empty_frames[i] = NULL; 00795 if (strcmp(ifus_txt, "") != 0) { //IFU selected by user given list 00796 found = 1; 00797 const char *tmpString; 00798 exposure_ifus[i] = (int) (cpl_vector_get(ifus, i) + 0.1); 00799 KMO_TRY_EXIT_IF_NULL( 00800 pl = kmclipm_propertylist_load(exposure_filename[i], 0)); 00801 KMO_TRY_EXIT_IF_NULL( 00802 tmp_ocs = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, 00803 exposure_ifus[i], IFU_NAME_POSTFIX)); 00804 if (cpl_propertylist_has(pl, tmp_ocs)) { 00805 tmpString = cpl_propertylist_get_string(pl, tmp_ocs); 00806 } else { 00807 tmpString = ""; 00808 } 00809 cpl_free(tmp_ocs); 00810 int len = strlen(tmpString); 00811 const int maxLen = 40; 00812 if (len > maxLen) { 00813 len = maxLen; 00814 } 00815 exposure_objectname[i] = (char *) cpl_malloc(len * sizeof(char)); 00816 strncpy(exposure_objectname[i], tmpString, len-1); 00817 if (len > 0) { 00818 (exposure_objectname[i])[len-1] = '\0'; 00819 } 00820 cpl_propertylist_delete(pl); pl = NULL; 00821 } else { //IFU selected by user given object name 00822 exposure_objectname[i] = (char*)name; 00823 KMO_TRY_EXIT_IF_NULL( 00824 tmp_str = cpl_sprintf("%d", i)); 00825 00826 KMO_TRY_EXIT_IF_NULL( 00827 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00828 cpl_free(tmp_str); 00829 00830 KMO_TRY_CHECK_ERROR_STATE(); 00831 int this_ifu = kmo_get_index_from_ocs_name(frame, name); 00832 KMO_TRY_CHECK_ERROR_STATE(); 00833 if (this_ifu > 0) { 00834 found = 1; 00835 exposure_ifus[i] = this_ifu; 00836 } else { 00837 empty_frames[i] = frame; 00838 exposure_ifus[i] = -1; 00839 cpl_msg_warning("", 00840 "Could not find any IFU with an object " 00841 "named '%s' in file %s", 00842 name, exposure_filename[i]); 00843 } 00844 } 00845 KMO_TRY_CHECK_ERROR_STATE(); 00846 } 00847 if (! found) { 00848 cpl_msg_error("", 00849 "Could not find any IFU with an object named '%s' in " 00850 "any input file", name); 00851 KMO_TRY_EXIT_WITH_ERROR(CPL_ERROR_ILLEGAL_INPUT); 00852 } 00853 int j = 0; 00854 for (int i = 0; i < nr_alloc; i++) { 00855 if (empty_frames[i] != NULL) { 00856 KMO_TRY_EXIT_IF_ERROR( 00857 cpl_frameset_erase_frame(exposures, empty_frames[i])); 00858 nr_exposures--; 00859 exposure_ifus[j] = exposure_ifus[i]; 00860 } else { 00861 exposure_ifus[j] = exposure_ifus[i]; 00862 j++; 00863 } 00864 } 00865 for (int i = 0; i < nr_exposures; i++) { 00866 KMO_TRY_EXIT_IF_NULL( 00867 tmp_str = cpl_sprintf("%d", i)); 00868 00869 KMO_TRY_EXIT_IF_NULL( 00870 frame = kmo_dfs_get_frame(exposures, tmp_str)); 00871 cpl_free(tmp_str); 00872 00873 KMO_TRY_EXIT_IF_NULL( 00874 exposure_filename[i] = (char*)cpl_frame_get_filename(frame)); 00875 } 00876 00877 cpl_free(empty_frames); empty_frames = NULL; 00878 00879 // get reference header, subheader and set grid definition 00880 device_nr = ((exposure_ifus[0] -1) / KMOS_IFUS_PER_DETECTOR) + 1; 00881 00882 KMO_TRY_EXIT_IF_NULL( 00883 ref_main_header = kmclipm_propertylist_load(exposure_filename[0],0)); 00884 KMO_TRY_EXIT_IF_NULL( 00885 ref_frame = cpl_frameset_get_first(exposures)); 00886 KMO_TRY_EXIT_IF_NULL( 00887 ref_sub_header = kmclipm_propertylist_load(exposure_filename[0], 00888 device_nr)); 00889 KMO_TRY_EXIT_IF_ERROR( 00890 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, KMOS_PIX_RESOLUTION)); 00891 00892 exposure_rotangle = kmo_mr_get_rot_angle(kmo_dfs_get_frame(exposures, "0")); 00893 KMO_TRY_EXIT_IF_NULL( 00894 lcal_frame = kmo_mr_get_closest_cal_frame(frameset, LCAL, 00895 exposure_rotangle)); 00896 KMO_TRY_EXIT_IF_NULL( 00897 lcalImg = kmo_dfs_load_image_frame(lcal_frame, device_nr, 0, 00898 FALSE, NULL)); 00899 00900 KMO_TRY_EXIT_IF_NULL( 00901 tmp_header = kmclipm_propertylist_load( 00902 cpl_frame_get_filename(lcal_frame), 0)); 00903 KMO_TRY_EXIT_IF_NULL( 00904 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, device_nr, 00905 IFU_FILTID_POSTFIX)); 00906 KMO_TRY_EXIT_IF_NULL( 00907 filter_id = cpl_propertylist_get_string(tmp_header, keyword)); 00908 00909 int band_method = 0; 00910 KMO_TRY_EXIT_IF_NULL( 00911 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0)); 00912 00913 KMO_TRY_EXIT_IF_ERROR( 00914 kmclipm_setup_grid_band_lcal(&gd, lcalImg, filter_id, 00915 band_method, band_table)); 00916 cpl_image_delete(lcalImg); lcalImg = NULL; 00917 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00918 cpl_free(keyword); keyword = NULL; 00919 cpl_table_delete(band_table); band_table = NULL; 00920 00921 //extract sub-headers for each exposures, calculate WCS 00922 KMO_TRY_EXIT_IF_NULL( 00923 header_data = cpl_malloc(nr_exposures*sizeof(cpl_propertylist*))); 00924 for (int i = 0; i < nr_exposures; i++) { 00925 device_nr = ((exposure_ifus[0] -1) / KMOS_IFUS_PER_DETECTOR) + 1; 00926 KMO_TRY_EXIT_IF_NULL( 00927 header_data[i] = kmclipm_propertylist_load(exposure_filename[i], 00928 device_nr)); 00929 KMO_TRY_EXIT_IF_ERROR( 00930 kmclipm_update_property_int(header_data[i],"NAXIS", 3,"")); 00931 KMO_TRY_EXIT_IF_ERROR( 00932 kmclipm_update_property_int(header_data[i],"NAXIS1",gd.x.dim,"")); 00933 KMO_TRY_EXIT_IF_ERROR( 00934 kmclipm_update_property_int(header_data[i],"NAXIS2",gd.y.dim,"")); 00935 KMO_TRY_EXIT_IF_ERROR( 00936 kmclipm_update_property_int(header_data[i],"NAXIS3",gd.l.dim,"")); 00937 cpl_propertylist *tmpHeader; 00938 KMO_TRY_EXIT_IF_NULL( 00939 tmpHeader = kmclipm_propertylist_load(exposure_filename[i],0)); 00940 KMO_TRY_EXIT_IF_ERROR( 00941 kmo_calc_wcs_gd(tmpHeader, header_data[i], exposure_ifus[i], gd)); 00942 cpl_propertylist_delete(tmpHeader); 00943 } 00944 00945 // check rotation angle 00946 cd1_1 = kmo_dfs_get_property_double(header_data[0], CD1_1); 00947 cd1_2 = kmo_dfs_get_property_double(header_data[0], CD1_2); 00948 KMO_TRY_CHECK_ERROR_STATE(); 00949 ang1 = atan(cd1_2/cd1_1)*180/CPL_MATH_PI; 00950 for (int i = 1; i < nr_exposures; i++) { 00951 cd1_1 = kmo_dfs_get_property_double(header_data[i], CD1_1); 00952 cd1_2 = kmo_dfs_get_property_double(header_data[i], CD1_2); 00953 KMO_TRY_CHECK_ERROR_STATE(); 00954 ang2 = atan(cd1_2/cd1_1)*180/CPL_MATH_PI; 00955 00956 if (strcmp(smethod, "none") != 0) { 00957 // center, header, user 00958 KMO_TRY_ASSURE(fabs(ang1-ang2) <= 0.5, 00959 CPL_ERROR_ILLEGAL_INPUT, 00960 "Orientation of cube 1 (%gdeg) and cube %d " 00961 "(%gdeg) differ! " 00962 "Align the orientation of this cube with " 00963 "kmo_rotate before applying this recipe.", 00964 ang1, i+1, ang2); 00965 } else { 00966 // none 00967 if (fabs(ang1-ang2) > 0.5) { 00968 cpl_msg_warning("", 00969 "Orientation of cube 1 (%gdeg) and cube %d " 00970 "(%gdeg) differ! Processing anyway.", 00971 ang1, i+1, ang2); 00972 } 00973 } 00974 } 00975 00976 // set x/y shifts 00977 KMO_TRY_EXIT_IF_NULL( 00978 xshifts = cpl_malloc(nr_exposures * sizeof(double))); 00979 KMO_TRY_EXIT_IF_NULL( 00980 yshifts = cpl_malloc(nr_exposures * sizeof(double))); 00981 KMO_TRY_EXIT_IF_ERROR( 00982 kmo_mr_get_offsets(nr_exposures, smethod, imethod, neighborhoodRange, 00983 filename, frameset, exposures, exposure_ifus, 00984 (const cpl_propertylist**)header_data, 00985 fmethod, 00986 cmethod, 00987 cpos_rej, 00988 cneg_rej, 00989 citer, 00990 cmin, 00991 cmax, 00992 xshifts, yshifts)); 00993 00994 for (int i = 0; i < nr_exposures; i++) { 00995 printf("exposure %d: filename %s, selected IFU %d, object name " 00996 "\"%s\", xshift %f, yshift %f\n", i, exposure_filename[i], 00997 exposure_ifus[i], exposure_objectname[i], xshifts[i], yshifts[i]); 00998 } 00999 01000 // 01001 // set spatial part of the grid 01002 // 01003 // size = "max"; 01004 if (strcmp(size, "max") == 0) { 01005 double xmin=0, xmax=0, ymin=0, ymax=0; 01006 double gxshift, gyshift, gxdim, gydim; 01007 double pixel_resolution = KMOS_PIXEL_RESOLUTION; 01008 int xdim, ydim; 01009 01010 for (int i = 0; i < nr_exposures; i++) { 01011 if (xmin > xshifts[i]) { xmin = xshifts[i]; } 01012 if (xmax < xshifts[i]) { xmax = xshifts[i]; } 01013 if (ymin > yshifts[i]) { ymin = yshifts[i]; } 01014 if (ymax < yshifts[i]) { ymax = yshifts[i]; } 01015 } 01016 if (xmax > 0.0001) { 01017 gxshift = - ceil(xmax); 01018 } else { 01019 gxshift = 0.; 01020 } 01021 if (ymin < -0.0001) { 01022 gyshift = floor(ymin); 01023 } else { 01024 gyshift = 0.; 01025 } 01026 if (xmin < -0.0001) { 01027 gxdim = - floor(xmin); 01028 } else { 01029 gxdim = 0.; 01030 } 01031 if (ymax > 0.0001) { 01032 gydim = ceil(ymax); 01033 } else { 01034 gydim = 0.; 01035 } 01036 01037 xdim = (int) (gxdim - gxshift + .5); 01038 ydim = (int) (gydim - gyshift + .5); 01039 gd.x.start += gxshift * pixel_resolution; 01040 gd.y.start += gyshift * pixel_resolution; 01041 gd.x.dim += xdim; 01042 gd.y.dim += ydim; 01043 // printf("X: %f < %f Y: %f < %f \n",xmin,xmax,ymin,ymax); 01044 // printf("gxshift: %f gxdim: %f xdim: %d gyshift: %f gydim: %f ydim: %d \n", 01045 // gxshift, gxdim, xdim, gyshift, gydim, ydim); 01046 // printf("GD: %f %d %f %d\n", gd.x.start, gd.x.dim, gd.y.start, gd.y.dim); 01047 } 01048 01049 // 01050 // reconstruct multiple detector images 01051 // 01052 01053 // printf("GD: %f %f %d %f %f %d %f %f %d\n", 01054 // gd.x.start, gd.x.delta, gd.x.dim, 01055 // gd.y.start, gd.y.delta, gd.y.dim, 01056 // gd.l.start, gd.l.delta, gd.l.dim); 01057 01058 KMO_TRY_EXIT_IF_ERROR( 01059 kmo_priv_multi_reconstruct(frameset, 01060 exposures, 01061 exposure_ifus, 01062 xshifts, 01063 yshifts, 01064 gd, 01065 &cube_combined_data, 01066 &cube_combined_noise)); 01067 01068 // setup output category COMBINE + ESO PRO CATG 01069 if (strcmp(ifus_txt, "") != 0) { //IFU selected by user given list 01070 KMO_TRY_EXIT_IF_NULL( 01071 tmp_str = cpl_sprintf("IFU")); 01072 } else { 01073 KMO_TRY_EXIT_IF_NULL( 01074 tmp_str = cpl_sprintf("%s", name)); 01075 } 01076 01077 KMO_TRY_EXIT_IF_NULL( 01078 filename_output_cube = cpl_sprintf("%s_%s", CUBE_MULTI, tmp_str)); 01079 cpl_free(tmp_str); tmp_str = NULL; 01080 01081 KMO_TRY_EXIT_IF_ERROR( 01082 kmo_dfs_save_main_header(frameset, filename_output_cube, "", 01083 ref_frame, NULL, parlist, cpl_func)); 01084 // save output 01085 KMO_TRY_EXIT_IF_NULL( 01086 extname = kmo_extname_creator(ifu_frame, exposure_ifus[0], 01087 EXT_DATA)); 01088 01089 // calculate WCS 01090 KMO_TRY_EXIT_IF_ERROR( 01091 kmo_calc_wcs_gd(ref_main_header, ref_sub_header, exposure_ifus[0], gd)); 01092 01093 KMO_TRY_EXIT_IF_ERROR( 01094 kmclipm_update_property_string(ref_sub_header, 01095 EXTNAME, 01096 extname, 01097 "FITS extension name")); 01098 cpl_free(extname); extname = NULL; 01099 01100 KMO_TRY_EXIT_IF_ERROR( 01101 kmo_dfs_save_cube(cube_combined_data, filename_output_cube, 01102 "", ref_sub_header, 0./0.)); 01103 01104 if (cube_combined_noise != NULL) { 01105 KMO_TRY_EXIT_IF_NULL( 01106 extname = kmo_extname_creator(ifu_frame, exposure_ifus[0], 01107 EXT_NOISE)); 01108 01109 KMO_TRY_EXIT_IF_ERROR( 01110 kmclipm_update_property_string(ref_sub_header, 01111 EXTNAME, 01112 extname, 01113 "FITS extension name")); 01114 cpl_free(extname); extname = NULL; 01115 01116 KMO_TRY_EXIT_IF_ERROR( 01117 kmo_dfs_save_cube(cube_combined_noise, filename_output_cube, 01118 "", ref_sub_header, 0./0.)); 01119 } 01120 } 01121 KMO_CATCH 01122 { 01123 KMO_CATCH_MSG(); 01124 ret_val = -1; 01125 } 01126 01127 cpl_free(filename_output_cube); filename_output_cube = NULL; 01128 cpl_propertylist_delete(main_header); main_header = NULL; 01129 cpl_vector_delete(ifus); ifus = NULL; 01130 cpl_imagelist_delete(cube_combined_data); cube_combined_data = NULL; 01131 cpl_imagelist_delete(cube_combined_noise); cube_combined_noise = NULL; 01132 if (exposures != NULL) {cpl_frameset_delete(exposures);} 01133 if (exposure_filename != NULL) {cpl_free(exposure_filename);} 01134 if ((ifus_txt != NULL) && (strcmp(ifus_txt, "") != 0)) { //IFU selected by user given list 01135 for (int i = 0; i < nr_alloc; i++) { 01136 cpl_free(exposure_objectname[i]); 01137 } 01138 } 01139 if (exposure_objectname != NULL) {cpl_free(exposure_objectname);} 01140 if (exposure_ifus != NULL) {cpl_free(exposure_ifus);} 01141 if (ref_main_header != NULL) {cpl_propertylist_delete(ref_main_header);} 01142 if (ref_sub_header != NULL) {cpl_propertylist_delete(ref_sub_header);} 01143 if (xshifts != NULL) {cpl_free(xshifts);} 01144 if (yshifts != NULL) {cpl_free(yshifts);} 01145 01146 if (data_cube_list != NULL) { 01147 for (int i = 0; i < nr_exposures; i++) { 01148 cpl_imagelist_delete(data_cube_list[i]); data_cube_list[i] = NULL; 01149 } 01150 cpl_free(data_cube_list); data_cube_list = NULL; 01151 } 01152 01153 if (noise_cube_list != NULL) { 01154 for (int i = 0; i < nr_exposures; i++) { 01155 cpl_imagelist_delete(noise_cube_list[i]); noise_cube_list[i] = NULL; 01156 } 01157 cpl_free(noise_cube_list); noise_cube_list = NULL; 01158 } 01159 01160 if (data_header_list != NULL) { 01161 for (int i = 0; i < nr_exposures; i++) { 01162 cpl_propertylist_delete(data_header_list[i]); 01163 data_header_list[i] = NULL; 01164 } 01165 cpl_free(data_header_list); data_header_list = NULL; 01166 } 01167 01168 if (noise_header_list != NULL) { 01169 for (int i = 0; i < nr_exposures; i++) { 01170 cpl_propertylist_delete(noise_header_list[i]); 01171 noise_header_list[i] = NULL; 01172 } 01173 cpl_free(noise_header_list); noise_header_list = NULL; 01174 } 01175 01176 if (header_data != NULL) { 01177 for (int i = 0; i < nr_exposures; i++) { 01178 cpl_propertylist_delete(header_data[i]); 01179 header_data[i] = NULL; 01180 } 01181 cpl_free(header_data); header_data = NULL; 01182 } 01183 01184 return ret_val; 01185 } 01186
1.7.6.1