|
KMOS Pipeline Reference Manual
1.1.0
|
00001 /* $Id: kmo_sci_red.c,v 1.45 2013/03/18 11:52:13 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/03/18 11:52:13 $ 00024 * $Revision: 1.45 $ 00025 * $Name: HEAD $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 * Includes 00034 *----------------------------------------------------------------------------*/ 00035 #include <string.h> 00036 00037 #include <cpl.h> 00038 #include "kmclipm_constants.h" 00039 #include "kmclipm_functions.h" 00040 00041 #include "kmo_debug.h" 00042 #include "kmo_constants.h" 00043 #include "kmo_utils.h" 00044 #include "kmo_error.h" 00045 #include "kmo_dfs.h" 00046 #include "kmo_functions.h" 00047 #include "kmo_priv_arithmetic.h" 00048 #include "kmo_priv_combine.h" 00049 #include "kmo_priv_functions.h" 00050 #include "kmo_priv_reconstruct.h" 00051 #include "kmo_priv_std_star.h" 00052 00053 /*----------------------------------------------------------------------------- 00054 * Types 00055 *-----------------------------------------------------------------------------*/ 00056 typedef struct { 00057 char *name; 00058 int count; 00059 } allObjStruct; 00060 00061 /*----------------------------------------------------------------------------- 00062 * Functions prototypes 00063 *----------------------------------------------------------------------------*/ 00064 00065 static int kmo_sci_red_create(cpl_plugin *); 00066 static int kmo_sci_red_exec(cpl_plugin *); 00067 static int kmo_sci_red_destroy(cpl_plugin *); 00068 static int kmo_sci_red(cpl_parameterlist *, cpl_frameset *); 00069 00070 /*----------------------------------------------------------------------------- 00071 * Static variables 00072 *----------------------------------------------------------------------------*/ 00073 00074 static char kmo_sci_red_description[] = 00075 "At least two data frames have to be provided since we need for each IFU poin-\n" 00076 "ting to an object also a sky frame from the same IFU.\n" 00077 "Every IFU containing an object will be reconstructed and divided by telluric\n" 00078 "and illumination correction. By default these intermediate cubes are saved to\n" 00079 "disk. Frames just containing skies won’t produce an output here, so the number\n" 00080 "of output frames can be smaller than the number of input frames.\n" 00081 "Then the reconstructed objects with the same object name are combined. These\n" 00082 "outputs are also saved to disk, the number of created files depends on the\n" 00083 "number of reconstructed objects of different name. If the user just wants to\n" 00084 "combine a certain object, the parameters --name or --ifus can be used.\n" 00085 "For exposures taken with the templates KMOS_spec_obs_mapping8 and\n" 00086 "KMOS_spec_obs_mapping24 the recipe behaves a bit different: All active IFUs\n" 00087 "will be combined, regardless of the object names.\n" 00088 "This recipe must be called after the kmo_std_star-recipe.\n" 00089 "\n" 00090 "BASIC PARAMETERS:\n" 00091 "-----------------\n" 00092 "--imethod\n" 00093 "The interpolation method used for reconstruction.\n" 00094 "\n" 00095 "--smethod\n" 00096 "The interpolation method used for shifting.\n" 00097 "\n" 00098 "ADVANCED PARAMETERS\n" 00099 "-------------------\n" 00100 "--flux\n" 00101 "Specify if flux conservation should be applied.\n" 00102 "\n" 00103 " Advanced reconstruction parameters\n" 00104 " ----------------------------------\n" 00105 "--neighborhoodRange\n" 00106 "Defines the range to search for neighbors during reconstruction\n" 00107 "\n" 00108 "--b_samples\n" 00109 "The number of samples in spectral direction for the reconstructed cube.\n" 00110 "Ideally this number should be greater than 2048, the detector size.\n" 00111 "\n" 00112 "--b_start\n" 00113 "--b_end\n" 00114 "Used to define manually the start and end wavelength for the reconstructed\n" 00115 "cube. By default the internally defined values are used.\n" 00116 "\n" 00117 "--fast-mode\n" 00118 "If set to TRUE, the reconstructed cubes will be collapsed (using median) and\n" 00119 "only then be shifted and combined.\n" 00120 "\n" 00121 " Advanced combining parameters\n" 00122 " ----------------------------------\n" 00123 "--name\n" 00124 "--ifus\n" 00125 "Since an object can be present only once per exposure and since it can be\n" 00126 "located in different IFUs for the existing exposures, there are two modes to\n" 00127 "identify the objects:\n" 00128 " * Combine by object names (default)\n" 00129 " In this case the object name must be provided via the --name parameter. The\n" 00130 " object name will be searched for in all primary headers of all provided\n" 00131 " frames in the keyword ESO OCS ARMx NAME.\n" 00132 "\n" 00133 " * Combine by index (advanced)\n" 00134 " In this case the --ifus parameter must be provided. The parameter must have\n" 00135 " the same number of entries as frames are provided, e.g. \"3;1;24\" for 3\n" 00136 " exposures. The index doesn't reference the extension in the frame but the\n" 00137 " real index of the IFU as defined in the EXTNAME keyword.\n" 00138 " (e.g. 'IFU.3.DATA')\n" 00139 "\n" 00140 "--method\n" 00141 "There are following sources to get the shift parameters from:\n" 00142 " * 'header' (default)\n" 00143 " The shifts are calculated according to the WCS information stored in the\n" 00144 " header of every IFU. The output frame will get larger, except the object is\n" 00145 " at the exact same position for all exposures. The size of the exposures can\n" 00146 " differ, but the orientation must be the same for all exposures.\n" 00147 "\n" 00148 " * 'none'\n" 00149 " The cubes are directly recombined, not shifting at all. The ouput frame\n" 00150 " will have the same dimensions as the input cubes.\n" 00151 " If the size differs a warning will be emitted and the cubes will be aligned\n" 00152 " to the lower left corner. If the orientation differs a warning will be\n" 00153 " emitted, but the cubes are combined anyway.\n" 00154 "\n" 00155 " * 'center'\n" 00156 " The shifts are calculated using a centering algorithm. The cube will be\n" 00157 " collapsed and a 2D profile will be fitted to it to identify the centre.\n" 00158 " With the parameter --fmethod the function to fit can be provided. The size\n" 00159 " of the exposures can differ, but the orientation must be the same for all\n" 00160 " exposures.\n" 00161 "\n" 00162 " * 'user'\n" 00163 " Read the shifts from a user specified file. The path of the file must be\n" 00164 " provided using the --filename parameter. For every exposure (except the\n" 00165 " first one) two shift values are expected per line, they have to be separa-\n" 00166 " ted with simple spaces. The values indicate pixel shifts and are referenced\n" 00167 " to the first frame. The 1st value is the shift in x-direction to the left,\n" 00168 " the 2nd the shift in y-direction upwards. The size of the exposures can\n" 00169 " differ, but the orientation must be the same for all exposures.\n" 00170 "\n" 00171 "--fmethod\n" 00172 "see --method='center'\n" 00173 "The type of function that should be fitted spatially to the collapsed image.\n" 00174 "This fit is used to create a mask to extract the spectrum of the object. Valid\n" 00175 "values are 'gauss' and 'moffat'.\n" 00176 "\n" 00177 "--filename\n" 00178 "see --method='user'\n" 00179 "\n" 00180 "--cpos_rej\n" 00181 "--cneg_rej\n" 00182 "--citer\n" 00183 "see --cmethod='ksigma'\n" 00184 "\n" 00185 "--cmax\n" 00186 "--cmin\n" 00187 "see --cmethod='min_max'\n" 00188 "\n" 00189 "--extrapolate\n" 00190 "By default no extrapolation is applied. This means that the intermediate\n" 00191 "reconstructed cubes will shrink at most one pixel, which is ok for templates\n" 00192 "like KMOS_spec_obs_nodtosky or KMOS_spec_obs_freedither. When the cubes will be\n" 00193 "arranged as a map, a grid is likely to occur between the IFUs. Therefore extra-\n" 00194 "polation during the shifting process can be switched on in order to get IFUs of\n" 00195 "original size. For frames taken with mapping templates, extrapolation is\n" 00196 "switched on automatically.\n" 00197 "\n" 00198 "------------------------------------------------------------------------------\n" 00199 " Input files:\n" 00200 "\n" 00201 " DO KMOS \n" 00202 " category Type Explanation Required #Frames\n" 00203 " -------- ----- ----------- -------- -------\n" 00204 " SCIENCE RAW The science frames Y >=1 \n" 00205 " XCAL F2D x calibration frame Y 1 \n" 00206 " YCAL F2D y calibration frame Y 1 \n" 00207 " LCAL F2D Wavelength calib. frame Y 1 \n" 00208 " MASTER_FLAT F2D Master flat Y 1 \n" 00209 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00210 " ILLUM_CORR F2I Illumination correction N 0,1 \n" 00211 " TELLURIC F1I normalised telluric spectrum N 0,1 \n" 00212 "\n" 00213 " Output files:\n" 00214 "\n" 00215 " DO KMOS\n" 00216 " category Type Explanation\n" 00217 " -------- ----- -----------\n" 00218 " SCI_COMBINED F3I Combined cubes with noise\n" 00219 " SCI_RECONSTRUCTED F3I Reconstructed cube with noise\n" 00220 "------------------------------------------------------------------------------\n" 00221 "\n"; 00222 00223 /*----------------------------------------------------------------------------- 00224 * Functions code 00225 *----------------------------------------------------------------------------*/ 00226 00243 int cpl_plugin_get_info(cpl_pluginlist *list) 00244 { 00245 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00246 cpl_plugin *plugin = &recipe->interface; 00247 00248 cpl_plugin_init(plugin, 00249 CPL_PLUGIN_API, 00250 KMOS_BINARY_VERSION, 00251 CPL_PLUGIN_TYPE_RECIPE, 00252 "kmo_sci_red", 00253 "Reconstruct and combine data frames dividing " 00254 "illumination and telluric correction.", 00255 kmo_sci_red_description, 00256 "Alex Agudo Berbel", 00257 "agudo@mpe.mpg.de", 00258 kmos_get_license(), 00259 kmo_sci_red_create, 00260 kmo_sci_red_exec, 00261 kmo_sci_red_destroy); 00262 00263 cpl_pluginlist_append(list, plugin); 00264 00265 return 0; 00266 } 00267 00275 static int kmo_sci_red_create(cpl_plugin *plugin) 00276 { 00277 cpl_recipe *recipe; 00278 cpl_parameter *p; 00279 00280 /* Check that the plugin is part of a valid recipe */ 00281 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00282 recipe = (cpl_recipe *)plugin; 00283 else 00284 return -1; 00285 00286 /* Create the parameters list in the cpl_recipe object */ 00287 recipe->parameters = cpl_parameterlist_new(); 00288 00289 /* --imethod */ 00290 p = cpl_parameter_new_value("kmos.kmo_sci_red.imethod", 00291 CPL_TYPE_STRING, 00292 "Method to use for interpolation during reconstruction. " 00293 "[\"NN\" (nearest neighbour), " 00294 "\"lwNN\" (linear weighted nearest neighbor), " 00295 "\"swNN\" (square weighted nearest neighbor), " 00296 "\"MS\" (Modified Shepard's method)" 00297 "\"CS\" (Cubic spline)]", 00298 "kmos.kmo_sci_red", 00299 "CS"); 00300 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00301 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00302 cpl_parameterlist_append(recipe->parameters, p); 00303 00304 /* --smethod */ 00305 p = cpl_parameter_new_value("kmos.kmo_sci_red.smethod", 00306 CPL_TYPE_STRING, 00307 "Method to use for interpolation during shifting. " 00308 "[\"NN\" (nearest neighbour), " 00309 "\"CS\" (Cubic spline)]", 00310 "kmos.kmo_sci_red", 00311 "CS"); 00312 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "smethod"); 00313 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00314 cpl_parameterlist_append(recipe->parameters, p); 00315 00316 /* --neighborhoodRange */ 00317 p = cpl_parameter_new_value("kmos.kmo_sci_red.neighborhoodRange", 00318 CPL_TYPE_DOUBLE, 00319 "Defines the range to search for neighbors " 00320 "in pixels", 00321 "kmos.kmo_sci_red", 00322 1.001); 00323 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00324 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00325 cpl_parameterlist_append(recipe->parameters, p); 00326 00327 /* --name */ 00328 p = cpl_parameter_new_value("kmos.kmo_sci_red.name", 00329 CPL_TYPE_STRING, 00330 "Name of the object to combine.", 00331 "kmos.kmo_sci_red", 00332 ""); 00333 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00334 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00335 cpl_parameterlist_append(recipe->parameters, p); 00336 00337 /* --ifus */ 00338 p = cpl_parameter_new_value("kmos.kmo_sci_red.ifus", 00339 CPL_TYPE_STRING, 00340 "The indices of the IFUs to combine. " 00341 "\"ifu1;ifu2;...\"", 00342 "kmos.kmo_sci_red", 00343 ""); 00344 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00345 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00346 cpl_parameterlist_append(recipe->parameters, p); 00347 00348 /* --method */ 00349 p = cpl_parameter_new_value("kmos.kmo_sci_red.method", 00350 CPL_TYPE_STRING, 00351 "The shifting method: " 00352 "'none': no shifting, combined directly, " 00353 "'header': shift according to WCS (default), " 00354 "'center': centering algorithm, " 00355 "'user': read shifts from file", 00356 "kmos.kmo_sci_red", 00357 "header"); 00358 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method"); 00359 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00360 cpl_parameterlist_append(recipe->parameters, p); 00361 00362 /* --fmethod */ 00363 p = cpl_parameter_new_value("kmos.kmo_sci_red.fmethod", 00364 CPL_TYPE_STRING, 00365 "The fitting method (applies only when " 00366 "method='center'): " 00367 "'gauss': fit a gauss function to collapsed " 00368 "image (default), " 00369 "'moffat': fit a moffat function to collapsed" 00370 " image", 00371 "kmos.kmo_sci_red", 00372 "gauss"); 00373 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00374 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00375 cpl_parameterlist_append(recipe->parameters, p); 00376 00377 /* --filename */ 00378 p = cpl_parameter_new_value("kmos.kmo_sci_red.filename", 00379 CPL_TYPE_STRING, 00380 "The path to the file with the shift vectors." 00381 "(Applies only to method='user')", 00382 "kmos.kmo_sci_red", 00383 ""); 00384 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filename"); 00385 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00386 cpl_parameterlist_append(recipe->parameters, p); 00387 00388 /* --flux */ 00389 p = cpl_parameter_new_value("kmos.kmo_sci_red.flux", 00390 CPL_TYPE_BOOL, 00391 "TRUE: Apply flux conservation. FALSE: otherwise", 00392 "kmos.kmo_sci_red", 00393 FALSE); 00394 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00395 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00396 cpl_parameterlist_append(recipe->parameters, p); 00397 00398 /* --extrapolate */ 00399 p = cpl_parameter_new_value("kmos.kmo_sci_red.extrapolate", 00400 CPL_TYPE_BOOL, 00401 "Applies only to 'method=CS' when doing sub-" 00402 "pixel shifts: " 00403 "FALSE: shifted IFU will be filled with NaN's " 00404 "at the borders," 00405 "TRUE: shifted IFU will be extrapolated at " 00406 "the borders", 00407 "kmos.kmo_sci_red", 00408 FALSE); 00409 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extrapolate"); 00410 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00411 cpl_parameterlist_append(recipe->parameters, p); 00412 00413 /* --fast-mode */ 00414 p = cpl_parameter_new_value("kmos.kmo_sci_red.fast-mode", 00415 CPL_TYPE_BOOL, 00416 "FALSE: cubes are shifted and combined," 00417 "TRUE: cubes are collapsed and then shifted and combined", 00418 "kmos.kmo_sci_red", 00419 FALSE); 00420 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fast-mode"); 00421 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00422 cpl_parameterlist_append(recipe->parameters, p); 00423 00424 // add parameters for band-definition 00425 kmo_band_pars_create(recipe->parameters, 00426 "kmos.kmo_sci_red"); 00427 00428 return kmo_combine_pars_create(recipe->parameters, 00429 "kmos.kmo_sci_red", 00430 DEF_REJ_METHOD, 00431 FALSE); 00432 } 00433 00439 static int kmo_sci_red_exec(cpl_plugin *plugin) 00440 { 00441 cpl_recipe *recipe; 00442 00443 /* Get the recipe out of the plugin */ 00444 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00445 recipe = (cpl_recipe *)plugin; 00446 else return -1 ; 00447 00448 return kmo_sci_red(recipe->parameters, recipe->frames); 00449 } 00450 00456 static int kmo_sci_red_destroy(cpl_plugin *plugin) 00457 { 00458 cpl_recipe *recipe; 00459 00460 /* Get the recipe out of the plugin */ 00461 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00462 recipe = (cpl_recipe *)plugin; 00463 else return -1 ; 00464 00465 cpl_parameterlist_delete(recipe->parameters); 00466 return 0 ; 00467 } 00468 00469 00470 00485 static int kmo_sci_red(cpl_parameterlist *parlist, cpl_frameset *frameset) 00486 { 00487 int ret_val = 0, 00488 nr_science_frames = 0, 00489 nr_reconstructed_frames = 0, 00490 has_illum_corr = 0, 00491 has_telluric = 0, 00492 *bounds = NULL, 00493 det_nr = 0, 00494 actual_msg_level = 0, 00495 print_once = FALSE, 00496 nr_avail_obj_names = 0, 00497 found_name = FALSE, 00498 cube_counter_data = 0, 00499 cube_counter_noise = 0, 00500 citer = 0, 00501 cmin = 0, 00502 cmax = 0, 00503 user_defined_ifu = 0, 00504 extrapolate = 0, 00505 flux = FALSE, 00506 index = 0, 00507 nr_data_alloc = 0, 00508 tmp_int = 0, 00509 fast_mode = FALSE; 00510 const int *punused_ifus = NULL; 00511 double neighborhoodRange = 1.001, 00512 cpos_rej = 0.0, 00513 cneg_rej = 0.0; 00514 char *suffix = NULL, 00515 *keyword = NULL, 00516 *extname = NULL, 00517 *fn_suffix = NULL, 00518 *mapping_mode = NULL, 00519 **split = NULL, 00520 content[256]; 00521 const char *imethod = NULL, 00522 *smethod = NULL, 00523 *ifus_txt = NULL, 00524 *name = NULL, 00525 *filter_id = NULL, 00526 *tmp_str = NULL, 00527 *filename = NULL, 00528 *fn_out = NULL, 00529 *fn_obj = NULL, 00530 *fn_sky = NULL, 00531 *fn_reconstr = NULL, 00532 *comb_method = NULL, 00533 *cmethod = NULL, 00534 *fmethod = NULL; 00535 cpl_array **unused_ifus = NULL; 00536 cpl_frame *xcal_frame = NULL, 00537 *ycal_frame = NULL, 00538 *lcal_frame = NULL, 00539 *flat_frame = NULL, 00540 *illum_frame = NULL, 00541 *telluric_frame = NULL, 00542 *tmp_frame = NULL; 00543 cpl_propertylist *tmp_header = NULL, 00544 *main_header = NULL, 00545 **header_data = NULL, 00546 **header_noise = NULL; 00547 cpl_vector *ifus = NULL; 00548 kmclipm_vector *telluric_data = NULL, 00549 *telluric_noise = NULL; 00550 cpl_image **lcal = NULL, 00551 *illum_data = NULL, 00552 *illum_noise = NULL, 00553 *tmpImg = NULL; 00554 cpl_imagelist **cube_data = NULL, 00555 **cube_noise = NULL, 00556 *combined_data = NULL, 00557 *combined_noise = NULL, 00558 *tmpCube = NULL; 00559 cpl_table *band_table = NULL; 00560 cpl_frame *sky_frame = NULL; 00561 main_fits_desc desc1, 00562 desc2; 00563 gridDefinition gd; 00564 objSkyFrameTableStruct *obj_sky_struct = NULL; 00565 allObjStruct *all_obj = NULL; 00566 enum extrapolationType extrapol_enum = 0; 00567 enum kmo_frame_type ft = 0; 00568 00569 KMO_TRY 00570 { 00571 00572 kmo_init_fits_desc(&desc1); 00573 kmo_init_fits_desc(&desc2); 00574 00575 // 00576 // check frameset 00577 // 00578 KMO_TRY_ASSURE((parlist != NULL) && 00579 (frameset != NULL), 00580 CPL_ERROR_NULL_INPUT, 00581 "Not all input data is provided!"); 00582 00583 nr_science_frames = cpl_frameset_count_tags(frameset, SCIENCE); 00584 KMO_TRY_ASSURE(nr_science_frames >= 1, 00585 CPL_ERROR_ILLEGAL_INPUT, 00586 "At least one SCIENCE frame is required!"); 00587 if (nr_science_frames == 1) { 00588 cpl_msg_warning("", "At least two SCIENCE frames should be provided " 00589 "in order to apply sky subtraction!"); 00590 } 00591 00592 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00593 CPL_ERROR_FILE_NOT_FOUND, 00594 "Exactly one XCAL frame is required!"); 00595 00596 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00597 CPL_ERROR_FILE_NOT_FOUND, 00598 "Exactly one YCAL frame is required!"); 00599 00600 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00601 CPL_ERROR_FILE_NOT_FOUND, 00602 "Exactly one LCAL frame is required!"); 00603 00604 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, MASTER_FLAT) == 1, 00605 CPL_ERROR_FILE_NOT_FOUND, 00606 "Exactly one MASTER_FLAT frame is required!"); 00607 00608 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00609 CPL_ERROR_FILE_NOT_FOUND, 00610 "Exactly one WAVE_BAND frame is required!"); 00611 00612 has_illum_corr = cpl_frameset_count_tags(frameset, ILLUM_CORR); 00613 KMO_TRY_ASSURE((has_illum_corr == 0) || (has_illum_corr == 1), 00614 CPL_ERROR_FILE_NOT_FOUND, 00615 "At most one ILLUM_CORR frame can be provided!"); 00616 00617 has_telluric = cpl_frameset_count_tags(frameset, TELLURIC); 00618 KMO_TRY_ASSURE((has_telluric == 0) || (has_telluric == 1), 00619 CPL_ERROR_FILE_NOT_FOUND, 00620 "At most one TELLURIC frame can be provided!"); 00621 00622 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_sci_red") == 1, 00623 CPL_ERROR_ILLEGAL_INPUT, 00624 "Cannot identify RAW and CALIB frames!"); 00625 00626 // 00627 // get parameters 00628 // 00629 cpl_msg_info("", "--- Parameter setup for kmo_sci_red ------"); 00630 00631 flux = kmo_dfs_get_parameter_bool(parlist, 00632 "kmos.kmo_sci_red.flux"); 00633 00634 KMO_TRY_ASSURE((flux == 0) || 00635 (flux == 1), 00636 CPL_ERROR_ILLEGAL_INPUT, 00637 "flux must be either FALSE or TRUE! %d", flux); 00638 00639 KMO_TRY_EXIT_IF_ERROR( 00640 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.flux")); 00641 00642 KMO_TRY_EXIT_IF_NULL( 00643 imethod = kmo_dfs_get_parameter_string(parlist, 00644 "kmos.kmo_sci_red.imethod")); 00645 00646 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00647 (strcmp(imethod, "lwNN") == 0) || 00648 (strcmp(imethod, "swNN") == 0) || 00649 (strcmp(imethod, "MS") == 0) || 00650 (strcmp(imethod, "CS") == 0), 00651 CPL_ERROR_ILLEGAL_INPUT, 00652 "imethod must be either \"NN\", \"lwNN\", " 00653 "\"swNN\", \"MS\" or \"CS\"!"); 00654 00655 KMO_TRY_EXIT_IF_ERROR( 00656 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.imethod")); 00657 00658 KMO_TRY_EXIT_IF_NULL( 00659 smethod = kmo_dfs_get_parameter_string(parlist, 00660 "kmos.kmo_sci_red.smethod")); 00661 00662 KMO_TRY_ASSURE((strcmp(smethod, "NN") == 0) || 00663 (strcmp(smethod, "CS") == 0), 00664 CPL_ERROR_ILLEGAL_INPUT, 00665 "smethod must be either \"NN\" or \"CS\"!"); 00666 00667 KMO_TRY_EXIT_IF_ERROR( 00668 kmo_dfs_print_parameter_help(parlist, 00669 "kmos.kmo_sci_red.smethod")); 00670 00671 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00672 "kmos.kmo_sci_red.neighborhoodRange"); 00673 KMO_TRY_CHECK_ERROR_STATE(); 00674 00675 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00676 CPL_ERROR_ILLEGAL_INPUT, 00677 "neighborhoodRange must be greater than 0.0"); 00678 00679 KMO_TRY_EXIT_IF_ERROR( 00680 kmo_dfs_print_parameter_help(parlist, 00681 "kmos.kmo_sci_red.neighborhoodRange")); 00682 00683 KMO_TRY_EXIT_IF_NULL( 00684 comb_method = kmo_dfs_get_parameter_string(parlist, 00685 "kmos.kmo_sci_red.method")); 00686 00687 KMO_TRY_EXIT_IF_NULL( 00688 fmethod = kmo_dfs_get_parameter_string(parlist, 00689 "kmos.kmo_sci_red.fmethod")); 00690 00691 KMO_TRY_ASSURE((strcmp(comb_method, "none") == 0) || 00692 (strcmp(comb_method, "header") == 0) || 00693 (strcmp(comb_method, "center") == 0) || 00694 (strcmp(comb_method, "user") == 0), 00695 CPL_ERROR_ILLEGAL_INPUT, 00696 "Following shift methods are available : 'none', " 00697 "'header', 'center' or 'user'"); 00698 00699 if (strcmp(comb_method, "user") == 0) { 00700 filename = kmo_dfs_get_parameter_string(parlist, 00701 "kmos.kmo_sci_red.filename"); 00702 KMO_TRY_CHECK_ERROR_STATE(); 00703 00704 KMO_TRY_ASSURE(strcmp(filename, "") != 0, 00705 CPL_ERROR_ILLEGAL_INPUT, 00706 "path of file with shift information must be " 00707 "provided!"); 00708 00709 KMO_TRY_EXIT_IF_ERROR( 00710 kmo_dfs_print_parameter_help(parlist, 00711 "kmos.kmo_sci_red.filename")); 00712 } 00713 00714 KMO_TRY_EXIT_IF_ERROR( 00715 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.method")); 00716 00717 ifus_txt = kmo_dfs_get_parameter_string(parlist, 00718 "kmos.kmo_sci_red.ifus"); 00719 KMO_TRY_CHECK_ERROR_STATE(); 00720 00721 name = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_sci_red.name"); 00722 KMO_TRY_CHECK_ERROR_STATE(); 00723 00724 if (strcmp(ifus_txt, "") != 0) { 00725 KMO_TRY_ASSURE(strcmp(name, "") == 0, 00726 CPL_ERROR_ILLEGAL_INPUT, 00727 "name parameter must be NULL if IFU indices are " 00728 "provided!"); 00729 00730 KMO_TRY_EXIT_IF_NULL( 00731 ifus = kmo_identify_values(ifus_txt)); 00732 00733 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_science_frames, 00734 CPL_ERROR_ILLEGAL_INPUT, 00735 "ifus parameter must have the same number of values " 00736 "than frames provided (for frames just containing " 00737 "skies insert 0)) (%lld!=%d)", 00738 cpl_vector_get_size(ifus), nr_science_frames); 00739 } 00740 00741 if (strcmp(name, "") != 0) { 00742 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, 00743 CPL_ERROR_ILLEGAL_INPUT, 00744 "ifus parameter must be NULL if name is provided!"); 00745 } 00746 00747 KMO_TRY_EXIT_IF_ERROR( 00748 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.ifus")); 00749 00750 KMO_TRY_EXIT_IF_ERROR( 00751 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.name")); 00752 00753 kmo_band_pars_load(parlist, "kmos.kmo_sci_red"); 00754 00755 extrapolate = kmo_dfs_get_parameter_bool(parlist, 00756 "kmos.kmo_sci_red.extrapolate"); 00757 KMO_TRY_CHECK_ERROR_STATE(); 00758 00759 if (strcmp(smethod, "NN") == 0) { 00760 if (extrapolate == TRUE) { 00761 cpl_msg_warning("", "extrapolation for smethod='NN' not available!"); 00762 } 00763 extrapol_enum = NONE_NANS; 00764 } else if (strcmp(smethod, "CS") == 0) { 00765 if (extrapolate == FALSE) { 00766 extrapol_enum = NONE_NANS; 00767 } else if (extrapolate == TRUE) { 00768 extrapol_enum = BCS_NATURAL; 00769 } else { 00770 KMO_TRY_ASSURE(1 == 0, 00771 CPL_ERROR_ILLEGAL_INPUT, 00772 "extrapolate must be either FALSE or TRUE!"); 00773 } 00774 smethod = "BCS"; 00775 } else { 00776 KMO_TRY_ASSURE(1 == 0, 00777 CPL_ERROR_ILLEGAL_INPUT, 00778 "method must be either \"CS\" or \"NN\" !"); 00779 } 00780 KMO_TRY_CHECK_ERROR_STATE(); 00781 00782 KMO_TRY_EXIT_IF_ERROR( 00783 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.extrapolate")); 00784 00785 fast_mode = kmo_dfs_get_parameter_bool(parlist, 00786 "kmos.kmo_sci_red.fast-mode"); 00787 KMO_TRY_CHECK_ERROR_STATE(); 00788 KMO_TRY_ASSURE((fast_mode == TRUE) || 00789 (fast_mode == FALSE), 00790 CPL_ERROR_ILLEGAL_INPUT, 00791 "fast_mode must be either FALSE or TRUE!"); 00792 KMO_TRY_EXIT_IF_ERROR( 00793 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.fast-mode")); 00794 00795 KMO_TRY_EXIT_IF_ERROR( 00796 kmo_combine_pars_load(parlist, 00797 "kmos.kmo_sci_red", 00798 &cmethod, 00799 &cpos_rej, 00800 &cneg_rej, 00801 &citer, 00802 &cmin, 00803 &cmax, 00804 FALSE)); 00805 00806 cpl_msg_info("", "-------------------------------------------"); 00807 00808 // 00809 // assure that filters, grating and rotation offsets match for 00810 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 00811 // frames) 00812 // 00813 00814 // check if filter_id and grating_id match for all detectors 00815 KMO_TRY_EXIT_IF_ERROR( 00816 kmo_check_frameset_setup(frameset, SCIENCE, 00817 TRUE, FALSE, TRUE)); 00818 KMO_TRY_EXIT_IF_ERROR( 00819 kmo_check_frame_setup(frameset, SCIENCE, YCAL, 00820 TRUE, FALSE, TRUE)); 00821 KMO_TRY_EXIT_IF_ERROR( 00822 kmo_check_frame_setup(frameset, XCAL, YCAL, 00823 TRUE, FALSE, TRUE)); 00824 KMO_TRY_EXIT_IF_ERROR( 00825 kmo_check_frame_setup(frameset, XCAL, LCAL, 00826 TRUE, FALSE, TRUE)); 00827 // KMO_TRY_EXIT_IF_ERROR( 00828 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00829 // KMO_TRY_EXIT_IF_ERROR( 00830 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00831 KMO_TRY_EXIT_IF_ERROR( 00832 kmo_check_frame_setup(frameset, XCAL, MASTER_FLAT, 00833 TRUE, FALSE, TRUE)); 00834 // omit this check because ILLUM_CORR is band-independend 00835 // if (has_illum_corr) { 00836 // KMO_TRY_EXIT_IF_ERROR( 00837 // kmo_check_frame_setup(frameset, XCAL, ILLUM_CORR, 00838 // TRUE, FALSE, TRUE)); 00839 // } 00840 00841 if (has_telluric) { 00842 KMO_TRY_EXIT_IF_ERROR( 00843 kmo_check_frame_setup(frameset, XCAL, TELLURIC, 00844 TRUE, FALSE, TRUE)); 00845 } 00846 00847 // check descriptors of all frames 00848 KMO_TRY_EXIT_IF_NULL( 00849 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 00850 00851 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 00852 KMO_TRY_CHECK_ERROR_STATE(); 00853 00854 KMO_TRY_ASSURE((desc1.nr_ext % 3 == 0) && 00855 (desc1.ex_badpix == FALSE) && 00856 (desc1.fits_type == f2d_fits) && 00857 (desc1.frame_type == detector_frame), 00858 CPL_ERROR_ILLEGAL_INPUT, 00859 "XCAL isn't in the correct format!!!"); 00860 00861 KMO_TRY_EXIT_IF_NULL( 00862 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 00863 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 00864 KMO_TRY_CHECK_ERROR_STATE(); 00865 00866 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 00867 (desc1.ex_badpix == desc2.ex_badpix) && 00868 (desc1.fits_type == desc2.fits_type) && 00869 (desc1.frame_type == desc2.frame_type), 00870 CPL_ERROR_ILLEGAL_INPUT, 00871 "YCAL isn't in the correct format!!!"); 00872 kmo_free_fits_desc(&desc2); 00873 kmo_init_fits_desc(&desc2); 00874 00875 KMO_TRY_EXIT_IF_NULL( 00876 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00877 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 00878 KMO_TRY_CHECK_ERROR_STATE(); 00879 00880 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 00881 (desc1.ex_badpix == desc2.ex_badpix) && 00882 (desc1.fits_type == desc2.fits_type) && 00883 (desc1.frame_type == desc2.frame_type), 00884 CPL_ERROR_ILLEGAL_INPUT, 00885 "YCAL isn't in the correct format!!!"); 00886 kmo_free_fits_desc(&desc2); 00887 kmo_init_fits_desc(&desc2); 00888 00889 KMO_TRY_EXIT_IF_NULL( 00890 flat_frame = kmo_dfs_get_frame(frameset, MASTER_FLAT)); 00891 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(flat_frame)); 00892 KMO_TRY_CHECK_ERROR_STATE(); 00893 00894 KMO_TRY_ASSURE((desc2.nr_ext % 6 == 0) && 00895 (desc1.ex_badpix == desc2.ex_badpix) && 00896 (desc1.fits_type == desc2.fits_type) && 00897 (desc1.frame_type == desc2.frame_type), 00898 CPL_ERROR_ILLEGAL_INPUT, 00899 "MASTER_FLAT isn't in the correct format!!!"); 00900 kmo_free_fits_desc(&desc2); 00901 kmo_init_fits_desc(&desc2); 00902 00903 if (has_illum_corr) { 00904 KMO_TRY_EXIT_IF_NULL( 00905 illum_frame = kmo_dfs_get_frame(frameset, ILLUM_CORR)); 00906 desc2 = kmo_identify_fits_header( 00907 cpl_frame_get_filename(illum_frame)); 00908 KMO_TRY_CHECK_ERROR_STATE(); 00909 KMO_TRY_ASSURE(((desc2.nr_ext == 24) || (desc2.nr_ext == 48)) && 00910 (desc2.ex_badpix == FALSE) && 00911 (desc2.fits_type == f2i_fits) && 00912 (desc2.frame_type == ifu_frame), 00913 CPL_ERROR_ILLEGAL_INPUT, 00914 "ILLUM_CORR isn't in the correct format!!!"); 00915 kmo_free_fits_desc(&desc2); 00916 kmo_init_fits_desc(&desc2); 00917 } 00918 00919 if (has_telluric) { 00920 KMO_TRY_EXIT_IF_NULL( 00921 telluric_frame = kmo_dfs_get_frame(frameset, TELLURIC)); 00922 desc2 = kmo_identify_fits_header( 00923 cpl_frame_get_filename(telluric_frame)); 00924 KMO_TRY_CHECK_ERROR_STATE(); 00925 KMO_TRY_ASSURE(((desc2.nr_ext == 24) || (desc2.nr_ext == 48)) && 00926 (desc2.ex_badpix == FALSE) && 00927 (desc2.fits_type == f1i_fits) && 00928 (desc2.frame_type == ifu_frame), 00929 CPL_ERROR_ILLEGAL_INPUT, 00930 "TELLURIC isn't in the correct format!!!"); 00931 kmo_free_fits_desc(&desc2); 00932 kmo_init_fits_desc(&desc2); 00933 } 00934 00935 KMO_TRY_EXIT_IF_NULL( 00936 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 00937 while (tmp_frame != NULL ) { 00938 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 00939 KMO_TRY_CHECK_ERROR_STATE(); 00940 KMO_TRY_ASSURE((desc2.nr_ext == 3) && 00941 (desc2.ex_badpix == FALSE) && 00942 (desc2.fits_type == raw_fits) && 00943 (desc2.frame_type == detector_frame), 00944 CPL_ERROR_ILLEGAL_INPUT, 00945 "SCIENCE isn't in the correct format!!!"); 00946 kmo_free_fits_desc(&desc2); 00947 kmo_init_fits_desc(&desc2); 00948 00949 if (mapping_mode == NULL) { 00950 KMO_TRY_EXIT_IF_NULL( 00951 tmp_header = 00952 kmclipm_propertylist_load( 00953 cpl_frame_get_filename(tmp_frame), 0)); 00954 if (cpl_propertylist_has(tmp_header, TPL_ID)) { 00955 KMO_TRY_EXIT_IF_NULL( 00956 tmp_str = cpl_propertylist_get_string(tmp_header, 00957 TPL_ID)); 00958 00959 if (strcmp(tmp_str, MAPPING8) == 0) 00960 { 00961 mapping_mode = cpl_sprintf("%s", "mapping8"); 00962 } 00963 if (strcmp(tmp_str, MAPPING24) == 0) 00964 { 00965 mapping_mode = cpl_sprintf("%s", "mapping24"); 00966 } 00967 } 00968 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00969 } 00970 00971 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 00972 KMO_TRY_CHECK_ERROR_STATE(); 00973 } 00974 00975 if (mapping_mode != NULL) { 00976 // we are in mapping mode 00977 if ((ifus != NULL) || (strcmp(name, "") != 0)) 00978 { 00979 cpl_msg_warning("","The SCIENCE frames have been taken in one of the " 00980 "mapping modes AND specific IFUs have been " 00981 "specified! --> Only processing these!"); 00982 } else { 00983 if (strcmp(smethod, "BCS") == 0) { 00984 extrapol_enum = BCS_NATURAL; 00985 cpl_msg_info("","Detected frames taken in mapping mode. " 00986 "Changing extrapolation mode to TRUE."); 00987 } 00988 } 00989 if (fast_mode) { 00990 cpl_msg_info("", "Creating map in fast-mode."); 00991 } 00992 } else { 00993 if (fast_mode) { 00994 cpl_msg_info("", "fast-mode has been selected but we aren't in " 00995 "mapping mode. So your choise for fast-mode is ignored."); 00996 } 00997 } 00998 00999 KMO_TRY_EXIT_IF_NULL( 01000 suffix = kmo_dfs_get_suffix(xcal_frame, TRUE, TRUE)); 01001 01002 KMO_TRY_EXIT_IF_ERROR( 01003 kmo_check_frame_setup_md5(frameset)); 01004 KMO_TRY_EXIT_IF_ERROR( 01005 kmo_check_frame_setup_sampling(frameset)); 01006 01007 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 01008 cpl_msg_info("", "(grating 1, 2 & 3, rotation angle)"); 01009 01010 // 01011 // check which IFUs are active for all frames 01012 // 01013 KMO_TRY_EXIT_IF_NULL( 01014 unused_ifus = kmo_get_unused_ifus(frameset, 1, 1)); 01015 01016 // KMO_TRY_EXIT_IF_NULL( 01017 // unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before)); 01018 01019 kmo_print_unused_ifus(unused_ifus, FALSE); 01020 01021 // 01022 // get bounds, setup grid, setup obj_sky-struct 01023 // 01024 01025 // get left and right bounds of IFUs 01026 KMO_TRY_EXIT_IF_NULL( 01027 tmp_header = 01028 kmclipm_propertylist_load(cpl_frame_get_filename(xcal_frame), 01029 0)); 01030 KMO_TRY_EXIT_IF_NULL( 01031 bounds = kmclipm_extract_bounds(tmp_header)); 01032 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01033 01034 // setup grid definition, wavelength start and end points will be set 01035 // in the detector loop 01036 KMO_TRY_EXIT_IF_ERROR( 01037 kmclipm_setup_grid(&gd, imethod, neighborhoodRange)); 01038 01039 // get valid STD frames with objects in it and associated sky exposures 01040 KMO_TRY_EXIT_IF_NULL( 01041 obj_sky_struct = kmo_get_obj_sky_frame_table(frameset, 01042 &nr_science_frames, 01043 SCIENCE)); 01044 // 01045 // load lcal-frames 01046 // 01047 KMO_TRY_EXIT_IF_NULL( 01048 lcal = (cpl_image**) 01049 cpl_calloc(KMOS_NR_DETECTORS, sizeof(cpl_image*))); 01050 for (int i = 0; i < KMOS_NR_DETECTORS; i++) { 01051 KMO_TRY_EXIT_IF_NULL( 01052 lcal[i] = kmo_dfs_load_image(frameset, LCAL, i+1, FALSE, FALSE, NULL)); 01053 } 01054 01055 // 01056 // allocate intermediate memory 01057 // 01058 KMO_TRY_EXIT_IF_NULL( 01059 all_obj = (allObjStruct*) 01060 cpl_calloc(nr_science_frames * KMOS_NR_IFUS, 01061 sizeof(allObjStruct))); 01062 // initialize intermediate memory 01063 for (int i = 0; i < nr_science_frames * KMOS_NR_IFUS; i++) { 01064 all_obj[i].name = NULL; 01065 all_obj[i].count = 0; 01066 } 01067 01068 nr_data_alloc = KMOS_NR_IFUS; 01069 KMO_TRY_EXIT_IF_NULL( 01070 cube_data = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01071 sizeof(cpl_imagelist*))); 01072 KMO_TRY_EXIT_IF_NULL( 01073 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01074 sizeof(cpl_imagelist*))); 01075 KMO_TRY_EXIT_IF_NULL( 01076 header_data = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01077 sizeof(cpl_propertylist*))); 01078 KMO_TRY_EXIT_IF_NULL( 01079 header_noise = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01080 sizeof(cpl_propertylist*))); 01081 01082 // 01083 // loop all science frames containing at least one object 01084 // 01085 cpl_msg_info("", "-------------------------------------------"); 01086 cpl_msg_info("", "Reconstructing & saving cubes containing objects"); 01087 cpl_msg_info("", " "); 01088 for (int sf = 0; sf < nr_science_frames; sf++) { 01089 KMO_TRY_EXIT_IF_NULL( 01090 fn_obj = cpl_frame_get_filename( 01091 obj_sky_struct[sf].objectFrame)); 01092 01093 KMO_TRY_EXIT_IF_NULL( 01094 main_header = kmclipm_propertylist_load(fn_obj, 0)); 01095 01096 // get ifu and detector number to work at 01097 actual_msg_level = cpl_msg_get_level(); 01098 user_defined_ifu = 0; 01099 if ((ifus != NULL) || (strcmp(name, "") != 0)) { 01100 if (ifus != NULL) { 01101 // user specified IFUs 01102 user_defined_ifu = cpl_vector_get(ifus, sf); 01103 KMO_TRY_CHECK_ERROR_STATE(); 01104 01105 if (user_defined_ifu < 1) { 01106 user_defined_ifu = -1; 01107 } 01108 } else { 01109 // user specified an object name 01110 cpl_msg_set_level(CPL_MSG_OFF); 01111 user_defined_ifu = 01112 kmo_get_index_from_ocs_name(obj_sky_struct[sf].objectFrame, 01113 name); 01114 cpl_msg_set_level(actual_msg_level); 01115 if (user_defined_ifu == -1) { 01116 cpl_error_reset(); 01117 } 01118 KMO_TRY_CHECK_ERROR_STATE(); 01119 } 01120 } 01121 01122 // 01123 // reconstruct science frame 01124 // 01125 cpl_msg_info("", " > processing frame: %s", fn_obj); 01126 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) 01127 { 01128 det_nr = (ifu_nr - 1)/KMOS_IFUS_PER_DETECTOR + 1; 01129 01130 KMO_TRY_ASSURE((det_nr >= 1) && 01131 (det_nr <= KMOS_NR_DETECTORS), 01132 CPL_ERROR_ILLEGAL_INPUT, 01133 "The provided ifu-numbers are incorrect! They " 01134 "must be between 1 and %d", KMOS_NR_IFUS); 01135 01136 KMO_TRY_EXIT_IF_NULL( 01137 punused_ifus = cpl_array_get_data_int_const( 01138 unused_ifus[det_nr-1])); 01139 01140 // get subheader data 01141 KMO_TRY_EXIT_IF_NULL( 01142 header_data[ifu_nr-1] = kmclipm_propertylist_load(fn_obj, 01143 det_nr)); 01144 KMO_TRY_EXIT_IF_NULL( 01145 extname = kmo_extname_creator(ifu_frame, ifu_nr, 01146 EXT_DATA)); 01147 KMO_TRY_EXIT_IF_ERROR( 01148 kmclipm_update_property_string(header_data[ifu_nr-1], 01149 EXTNAME, extname, 01150 "FITS extension name")); 01151 cpl_free(extname); extname = NULL; 01152 01153 // Search for keyword ESO OCS ARMi NOTUSED 01154 // If not present (CPL_ERROR_DATA_NOT_FOUND), do nothing 01155 KMO_TRY_EXIT_IF_NULL( 01156 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, 01157 IFU_VALID_POSTFIX)); 01158 tmp_str = cpl_propertylist_get_string(main_header, keyword); 01159 cpl_free(keyword); keyword = NULL; 01160 01161 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 01162 (bounds[2*(ifu_nr-1)] != -1) && 01163 (bounds[2*(ifu_nr-1)+1] != -1) && 01164 (obj_sky_struct[sf].skyframes[ifu_nr-1] != NULL) && 01165 (punused_ifus[(ifu_nr-1) % KMOS_IFUS_PER_DETECTOR] == 0) && 01166 ((user_defined_ifu == 0) || (user_defined_ifu == ifu_nr))) 01167 { 01168 // IFU is valid 01169 cpl_error_reset(); 01170 01171 if (obj_sky_struct[sf].skyframes[ifu_nr-1] != NO_CORRESPONDING_SKYFRAME) { 01172 sky_frame = obj_sky_struct[sf].skyframes[ifu_nr-1]; 01173 KMO_TRY_EXIT_IF_NULL( 01174 fn_sky = cpl_frame_get_filename(sky_frame)); 01175 cpl_msg_info("", " > IFU %d (with sky in frame: %s)", 01176 ifu_nr, fn_sky); 01177 } else { 01178 sky_frame = NULL; 01179 cpl_msg_warning("", " > IFU %d with no corresponding sky frame", 01180 ifu_nr); 01181 } 01182 01183 01184 // get filter for this detector and setup grid definition 01185 // ESO INS FILTi ID 01186 char *tmp_band_method = getenv("KMO_BAND_METHOD"); 01187 int band_method = 0; 01188 if (tmp_band_method != NULL) { 01189 band_method = atoi(tmp_band_method); 01190 } 01191 01192 KMO_TRY_EXIT_IF_NULL( 01193 keyword = cpl_sprintf("%s%d%s", 01194 IFU_FILTID_PREFIX, det_nr, 01195 IFU_FILTID_POSTFIX)); 01196 KMO_TRY_EXIT_IF_NULL( 01197 filter_id = cpl_propertylist_get_string(main_header, 01198 keyword)); 01199 cpl_free(keyword); keyword = NULL; 01200 01201 if (print_once) { 01202 cpl_msg_set_level(CPL_MSG_WARNING); 01203 } 01204 01205 KMO_TRY_EXIT_IF_NULL( 01206 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 01207 1, 0)); 01208 KMO_TRY_EXIT_IF_ERROR( 01209 kmclipm_setup_grid_band_lcal(&gd, lcal[det_nr-1], 01210 filter_id, band_method, 01211 band_table)); 01212 cpl_table_delete(band_table); band_table = NULL; 01213 01214 print_once = TRUE; 01215 cpl_msg_set_level(actual_msg_level); 01216 01217 // 01218 // reconstruct 01219 // 01220 KMO_TRY_EXIT_IF_ERROR( 01221 kmo_reconstruct_sci(ifu_nr, 01222 bounds[2*(ifu_nr-1)], 01223 bounds[2*(ifu_nr-1)+1], 01224 obj_sky_struct[sf].objectFrame, 01225 SCIENCE, 01226 sky_frame, 01227 SCIENCE, 01228 flat_frame, 01229 xcal_frame, 01230 ycal_frame, 01231 lcal_frame, 01232 &gd, 01233 &cube_data[ifu_nr-1], 01234 &cube_noise[ifu_nr-1], 01235 flux)); 01236 01237 // 01238 // divide cube by telluric correction 01239 // 01240 if (has_telluric) { 01241 telluric_data = kmo_tweak_load_telluric(frameset, ifu_nr, FALSE, 01242 cube_noise[ifu_nr-1] != NULL); 01243 KMO_TRY_CHECK_ERROR_STATE(); 01244 if (telluric_data != NULL) { 01245 // load noise if present 01246 telluric_noise = kmo_tweak_load_telluric(frameset, ifu_nr, TRUE, 01247 cube_noise[ifu_nr-1] != NULL); 01248 KMO_TRY_CHECK_ERROR_STATE(); 01249 01250 KMO_TRY_EXIT_IF_ERROR( 01251 kmo_arithmetic_3D_1D( 01252 cube_data[ifu_nr-1], telluric_data, 01253 cube_noise[ifu_nr-1], telluric_noise, "/")); 01254 01255 kmclipm_vector_delete(telluric_data); 01256 telluric_data = NULL; 01257 kmclipm_vector_delete(telluric_noise); 01258 telluric_noise = NULL; 01259 } 01260 } 01261 01262 // 01263 // divide cube by illumination correction 01264 // 01265 if (has_illum_corr) { 01266 cpl_msg_set_level(CPL_MSG_OFF); 01267 illum_data = kmo_dfs_load_image(frameset, ILLUM_CORR, 01268 ifu_nr, FALSE, FALSE, NULL); 01269 cpl_msg_set_level(actual_msg_level); 01270 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01271 cpl_msg_warning("","No illumination correction for IFU %d available! " 01272 "Proceeding anyway.", ifu_nr); 01273 cpl_error_reset(); 01274 } else { 01275 cpl_msg_set_level(CPL_MSG_OFF); 01276 illum_noise = kmo_dfs_load_image(frameset, 01277 ILLUM_CORR, 01278 ifu_nr, TRUE, 01279 FALSE, NULL); 01280 cpl_msg_set_level(actual_msg_level); 01281 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01282 cpl_msg_warning("","No illumination correction for IFU %d " 01283 "available! Proceeding anyway.", ifu_nr); 01284 cpl_image_delete(illum_data); illum_data = NULL; 01285 cpl_error_reset(); 01286 } 01287 } 01288 01289 if (illum_data != NULL) { 01290 KMO_TRY_EXIT_IF_ERROR( 01291 kmo_arithmetic_3D_2D( 01292 cube_data[ifu_nr-1], illum_data, 01293 cube_noise[ifu_nr-1], illum_noise, "/")); 01294 cpl_image_delete(illum_data); illum_data = NULL; 01295 cpl_image_delete(illum_noise); illum_noise = NULL; 01296 } 01297 } 01298 01299 // 01300 // calc WCS & update subheader 01301 // 01302 KMO_TRY_EXIT_IF_ERROR( 01303 kmo_calc_wcs(main_header, header_data[ifu_nr-1], 01304 ifu_nr, gd.l.start, gd.l.delta)); 01305 01306 KMO_TRY_EXIT_IF_ERROR( 01307 kmclipm_update_property_int(header_data[ifu_nr-1], 01308 NAXIS, 3, 01309 "number of data axes")); 01310 KMO_TRY_EXIT_IF_ERROR( 01311 kmclipm_update_property_int(header_data[ifu_nr-1], 01312 NAXIS1, gd.x.dim, 01313 "length of data axis 1")); 01314 KMO_TRY_EXIT_IF_ERROR( 01315 kmclipm_update_property_int(header_data[ifu_nr-1], 01316 NAXIS2, gd.y.dim, 01317 "length of data axis 2")); 01318 KMO_TRY_EXIT_IF_ERROR( 01319 kmclipm_update_property_int(header_data[ifu_nr-1], 01320 NAXIS3, gd.l.dim, 01321 "length of data axis 3")); 01322 01323 // get object name and store if not already present 01324 KMO_TRY_EXIT_IF_NULL( 01325 keyword = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, ifu_nr, 01326 IFU_NAME_POSTFIX)); 01327 KMO_TRY_EXIT_IF_NULL( 01328 tmp_str = cpl_propertylist_get_string(header_data[ifu_nr-1], 01329 keyword)); 01330 cpl_free(keyword); keyword = NULL; 01331 01332 // found keyword, check if it is already in all_obj 01333 found_name = 0; 01334 for(int i = 0; i < nr_avail_obj_names; i++) { 01335 if (strcmp(all_obj[i].name, tmp_str) == 0) { 01336 found_name = TRUE; 01337 all_obj[i].count++; 01338 break; 01339 } 01340 } 01341 if (!found_name) { 01342 all_obj[nr_avail_obj_names].count++; 01343 KMO_TRY_EXIT_IF_NULL( 01344 all_obj[nr_avail_obj_names++].name = 01345 cpl_sprintf("%s", tmp_str)); 01346 } 01347 } else { 01348 cpl_error_reset(); 01349 01350 // IFU is invalid 01351 } 01352 01353 // duplicate subheader data 01354 KMO_TRY_EXIT_IF_NULL( 01355 header_noise[ifu_nr-1] = 01356 cpl_propertylist_duplicate(header_data[ifu_nr-1])); 01357 01358 KMO_TRY_EXIT_IF_NULL( 01359 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE)); 01360 KMO_TRY_EXIT_IF_ERROR( 01361 kmclipm_update_property_string(header_noise[ifu_nr-1], 01362 EXTNAME, extname, 01363 "FITS extension name")); 01364 cpl_free(extname); extname = NULL; 01365 } // end for ifu_nr 01366 01367 // 01368 // count number of reconstructed data- and noise-cubes 01369 // 01370 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 01371 if (cube_data[ifu_nr-1] != NULL) { 01372 cube_counter_data++; 01373 } 01374 if (cube_noise[ifu_nr-1] != NULL) { 01375 cube_counter_noise++; 01376 } 01377 } 01378 01379 // 01380 // save reconstructed cubes of science frame 01381 // 01382 if (cube_counter_data > 0) { 01383 cpl_msg_info("", " > saving..."); 01384 01385 fn_out = fn_obj; 01386 01387 int nr_found = 0; 01388 // remove any path-elements from filename and use it as 01389 // suffix 01390 split = kmo_strsplit(fn_out, "/", &nr_found); 01391 01392 fn_suffix = cpl_sprintf("_%s", split[nr_found-1]); 01393 kmo_strfreev(split); 01394 01395 // remove '.fits' at the end if there is any 01396 char *fff = fn_suffix; 01397 fff += strlen(fn_suffix)-5; 01398 if (strcmp(fff, ".fits") == 0) { 01399 fn_suffix[strlen(fn_suffix)-5] = '\0'; 01400 } 01401 01402 fn_out = RECONSTRUCTED_CUBE; 01403 01404 KMO_TRY_EXIT_IF_ERROR( 01405 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, 01406 obj_sky_struct[sf].objectFrame, 01407 NULL, parlist, cpl_func)); 01408 01409 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01410 KMO_TRY_EXIT_IF_ERROR( 01411 kmo_dfs_save_cube(cube_data[ifu_nr-1], fn_out, 01412 fn_suffix, header_data[ifu_nr-1], 0./0.)); 01413 01414 if (cube_counter_noise > 0) { 01415 KMO_TRY_EXIT_IF_ERROR( 01416 kmo_dfs_save_cube(cube_noise[ifu_nr-1], fn_out, 01417 fn_suffix, header_noise[ifu_nr-1], 01418 0./0.)); 01419 } 01420 01421 cpl_imagelist_delete(cube_data[ifu_nr-1]); cube_data[ifu_nr-1] = NULL; 01422 cpl_imagelist_delete(cube_noise[ifu_nr-1]); cube_noise[ifu_nr-1] = NULL; 01423 cpl_propertylist_delete(header_data[ifu_nr-1]); header_data[ifu_nr-1] = NULL; 01424 cpl_propertylist_delete(header_noise[ifu_nr-1]); header_noise[ifu_nr-1] = NULL; 01425 } // end for ifu_nr 01426 cpl_free(fn_suffix); fn_suffix = NULL; 01427 } else { 01428 cpl_msg_info("", " > all IFUs invalid, don't save"); 01429 } // if (cube_counter_data > 0) { 01430 01431 cpl_propertylist_delete(main_header); main_header = NULL; 01432 } // end for sf (nr_science_frames) 01433 cpl_free(cube_data); cube_data = NULL; 01434 cpl_free(cube_noise); cube_noise = NULL; 01435 cpl_free(header_data); header_data = NULL; 01436 cpl_free(header_noise); header_noise = NULL; 01437 cpl_msg_info("", "-------------------------------------------"); 01438 01439 if (lcal != NULL) { 01440 for (int i = 0; i < KMOS_NR_DETECTORS; i++) { 01441 cpl_image_delete(lcal[i]); 01442 } 01443 } 01444 cpl_free(lcal); lcal = NULL; 01445 01446 // 01447 // combine 01448 // 01449 cpl_msg_info("", "Combining reconstructed objects"); 01450 cpl_msg_info("", " "); 01451 01452 nr_reconstructed_frames = cpl_frameset_count_tags(frameset, RECONSTRUCTED_CUBE); 01453 01454 if ( (mapping_mode == NULL) || ((mapping_mode != NULL) && 01455 ((ifus != NULL) || (strcmp(name, "") != 0))) 01456 ) 01457 { 01458 // loop all available objects 01459 for (int i = 0; i < nr_avail_obj_names; i++) { 01460 cpl_msg_info("", " > object: %s", all_obj[i].name); 01461 nr_data_alloc = all_obj[i].count; 01462 KMO_TRY_EXIT_IF_NULL( 01463 cube_data = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01464 sizeof(cpl_imagelist*))); 01465 KMO_TRY_EXIT_IF_NULL( 01466 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01467 sizeof(cpl_imagelist*))); 01468 KMO_TRY_EXIT_IF_NULL( 01469 header_data = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01470 sizeof(cpl_propertylist*))); 01471 KMO_TRY_EXIT_IF_NULL( 01472 header_noise = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01473 sizeof(cpl_propertylist*))); 01474 01475 // setup cube-list and header-list for kmo_priv_combine() 01476 cube_counter_data = 0; 01477 cube_counter_noise = 0; 01478 KMO_TRY_EXIT_IF_NULL( 01479 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01480 while (tmp_frame != NULL ) { 01481 KMO_TRY_EXIT_IF_NULL( 01482 fn_reconstr = cpl_frame_get_filename(tmp_frame)); 01483 01484 KMO_TRY_EXIT_IF_NULL( 01485 tmp_header = kmclipm_propertylist_load(fn_reconstr, 0)); 01486 01487 kmo_free_fits_desc(&desc1); 01488 kmo_init_fits_desc(&desc1); 01489 desc1 = kmo_identify_fits_header(fn_reconstr); 01490 01491 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01492 // check if object-name equals the one in our list 01493 KMO_TRY_EXIT_IF_NULL( 01494 keyword = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, 01495 ifu_nr, IFU_NAME_POSTFIX)); 01496 KMO_TRY_EXIT_IF_NULL( 01497 tmp_str = cpl_propertylist_get_string(tmp_header, 01498 keyword)); 01499 cpl_free(keyword); keyword = NULL; 01500 01501 if (strcmp(all_obj[i].name, tmp_str) == 0) { 01502 // found object-IFU with matching name 01503 // load data & subheader 01504 index = kmo_identify_index(fn_reconstr, ifu_nr, FALSE); 01505 KMO_TRY_CHECK_ERROR_STATE(); 01506 01507 if (desc1.sub_desc[index-1].valid_data) { 01508 KMO_TRY_EXIT_IF_NULL( 01509 cube_data[cube_counter_data] = 01510 kmclipm_imagelist_load(fn_reconstr, 01511 CPL_TYPE_FLOAT, 01512 index)); 01513 KMO_TRY_EXIT_IF_NULL( 01514 header_data[cube_counter_data] = 01515 kmclipm_propertylist_load(fn_reconstr, 01516 index)); 01517 cpl_propertylist_update_string(header_data[cube_counter_data], 01518 "ESO PRO FRNAME", 01519 fn_reconstr); 01520 cpl_propertylist_update_int(header_data[cube_counter_data], 01521 "ESO PRO IFUNR", 01522 index); 01523 cube_counter_data++; 01524 } 01525 01526 // load noise & subheader (if existing) 01527 if (desc1.ex_noise) { 01528 index = kmo_identify_index(fn_reconstr, ifu_nr, TRUE); 01529 KMO_TRY_CHECK_ERROR_STATE(); 01530 01531 if (desc1.sub_desc[index-1].valid_data) { 01532 KMO_TRY_EXIT_IF_NULL( 01533 cube_noise[cube_counter_noise] = 01534 kmclipm_imagelist_load(fn_reconstr, 01535 CPL_TYPE_FLOAT, 01536 index)); 01537 KMO_TRY_EXIT_IF_NULL( 01538 header_noise[cube_counter_noise] = 01539 kmclipm_propertylist_load(fn_reconstr, 01540 index)); 01541 cube_counter_noise++; 01542 } 01543 } 01544 cpl_error_reset(); 01545 } // end if found obj 01546 } // end for ifu_nr 01547 01548 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01549 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01550 KMO_TRY_CHECK_ERROR_STATE(); 01551 } // end while-loop RECONSTRUCTED_CUBE frames 01552 01553 if (cube_counter_data > 1) { 01554 if (cube_counter_data == cube_counter_noise) { 01555 KMO_TRY_EXIT_IF_ERROR( 01556 kmo_priv_combine(cube_data, 01557 cube_noise, 01558 header_data, 01559 header_noise, 01560 cube_counter_data, 01561 cube_counter_noise, 01562 all_obj[i].name, 01563 "", 01564 comb_method, 01565 smethod, 01566 fmethod, 01567 filename, 01568 cmethod, 01569 cpos_rej, 01570 cneg_rej, 01571 citer, 01572 cmin, 01573 cmax, 01574 extrapol_enum, 01575 flux, 01576 &combined_data, 01577 &combined_noise)); 01578 } else if (cube_counter_noise == 0) { 01579 // if imethod == "CS" 01580 KMO_TRY_EXIT_IF_ERROR( 01581 kmo_priv_combine(cube_data, 01582 NULL, 01583 header_data, 01584 header_noise, 01585 cube_counter_data, 01586 cube_counter_noise, 01587 all_obj[i].name, 01588 "", 01589 comb_method, 01590 smethod, 01591 fmethod, 01592 filename, 01593 cmethod, 01594 cpos_rej, 01595 cneg_rej, 01596 citer, 01597 cmin, 01598 cmax, 01599 extrapol_enum, 01600 flux, 01601 &combined_data, 01602 &combined_noise)); 01603 } else { 01604 KMO_TRY_ASSURE(1 == 0, 01605 CPL_ERROR_ILLEGAL_INPUT, 01606 "The number of cube-data and cube-noise " 01607 "isn't the same (%d vs. %d)!", 01608 cube_counter_data, cube_counter_noise); 01609 } 01610 } else { 01611 cpl_msg_warning("", "There is only one reconstructed cube with " 01612 "this object! Saving it as it is."); 01613 KMO_TRY_EXIT_IF_NULL( 01614 combined_data = cpl_imagelist_duplicate(cube_data[0])); 01615 01616 if (cube_noise[0] != NULL) { 01617 KMO_TRY_EXIT_IF_NULL( 01618 combined_noise = cpl_imagelist_duplicate(cube_noise[0])); 01619 } 01620 } // end if (cube_counter_data > 1) 01621 01622 fn_out = COMBINED_CUBE; 01623 KMO_TRY_EXIT_IF_NULL( 01624 fn_suffix = cpl_sprintf("_%s", all_obj[i].name)); 01625 01626 // save combined cube 01627 KMO_TRY_EXIT_IF_NULL( 01628 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01629 KMO_TRY_EXIT_IF_ERROR( 01630 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, 01631 tmp_frame, NULL, parlist, cpl_func)); 01632 01633 KMO_TRY_EXIT_IF_ERROR( 01634 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, 01635 header_data[0], 0./0.)); 01636 01637 // if (combined_noise != NULL) { 01638 if (header_noise[0] == NULL) { 01639 KMO_TRY_EXIT_IF_NULL( 01640 header_noise[0] = 01641 cpl_propertylist_duplicate(header_data[0])); 01642 01643 KMO_TRY_EXIT_IF_NULL( 01644 tmp_str = cpl_propertylist_get_string(header_data[0], 01645 EXTNAME)); 01646 KMO_TRY_EXIT_IF_ERROR( 01647 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content)); 01648 KMO_TRY_EXIT_IF_NULL( 01649 extname = kmo_extname_creator(ifu_frame, tmp_int, 01650 EXT_NOISE)); 01651 KMO_TRY_EXIT_IF_ERROR( 01652 kmclipm_update_property_string(header_noise[0], 01653 EXTNAME, extname, 01654 "FITS extension name")); 01655 cpl_free(extname); extname = NULL; 01656 } 01657 KMO_TRY_EXIT_IF_ERROR( 01658 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix, 01659 header_noise[0], 0./0.)); 01660 // } 01661 01662 for (int jj = 0; jj < nr_data_alloc; jj++) { 01663 cpl_imagelist_delete(cube_data[jj]); cube_data[jj] = NULL; 01664 cpl_imagelist_delete(cube_noise[jj]); cube_noise[jj] = NULL; 01665 cpl_propertylist_delete(header_data[jj]); header_data[jj] = NULL; 01666 cpl_propertylist_delete(header_noise[jj]); header_noise[jj] = NULL; 01667 } 01668 cpl_free(cube_data); cube_data = NULL; 01669 cpl_free(cube_noise); cube_noise = NULL; 01670 cpl_free(header_data); header_data = NULL; 01671 cpl_free(header_noise); header_noise = NULL; 01672 cpl_free(fn_suffix); fn_suffix = NULL; 01673 cpl_imagelist_delete(combined_data); combined_data = NULL; 01674 cpl_imagelist_delete(combined_noise); combined_noise = NULL; 01675 } // for i = nr_avail_obj_names 01676 } else { 01677 // we are in mapping_mode 01678 nr_data_alloc = nr_reconstructed_frames*KMOS_NR_IFUS; 01679 KMO_TRY_EXIT_IF_NULL( 01680 cube_data = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01681 sizeof(cpl_imagelist*))); 01682 KMO_TRY_EXIT_IF_NULL( 01683 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01684 sizeof(cpl_imagelist*))); 01685 KMO_TRY_EXIT_IF_NULL( 01686 header_data = (cpl_propertylist**)cpl_calloc( nr_data_alloc, 01687 sizeof(cpl_propertylist*))); 01688 KMO_TRY_EXIT_IF_NULL( 01689 header_noise = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01690 sizeof(cpl_propertylist*))); 01691 01692 cube_counter_data = 0; 01693 cube_counter_noise = 0; 01694 KMO_TRY_EXIT_IF_NULL( 01695 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01696 while (tmp_frame != NULL ) { 01697 KMO_TRY_EXIT_IF_NULL( 01698 fn_reconstr = cpl_frame_get_filename(tmp_frame)); 01699 01700 KMO_TRY_EXIT_IF_NULL( 01701 tmp_header = kmclipm_propertylist_load(fn_reconstr, 0)); 01702 01703 kmo_free_fits_desc(&desc1); 01704 kmo_init_fits_desc(&desc1); 01705 desc1 = kmo_identify_fits_header(fn_reconstr); 01706 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01707 index = kmo_identify_index(fn_reconstr, ifu_nr, FALSE); 01708 KMO_TRY_CHECK_ERROR_STATE(); 01709 01710 if (desc1.sub_desc[index-1].valid_data) { 01711 KMO_TRY_EXIT_IF_NULL( 01712 cube_data[cube_counter_data] = 01713 kmclipm_imagelist_load(fn_reconstr, CPL_TYPE_FLOAT, 01714 index)); 01715 if (fast_mode) { 01716 KMO_TRY_EXIT_IF_NULL( 01717 tmpImg = cpl_imagelist_collapse_median_create(cube_data[cube_counter_data])); 01718 KMO_TRY_EXIT_IF_NULL( 01719 tmpCube = cpl_imagelist_new()); 01720 KMO_TRY_EXIT_IF_ERROR( 01721 cpl_imagelist_set(tmpCube, tmpImg, 0)); 01722 cpl_imagelist_delete(cube_data[cube_counter_data]); 01723 cube_data[cube_counter_data] = tmpCube; 01724 } 01725 01726 KMO_TRY_EXIT_IF_NULL( 01727 header_data[cube_counter_data] = 01728 kmclipm_propertylist_load(fn_reconstr, index)); 01729 cpl_propertylist_update_string(header_data[cube_counter_data], 01730 "ESO PRO FRNAME", 01731 fn_reconstr); 01732 cpl_propertylist_update_int(header_data[cube_counter_data], 01733 "ESO PRO IFUNR", 01734 index); 01735 cube_counter_data++; 01736 } 01737 01738 // load noise & subheader (if existing) 01739 if (desc1.ex_noise) { 01740 index = kmo_identify_index(fn_reconstr, ifu_nr, TRUE); 01741 KMO_TRY_CHECK_ERROR_STATE(); 01742 if (desc1.sub_desc[index-1].valid_data) { 01743 KMO_TRY_EXIT_IF_NULL( 01744 cube_noise[cube_counter_noise] = 01745 kmclipm_imagelist_load(fn_reconstr, CPL_TYPE_FLOAT, 01746 index)); 01747 if (fast_mode) { 01748 KMO_TRY_EXIT_IF_NULL( 01749 tmpImg = cpl_imagelist_collapse_median_create(cube_noise[cube_counter_noise])); 01750 KMO_TRY_EXIT_IF_NULL( 01751 tmpCube = cpl_imagelist_new()); 01752 KMO_TRY_EXIT_IF_ERROR( 01753 cpl_imagelist_set(tmpCube, tmpImg, 0)); 01754 cpl_imagelist_delete(cube_noise[cube_counter_noise]); 01755 cube_noise[cube_counter_noise] = tmpCube; 01756 } 01757 KMO_TRY_EXIT_IF_NULL( 01758 header_noise[cube_counter_noise] = 01759 kmclipm_propertylist_load(fn_reconstr, index)); 01760 cube_counter_noise++; 01761 } 01762 } 01763 cpl_error_reset(); 01764 } // end for ifu_nr 01765 01766 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01767 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01768 KMO_TRY_CHECK_ERROR_STATE(); 01769 } // end while-loop RECONSTRUCTED_CUBE frames 01770 01771 if (cube_counter_data > 1) { 01772 if (cube_counter_data == cube_counter_noise) { 01773 KMO_TRY_EXIT_IF_ERROR( 01774 kmo_priv_combine(cube_data, 01775 cube_noise, 01776 header_data, 01777 header_noise, 01778 cube_counter_data, 01779 cube_counter_noise, 01780 mapping_mode, 01781 "", 01782 comb_method, 01783 smethod, 01784 fmethod, 01785 filename, 01786 cmethod, 01787 cpos_rej, 01788 cneg_rej, 01789 citer, 01790 cmin, 01791 cmax, 01792 extrapol_enum, 01793 flux, 01794 &combined_data, 01795 &combined_noise)); 01796 } else if (cube_counter_noise == 0) { 01797 // if imethod == "CS" 01798 KMO_TRY_EXIT_IF_ERROR( 01799 kmo_priv_combine(cube_data, 01800 NULL, 01801 header_data, 01802 header_noise, 01803 cube_counter_data, 01804 cube_counter_noise, 01805 mapping_mode, 01806 "", 01807 comb_method, 01808 smethod, 01809 fmethod, 01810 filename, 01811 cmethod, 01812 cpos_rej, 01813 cneg_rej, 01814 citer, 01815 cmin, 01816 cmax, 01817 extrapol_enum, 01818 flux, 01819 &combined_data, 01820 &combined_noise)); 01821 } else { 01822 KMO_TRY_ASSURE(1 == 0, 01823 CPL_ERROR_ILLEGAL_INPUT, 01824 "The number of cube-data and cube-noise " 01825 "isn't the same (%d vs. %d)!", 01826 cube_counter_data, cube_counter_noise); 01827 } 01828 } else { 01829 cpl_msg_warning("", "There is only one reconstructed cube! " 01830 "Saving it as it is."); 01831 KMO_TRY_EXIT_IF_NULL( 01832 combined_data = cpl_imagelist_duplicate(cube_data[0])); 01833 01834 if (cube_noise[0] != NULL) { 01835 KMO_TRY_EXIT_IF_NULL( 01836 combined_noise = cpl_imagelist_duplicate(cube_noise[0])); 01837 } 01838 } 01839 01840 fn_out = COMBINED_CUBE; 01841 KMO_TRY_EXIT_IF_NULL( 01842 fn_suffix = cpl_sprintf("_%s", mapping_mode)); 01843 01844 // save combined cube 01845 KMO_TRY_EXIT_IF_NULL( 01846 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01847 KMO_TRY_EXIT_IF_ERROR( 01848 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, tmp_frame, 01849 NULL, parlist, cpl_func)); 01850 01851 KMO_TRY_EXIT_IF_ERROR( 01852 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, 01853 header_data[0], 0./0.)); 01854 01855 // if (combined_noise != NULL) { 01856 if (header_noise[0] == NULL) { 01857 KMO_TRY_EXIT_IF_NULL( 01858 header_noise[0] = 01859 cpl_propertylist_duplicate(header_data[0])); 01860 01861 KMO_TRY_EXIT_IF_NULL( 01862 tmp_str = cpl_propertylist_get_string(header_data[0], 01863 EXTNAME)); 01864 KMO_TRY_EXIT_IF_ERROR( 01865 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content)); 01866 KMO_TRY_EXIT_IF_NULL( 01867 extname = kmo_extname_creator(ifu_frame, tmp_int, 01868 EXT_NOISE)); 01869 KMO_TRY_EXIT_IF_ERROR( 01870 kmclipm_update_property_string(header_noise[0], 01871 EXTNAME, extname, 01872 "FITS extension name")); 01873 cpl_free(extname); extname = NULL; 01874 } 01875 KMO_TRY_EXIT_IF_ERROR( 01876 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix, 01877 header_noise[0], 0./0.)); 01878 // } 01879 01880 for (int i = 0; i < nr_data_alloc; i++) { 01881 cpl_imagelist_delete(cube_data[i]); cube_data[i] = NULL; 01882 cpl_imagelist_delete(cube_noise[i]); cube_noise[i] = NULL; 01883 cpl_propertylist_delete(header_data[i]); header_data[i] = NULL; 01884 cpl_propertylist_delete(header_noise[i]); header_noise[i] = NULL; 01885 } 01886 cpl_free(cube_data); cube_data = NULL; 01887 cpl_free(cube_noise); cube_noise = NULL; 01888 cpl_free(header_data); header_data = NULL; 01889 cpl_free(header_noise); header_noise = NULL; 01890 cpl_free(fn_suffix); fn_suffix = NULL; 01891 cpl_imagelist_delete(combined_data); combined_data = NULL; 01892 cpl_imagelist_delete(combined_noise); combined_noise = NULL; 01893 } // if mapping_mode 01894 01895 cpl_msg_info("", "-------------------------------------------"); 01896 } 01897 KMO_CATCH 01898 { 01899 KMO_CATCH_MSG(); 01900 ret_val = -1; 01901 } 01902 01903 if (cube_data != NULL) { 01904 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 01905 cpl_imagelist_delete(cube_data[ifu_nr-1]); cube_data[ifu_nr-1] = NULL; 01906 } 01907 } 01908 cpl_free(cube_data); cube_data = NULL; 01909 if (cube_noise != NULL) { 01910 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 01911 cpl_imagelist_delete(cube_noise[ifu_nr-1]); cube_noise[ifu_nr-1] = NULL; 01912 } 01913 } 01914 cpl_free(cube_noise); cube_noise = NULL; 01915 if (header_data != NULL) { 01916 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 01917 cpl_propertylist_delete(header_data[ifu_nr-1]); header_data[ifu_nr-1] = NULL; 01918 } 01919 } 01920 cpl_free(header_data); header_data = NULL; 01921 if (header_noise != NULL) { 01922 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 01923 cpl_propertylist_delete(header_noise[ifu_nr-1]); header_noise[ifu_nr-1] = NULL; 01924 } 01925 } 01926 cpl_free(header_noise); header_noise = NULL; 01927 01928 01929 kmo_free_fits_desc(&desc1); 01930 kmo_free_fits_desc(&desc2); 01931 cpl_vector_delete(ifus); ifus = NULL; 01932 cpl_free(mapping_mode); mapping_mode = NULL; 01933 if (unused_ifus != NULL) { 01934 kmo_free_unused_ifus(unused_ifus); unused_ifus = NULL; 01935 } 01936 if (bounds != NULL) { 01937 cpl_free(bounds); bounds = NULL; 01938 } 01939 if (obj_sky_struct != NULL) { 01940 cpl_free(obj_sky_struct); obj_sky_struct = NULL; 01941 } 01942 01943 // frees for the case of errors 01944 kmclipm_vector_delete(telluric_data); telluric_data = NULL; 01945 kmclipm_vector_delete(telluric_noise); telluric_noise = NULL; 01946 cpl_image_delete(illum_data); illum_data = NULL; 01947 cpl_image_delete(illum_noise); illum_noise = NULL; 01948 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01949 cpl_table_delete(band_table); band_table = NULL; 01950 cpl_propertylist_delete(main_header); main_header = NULL; 01951 if (lcal != NULL) { 01952 for (int i = 0; i < KMOS_NR_DETECTORS; i++) { 01953 cpl_image_delete(lcal[i]); 01954 } 01955 } 01956 cpl_free(lcal); lcal = NULL; 01957 cpl_free(fn_suffix); fn_suffix = NULL; 01958 cpl_free(suffix); suffix = NULL; 01959 01960 if (all_obj != NULL) { 01961 for (int i = 0; i < nr_science_frames*KMOS_NR_IFUS; i++) { 01962 cpl_free(all_obj[i].name); 01963 } 01964 } 01965 cpl_free(all_obj); all_obj = NULL; 01966 01967 return ret_val; 01968 } 01969
1.7.6.1