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