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