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