|
KMOS Pipeline Reference Manual
1.3.7
|
00001 /* 00002 * This file is part of the KMOS Pipeline 00003 * Copyright (C) 2002,2003 European Southern Observatory 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 */ 00019 00020 #ifdef HAVE_CONFIG_H 00021 #include <config.h> 00022 #endif 00023 00024 /*----------------------------------------------------------------------------- 00025 * Includes 00026 *----------------------------------------------------------------------------*/ 00027 00028 #include <string.h> 00029 #include <math.h> 00030 00031 #include <cpl.h> 00032 00033 #include "kmclipm_constants.h" 00034 #include "kmclipm_functions.h" 00035 00036 #include "kmo_debug.h" 00037 #include "kmo_constants.h" 00038 #include "kmo_cpl_extensions.h" 00039 #include "kmo_priv_lcorr.h" 00040 #include "kmo_utils.h" 00041 #include "kmo_error.h" 00042 #include "kmo_dfs.h" 00043 #include "kmo_functions.h" 00044 #include "kmo_priv_arithmetic.h" 00045 #include "kmo_priv_combine.h" 00046 #include "kmo_priv_functions.h" 00047 #include "kmo_priv_reconstruct.h" 00048 #include "kmo_priv_sky_tweak.h" 00049 00050 /*----------------------------------------------------------------------------- 00051 * Functions prototypes 00052 *----------------------------------------------------------------------------*/ 00053 00054 static int kmo_sci_red_create(cpl_plugin *); 00055 static int kmo_sci_red_exec(cpl_plugin *); 00056 static int kmo_sci_red_destroy(cpl_plugin *); 00057 static int kmo_sci_red(cpl_parameterlist *, cpl_frameset *); 00058 00059 /*----------------------------------------------------------------------------- 00060 * Static variables 00061 *----------------------------------------------------------------------------*/ 00062 00063 static char kmo_sci_red_description[] = 00064 "Ideally at least two data frames have to be provided since we need for each\n" 00065 "IFU pointing to an object as well a sky frame for the same IFU.\n" 00066 "If an OH spectrum is given in the SOF file the lambda axis will be corrected\n" 00067 "using the OH lines as reference.\n" 00068 "Every IFU containing an object will be reconstructed and divided by telluric\n" 00069 "and illumination correction. By default these intermediate cubes are saved\n" 00070 "to disk. Frames just containing skies won’t produce an output here, so the\n" 00071 "number of output frames can be smaller than the number of input frames.\n" 00072 "Then the reconstructed objects with the same object name are combined. These\n" 00073 "outputs are also saved to disk, the number of created files depends on the\n" 00074 "number of reconstructed objects of different name. If the user just wants to\n" 00075 "combine a certain object, the parameters --name or --ifus can be used.\n" 00076 "For exposures taken with the templates KMOS_spec_obs_mapping8 and\n" 00077 "KMOS_spec_obs_mapping24 the recipe behaves a bit different: All active IFUs\n" 00078 "will be combined, regardless of the object names.\n" 00079 "\n" 00080 "BASIC PARAMETERS:\n" 00081 "-----------------\n" 00082 "--imethod\n" 00083 "The interpolation method used for reconstruction.\n" 00084 "\n" 00085 "--smethod\n" 00086 "The interpolation method used for shifting.\n" 00087 "\n" 00088 "--name\n" 00089 "--ifus\n" 00090 "Since an object can be present only once per exposure and since it can be\n" 00091 "located in different IFUs for the existing exposures, there are two modes\n" 00092 "to identify the objects:\n" 00093 " * Combine by object names (default)\n" 00094 " In this case the object name must be provided via the --name parameter.\n" 00095 " The object name will be searched for in all primary headers of all\n" 00096 " provided frames in the keyword ESO OCS ARMx NAME.\n" 00097 "\n" 00098 " * Combine by index (advanced)\n" 00099 " In this case the --ifus parameter must be provided. The parameter must\n" 00100 " have the same number of entries as frames are provided, e.g. \"3;1;24\"\n" 00101 " for 3 exposures. The index doesn't reference the extension in the frame\n" 00102 " but the real index of the IFU as defined in the EXTNAME keyword.\n" 00103 " (e.g. 'IFU.3.DATA')\n" 00104 "\n" 00105 "ADVANCED PARAMETERS\n" 00106 "-------------------\n" 00107 "--flux\n" 00108 "Specify if flux conservation should be applied.\n" 00109 "\n" 00110 "--background\n" 00111 "Specify if background removal should be applied.\n" 00112 "\n" 00113 "--suppress_extension\n" 00114 "If set to TRUE, the arbitrary filename extensions are supressed. If multiple\n" 00115 "products with the same category are produced, they will be numered\n" 00116 "consecutively starting from 0.\n" 00117 "\n" 00118 "--sky_tweak\n" 00119 "If set to TRUE sky substraction is not done by subtracting the corresponding\n" 00120 "detector images but subtracting a modified sky cube from the object cube.\n" 00121 "It is not allowed that \"--sky_tweak\" and \"--no_subtract\" both are TRUE.\n" 00122 "\n" 00123 "--tbsub\n" 00124 "If set to TRUE subtract the thermal background from the cube resulting from\n" 00125 "sky tweaking.\n" 00126 "Default value is TRUE.\n" 00127 "\n" 00128 "--obj_sky_table\n" 00129 "The automatic obj-sky-associations can be modified by indicating a file with\n" 00130 "the desired associations. Therefore the file written to disk by default\n" 00131 "(without setting this option) can be edited manually. The formatting must\n" 00132 "absolutely be retained, just the type codes ('O' and'S') and the associated\n" 00133 "frame indices should be altered\n" 00134 "\n" 00135 " Advanced reconstruction parameters\n" 00136 " ----------------------------------\n" 00137 "--neighborhoodRange\n" 00138 "Defines the range to search for neighbors during reconstruction\n" 00139 "\n" 00140 "--b_samples\n" 00141 "The number of samples in spectral direction for the reconstructed cube.\n" 00142 "Ideally this number should be greater than 2048, the detector size.\n" 00143 "\n" 00144 "--b_start\n" 00145 "--b_end\n" 00146 "Used to define manually the start and end wavelength for the reconstructed\n" 00147 "cube. By default the internally defined values are used.\n" 00148 "\n" 00149 "--fast_mode\n" 00150 "If set to TRUE, the reconstructed cubes will be collapsed (using median) and\n" 00151 "only then be shifted and combined.\n" 00152 "\n" 00153 "--pix_scale\n" 00154 "Change the pixel scale [arcsec]. Default of 0.2\" results into cubes of\n" 00155 "14x14pix, a scale of 0.1\" results into cubes of 28x28pix, etc.\n" 00156 "\n" 00157 "--no_subtract\n" 00158 "If set to TRUE, the found objects and references won't be sky subtracted. \n" 00159 "Additionally all IFUs will be reconstructed, even the ones containing skies.\n" 00160 "This option sets the parameter no_combine to TRUE automatically.\n" 00161 "\n" 00162 "--xcal_interpolation\n" 00163 "If true interpolate the pixel position in the slitlet (xcal) using the two\n" 00164 "closest rotator angles in the calibration file. Otherwise take the values\n" 00165 "of the closest rotator angle\n" 00166 "\n" 00167 "--extrapolate\n" 00168 "By default no extrapolation is applied. This means that the intermediate\n" 00169 "reconstructed cubes will shrink at most one pixel, which is ok for templates\n" 00170 "like KMOS_spec_obs_nodtosky or KMOS_spec_obs_freedither. When the cubes will\n" 00171 "be arranged as a map, a grid is likely to occur between the IFUs. Therefore\n" 00172 "extrapolation during the shifting process can be switched on in order to get\n" 00173 "IFUs of original size. For frames taken with mapping templates,\n" 00174 "extrapolation is switched on automatically.\n" 00175 "\n" 00176 "--velocity_offset\n" 00177 "Specifies the velocity offset correction in km/s for lambda scale.\n" 00178 "Default is 0.0 km/s, i.e. no velocity correction.\n" 00179 "\n" 00180 "--save_interims\n" 00181 "If set to TRUE the interim object and sky cubes used for sky tweaking are\n" 00182 "saved to FITS file in the same format as SCI_RECONSTRUCTED\n" 00183 "Default is FALSE.\n" 00184 "\n" 00185 " Advanced combining parameters\n" 00186 " ----------------------------------\n" 00187 "--edge_nan\n" 00188 "Set borders of two sides of the cubes to NaN before combining them. This\n" 00189 "minimises unwanted border effects when dithering.\n" 00190 "\n" 00191 "--no_combine\n" 00192 "If set to TRUE, the reconstructed cubes will not be combined.\n" 00193 "\n" 00194 "--method\n" 00195 "There are following sources to get the shift parameters from:\n" 00196 " * 'header' (default)\n" 00197 " The shifts are calculated according to the WCS information stored in the\n" 00198 " header of every IFU. The output frame will get larger, except the object\n" 00199 " is at the exact same position for all exposures. The size of the\n" 00200 " exposures can differ, but the orientation must be the same for all\n" 00201 " exposures.\n" 00202 "\n" 00203 " * 'none'\n" 00204 " The cubes are directly recombined, not shifting at all. The ouput frame\n" 00205 " will have the same dimensions as the input cubes.\n" 00206 " If the size differs a warning will be emitted and the cubes will be\n" 00207 " aligned to the lower left corner. If the orientation differs a warning\n" 00208 " will be emitted, but the cubes are combined anyway.\n" 00209 "\n" 00210 " * 'center'\n" 00211 " The shifts are calculated using a centering algorithm. The cube will be\n" 00212 " collapsed and a 2D profile will be fitted to it to identify the centre.\n" 00213 " With the parameter --fmethod the function to fit can be provided. The\n" 00214 " size of the exposures can differ, but the orientation must be the same\n" 00215 " for all exposures.\n" 00216 "\n" 00217 " * 'user'\n" 00218 " Read the shifts from a user specified file. The path of the file must be\n" 00219 " provided using the --filename parameter. For every exposure (except the\n" 00220 " first one) two shift values are expected per line, they have to be\n" 00221 " separated with simple spaces. The values indicate pixel shifts and are\n" 00222 " referenced to the first frame. The 1st value is the shift in x-direction\n" 00223 " to the left, the 2nd the shift in y-direction upwards. The size of the\n" 00224 " exposures can differ, but the orientation must be the same for all\n" 00225 " exposures.\n" 00226 "\n" 00227 "--fmethod\n" 00228 "see --method='center'\n" 00229 "The type of function that should be fitted spatially to the collapsed image.\n" 00230 "This fit is used to create a mask to extract the spectrum of the object.\n" 00231 "Valid values are 'gauss' and 'moffat'.\n" 00232 "\n" 00233 "--filename\n" 00234 "see --method='user'\n" 00235 "\n" 00236 "--cmethod\n" 00237 "Following methods of frame combination are available:\n" 00238 " * 'ksigma' (Default)\n" 00239 " An iterative sigma clipping. For each position all pixels in the spectrum\n" 00240 " are examined. If they deviate significantly, they will be rejected\n" 00241 " according to the conditions:\n" 00242 " val > mean + stdev * cpos_rej\n" 00243 " and\n" 00244 " val < mean - stdev * cneg_rej\n" 00245 " where --cpos_rej, --cneg_rej and --citer are the corresponding\n" 00246 " configuration parameters. In the first iteration median and percentile\n" 00247 " level are used.\n" 00248 "\n" 00249 " * 'median'\n" 00250 " At each pixel position the median is calculated.\n" 00251 "\n" 00252 " * 'average'\n" 00253 " At each pixel position the average is calculated.\n" 00254 "\n" 00255 " * 'sum'\n" 00256 " At each pixel position the sum is calculated.\n" 00257 "\n" 00258 " * 'min_max'\n" 00259 " The specified number of minimum and maximum pixel values will be\n" 00260 " rejected.\n" 00261 " --cmax and --cmin apply to this method.\n" 00262 "\n" 00263 "--cpos_rej\n" 00264 "--cneg_rej\n" 00265 "--citer\n" 00266 "see --cmethod='ksigma'\n" 00267 "\n" 00268 "--cmax\n" 00269 "--cmin\n" 00270 "see --cmethod='min_max'\n" 00271 "\n" 00272 "--------------------------------------------------------------------------\n" 00273 " Input files:\n" 00274 "\n" 00275 " DO KMOS \n" 00276 " category Type Explanation Required #Frames\n" 00277 " -------- ----- ----------- -------- -------\n" 00278 " SCIENCE RAW The science frames Y >=1 \n" 00279 " XCAL F2D x calibration frame Y 1 \n" 00280 " YCAL F2D y calibration frame Y 1 \n" 00281 " LCAL F2D Wavelength calib. frame Y 1 \n" 00282 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00283 " MASTER_FLAT F2D Master flat Y 0,1 \n" 00284 " ILLUM_CORR F2I Illumination correction N 0,1 \n" 00285 " TELLURIC F1I normalised telluric spectrum N 0,1 \n" 00286 " OH_SPEC F1S Vector holding OH lines N 0,1 \n" 00287 "\n" 00288 " Output files:\n" 00289 "\n" 00290 " DO KMOS\n" 00291 " category Type Explanation\n" 00292 " -------- ----- -----------\n" 00293 " SCI_COMBINED F3I Combined cubes with noise\n" 00294 " SCI_RECONSTRUCTED F3I Reconstructed cube with noise\n" 00295 " EXP_MASK F3I Exposure time mask (not for mapping-templates!)\n" 00296 " SCI_INTERIM_OBJECT F3I (optional) Intermediate reconstructed object \n" 00297 " cubes used for sky tweaking, no noise \n" 00298 " (set --sky_tweak and --save_interims)\n" 00299 " SCI_INTERIM_SKY F3I (optional) Intermediate reconstructed sky \n" 00300 " cubes used for sky tweaking, no noise\n" 00301 " (set --sky_tweak and --save_interims)\n" 00302 "--------------------------------------------------------------------------\n" 00303 "\n"; 00304 00305 /*----------------------------------------------------------------------------- 00306 * Functions code 00307 *----------------------------------------------------------------------------*/ 00308 00309 /*----------------------------------------------------------------------------*/ 00314 /*----------------------------------------------------------------------------*/ 00315 00318 /*----------------------------------------------------------------------------*/ 00327 /*----------------------------------------------------------------------------*/ 00328 int cpl_plugin_get_info(cpl_pluginlist *list) 00329 { 00330 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00331 cpl_plugin *plugin = &recipe->interface; 00332 00333 cpl_plugin_init(plugin, 00334 CPL_PLUGIN_API, 00335 KMOS_BINARY_VERSION, 00336 CPL_PLUGIN_TYPE_RECIPE, 00337 "kmo_sci_red", 00338 "Reconstruct obj/sky-pairs individually and combine " 00339 "them afterwards", 00340 kmo_sci_red_description, 00341 "Alex Agudo Berbel", 00342 "usd-help@eso.org", 00343 kmos_get_license(), 00344 kmo_sci_red_create, 00345 kmo_sci_red_exec, 00346 kmo_sci_red_destroy); 00347 00348 cpl_pluginlist_append(list, plugin); 00349 00350 return 0; 00351 } 00352 00353 /*----------------------------------------------------------------------------*/ 00361 /*----------------------------------------------------------------------------*/ 00362 static int kmo_sci_red_create(cpl_plugin *plugin) 00363 { 00364 cpl_recipe *recipe; 00365 cpl_parameter *p; 00366 00367 /* Check that the plugin is part of a valid recipe */ 00368 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00369 recipe = (cpl_recipe *)plugin; 00370 else 00371 return -1; 00372 00373 /* Create the parameters list in the cpl_recipe object */ 00374 recipe->parameters = cpl_parameterlist_new(); 00375 00376 /* --imethod (interpolation method) */ 00377 p = cpl_parameter_new_value("kmos.kmo_sci_red.imethod", CPL_TYPE_STRING, 00378 "Method to use for interpolation during reconstruction. " 00379 "[\"NN\" (nearest neighbour), " 00380 "\"lwNN\" (linear weighted nearest neighbor), " 00381 "\"swNN\" (square weighted nearest neighbor), " 00382 "\"MS\" (Modified Shepard's method)" 00383 "\"CS\" (Cubic spline)]", 00384 "kmos.kmo_sci_red", "CS"); 00385 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00386 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00387 cpl_parameterlist_append(recipe->parameters, p); 00388 00389 /* --smethod (shift interpolation method) */ 00390 p = cpl_parameter_new_value("kmos.kmo_sci_red.smethod", CPL_TYPE_STRING, 00391 "Method to use for interpolation during shifting. " 00392 "[\"NN\" (nearest neighbour), " 00393 "\"CS\" (Cubic spline)]", 00394 "kmos.kmo_sci_red", "CS"); 00395 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "smethod"); 00396 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00397 cpl_parameterlist_append(recipe->parameters, p); 00398 00399 /* --method (shift method) */ 00400 p = cpl_parameter_new_value("kmos.kmo_sci_red.method", CPL_TYPE_STRING, 00401 "The shifting method: " 00402 "'none': no shifting, combined directly, " 00403 "'header': shift according to WCS (default), " 00404 "'center': centering algorithm, " 00405 "'user': read shifts from file", 00406 "kmos.kmo_sci_red", "header"); 00407 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method"); 00408 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00409 cpl_parameterlist_append(recipe->parameters, p); 00410 00411 /* --fmethod */ 00412 p = cpl_parameter_new_value("kmos.kmo_sci_red.fmethod", CPL_TYPE_STRING, 00413 "The fitting method (applies only when method='center'): " 00414 "'gauss': fit a gauss function to collapsed image (default), " 00415 "'moffat': fit a moffat function to collapsed image", 00416 "kmos.kmo_sci_red", "gauss"); 00417 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00418 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00419 cpl_parameterlist_append(recipe->parameters, p); 00420 00421 /* --name */ 00422 p = cpl_parameter_new_value("kmos.kmo_sci_red.name", CPL_TYPE_STRING, 00423 "Name of the object to combine.", "kmos.kmo_sci_red", ""); 00424 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00425 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00426 cpl_parameterlist_append(recipe->parameters, p); 00427 00428 /* --ifus */ 00429 p = cpl_parameter_new_value("kmos.kmo_sci_red.ifus", CPL_TYPE_STRING, 00430 "The indices of the IFUs to combine. \"ifu1;ifu2;...\"", 00431 "kmos.kmo_sci_red", ""); 00432 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00433 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00434 cpl_parameterlist_append(recipe->parameters, p); 00435 00436 /* --pix_scale */ 00437 p = cpl_parameter_new_value("kmos.kmo_sci_red.pix_scale", CPL_TYPE_DOUBLE, 00438 "Change the pixel scale [arcsec]. " 00439 "Default of 0.2\" results into cubes of 14x14pix, " 00440 "a scale of 0.1\" results into cubes of 28x28pix, etc.", 00441 "kmos.kmo_sci_red", KMOS_PIX_RESOLUTION); 00442 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pix_scale"); 00443 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00444 cpl_parameterlist_append(recipe->parameters, p); 00445 00446 /* --suppress_extension */ 00447 p = cpl_parameter_new_value("kmos.kmo_sci_red.suppress_extension", 00448 CPL_TYPE_BOOL, 00449 "Suppress arbitrary filename extension." 00450 "(TRUE (apply) or FALSE (don't apply)", 00451 "kmos.kmo_sci_red", FALSE); 00452 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00453 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00454 cpl_parameterlist_append(recipe->parameters, p); 00455 00456 /* --neighborhoodRange */ 00457 p = cpl_parameter_new_value("kmos.kmo_sci_red.neighborhoodRange", 00458 CPL_TYPE_DOUBLE, 00459 "Defines the range to search for neighbors in pixels", 00460 "kmos.kmo_sci_red", 1.001); 00461 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00462 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00463 cpl_parameterlist_append(recipe->parameters, p); 00464 00465 /* --filename */ 00466 p = cpl_parameter_new_value("kmos.kmo_sci_red.filename", CPL_TYPE_STRING, 00467 "The path to the file with the shift vectors." 00468 "(Applies only to method='user')", 00469 "kmos.kmo_sci_red", ""); 00470 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filename"); 00471 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00472 cpl_parameterlist_append(recipe->parameters, p); 00473 00474 /* --flux */ 00475 p = cpl_parameter_new_value("kmos.kmo_sci_red.flux", CPL_TYPE_BOOL, 00476 "TRUE: Apply flux conservation. FALSE: otherwise", 00477 "kmos.kmo_sci_red", FALSE); 00478 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00479 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00480 cpl_parameterlist_append(recipe->parameters, p); 00481 00482 /* --background */ 00483 p = cpl_parameter_new_value("kmos.kmo_sci_red.background", CPL_TYPE_BOOL, 00484 "TRUE: Apply background removal. FALSE: otherwise", 00485 "kmos.kmo_sci_red", FALSE); 00486 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "background"); 00487 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00488 cpl_parameterlist_append(recipe->parameters, p); 00489 00490 /* --fast_mode */ 00491 p = cpl_parameter_new_value("kmos.kmo_sci_red.fast_mode", CPL_TYPE_BOOL, 00492 "FALSE: cubes are shifted and combined," 00493 "TRUE: cubes are collapsed and then shifted and combined", 00494 "kmos.kmo_sci_red", FALSE); 00495 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fast_mode"); 00496 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00497 cpl_parameterlist_append(recipe->parameters, p); 00498 00499 /* --extrapolate */ 00500 p = cpl_parameter_new_value("kmos.kmo_sci_red.extrapolate", CPL_TYPE_BOOL, 00501 "Applies only to 'smethod=CS' when doing sub-pixel shifts: " 00502 "FALSE: shifted IFU will be filled with NaN's at the borders," 00503 "TRUE: shifted IFU will be extrapolated at the borders", 00504 "kmos.kmo_sci_red", FALSE); 00505 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extrapolate"); 00506 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00507 cpl_parameterlist_append(recipe->parameters, p); 00508 00509 /* --xcal_interpolation */ 00510 p = cpl_parameter_new_value("kmos.kmo_sci_red.xcal_interpolation", 00511 CPL_TYPE_BOOL, 00512 "TRUE: Interpolate xcal between rotator angles. FALSE: otherwise", 00513 "kmos.kmo_sci_red", TRUE); 00514 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcal_interpolation"); 00515 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00516 cpl_parameterlist_append(recipe->parameters, p); 00517 00518 /* --edge_nan */ 00519 p = cpl_parameter_new_value("kmos.kmo_sci_red.edge_nan", CPL_TYPE_BOOL, 00520 "Set borders of cubes to NaN before combining them." 00521 "(TRUE (apply) or FALSE (don't apply)", 00522 "kmos.kmo_sci_red", FALSE); 00523 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "edge_nan"); 00524 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00525 cpl_parameterlist_append(recipe->parameters, p); 00526 00527 /* --no_combine */ 00528 p = cpl_parameter_new_value("kmos.kmo_sci_red.no_combine", CPL_TYPE_BOOL, 00529 "Don't combine cubes after reconstruction." 00530 "(TRUE (apply) or FALSE (don't apply)", 00531 "kmos.kmo_sci_red", FALSE); 00532 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "no_combine"); 00533 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00534 cpl_parameterlist_append(recipe->parameters, p); 00535 00536 /* --no_subtract */ 00537 p = cpl_parameter_new_value("kmos.kmo_sci_red.no_subtract", CPL_TYPE_BOOL, 00538 "Don't sky subtract object and references." 00539 "(TRUE (apply) or FALSE (don't apply)", 00540 "kmos.kmo_sci_red", FALSE); 00541 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "no_subtract"); 00542 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00543 cpl_parameterlist_append(recipe->parameters, p); 00544 00545 /* --sky_tweak */ 00546 p = cpl_parameter_new_value("kmos.kmo_sci_red.sky_tweak", CPL_TYPE_BOOL, 00547 "Use modified sky cube for sky subtraction." 00548 "(TRUE (apply) or FALSE (don't apply)", 00549 "kmos.kmo_sci_red", FALSE); 00550 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sky_tweak"); 00551 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00552 cpl_parameterlist_append(recipe->parameters, p); 00553 00554 /* --tbsub */ 00555 p = cpl_parameter_new_value("kmos.kmo_sci_red.tbsub", CPL_TYPE_BOOL, 00556 "Subtract thermal background from input cube." 00557 "(TRUE (apply) or FALSE (don't apply)", 00558 "kmos.kmo_sci_red", TRUE); 00559 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "tbsub"); 00560 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00561 cpl_parameterlist_append(recipe->parameters, p); 00562 00563 // add parameters for band-definition 00564 kmos_band_pars_create(recipe->parameters, "kmos.kmo_sci_red"); 00565 00566 /* --obj_sky_table */ 00567 p = cpl_parameter_new_value("kmos.kmo_sci_red.obj_sky_table", 00568 CPL_TYPE_STRING, 00569 "The path to the file with the modified obj/sky associations.", 00570 "kmos.kmo_sci_red", ""); 00571 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "obj_sky_table"); 00572 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00573 cpl_parameterlist_append(recipe->parameters, p); 00574 00575 /* --velocity_offset */ 00576 p = cpl_parameter_new_value("kmos.kmo_sci_red.velocity_offset", 00577 CPL_TYPE_DOUBLE, 00578 "Specify velocity offset correction in km/s for lambda scale", 00579 "kmos.kmo_sci_red", 0.0); 00580 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "velocity_offset"); 00581 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00582 cpl_parameterlist_append(recipe->parameters, p); 00583 00584 /* --save_interims */ 00585 p = cpl_parameter_new_value("kmos.kmo_sci_red.save_interims", CPL_TYPE_BOOL, 00586 "Save interim object and sky cubes. " 00587 "Can only be used together with --sky_tweak", 00588 "kmos.kmo_sci_red", FALSE); 00589 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save_interims"); 00590 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00591 cpl_parameterlist_append(recipe->parameters, p); 00592 00593 return kmos_combine_pars_create(recipe->parameters, "kmos.kmo_sci_red", 00594 DEF_REJ_METHOD, FALSE); 00595 } 00596 00597 /*----------------------------------------------------------------------------*/ 00603 /*----------------------------------------------------------------------------*/ 00604 static int kmo_sci_red_exec(cpl_plugin *plugin) 00605 { 00606 cpl_recipe *recipe; 00607 00608 /* Get the recipe out of the plugin */ 00609 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00610 recipe = (cpl_recipe *)plugin; 00611 else return -1 ; 00612 00613 return kmo_sci_red(recipe->parameters, recipe->frames); 00614 } 00615 00616 /*----------------------------------------------------------------------------*/ 00622 /*----------------------------------------------------------------------------*/ 00623 static int kmo_sci_red_destroy(cpl_plugin *plugin) 00624 { 00625 cpl_recipe *recipe; 00626 00627 /* Get the recipe out of the plugin */ 00628 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00629 recipe = (cpl_recipe *)plugin; 00630 else return -1 ; 00631 00632 cpl_parameterlist_delete(recipe->parameters); 00633 return 0 ; 00634 } 00635 00636 /*----------------------------------------------------------------------------*/ 00649 /*----------------------------------------------------------------------------*/ 00650 static int kmo_sci_red(cpl_parameterlist *parlist, cpl_frameset *frameset) 00651 { 00652 int ret_val = 0, 00653 nr_science_frames = 0, 00654 nr_reconstructed_frames = 0, 00655 has_illum_corr = 0, 00656 has_master_flat = 0, 00657 has_telluric = 0, 00658 has_oh_spec = 0, 00659 telluric_ok = 0, 00660 *bounds = NULL, 00661 det_nr = 0, 00662 actual_msg_level = 0, 00663 print_once = FALSE, 00664 cube_counter_data = 0, 00665 cube_counter_noise = 0, 00666 citer = 0, 00667 cmin = 0, 00668 cmax = 0, 00669 extrapolate = 0, 00670 flux = FALSE, 00671 background = FALSE, 00672 index = 0, 00673 nr_data_alloc = 0, 00674 tmp_int = 0, 00675 fast_mode = FALSE, 00676 edge_nan = FALSE, 00677 no_combine = FALSE, 00678 no_subtract = FALSE, 00679 do_sky_subtraction = FALSE, 00680 sky_tweak = FALSE, 00681 tbsub = TRUE, 00682 save_interims = FALSE, 00683 xcal_interpolation = FALSE, 00684 suppress_extension = FALSE, 00685 suppress_index = 0, 00686 i = 0, 00687 sf = 0, 00688 jj = 0, 00689 ifu_nr = 0, 00690 sky_ifu_nr = 0; 00691 double neighborhoodRange = 1.001, 00692 cpos_rej = 0.0, 00693 cneg_rej = 0.0, 00694 pix_scale = 0.0, 00695 velo_offset = 0.0, 00696 velo_corr = 0.0; 00697 double *velo_corr_ptr = NULL; 00698 char *suffix = NULL, 00699 *keyword = NULL, 00700 *extname = NULL, 00701 *fn_suffix = NULL, 00702 *mapping_mode = NULL, 00703 **split = NULL, 00704 content[256]; 00705 const char *imethod = NULL, 00706 *smethod = NULL, 00707 *ifus_txt = NULL, 00708 *name = NULL, 00709 *filter_id = NULL, 00710 *tmp_str = NULL, 00711 *filename = NULL, 00712 *fn_obj_sky_table = NULL, 00713 *fn_out = NULL, 00714 *fn_out_mask = NULL, 00715 *fn_obj = NULL, 00716 *fn_sky = NULL, 00717 *fn_reconstr = NULL, 00718 *fn_interim_object = NULL, 00719 *fn_interim_sky = NULL, 00720 *comb_method = NULL, 00721 *cmethod = NULL, 00722 *fmethod = NULL; 00723 cpl_array **unused_ifus_before = NULL, 00724 **unused_ifus_after = NULL; 00725 cpl_frame *xcal_frame = NULL, 00726 *ycal_frame = NULL, 00727 *lcal_frame = NULL, 00728 *flat_frame = NULL, 00729 *illum_frame = NULL, 00730 *telluric_frame = NULL, 00731 *tmp_frame = NULL; 00732 cpl_propertylist *tmp_header = NULL, 00733 *main_header = NULL, 00734 *main_sky_header = NULL, 00735 **header_data = NULL, 00736 **header_noise = NULL, 00737 **header_sky = NULL; 00738 cpl_vector *ifus = NULL; 00739 kmclipm_vector *telluric_data = NULL, 00740 *telluric_noise = NULL; 00741 cpl_image **lcal = NULL, 00742 *illum_data = NULL, 00743 *illum_noise = NULL, 00744 *tmpImg = NULL, 00745 *exp_mask = NULL; 00746 cpl_imagelist **cube_data = NULL, 00747 **cube_noise = NULL, 00748 **cube_interim_object = NULL, 00749 **cube_interim_sky = NULL, 00750 *sky_data = NULL, 00751 *sky_noise = NULL, 00752 *combined_data = NULL, 00753 *combined_noise = NULL, 00754 *tmpCube = NULL; 00755 cpl_table *band_table = NULL; 00756 cpl_frame *sky_frame = NULL, 00757 *sky_as_object_frame = NULL, 00758 *ref_spectrum_frame = NULL; 00759 cpl_polynomial *oh_lcorr_coeffs = NULL; 00760 main_fits_desc desc1, 00761 desc2, 00762 desc_telluric; 00763 gridDefinition gd; 00764 armNameStruct *arm_name_struct = NULL; 00765 enum extrapolationType extrapol_enum = 0; 00766 enum kmo_frame_type ft = 0; 00767 00768 KMO_TRY 00769 { 00770 kmo_init_fits_desc(&desc1); 00771 kmo_init_fits_desc(&desc2); 00772 kmo_init_fits_desc(&desc_telluric); 00773 00774 /* Check frameset */ 00775 KMO_TRY_ASSURE((parlist != NULL) && (frameset != NULL), 00776 CPL_ERROR_NULL_INPUT, "Not all input data is provided!"); 00777 00778 nr_science_frames = cpl_frameset_count_tags(frameset, SCIENCE); 00779 KMO_TRY_ASSURE(nr_science_frames >= 1, CPL_ERROR_ILLEGAL_INPUT, 00780 "At least one SCIENCE frame is required!"); 00781 if (nr_science_frames == 1) { 00782 cpl_msg_warning(__func__, 00783 "2 SCIENCE frames are needed for sky subtraction"); 00784 cpl_msg_warning(__func__, 00785 "All IFUs are reconstructed (object, reference and sky"); 00786 } 00787 00788 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00789 CPL_ERROR_FILE_NOT_FOUND, 00790 "Exactly one XCAL frame is required"); 00791 00792 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00793 CPL_ERROR_FILE_NOT_FOUND, 00794 "Exactly one YCAL frame is required"); 00795 00796 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00797 CPL_ERROR_FILE_NOT_FOUND, 00798 "Exactly one LCAL frame is required"); 00799 00800 has_master_flat = cpl_frameset_count_tags(frameset, MASTER_FLAT); 00801 KMO_TRY_ASSURE((has_master_flat == 0) || (has_master_flat == 1), 00802 CPL_ERROR_FILE_NOT_FOUND, 00803 "At most one MASTER_FLAT frame can be provided"); 00804 00805 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00806 CPL_ERROR_FILE_NOT_FOUND, 00807 "Exactly one WAVE_BAND frame is required"); 00808 00809 has_illum_corr = cpl_frameset_count_tags(frameset, ILLUM_CORR); 00810 KMO_TRY_ASSURE((has_illum_corr == 0) || (has_illum_corr == 1), 00811 CPL_ERROR_FILE_NOT_FOUND, 00812 "At most one ILLUM_CORR frame can be provided"); 00813 00814 has_telluric = cpl_frameset_count_tags(frameset, TELLURIC); 00815 KMO_TRY_ASSURE((has_telluric == 0) || (has_telluric == 1), 00816 CPL_ERROR_FILE_NOT_FOUND, 00817 "At most one TELLURIC frame can be provided"); 00818 00819 has_oh_spec = cpl_frameset_count_tags(frameset, OH_SPEC) ; 00820 KMO_TRY_ASSURE(has_oh_spec == 0 || has_oh_spec == 1, 00821 CPL_ERROR_ILLEGAL_INPUT, 00822 "Only a single reference spectrum can be provided!"); 00823 00824 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_sci_red") == 1, 00825 CPL_ERROR_ILLEGAL_INPUT, 00826 "Cannot identify RAW and CALIB frames!"); 00827 00828 /* Get parameters */ 00829 cpl_msg_info("", "--- Parameter setup for kmo_sci_red ------"); 00830 flux = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_sci_red.flux"); 00831 KMO_TRY_ASSURE((flux == 0) || (flux == 1), CPL_ERROR_ILLEGAL_INPUT, 00832 "flux must be either FALSE or TRUE! %d", flux); 00833 KMO_TRY_EXIT_IF_ERROR( 00834 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.flux")); 00835 background = kmo_dfs_get_parameter_bool(parlist, 00836 "kmos.kmo_sci_red.background"); 00837 KMO_TRY_ASSURE((background == 0) || (background == 1), 00838 CPL_ERROR_ILLEGAL_INPUT, 00839 "background must be either FALSE or TRUE! %d", background); 00840 KMO_TRY_EXIT_IF_ERROR( 00841 kmo_dfs_print_parameter_help(parlist, 00842 "kmos.kmo_sci_red.background")); 00843 KMO_TRY_EXIT_IF_NULL( 00844 imethod = kmo_dfs_get_parameter_string(parlist, 00845 "kmos.kmo_sci_red.imethod")); 00846 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00847 (strcmp(imethod, "lwNN") == 0) || 00848 (strcmp(imethod, "swNN") == 0) || 00849 (strcmp(imethod, "MS") == 0) || 00850 (strcmp(imethod, "CS") == 0), 00851 CPL_ERROR_ILLEGAL_INPUT, 00852 "imethod must be either \"NN\", \"lwNN\", \"swNN\", \"MS\" or \"CS\"!"); 00853 KMO_TRY_EXIT_IF_ERROR( 00854 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.imethod")); 00855 KMO_TRY_EXIT_IF_NULL( 00856 smethod = kmo_dfs_get_parameter_string(parlist, 00857 "kmos.kmo_sci_red.smethod")); 00858 KMO_TRY_ASSURE((strcmp(smethod, "NN") == 0) || 00859 (strcmp(smethod, "CS") == 0), CPL_ERROR_ILLEGAL_INPUT, 00860 "smethod must be either \"NN\" or \"CS\"!"); 00861 KMO_TRY_EXIT_IF_ERROR( 00862 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.smethod")); 00863 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00864 "kmos.kmo_sci_red.neighborhoodRange"); 00865 KMO_TRY_CHECK_ERROR_STATE(); 00866 KMO_TRY_ASSURE(neighborhoodRange > 0.0, CPL_ERROR_ILLEGAL_INPUT, 00867 "neighborhoodRange must be greater than 0.0"); 00868 KMO_TRY_EXIT_IF_ERROR( 00869 kmo_dfs_print_parameter_help(parlist, 00870 "kmos.kmo_sci_red.neighborhoodRange")); 00871 KMO_TRY_EXIT_IF_NULL( 00872 comb_method = kmo_dfs_get_parameter_string(parlist, 00873 "kmos.kmo_sci_red.method")); 00874 KMO_TRY_EXIT_IF_NULL( 00875 fmethod = kmo_dfs_get_parameter_string(parlist, 00876 "kmos.kmo_sci_red.fmethod")); 00877 KMO_TRY_ASSURE((strcmp(comb_method, "none") == 0) || 00878 (strcmp(comb_method, "header") == 0) || 00879 (strcmp(comb_method, "center") == 0) || 00880 (strcmp(comb_method, "user") == 0), CPL_ERROR_ILLEGAL_INPUT, 00881 "Following shift methods are available : 'none', 'header', 'center' or 'user'"); 00882 if (strcmp(comb_method, "user") == 0) { 00883 filename = kmo_dfs_get_parameter_string(parlist, 00884 "kmos.kmo_sci_red.filename"); 00885 KMO_TRY_CHECK_ERROR_STATE(); 00886 KMO_TRY_ASSURE(strcmp(filename, "") != 0, CPL_ERROR_ILLEGAL_INPUT, 00887 "path of file with shift information must be provided!"); 00888 KMO_TRY_EXIT_IF_ERROR( 00889 kmo_dfs_print_parameter_help(parlist, 00890 "kmos.kmo_sci_red.filename")); 00891 } 00892 KMO_TRY_EXIT_IF_ERROR( 00893 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.method")); 00894 00895 ifus_txt=kmo_dfs_get_parameter_string(parlist, "kmos.kmo_sci_red.ifus"); 00896 KMO_TRY_CHECK_ERROR_STATE(); 00897 name = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_sci_red.name"); 00898 KMO_TRY_CHECK_ERROR_STATE(); 00899 if (strcmp(ifus_txt, "") != 0) { 00900 KMO_TRY_ASSURE(strcmp(name, "") == 0, CPL_ERROR_ILLEGAL_INPUT, 00901 "name parameter must be NULL if IFU indices are provided!"); 00902 KMO_TRY_EXIT_IF_NULL(ifus = kmo_identify_values(ifus_txt)); 00903 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_science_frames, 00904 CPL_ERROR_ILLEGAL_INPUT, 00905 "ifus parameter must have the same number of values than" 00906 "frames provided (for frames just containing " 00907 "skies insert 0)) (%lld!=%d)", 00908 cpl_vector_get_size(ifus), nr_science_frames); 00909 } 00910 00911 if (strcmp(name, "") != 0) { 00912 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, CPL_ERROR_ILLEGAL_INPUT, 00913 "ifus parameter must be NULL if name is provided!"); 00914 } 00915 00916 KMO_TRY_EXIT_IF_ERROR( 00917 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.ifus")); 00918 00919 KMO_TRY_EXIT_IF_ERROR( 00920 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.name")); 00921 00922 kmos_band_pars_load(parlist, "kmos.kmo_sci_red"); 00923 00924 extrapolate = kmo_dfs_get_parameter_bool(parlist, 00925 "kmos.kmo_sci_red.extrapolate"); 00926 KMO_TRY_CHECK_ERROR_STATE(); 00927 00928 if (strcmp(smethod, "NN") == 0) { 00929 if (extrapolate == TRUE) { 00930 cpl_msg_warning(__func__, 00931 "extrapolation for smethod='NN' not available!"); 00932 } 00933 extrapol_enum = NONE_NANS; 00934 } else if (strcmp(smethod, "CS") == 0) { 00935 if (extrapolate == FALSE) { 00936 extrapol_enum = NONE_NANS; 00937 } else if (extrapolate == TRUE) { 00938 extrapol_enum = BCS_NATURAL; 00939 } else { 00940 KMO_TRY_ASSURE(1 == 0, CPL_ERROR_ILLEGAL_INPUT, 00941 "extrapolate must be either FALSE or TRUE"); 00942 } 00943 smethod = "BCS"; 00944 } else { 00945 KMO_TRY_ASSURE(1 == 0, CPL_ERROR_ILLEGAL_INPUT, 00946 "smethod must be either \"CS\" or \"NN\""); 00947 } 00948 KMO_TRY_CHECK_ERROR_STATE(); 00949 00950 KMO_TRY_EXIT_IF_ERROR( 00951 kmo_dfs_print_parameter_help(parlist, 00952 "kmos.kmo_sci_red.extrapolate")); 00953 00954 fast_mode = kmo_dfs_get_parameter_bool(parlist, 00955 "kmos.kmo_sci_red.fast_mode"); 00956 KMO_TRY_CHECK_ERROR_STATE(); 00957 KMO_TRY_ASSURE((fast_mode == TRUE) || (fast_mode == FALSE), 00958 CPL_ERROR_ILLEGAL_INPUT, "fast_mode is either FALSE or TRUE"); 00959 KMO_TRY_EXIT_IF_ERROR( 00960 kmo_dfs_print_parameter_help(parlist,"kmos.kmo_sci_red.fast_mode")); 00961 edge_nan = kmo_dfs_get_parameter_bool(parlist, 00962 "kmos.kmo_sci_red.edge_nan"); 00963 KMO_TRY_CHECK_ERROR_STATE(); 00964 KMO_TRY_EXIT_IF_ERROR( 00965 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.edge_nan")); 00966 KMO_TRY_ASSURE((edge_nan == TRUE) || (edge_nan == FALSE), 00967 CPL_ERROR_ILLEGAL_INPUT, "edge_nan must be TRUE or FALSE"); 00968 no_combine = kmo_dfs_get_parameter_bool(parlist, 00969 "kmos.kmo_sci_red.no_combine"); 00970 KMO_TRY_CHECK_ERROR_STATE(); 00971 KMO_TRY_EXIT_IF_ERROR( 00972 kmo_dfs_print_parameter_help(parlist, 00973 "kmos.kmo_sci_red.no_combine")); 00974 KMO_TRY_ASSURE((no_combine == TRUE) || (no_combine == FALSE), 00975 CPL_ERROR_ILLEGAL_INPUT, "no_combine must be TRUE or FALSE!"); 00976 no_subtract = kmo_dfs_get_parameter_bool(parlist, 00977 "kmos.kmo_sci_red.no_subtract"); 00978 KMO_TRY_CHECK_ERROR_STATE(); 00979 KMO_TRY_EXIT_IF_ERROR( 00980 kmo_dfs_print_parameter_help(parlist, 00981 "kmos.kmo_sci_red.no_subtract")); 00982 KMO_TRY_ASSURE((no_subtract == TRUE) || (no_subtract == FALSE), 00983 CPL_ERROR_ILLEGAL_INPUT, "no_subtract must be TRUE or FALSE"); 00984 sky_tweak = kmo_dfs_get_parameter_bool(parlist, 00985 "kmos.kmo_sci_red.sky_tweak"); 00986 KMO_TRY_CHECK_ERROR_STATE(); 00987 KMO_TRY_EXIT_IF_ERROR( 00988 kmo_dfs_print_parameter_help(parlist,"kmos.kmo_sci_red.sky_tweak")); 00989 KMO_TRY_ASSURE((sky_tweak == TRUE) || (sky_tweak == FALSE), 00990 CPL_ERROR_ILLEGAL_INPUT, "sky_tweak must be TRUE or FALSE"); 00991 KMO_TRY_ASSURE(!((no_subtract == TRUE) && (sky_tweak == TRUE)), 00992 CPL_ERROR_ILLEGAL_INPUT, 00993 "Either no_subtract or sky_tweak or both must be FALSE (try instead sky_tweak and save_interims)!"); 00994 tbsub = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_sci_red.tbsub"); 00995 KMO_TRY_CHECK_ERROR_STATE(); 00996 00997 pix_scale = kmo_dfs_get_parameter_double(parlist, 00998 "kmos.kmo_sci_red.pix_scale"); 00999 KMO_TRY_CHECK_ERROR_STATE(); 01000 KMO_TRY_EXIT_IF_ERROR( 01001 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.pix_scale")); 01002 KMO_TRY_ASSURE((pix_scale >= 0.01) && (pix_scale <= 0.4), 01003 CPL_ERROR_ILLEGAL_INPUT, 01004 "pix_scale must be between 0.01 and 0.4 (results in cubes " 01005 "with 7x7 to 280x280 pixels)!"); 01006 xcal_interpolation = kmo_dfs_get_parameter_bool(parlist, 01007 "kmos.kmo_sci_red.xcal_interpolation"); 01008 KMO_TRY_CHECK_ERROR_STATE(); 01009 KMO_TRY_EXIT_IF_ERROR( 01010 kmo_dfs_print_parameter_help(parlist, 01011 "kmos.kmo_sci_red.xcal_interpolation")); 01012 KMO_TRY_ASSURE((xcal_interpolation == TRUE) || 01013 (xcal_interpolation == FALSE), 01014 CPL_ERROR_ILLEGAL_INPUT, 01015 "xcal_interpolation must be TRUE or FALSE!"); 01016 suppress_extension = kmo_dfs_get_parameter_bool(parlist, 01017 "kmos.kmo_sci_red.suppress_extension"); 01018 KMO_TRY_CHECK_ERROR_STATE(); 01019 KMO_TRY_EXIT_IF_ERROR( 01020 kmo_dfs_print_parameter_help(parlist, 01021 "kmos.kmo_sci_red.suppress_extension")); 01022 KMO_TRY_ASSURE((suppress_extension == TRUE) || 01023 (suppress_extension == FALSE), 01024 CPL_ERROR_ILLEGAL_INPUT, 01025 "suppress_extension must be TRUE or FALSE!"); 01026 fn_obj_sky_table = kmo_dfs_get_parameter_string(parlist, 01027 "kmos.kmo_sci_red.obj_sky_table"); 01028 KMO_TRY_CHECK_ERROR_STATE(); 01029 KMO_TRY_EXIT_IF_ERROR( 01030 kmo_dfs_print_parameter_help(parlist, 01031 "kmos.kmo_sci_red.obj_sky_table")); 01032 KMO_TRY_EXIT_IF_ERROR( 01033 kmos_combine_pars_load(parlist, "kmos.kmo_sci_red", &cmethod, 01034 &cpos_rej, &cneg_rej, &citer, &cmin, &cmax, FALSE)); 01035 velo_offset = kmo_dfs_get_parameter_double(parlist, 01036 "kmos.kmo_sci_red.velocity_offset"); 01037 KMO_TRY_CHECK_ERROR_STATE(); 01038 01039 velo_corr = 1. + velo_offset * 1000. / CPL_PHYS_C; 01040 velo_corr_ptr = &velo_corr; 01041 KMO_TRY_EXIT_IF_ERROR( 01042 kmo_dfs_print_parameter_help(parlist, 01043 "kmos.kmo_sci_red.velocity_offset")); 01044 save_interims = kmo_dfs_get_parameter_bool(parlist, 01045 "kmos.kmo_sci_red.save_interims"); 01046 KMO_TRY_CHECK_ERROR_STATE(); 01047 KMO_TRY_ASSURE((save_interims == TRUE) || (save_interims == FALSE), 01048 CPL_ERROR_ILLEGAL_INPUT, "save_interims must be TRUE or FALSE"); 01049 KMO_TRY_ASSURE(!((save_interims == TRUE) && (sky_tweak == FALSE)), 01050 CPL_ERROR_ILLEGAL_INPUT, 01051 "Save_interims saves sky_tweak objects so sky_tweak must be enabled too"); 01052 KMO_TRY_EXIT_IF_ERROR( 01053 kmo_dfs_print_parameter_help(parlist, 01054 "kmos.kmo_sci_red.save_interims")); 01055 cpl_msg_info("", "-------------------------------------------"); 01056 01057 // assure that filters, grating and rotation offsets match for 01058 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 01059 // frames) 01060 /* Check if filter_id and grating_id match for all detectors */ 01061 KMO_TRY_EXIT_IF_ERROR( 01062 kmo_check_frameset_setup(frameset, SCIENCE, TRUE, FALSE, TRUE)); 01063 KMO_TRY_EXIT_IF_ERROR( 01064 kmo_check_frame_setup(frameset, SCIENCE, YCAL, TRUE, FALSE, TRUE)); 01065 KMO_TRY_EXIT_IF_ERROR( 01066 kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE)); 01067 KMO_TRY_EXIT_IF_ERROR( 01068 kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE)); 01069 if (has_master_flat) { 01070 KMO_TRY_EXIT_IF_ERROR(kmo_check_frame_setup(frameset, XCAL, 01071 MASTER_FLAT, TRUE, FALSE, TRUE)); 01072 } 01073 if (has_telluric) { 01074 KMO_TRY_EXIT_IF_ERROR(kmo_check_frame_setup(frameset, XCAL, 01075 TELLURIC, TRUE, FALSE, TRUE)); 01076 } 01077 if (has_oh_spec) { 01078 KMO_TRY_EXIT_IF_ERROR(kmo_check_oh_spec_setup(frameset, XCAL)); 01079 } 01080 01081 // check descriptors of all frames 01082 KMO_TRY_EXIT_IF_NULL(xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 01083 01084 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 01085 KMO_TRY_CHECK_ERROR_STATE(); 01086 01087 KMO_TRY_ASSURE((desc1.nr_ext % KMOS_NR_DETECTORS == 0) && 01088 (desc1.ex_badpix == FALSE) && 01089 (desc1.fits_type == f2d_fits) && 01090 (desc1.frame_type == detector_frame), 01091 CPL_ERROR_ILLEGAL_INPUT, 01092 "XCAL isn't in the correct format!!!"); 01093 01094 KMO_TRY_EXIT_IF_NULL(ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 01095 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 01096 KMO_TRY_CHECK_ERROR_STATE(); 01097 01098 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 01099 (desc1.ex_badpix == desc2.ex_badpix) && 01100 (desc1.fits_type == desc2.fits_type) && 01101 (desc1.frame_type == desc2.frame_type), 01102 CPL_ERROR_ILLEGAL_INPUT, 01103 "YCAL isn't in the correct format!!!"); 01104 kmo_free_fits_desc(&desc2); 01105 kmo_init_fits_desc(&desc2); 01106 01107 KMO_TRY_EXIT_IF_NULL(lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 01108 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 01109 KMO_TRY_CHECK_ERROR_STATE(); 01110 01111 KMO_TRY_ASSURE((desc2.nr_ext % KMOS_NR_DETECTORS == 0) && 01112 (desc1.ex_badpix == desc2.ex_badpix) && 01113 (desc1.fits_type == desc2.fits_type) && 01114 (desc1.frame_type == desc2.frame_type), 01115 CPL_ERROR_ILLEGAL_INPUT, 01116 "LCAL isn't in the correct format!!!"); 01117 kmo_free_fits_desc(&desc2); 01118 kmo_init_fits_desc(&desc2); 01119 01120 if (has_master_flat) { 01121 KMO_TRY_EXIT_IF_NULL(flat_frame = kmo_dfs_get_frame(frameset, 01122 MASTER_FLAT)); 01123 desc2=kmo_identify_fits_header(cpl_frame_get_filename(flat_frame)); 01124 KMO_TRY_CHECK_ERROR_STATE(); 01125 01126 KMO_TRY_ASSURE((desc2.nr_ext % (2*KMOS_NR_DETECTORS) == 0) && 01127 (desc1.ex_badpix == desc2.ex_badpix) && 01128 (desc1.fits_type == desc2.fits_type) && 01129 (desc1.frame_type == desc2.frame_type), 01130 CPL_ERROR_ILLEGAL_INPUT, 01131 "MASTER_FLAT isn't in the correct format!!!"); 01132 kmo_free_fits_desc(&desc2); 01133 kmo_init_fits_desc(&desc2); 01134 } 01135 01136 if (has_illum_corr) { 01137 KMO_TRY_EXIT_IF_NULL(illum_frame = kmo_dfs_get_frame(frameset, 01138 ILLUM_CORR)); 01139 desc2=kmo_identify_fits_header(cpl_frame_get_filename(illum_frame)); 01140 KMO_TRY_CHECK_ERROR_STATE(); 01141 KMO_TRY_ASSURE(((desc2.nr_ext == 24) || (desc2.nr_ext == 48)) && 01142 (desc2.ex_badpix == FALSE) && 01143 (desc2.fits_type == f2i_fits) && 01144 (desc2.frame_type == ifu_frame), 01145 CPL_ERROR_ILLEGAL_INPUT, 01146 "ILLUM_CORR isn't in the correct format!!!"); 01147 kmo_free_fits_desc(&desc2); 01148 kmo_init_fits_desc(&desc2); 01149 } 01150 01151 if (has_telluric) { 01152 KMO_TRY_EXIT_IF_NULL(telluric_frame = kmo_dfs_get_frame(frameset, 01153 TELLURIC)); 01154 desc_telluric=kmo_identify_fits_header( 01155 cpl_frame_get_filename(telluric_frame)); 01156 KMO_TRY_CHECK_ERROR_STATE(); 01157 KMO_TRY_ASSURE(((desc_telluric.nr_ext == 24) || 01158 (desc_telluric.nr_ext == 48)) && 01159 (desc_telluric.ex_badpix == FALSE) && 01160 (desc_telluric.fits_type == f1i_fits) && 01161 (desc_telluric.frame_type == ifu_frame), 01162 CPL_ERROR_ILLEGAL_INPUT, 01163 "TELLURIC isn't in the correct format!!!"); 01164 } 01165 kmo_free_fits_desc(&desc2); 01166 01167 KMO_TRY_EXIT_IF_NULL(tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 01168 while (tmp_frame != NULL ) { 01169 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01170 KMO_TRY_CHECK_ERROR_STATE(); 01171 KMO_TRY_ASSURE((desc2.nr_ext == 3) && 01172 (desc2.ex_badpix == FALSE) && 01173 (desc2.fits_type == raw_fits) && 01174 (desc2.frame_type == detector_frame), 01175 CPL_ERROR_ILLEGAL_INPUT, 01176 "SCIENCE isn't in the correct format"); 01177 kmo_free_fits_desc(&desc2); 01178 kmo_init_fits_desc(&desc2); 01179 01180 if (mapping_mode == NULL) { 01181 KMO_TRY_EXIT_IF_NULL( 01182 tmp_header = kmclipm_propertylist_load( 01183 cpl_frame_get_filename(tmp_frame), 0)); 01184 if (cpl_propertylist_has(tmp_header, TPL_ID)) { 01185 KMO_TRY_EXIT_IF_NULL(tmp_str = 01186 cpl_propertylist_get_string(tmp_header, TPL_ID)); 01187 if (strcmp(tmp_str, MAPPING8) == 0) { 01188 mapping_mode = cpl_sprintf("%s", "mapping8"); 01189 } 01190 if (strcmp(tmp_str, MAPPING24) == 0) { 01191 mapping_mode = cpl_sprintf("%s", "mapping24"); 01192 } 01193 } 01194 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01195 } 01196 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01197 KMO_TRY_CHECK_ERROR_STATE(); 01198 } 01199 01200 if (mapping_mode != NULL) { 01201 // we are in mapping mode 01202 if ((ifus != NULL) || (strcmp(name, "") != 0)) { 01203 cpl_msg_warning(__func__, 01204 "The SCIENCE frames have been taken in one of the " 01205 "mapping modes AND specific IFUs have been " 01206 "specified! --> Only processing these!"); 01207 } else { 01208 if (strcmp(smethod, "BCS") == 0) { 01209 extrapol_enum = BCS_NATURAL; 01210 cpl_msg_info(__func__, 01211 "Detected frames taken in mapping mode. " 01212 "Changing extrapolation mode to TRUE."); 01213 } 01214 } 01215 if (fast_mode) { 01216 cpl_msg_info(__func__, "Creating map in fast_mode."); 01217 } 01218 } else { 01219 if (fast_mode) { 01220 cpl_msg_info(__func__, 01221 "fast_mode has been selected but we aren't in " 01222 "mapping mode. The choice for fast_mode is ignored."); 01223 } 01224 } 01225 01226 KMO_TRY_EXIT_IF_NULL( 01227 suffix = kmo_dfs_get_suffix(xcal_frame, TRUE, FALSE)); 01228 01229 /* Verify that XCAL / YCAL were generated together */ 01230 KMO_TRY_EXIT_IF_ERROR(kmo_check_frame_setup_md5_xycal(frameset)); 01231 /* Verify that XCAL and YCAL / LCAL were generated together */ 01232 KMO_TRY_EXIT_IF_ERROR(kmo_check_frame_setup_md5(frameset)); 01233 /* b_start/b_end/b_samples used for LCAL and TELLURIC were the same */ 01234 KMO_TRY_EXIT_IF_ERROR(kmo_check_frame_setup_sampling(frameset)); 01235 01236 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 01237 cpl_msg_info("", "(grating 1, 2 & 3)"); 01238 01239 /* Check which IFUs are active for all frames */ 01240 KMO_TRY_EXIT_IF_NULL(unused_ifus_before = 01241 kmo_get_unused_ifus(frameset, 1, 1)); 01242 KMO_TRY_EXIT_IF_NULL(unused_ifus_after = 01243 kmo_duplicate_unused_ifus(unused_ifus_before)); 01244 kmo_print_unused_ifus(unused_ifus_before, FALSE); 01245 01246 /* Get bounds, setup grid, setup arm_name-struct */ 01247 /* Get left and right bounds of IFUs from XCAL */ 01248 KMO_TRY_EXIT_IF_NULL( 01249 tmp_header = kmo_dfs_load_primary_header(frameset, XCAL)); 01250 KMO_TRY_EXIT_IF_NULL(bounds = kmclipm_extract_bounds(tmp_header)); 01251 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01252 01253 /* Setup grid definition, wavelength start and end points will be */ 01254 /* set in the detector loop */ 01255 KMO_TRY_EXIT_IF_ERROR( 01256 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale, 0.)); 01257 01258 /* 01259 Create armNameStruct : Contains info about objects that need 01260 to be reconstructed and for each of them which sky need to be used 01261 Get valid STD frames with objects in it and associated sky 01262 exposures and get valid object names to process, either one object 01263 name across several SCIENCE frames, or all object names 01264 */ 01265 if (strcmp(fn_obj_sky_table, "") == 0) { 01266 KMO_TRY_EXIT_IF_NULL( 01267 arm_name_struct = kmo_create_armNameStruct(frameset, SCIENCE, 01268 ifus, name, unused_ifus_after, bounds, mapping_mode, 01269 no_subtract)); 01270 KMO_TRY_EXIT_IF_ERROR( 01271 kmo_save_objSkyStruct(arm_name_struct->obj_sky_struct)); 01272 } else { 01273 // read in obj/sky-table 01274 objSkyStruct *obj_sky_struct = NULL; 01275 01276 KMO_TRY_EXIT_IF_NULL( 01277 obj_sky_struct = kmo_read_objSkyStruct(fn_obj_sky_table, 01278 frameset, SCIENCE)); 01279 01280 /* Check if any sky-IFUs have been specified not beeing the */ 01281 /* same IFU# for objects. */ 01282 // In this case sky_tweak must be activated 01283 for (i = 0; i < obj_sky_struct->size; i++) { 01284 if (obj_sky_struct->table[i].objFrame != NULL) { 01285 for (jj = 0; jj < KMOS_NR_IFUS; jj++) { 01286 if ((obj_sky_struct->table[i].skyIfus[jj] > 0) && 01287 (sky_tweak == FALSE)) { 01288 kmo_print_objSkyStruct(obj_sky_struct); 01289 01290 cpl_msg_error("","*************************************************************************"); 01291 cpl_msg_error("","* The provided obj/sky-association-table (parameter --obj_sky_table) *"); 01292 cpl_msg_error("","* contains skies assigned to objects originating from different IFUs! *"); 01293 cpl_msg_error("","* In this case the parameter --sky_tweak has to be set by the user! *"); 01294 cpl_msg_error("","*************************************************************************"); 01295 01296 kmo_delete_objSkyStruct(obj_sky_struct); 01297 KMO_TRY_ASSURE(1 == 0, CPL_ERROR_ILLEGAL_INPUT," "); 01298 } 01299 } 01300 } 01301 } 01302 01303 KMO_TRY_EXIT_IF_NULL( 01304 arm_name_struct = kmo_create_armNameStruct2(obj_sky_struct, 01305 frameset, SCIENCE, ifus, name, unused_ifus_after, bounds, 01306 mapping_mode, no_subtract)); 01307 } 01308 kmo_print_armNameStruct(frameset, arm_name_struct); 01309 01310 /* Check Telluric availability for each Object */ 01311 /* Why only mapping ? Not clear */ 01312 /* in mapping-mode check if for all IFUs there is either no */ 01313 /* telluric at all or the same number of tellurics than object names */ 01314 if ((has_telluric) && (mapping_mode != NULL)) { 01315 telluric_ok = TRUE; 01316 for (jj = 0; jj < arm_name_struct->nrNames; jj++) { 01317 if (!((arm_name_struct->telluricCnt[jj] == arm_name_struct->namesCnt[jj]) || 01318 (arm_name_struct->telluricCnt[jj] == 0))) { 01319 telluric_ok = FALSE; 01320 break; 01321 } 01322 } 01323 if (!telluric_ok) { 01324 KMO_TRY_ASSURE(1==0, CPL_ERROR_UNSUPPORTED_MODE, 01325 "Mosaics need a TELLURIC frame with at least a telluric correction per detector available! " 01326 "Omit the TELLURIC from your sof-file or choose another TELLURIC!"); 01327 } 01328 } 01329 01330 /* Load lcal-frames */ 01331 KMO_TRY_EXIT_IF_NULL(lcal = (cpl_image**)cpl_calloc(KMOS_NR_DETECTORS, 01332 sizeof(cpl_image*))); 01333 for (i = 0; i < KMOS_NR_DETECTORS; i++) { 01334 KMO_TRY_EXIT_IF_NULL(lcal[i] = kmo_dfs_load_image(frameset, LCAL, 01335 i+1, FALSE, FALSE, NULL)); 01336 } 01337 01338 nr_data_alloc = KMOS_NR_IFUS; 01339 KMO_TRY_EXIT_IF_NULL(cube_data = (cpl_imagelist**)cpl_calloc( 01340 nr_data_alloc, sizeof(cpl_imagelist*))); 01341 KMO_TRY_EXIT_IF_NULL(cube_noise = (cpl_imagelist**)cpl_calloc( 01342 nr_data_alloc, sizeof(cpl_imagelist*))); 01343 KMO_TRY_EXIT_IF_NULL(header_data = (cpl_propertylist**)cpl_calloc( 01344 nr_data_alloc, sizeof(cpl_propertylist*))); 01345 KMO_TRY_EXIT_IF_NULL(header_noise = (cpl_propertylist**)cpl_calloc( 01346 nr_data_alloc, sizeof(cpl_propertylist*))); 01347 01348 if (save_interims) { 01349 KMO_TRY_EXIT_IF_NULL(cube_interim_object=(cpl_imagelist**)cpl_calloc( 01350 nr_data_alloc, sizeof(cpl_imagelist*))); 01351 KMO_TRY_EXIT_IF_NULL(cube_interim_sky =(cpl_imagelist**)cpl_calloc( 01352 nr_data_alloc, sizeof(cpl_imagelist*))); 01353 KMO_TRY_EXIT_IF_NULL(header_sky = (cpl_propertylist**)cpl_calloc( 01354 nr_data_alloc, sizeof(cpl_propertylist*))); 01355 } 01356 01357 if (cpl_frameset_count_tags(frameset, SCIENCE) == 1) { 01358 no_combine = TRUE; 01359 cpl_msg_info(__func__, 01360 "--no_combine set to TRUE since there is 1 SCIENCE frame"); 01361 } 01362 01363 if (no_subtract) { 01364 no_combine = TRUE; 01365 cpl_msg_info(__func__, 01366 "--no_combine set to TRUE since --no_subtract is set"); 01367 } 01368 actual_msg_level = cpl_msg_get_level(); 01369 cpl_msg_info("", "-------------------------------------------"); 01370 01371 /* Check if input SCIENCE frames are really ALL observations */ 01372 /* If not, Omit the OH_SPEC, even if it is passed - issue a Warning */ 01373 if (has_oh_spec) { 01374 int is_all_obs = TRUE, 01375 has_all_origfile = TRUE; 01376 01377 KMO_TRY_EXIT_IF_NULL( 01378 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 01379 while (tmp_frame != NULL ) { 01380 KMO_TRY_EXIT_IF_NULL(tmp_header = kmclipm_propertylist_load( 01381 cpl_frame_get_filename(tmp_frame), 0)); 01382 if (cpl_propertylist_has(tmp_header, ORIGFILE)) { 01383 KMO_TRY_EXIT_IF_NULL(tmp_str = 01384 cpl_propertylist_get_string(tmp_header, ORIGFILE)); 01385 if (strstr(tmp_str, "OBS") == NULL) { 01386 is_all_obs = FALSE; 01387 } 01388 } else { 01389 has_all_origfile = FALSE; 01390 } 01391 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01392 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01393 KMO_TRY_CHECK_ERROR_STATE(); 01394 } 01395 01396 if (has_all_origfile) { 01397 if (is_all_obs) { 01398 /* OBS-frame reconstruction - allow OH_SPEC */ 01399 KMO_TRY_EXIT_IF_NULL(ref_spectrum_frame = 01400 kmo_dfs_get_frame(frameset, OH_SPEC)); 01401 01402 /* Verify OH_SPEC */ 01403 /* TODO */ 01404 01405 } else { 01406 cpl_msg_warning(__func__, 01407 "Supplied OH_SPEC is ignored since a calibration " 01408 "frame is being used as SCIENCE frame."); 01409 } 01410 } else { 01411 cpl_msg_warning(__func__, 01412 "Supplied OH_SPEC is ignored since a calibration " 01413 "frame is being used as SCIENCE frame."); 01414 } 01415 } 01416 01417 /* Loop all science frames containing at least one object */ 01418 cpl_msg_info(__func__, "Reconstructing & saving cubes with objects"); 01419 for (sf = 0; sf < arm_name_struct->size; sf++) { 01420 KMO_TRY_EXIT_IF_NULL(fn_obj = cpl_frame_get_filename( 01421 arm_name_struct->obj_sky_struct->table[sf].objFrame)); 01422 KMO_TRY_EXIT_IF_NULL( 01423 main_header = kmclipm_propertylist_load(fn_obj, 0)); 01424 actual_msg_level = cpl_msg_get_level(); 01425 01426 /* Reconstruct science frame */ 01427 cpl_msg_info(__func__, " > processing frame: %s", fn_obj); 01428 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01429 sky_ifu_nr = ifu_nr; 01430 det_nr = (ifu_nr - 1)/KMOS_IFUS_PER_DETECTOR + 1; 01431 01432 KMO_TRY_ASSURE((det_nr >= 1) && (det_nr <= KMOS_NR_DETECTORS), 01433 CPL_ERROR_ILLEGAL_INPUT, 01434 "The provided ifu-numbers are incorrect! They " 01435 "must be between 1 and %d", KMOS_NR_IFUS); 01436 01437 /* Get subheader data */ 01438 KMO_TRY_EXIT_IF_NULL(header_data[ifu_nr-1] = 01439 kmclipm_propertylist_load(fn_obj, det_nr)); 01440 KMO_TRY_EXIT_IF_NULL(extname = kmo_extname_creator(ifu_frame, 01441 ifu_nr, EXT_DATA)); 01442 KMO_TRY_EXIT_IF_ERROR(kmclipm_update_property_string( 01443 header_data[ifu_nr-1], EXTNAME, extname, 01444 "FITS extension name")); 01445 cpl_free(extname); extname = NULL; 01446 01447 if (arm_name_struct->name_ids[ifu_nr-1+sf*KMOS_NR_IFUS] >= 1) { 01448 // IFU is valid 01449 01450 /* Fill do_sky_subtraction and sky_frame */ 01451 if ((arm_name_struct->obj_sky_struct->table[sf].skyFrames[ifu_nr-1] != NO_CORRESPONDING_SKYFRAME) && !no_subtract) { 01452 do_sky_subtraction = TRUE; 01453 if (no_subtract) { 01454 sky_frame = NULL; 01455 } else { 01456 sky_frame = arm_name_struct->obj_sky_struct->table[sf].skyFrames[ifu_nr-1]; 01457 KMO_TRY_EXIT_IF_NULL( 01458 fn_sky = cpl_frame_get_filename(sky_frame)); 01459 } 01460 01461 if (sky_tweak){ 01462 sky_as_object_frame = sky_frame; 01463 sky_frame = NULL; 01464 /* printf("a - %d\n", sky_ifu_nr) ; */ 01465 sky_ifu_nr = arm_name_struct->obj_sky_struct->table[sf].skyIfus[ifu_nr-1]; 01466 /* printf("b - %d\n", sky_ifu_nr) ; */ 01467 } 01468 01469 if (no_subtract) { 01470 cpl_msg_warning(__func__, 01471 " > Omit sky subtraction on IFU %d", 01472 ifu_nr); 01473 } else { 01474 if (sky_ifu_nr == ifu_nr) { 01475 cpl_msg_info(__func__, 01476 " > IFU %d (sky in frame: %s)", 01477 ifu_nr, fn_sky); 01478 } else { 01479 cpl_msg_info(__func__, 01480 " > IFU %d (sky in IFU %d of frame: %s)", 01481 ifu_nr, sky_ifu_nr, fn_sky); 01482 } 01483 } 01484 } else { 01485 do_sky_subtraction = FALSE; 01486 sky_frame = NULL; 01487 if (!no_subtract) { 01488 cpl_msg_warning(__func__, 01489 " > IFU %d with no corresponding sky frame", 01490 ifu_nr); 01491 } 01492 } 01493 01494 /* Get filter for this detector and setup grid definition using WAVE_BAND */ 01495 KMO_TRY_EXIT_IF_NULL(keyword = cpl_sprintf("%s%d%s", 01496 IFU_FILTID_PREFIX, det_nr, IFU_FILTID_POSTFIX)); 01497 KMO_TRY_EXIT_IF_NULL(filter_id = 01498 cpl_propertylist_get_string(main_header, keyword)); 01499 cpl_free(keyword); keyword = NULL; 01500 01501 /* TODO : Review print_once mechanism */ 01502 /* Used to print once per detector - problematic for parallelisation */ 01503 if (print_once) cpl_msg_set_level(CPL_MSG_WARNING); 01504 01505 KMO_TRY_EXIT_IF_NULL(band_table = kmo_dfs_load_table( 01506 frameset, WAVE_BAND, 1, 0)); 01507 KMO_TRY_EXIT_IF_ERROR(kmclipm_setup_grid_band_lcal(&gd, 01508 filter_id, band_table)); 01509 cpl_table_delete(band_table); band_table = NULL; 01510 01511 print_once = TRUE; 01512 cpl_msg_set_level(actual_msg_level); 01513 01514 /* calc WCS & update subheader */ 01515 KMO_TRY_EXIT_IF_ERROR(kmo_calc_wcs_gd(main_header, 01516 header_data[ifu_nr-1], ifu_nr, gd)); 01517 01518 /* Update some keywords */ 01519 KMO_TRY_EXIT_IF_ERROR( 01520 kmclipm_update_property_int(header_data[ifu_nr-1], 01521 NAXIS, 3, "number of data axes")); 01522 KMO_TRY_EXIT_IF_ERROR( 01523 kmclipm_update_property_int(header_data[ifu_nr-1], 01524 NAXIS1, gd.x.dim, "length of data axis 1")); 01525 KMO_TRY_EXIT_IF_ERROR( 01526 kmclipm_update_property_int(header_data[ifu_nr-1], 01527 NAXIS2, gd.y.dim, "length of data axis 2")); 01528 KMO_TRY_EXIT_IF_ERROR( 01529 kmclipm_update_property_int(header_data[ifu_nr-1], 01530 NAXIS3, gd.l.dim, "length of data axis 3")); 01531 01532 /* Option save_interim only applies if sky_tweak is used */ 01533 if (save_interims && (sky_as_object_frame != NULL)) { 01534 KMO_TRY_EXIT_IF_NULL( 01535 main_sky_header = kmclipm_propertylist_load( 01536 cpl_frame_get_filename( 01537 sky_as_object_frame), 0)); 01538 KMO_TRY_EXIT_IF_NULL( 01539 header_sky[ifu_nr-1]=kmclipm_propertylist_load( 01540 cpl_frame_get_filename( 01541 sky_as_object_frame), det_nr)); 01542 KMO_TRY_EXIT_IF_NULL(extname = kmo_extname_creator( 01543 ifu_frame, ifu_nr, EXT_DATA)); 01544 KMO_TRY_EXIT_IF_ERROR( 01545 kmclipm_update_property_string( 01546 header_sky[ifu_nr-1], EXTNAME, extname, 01547 "FITS extension name")); 01548 cpl_free(extname); extname = NULL; 01549 01550 KMO_TRY_EXIT_IF_ERROR(kmo_calc_wcs_gd(main_sky_header, 01551 header_sky[ifu_nr-1], ifu_nr, gd)); 01552 01553 KMO_TRY_EXIT_IF_ERROR(kmclipm_update_property_int( 01554 header_sky[ifu_nr-1], NAXIS, 3, 01555 "number of data axes")); 01556 KMO_TRY_EXIT_IF_ERROR(kmclipm_update_property_int( 01557 header_sky[ifu_nr-1], NAXIS1, gd.x.dim, 01558 "length of data axis 1")); 01559 KMO_TRY_EXIT_IF_ERROR(kmclipm_update_property_int( 01560 header_sky[ifu_nr-1], NAXIS2, gd.y.dim, 01561 "length of data axis 2")); 01562 KMO_TRY_EXIT_IF_ERROR(kmclipm_update_property_int( 01563 header_sky[ifu_nr-1], NAXIS3, gd.l.dim, 01564 "length of data axis 3")); 01565 cpl_propertylist_delete(main_sky_header); 01566 main_sky_header = NULL; 01567 } 01568 01569 /* Reconstruct object */ 01570 if (ref_spectrum_frame == NULL) { 01571 /* No lambda correction using OH lines */ 01572 KMO_TRY_EXIT_IF_ERROR( 01573 kmo_reconstruct_sci( 01574 ifu_nr, 01575 bounds[2*(ifu_nr-1)], 01576 bounds[2*(ifu_nr-1)+1], 01577 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01578 SCIENCE, 01579 sky_frame, 01580 SCIENCE, 01581 flat_frame, 01582 xcal_frame, 01583 ycal_frame, 01584 lcal_frame, 01585 NULL, 01586 velo_corr_ptr, 01587 &gd, 01588 &cube_data[ifu_nr-1], 01589 &cube_noise[ifu_nr-1], 01590 flux, 01591 background, 01592 xcal_interpolation)); 01593 } else { 01594 /* Lambda correction using OH lines */ 01595 KMO_TRY_EXIT_IF_ERROR( 01596 kmo_reconstruct_sci( 01597 ifu_nr, 01598 bounds[2*(ifu_nr-1)], 01599 bounds[2*(ifu_nr-1)+1], 01600 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01601 SCIENCE, 01602 NULL, 01603 NULL, 01604 flat_frame, 01605 xcal_frame, 01606 ycal_frame, 01607 lcal_frame, 01608 NULL, 01609 NULL, 01610 &gd, 01611 &cube_data[ifu_nr-1], 01612 &cube_noise[ifu_nr-1], 01613 FALSE, 01614 FALSE, 01615 xcal_interpolation)); 01616 if (cube_data[ifu_nr-1] != NULL) { 01617 KMO_TRY_EXIT_IF_NULL( 01618 oh_lcorr_coeffs = kmo_lcorr_get( 01619 cube_data[ifu_nr-1], header_data[ifu_nr-1], 01620 ref_spectrum_frame, gd, filter_id, ifu_nr)); 01621 cpl_imagelist_delete(cube_data[ifu_nr-1]); 01622 cube_data[ifu_nr-1] = NULL; 01623 if (cube_noise[ifu_nr-1] != NULL) { 01624 cpl_imagelist_delete(cube_noise[ifu_nr-1]); 01625 cube_noise[ifu_nr-1] = NULL; 01626 } 01627 01628 KMO_TRY_EXIT_IF_ERROR( 01629 kmo_reconstruct_sci( 01630 ifu_nr, 01631 bounds[2*(ifu_nr-1)], 01632 bounds[2*(ifu_nr-1)+1], 01633 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01634 SCIENCE, 01635 sky_frame, 01636 SCIENCE, 01637 flat_frame, 01638 xcal_frame, 01639 ycal_frame, 01640 lcal_frame, 01641 oh_lcorr_coeffs, 01642 velo_corr_ptr, 01643 &gd, 01644 &cube_data[ifu_nr-1], 01645 &cube_noise[ifu_nr-1], 01646 flux, 01647 background, 01648 xcal_interpolation)); 01649 cpl_polynomial_delete(oh_lcorr_coeffs); 01650 oh_lcorr_coeffs = NULL; 01651 } 01652 } 01653 01654 /* If sky_tweak is set,reconstruct sky frame as object */ 01655 /* and use kmo_priv_sky_tweak to subtract */ 01656 /* a modified sky cube */ 01657 if (do_sky_subtraction && sky_tweak) { 01658 if (ref_spectrum_frame == NULL) { 01659 /* No lambda correction using OH lines */ 01660 KMO_TRY_EXIT_IF_ERROR( 01661 kmo_reconstruct_sci( 01662 sky_ifu_nr, 01663 bounds[2*(sky_ifu_nr-1)], 01664 bounds[2*(sky_ifu_nr-1)+1], 01665 sky_as_object_frame, 01666 SCIENCE, 01667 sky_frame, 01668 SCIENCE, 01669 flat_frame, 01670 xcal_frame, 01671 ycal_frame, 01672 lcal_frame, 01673 NULL, 01674 velo_corr_ptr, 01675 &gd, 01676 &sky_data, 01677 &sky_noise, 01678 flux, 01679 background, 01680 xcal_interpolation)); 01681 } else { 01682 /* Lambda correction using OH lines */ 01683 KMO_TRY_EXIT_IF_ERROR( 01684 kmo_reconstruct_sci( 01685 sky_ifu_nr, 01686 bounds[2*(sky_ifu_nr-1)], 01687 bounds[2*(sky_ifu_nr-1)+1], 01688 sky_as_object_frame, 01689 SCIENCE, 01690 NULL, 01691 NULL, 01692 flat_frame, 01693 xcal_frame, 01694 ycal_frame, 01695 lcal_frame, 01696 NULL, 01697 NULL, 01698 &gd, 01699 &sky_data, 01700 &sky_noise, 01701 FALSE, 01702 FALSE, 01703 xcal_interpolation)); 01704 if (sky_data != NULL) { 01705 KMO_TRY_EXIT_IF_NULL( 01706 oh_lcorr_coeffs = kmo_lcorr_get(sky_data, 01707 header_data[ifu_nr-1], 01708 ref_spectrum_frame, gd, filter_id, 01709 ifu_nr)); 01710 cpl_imagelist_delete(sky_data); sky_data = NULL; 01711 if (sky_noise != NULL) { 01712 cpl_imagelist_delete(sky_noise); 01713 sky_noise = NULL; 01714 } 01715 KMO_TRY_EXIT_IF_ERROR( 01716 kmo_reconstruct_sci( 01717 sky_ifu_nr, 01718 bounds[2*(sky_ifu_nr-1)], 01719 bounds[2*(sky_ifu_nr-1)+1], 01720 sky_as_object_frame, 01721 SCIENCE, 01722 sky_frame, 01723 SCIENCE, 01724 flat_frame, 01725 xcal_frame, 01726 ycal_frame, 01727 lcal_frame, 01728 oh_lcorr_coeffs, 01729 velo_corr_ptr, 01730 &gd, 01731 &sky_data, 01732 &sky_noise, 01733 flux, 01734 background, 01735 xcal_interpolation)); 01736 cpl_polynomial_delete(oh_lcorr_coeffs); 01737 oh_lcorr_coeffs = NULL; 01738 } 01739 } // end if (ref_spectrum_frame == NULL) 01740 01741 if (save_interims && (sky_as_object_frame != NULL)) { 01742 KMO_TRY_EXIT_IF_NULL(cube_interim_object[ifu_nr-1]= 01743 cpl_imagelist_duplicate(cube_data[ifu_nr-1])); 01744 KMO_TRY_EXIT_IF_NULL(cube_interim_sky[ifu_nr-1]= 01745 cpl_imagelist_duplicate(sky_data)); 01746 } 01747 01748 cpl_imagelist *tmp_object_cube = cube_data[ifu_nr-1]; 01749 KMO_TRY_EXIT_IF_NULL(cube_data[ifu_nr-1] = 01750 kmo_priv_sky_tweak (tmp_object_cube, sky_data, 01751 header_data[ifu_nr-1], .3, tbsub, ifu_nr)); 01752 if (tmp_object_cube != NULL) { 01753 cpl_imagelist_delete(tmp_object_cube); 01754 tmp_object_cube = NULL; 01755 } 01756 if (sky_data != NULL) { 01757 cpl_imagelist_delete(sky_data); sky_data = NULL; 01758 } 01759 if (sky_noise != NULL) { 01760 cpl_imagelist_delete(sky_noise); sky_noise = NULL; 01761 } 01762 } // end if (do_sky_subtraction && sky_tweak) 01763 01764 /* Maintain flux constant in case the pixscale is diff */ 01765 /* For example, pixscale=0.1 => images 28x28 => scaling=4 */ 01766 KMO_TRY_EXIT_IF_NULL( 01767 tmpImg = cpl_imagelist_get(cube_data[ifu_nr-1], 0)); 01768 double scaling = (cpl_image_get_size_x(tmpImg)* 01769 cpl_image_get_size_y(tmpImg)) / 01770 (KMOS_SLITLET_X*KMOS_SLITLET_Y); 01771 KMO_TRY_EXIT_IF_ERROR( 01772 cpl_imagelist_divide_scalar(cube_data[ifu_nr-1], 01773 scaling)); 01774 if (cube_noise[ifu_nr-1] != NULL) { 01775 KMO_TRY_EXIT_IF_ERROR( 01776 cpl_imagelist_divide_scalar(cube_noise[ifu_nr-1], 01777 scaling)); 01778 } 01779 01780 if (mapping_mode == NULL) { 01781 /* Get object name */ 01782 KMO_TRY_EXIT_IF_NULL(keyword = cpl_sprintf("%s%d%s", 01783 IFU_NAME_PREFIX, ifu_nr, IFU_NAME_POSTFIX)); 01784 KMO_TRY_EXIT_IF_NULL(tmp_str = cpl_propertylist_get_string( 01785 header_data[ifu_nr-1], keyword)); 01786 cpl_free(keyword); keyword = NULL; 01787 } else { 01788 tmp_str = mapping_mode; 01789 } 01790 01791 /* Divide cube by telluric correction */ 01792 if (has_telluric) { 01793 /* Check if the nb of occurences of the object name */ 01794 /* is the same as the number of found tellurics for */ 01795 /* this object (which can be on different arms) */ 01796 telluric_ok = FALSE; 01797 for (jj = 0; jj < arm_name_struct->nrNames; jj++) { 01798 if (((strcmp(arm_name_struct->names[jj], tmp_str) == 0) || 01799 (strcmp(arm_name_struct->names[jj], IFUS_USER_DEFINED) == 0)) && 01800 (arm_name_struct->telluricCnt[jj] == arm_name_struct->namesCnt[jj])) { 01801 telluric_ok = TRUE; 01802 break; 01803 } 01804 } 01805 01806 if (telluric_ok) { 01807 telluric_data = kmo_tweak_load_telluric(frameset, 01808 ifu_nr, FALSE, no_subtract); 01809 KMO_TRY_CHECK_ERROR_STATE(); 01810 if (telluric_data != NULL) { 01811 /* Get the index of the telluric noise */ 01812 index = kmo_identify_index_desc(desc_telluric, 01813 ifu_nr, TRUE); 01814 KMO_TRY_CHECK_ERROR_STATE(); 01815 if (desc_telluric.sub_desc[index-1].valid_data 01816 == TRUE) { 01817 // load noise if present 01818 telluric_noise = kmo_tweak_load_telluric( 01819 frameset,ifu_nr, TRUE, no_subtract); 01820 KMO_TRY_CHECK_ERROR_STATE(); 01821 } else { 01822 if (print_warning_once_tweak_std_noise && 01823 (cube_noise[ifu_nr-1] != NULL)) { 01824 cpl_msg_warning(__func__,"************************************************************"); 01825 cpl_msg_warning(__func__,"* Noise cubes were calculated, but won't be divided by *"); 01826 cpl_msg_warning(__func__,"* telluric error since it is missing. *"); 01827 cpl_msg_warning(__func__,"* In order to get a telluric with errors, execute *"); 01828 cpl_msg_warning(__func__,"* kmo_std_star with one of the nearest neighbour methods *"); 01829 cpl_msg_warning(__func__,"* (set --imethod to NN, lwNN or swNN) *"); 01830 cpl_msg_warning(__func__,"************************************************************"); 01831 print_warning_once_tweak_std_noise = 01832 FALSE; 01833 } 01834 } 01835 01836 KMO_TRY_EXIT_IF_ERROR(kmo_arithmetic_3D_1D( 01837 cube_data[ifu_nr-1], telluric_data, 01838 cube_noise[ifu_nr-1], 01839 telluric_noise, "/")); 01840 } 01841 } 01842 } 01843 01844 /* Divide cube by illumination correction */ 01845 if (has_illum_corr) { 01846 illum_data = kmo_dfs_load_image(frameset, ILLUM_CORR, 01847 ifu_nr, FALSE, FALSE, NULL); 01848 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01849 cpl_msg_warning(__func__, 01850 "No illumination correction for IFU %d available! " 01851 "Proceeding anyway.", ifu_nr); 01852 cpl_error_reset(); 01853 } else { 01854 illum_noise = kmo_dfs_load_image(frameset, 01855 ILLUM_CORR, ifu_nr, TRUE, FALSE, NULL); 01856 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01857 cpl_msg_warning(__func__, 01858 "No illumination correction for IFU %d available! " 01859 "Proceeding anyway.", ifu_nr); 01860 cpl_image_delete(illum_data); illum_data = NULL; 01861 cpl_error_reset(); 01862 } 01863 } 01864 01865 if (illum_data != NULL) { 01866 KMO_TRY_EXIT_IF_ERROR( 01867 kmo_arithmetic_3D_2D(cube_data[ifu_nr-1], 01868 illum_data, cube_noise[ifu_nr-1], 01869 illum_noise, "/")); 01870 cpl_image_delete(illum_data); illum_data = NULL; 01871 cpl_image_delete(illum_noise); illum_noise = NULL; 01872 } 01873 } 01874 01875 kmclipm_vector_delete(telluric_data); telluric_data = NULL; 01876 kmclipm_vector_delete(telluric_noise);telluric_noise= NULL; 01877 } else { 01878 // IFU is invalid 01879 } 01880 01881 // duplicate subheader data 01882 KMO_TRY_EXIT_IF_NULL(header_noise[ifu_nr-1] = 01883 cpl_propertylist_duplicate(header_data[ifu_nr-1])); 01884 KMO_TRY_EXIT_IF_NULL(extname = kmo_extname_creator(ifu_frame, 01885 ifu_nr, EXT_NOISE)); 01886 KMO_TRY_EXIT_IF_ERROR(kmclipm_update_property_string( 01887 header_noise[ifu_nr-1], EXTNAME, extname, 01888 "FITS extension name")); 01889 cpl_free(extname); extname = NULL; 01890 } // end for ifu_nr 01891 01892 /* Count number of reconstructed data- and noise-cubes */ 01893 for (ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 01894 if (cube_data[ifu_nr-1] != NULL) cube_counter_data++; 01895 if (cube_noise[ifu_nr-1] != NULL) cube_counter_noise++; 01896 } 01897 01898 /* Save reconstructed cubes of science frame */ 01899 if (cube_counter_data > 0) { 01900 cpl_msg_info(__func__, " > saving..."); 01901 01902 if (!suppress_extension) { 01903 fn_out = fn_obj; 01904 01905 int nr_found = 0; 01906 // remove any path-elements from filename and use it as 01907 // suffix 01908 split = kmo_strsplit(fn_out, "/", &nr_found); 01909 01910 fn_suffix = cpl_sprintf("_%s", split[nr_found-1]); 01911 kmo_strfreev(split); 01912 01913 // remove '.fits' at the end if there is any 01914 char *fff = fn_suffix; 01915 fff += strlen(fn_suffix)-5; 01916 if (strcmp(fff, ".fits") == 0) { 01917 fn_suffix[strlen(fn_suffix)-5] = '\0'; 01918 } 01919 } else { 01920 KMO_TRY_EXIT_IF_NULL( 01921 fn_suffix = cpl_sprintf("_%d", suppress_index++)); 01922 } 01923 01924 fn_out = RECONSTRUCTED_CUBE; 01925 fn_interim_object = INTERIM_OBJECT_CUBE; 01926 fn_interim_sky = INTERIM_OBJECT_SKY; 01927 01928 /* Create Primary Header */ 01929 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_main_header(frameset, 01930 fn_out, fn_suffix, 01931 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01932 NULL, parlist, cpl_func)); 01933 /* save intermediate products (only in sky tweak case) */ 01934 if (save_interims && (sky_as_object_frame != NULL)) { 01935 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_main_header(frameset, 01936 fn_interim_object, fn_suffix, 01937 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01938 NULL, parlist, cpl_func)); 01939 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_main_header(frameset, 01940 fn_interim_sky, fn_suffix, 01941 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01942 NULL, parlist, cpl_func)); 01943 } 01944 01945 /* Loop on IFUs */ 01946 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01947 /* Save data Extension */ 01948 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_cube(cube_data[ifu_nr-1], 01949 fn_out,fn_suffix,header_data[ifu_nr-1], 0./0.)); 01950 01951 /* Save noise Extension */ 01952 if (cube_counter_noise > 0) { 01953 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_cube( 01954 cube_noise[ifu_nr-1], fn_out, fn_suffix, 01955 header_noise[ifu_nr-1], 0./0.)); 01956 } 01957 01958 /* save intermediate products (only in sky tweak case */ 01959 if (save_interims && (sky_as_object_frame != NULL)) { 01960 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_cube( 01961 cube_interim_object[ifu_nr-1], 01962 fn_interim_object, fn_suffix, 01963 header_data[ifu_nr-1], 0./0.)); 01964 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_cube( 01965 cube_interim_sky[ifu_nr-1], fn_interim_sky, 01966 fn_suffix, header_sky[ifu_nr-1], 0./0.)); 01967 } 01968 01969 cpl_imagelist_delete(cube_data[ifu_nr-1]); 01970 cube_data[ifu_nr-1] = NULL; 01971 cpl_imagelist_delete(cube_noise[ifu_nr-1]); 01972 cube_noise[ifu_nr-1] = NULL; 01973 cpl_propertylist_delete(header_data[ifu_nr-1]); 01974 header_data[ifu_nr-1] = NULL; 01975 cpl_propertylist_delete(header_noise[ifu_nr-1]); 01976 header_noise[ifu_nr-1] = NULL; 01977 if (save_interims) { 01978 cpl_imagelist_delete(cube_interim_object[ifu_nr-1]); 01979 cube_interim_object[ifu_nr-1] = NULL; 01980 cpl_imagelist_delete(cube_interim_sky[ifu_nr-1]); 01981 cube_interim_sky[ifu_nr-1] = NULL; 01982 cpl_propertylist_delete(header_sky[ifu_nr-1]); 01983 header_sky[ifu_nr-1] = NULL; 01984 } 01985 } // end for ifu_nr 01986 cpl_free(fn_suffix); fn_suffix = NULL; 01987 } else { 01988 cpl_msg_info(__func__, " > all IFUs invalid, don't save"); 01989 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01990 cpl_propertylist_delete(header_data[ifu_nr-1]); 01991 header_data[ifu_nr-1] = NULL; 01992 cpl_propertylist_delete(header_noise[ifu_nr-1]); 01993 header_noise[ifu_nr-1] = NULL; 01994 } 01995 } // if (cube_counter_data > 0) { 01996 01997 cpl_propertylist_delete(main_header); main_header = NULL; 01998 } // end for sf (arm_name_struct->obj_sky_struct->size) 01999 cpl_free(cube_data); cube_data = NULL; 02000 cpl_free(cube_noise); cube_noise = NULL; 02001 cpl_free(header_data); header_data = NULL; 02002 cpl_free(header_noise); header_noise = NULL; 02003 if (save_interims) { 02004 cpl_free(cube_interim_object); cube_interim_object = NULL; 02005 cpl_free(cube_interim_sky); cube_interim_sky = NULL; 02006 cpl_free(header_sky); header_sky = NULL; 02007 } 02008 02009 kmo_print_unused_ifus(unused_ifus_after, TRUE); 02010 02011 cpl_msg_info("", "-------------------------------------------"); 02012 02013 if (lcal != NULL) { 02014 for (i = 0; i < KMOS_NR_DETECTORS; i++) { 02015 cpl_image_delete(lcal[i]); 02016 } 02017 } 02018 cpl_free(lcal); lcal = NULL; 02019 02020 /* Combine */ 02021 suppress_index = 0; 02022 if (!no_combine) { 02023 cpl_msg_info(__func__, "Combining reconstructed objects"); 02024 nr_reconstructed_frames = cpl_frameset_count_tags(frameset, 02025 RECONSTRUCTED_CUBE); 02026 if ((mapping_mode == NULL) || ((mapping_mode != NULL) && 02027 ((ifus != NULL) || (strcmp(name, "") != 0)))) { 02028 // loop all available objects 02029 for (i = 0; i < arm_name_struct->nrNames; i++) { 02030 cpl_msg_info(__func__, 02031 " > object: %s", arm_name_struct->names[i]); 02032 nr_data_alloc = arm_name_struct->namesCnt[i]; 02033 KMO_TRY_EXIT_IF_NULL(cube_data=(cpl_imagelist**)cpl_calloc( 02034 nr_data_alloc, sizeof(cpl_imagelist*))); 02035 KMO_TRY_EXIT_IF_NULL(cube_noise=(cpl_imagelist**)cpl_calloc( 02036 nr_data_alloc, sizeof(cpl_imagelist*))); 02037 KMO_TRY_EXIT_IF_NULL(header_data= 02038 (cpl_propertylist**)cpl_calloc(nr_data_alloc, 02039 sizeof(cpl_propertylist*))); 02040 KMO_TRY_EXIT_IF_NULL(header_noise= 02041 (cpl_propertylist**)cpl_calloc(nr_data_alloc, 02042 sizeof(cpl_propertylist*))); 02043 02044 // setup cube-list and header-list for kmo_priv_combine() 02045 cube_counter_data = 0; 02046 cube_counter_noise = 0; 02047 KMO_TRY_EXIT_IF_NULL(tmp_frame = kmo_dfs_get_frame(frameset, 02048 RECONSTRUCTED_CUBE)); 02049 while (tmp_frame != NULL ) { 02050 KMO_TRY_EXIT_IF_NULL( 02051 fn_reconstr = cpl_frame_get_filename(tmp_frame)); 02052 KMO_TRY_EXIT_IF_NULL(tmp_header = 02053 kmclipm_propertylist_load(fn_reconstr, 0)); 02054 kmo_free_fits_desc(&desc1); 02055 kmo_init_fits_desc(&desc1); 02056 desc1 = kmo_identify_fits_header(fn_reconstr); 02057 02058 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 02059 // check if object-name equals the one in our list 02060 KMO_TRY_EXIT_IF_NULL(keyword = cpl_sprintf("%s%d%s", 02061 IFU_NAME_PREFIX, ifu_nr, 02062 IFU_NAME_POSTFIX)); 02063 KMO_TRY_EXIT_IF_NULL(tmp_str = 02064 cpl_propertylist_get_string(tmp_header, 02065 keyword)); 02066 cpl_free(keyword); keyword = NULL; 02067 02068 if ((strcmp(arm_name_struct->names[i],tmp_str)==0) 02069 || (strcmp(arm_name_struct->names[i], 02070 IFUS_USER_DEFINED) == 0)) { 02071 // found object-IFU with matching name 02072 // load data & subheader 02073 index = kmo_identify_index(fn_reconstr, ifu_nr, 02074 FALSE); 02075 KMO_TRY_CHECK_ERROR_STATE(); 02076 02077 if (desc1.sub_desc[index-1].valid_data) { 02078 KMO_TRY_EXIT_IF_NULL( 02079 cube_data[cube_counter_data] = 02080 kmclipm_imagelist_load(fn_reconstr, 02081 CPL_TYPE_FLOAT, index)); 02082 /* Set cubes borders (1 pixel) to Nan to avoid jumps in combined cube */ 02083 if (edge_nan) { 02084 KMO_TRY_EXIT_IF_ERROR(kmo_edge_nan( 02085 cube_data[cube_counter_data], 02086 ifu_nr)); 02087 } 02088 02089 KMO_TRY_EXIT_IF_NULL( 02090 header_data[cube_counter_data] = 02091 kmclipm_propertylist_load( 02092 fn_reconstr, index)); 02093 cpl_propertylist_update_string( 02094 header_data[cube_counter_data], 02095 "ESO PRO FRNAME", fn_reconstr); 02096 cpl_propertylist_update_int( 02097 header_data[cube_counter_data], 02098 "ESO PRO IFUNR", ifu_nr); 02099 cube_counter_data++; 02100 } 02101 02102 // load noise & subheader (if existing) 02103 if (desc1.ex_noise) { 02104 index = kmo_identify_index(fn_reconstr, 02105 ifu_nr, TRUE); 02106 KMO_TRY_CHECK_ERROR_STATE(); 02107 02108 if (desc1.sub_desc[index-1].valid_data) { 02109 KMO_TRY_EXIT_IF_NULL( 02110 cube_noise[cube_counter_noise] = 02111 kmclipm_imagelist_load( 02112 fn_reconstr, CPL_TYPE_FLOAT, 02113 index)); 02114 if (edge_nan) { 02115 KMO_TRY_EXIT_IF_ERROR( 02116 kmo_edge_nan(cube_noise[cube_counter_noise], ifu_nr)); 02117 } 02118 KMO_TRY_EXIT_IF_NULL( 02119 header_noise[cube_counter_noise] = 02120 kmclipm_propertylist_load( 02121 fn_reconstr, index)); 02122 cube_counter_noise++; 02123 } 02124 } 02125 cpl_error_reset(); 02126 } // end if found obj 02127 } // end for ifu_nr 02128 02129 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 02130 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 02131 KMO_TRY_CHECK_ERROR_STATE(); 02132 } // end while-loop RECONSTRUCTED_CUBE frames 02133 02134 if (cube_counter_data > 1) { 02135 if (cube_counter_data == cube_counter_noise) { 02136 KMO_TRY_EXIT_IF_ERROR( 02137 kmo_priv_combine(cube_data, 02138 cube_noise, 02139 header_data, 02140 header_noise, 02141 cube_counter_data, 02142 cube_counter_noise, 02143 arm_name_struct->names[i], 02144 "", 02145 comb_method, 02146 smethod, 02147 fmethod, 02148 filename, 02149 cmethod, 02150 cpos_rej, 02151 cneg_rej, 02152 citer, 02153 cmin, 02154 cmax, 02155 extrapol_enum, 02156 flux, 02157 &combined_data, 02158 &combined_noise, 02159 &exp_mask)); 02160 } else if (cube_counter_noise == 0) { 02161 KMO_TRY_EXIT_IF_ERROR( 02162 kmo_priv_combine(cube_data, 02163 NULL, 02164 header_data, 02165 header_noise, 02166 cube_counter_data, 02167 cube_counter_noise, 02168 arm_name_struct->names[i], 02169 "", 02170 comb_method, 02171 smethod, 02172 fmethod, 02173 filename, 02174 cmethod, 02175 cpos_rej, 02176 cneg_rej, 02177 citer, 02178 cmin, 02179 cmax, 02180 extrapol_enum, 02181 flux, 02182 &combined_data, 02183 &combined_noise, 02184 &exp_mask)); 02185 } else { 02186 KMO_TRY_ASSURE(1 == 0, CPL_ERROR_ILLEGAL_INPUT, 02187 "The number of cube-data and cube-noise " 02188 "isn't the same (%d vs. %d)!", 02189 cube_counter_data, cube_counter_noise); 02190 } 02191 } else if (cube_counter_data == 1) { 02192 cpl_msg_warning(__func__, 02193 "There is only one reconstructed cube with " 02194 "this object! Saving it as it is."); 02195 KMO_TRY_EXIT_IF_NULL(combined_data = 02196 cpl_imagelist_duplicate(cube_data[0])); 02197 KMO_TRY_EXIT_IF_NULL(tmpImg = 02198 cpl_imagelist_get(combined_data, 0)); 02199 KMO_TRY_EXIT_IF_NULL(exp_mask = cpl_image_new( 02200 cpl_image_get_size_x(tmpImg), 02201 cpl_image_get_size_y(tmpImg), 02202 CPL_TYPE_FLOAT)); 02203 KMO_TRY_EXIT_IF_ERROR(kmo_image_fill(exp_mask, 1.)); 02204 02205 if (cube_noise[0] != NULL) { 02206 KMO_TRY_EXIT_IF_NULL( 02207 combined_noise = cpl_imagelist_duplicate( 02208 cube_noise[0])); 02209 } 02210 } else { 02211 KMO_TRY_ASSURE(1==0, CPL_ERROR_ILLEGAL_INPUT, 02212 "No cubes found with this object name!"); 02213 } // end if (cube_counter_data > 1) 02214 02215 fn_out = COMBINED_CUBE; 02216 fn_out_mask = EXP_MASK; 02217 if (!suppress_extension) { 02218 char tmp_suffix[1024]; 02219 tmp_suffix[0] = '\0'; 02220 02221 if (arm_name_struct->telluricCnt[i] == 02222 arm_name_struct->namesCnt[i]) { 02223 strcat(tmp_suffix, "_telluric"); 02224 } 02225 if (has_illum_corr) strcat(tmp_suffix, "_illum"); 02226 if (sky_tweak) strcat(tmp_suffix, "_skytweak"); 02227 02228 if (strlen(tmp_suffix) > 0) { 02229 KMO_TRY_EXIT_IF_NULL( 02230 fn_suffix = cpl_sprintf("_%s_%s", 02231 arm_name_struct->names[i], tmp_suffix)); 02232 } else { 02233 KMO_TRY_EXIT_IF_NULL( 02234 fn_suffix = cpl_sprintf("_%s", 02235 arm_name_struct->names[i])); 02236 } 02237 } else { 02238 KMO_TRY_EXIT_IF_NULL( 02239 fn_suffix = cpl_sprintf("_%d", suppress_index++)); 02240 } 02241 02242 // save combined cube 02243 KMO_TRY_EXIT_IF_NULL(tmp_frame = 02244 kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 02245 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_main_header(frameset, 02246 fn_out, fn_suffix, tmp_frame, NULL, parlist, 02247 cpl_func)); 02248 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_main_header(frameset, 02249 fn_out_mask, fn_suffix, tmp_frame, NULL, 02250 parlist, cpl_func)); 02251 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_cube(combined_data, 02252 fn_out, fn_suffix, header_data[0], 0./0.)); 02253 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_image(exp_mask, 02254 fn_out_mask, fn_suffix, header_data[0], 0./0.)); 02255 02256 if (header_noise[0] == NULL) { 02257 KMO_TRY_EXIT_IF_NULL(header_noise[0] = 02258 cpl_propertylist_duplicate(header_data[0])); 02259 02260 KMO_TRY_EXIT_IF_NULL(tmp_str = 02261 cpl_propertylist_get_string(header_data[0], 02262 EXTNAME)); 02263 KMO_TRY_EXIT_IF_ERROR(kmo_extname_extractor(tmp_str, 02264 &ft, &tmp_int, content)); 02265 KMO_TRY_EXIT_IF_NULL(extname = kmo_extname_creator( 02266 ifu_frame, tmp_int, EXT_NOISE)); 02267 KMO_TRY_EXIT_IF_ERROR(kmclipm_update_property_string( 02268 header_noise[0], EXTNAME, extname, 02269 "FITS extension name")); 02270 cpl_free(extname); extname = NULL; 02271 } 02272 KMO_TRY_EXIT_IF_ERROR(kmo_dfs_save_cube(combined_noise, 02273 fn_out, fn_suffix, header_noise[0], 0./0.)); 02274 02275 for (jj = 0; jj < nr_data_alloc; jj++) { 02276 cpl_imagelist_delete(cube_data[jj]); 02277 cube_data[jj] = NULL; 02278 cpl_imagelist_delete(cube_noise[jj]); 02279 cube_noise[jj] = NULL; 02280 cpl_propertylist_delete(header_data[jj]); 02281 header_data[jj] = NULL; 02282 cpl_propertylist_delete(header_noise[jj]); 02283 header_noise[jj] = NULL; 02284 } 02285 cpl_free(cube_data); cube_data = NULL; 02286 cpl_free(cube_noise); cube_noise = NULL; 02287 cpl_free(header_data); header_data = NULL; 02288 cpl_free(header_noise); header_noise = NULL; 02289 cpl_free(fn_suffix); fn_suffix = NULL; 02290 cpl_imagelist_delete(combined_data); combined_data = NULL; 02291 cpl_imagelist_delete(combined_noise); combined_noise = NULL; 02292 cpl_image_delete(exp_mask); exp_mask = NULL; 02293 } // for i = nr_avail_obj_names 02294 } else { 02295 // we are in mapping_mode 02296 nr_data_alloc = nr_reconstructed_frames*KMOS_NR_IFUS; 02297 KMO_TRY_EXIT_IF_NULL(cube_data = (cpl_imagelist**)cpl_calloc( 02298 nr_data_alloc, sizeof(cpl_imagelist*))); 02299 KMO_TRY_EXIT_IF_NULL(cube_noise = (cpl_imagelist**)cpl_calloc( 02300 nr_data_alloc, sizeof(cpl_imagelist*))); 02301 KMO_TRY_EXIT_IF_NULL(header_data=(cpl_propertylist**)cpl_calloc( 02302 nr_data_alloc, sizeof(cpl_propertylist*))); 02303 KMO_TRY_EXIT_IF_NULL(header_noise=(cpl_propertylist**)cpl_calloc( 02304 nr_data_alloc, sizeof(cpl_propertylist*))); 02305 02306 cube_counter_data = 0; 02307 cube_counter_noise = 0; 02308 KMO_TRY_EXIT_IF_NULL(tmp_frame = 02309 kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 02310 while (tmp_frame != NULL ) { 02311 KMO_TRY_EXIT_IF_NULL( 02312 fn_reconstr = cpl_frame_get_filename(tmp_frame)); 02313 KMO_TRY_EXIT_IF_NULL( 02314 tmp_header = kmclipm_propertylist_load(fn_reconstr, 0)); 02315 02316 kmo_free_fits_desc(&desc1); 02317 kmo_init_fits_desc(&desc1); 02318 desc1 = kmo_identify_fits_header(fn_reconstr); 02319 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 02320 index = kmo_identify_index(fn_reconstr, ifu_nr, FALSE); 02321 KMO_TRY_CHECK_ERROR_STATE(); 02322 02323 if (desc1.sub_desc[index-1].valid_data) { 02324 KMO_TRY_EXIT_IF_NULL(cube_data[cube_counter_data] = 02325 kmclipm_imagelist_load(fn_reconstr, 02326 CPL_TYPE_FLOAT, index)); 02327 if (edge_nan) { 02328 KMO_TRY_EXIT_IF_ERROR( 02329 kmo_edge_nan(cube_data[cube_counter_data], 02330 ifu_nr)); 02331 } 02332 02333 if (fast_mode) { 02334 KMO_TRY_EXIT_IF_NULL(tmpImg = 02335 cpl_imagelist_collapse_median_create( 02336 cube_data[cube_counter_data])); 02337 KMO_TRY_EXIT_IF_NULL( 02338 tmpCube = cpl_imagelist_new()); 02339 KMO_TRY_EXIT_IF_ERROR( 02340 cpl_imagelist_set(tmpCube, tmpImg, 0)); 02341 cpl_imagelist_delete(cube_data[cube_counter_data]); 02342 cube_data[cube_counter_data] = tmpCube; 02343 } 02344 02345 KMO_TRY_EXIT_IF_NULL( 02346 header_data[cube_counter_data] = 02347 kmclipm_propertylist_load(fn_reconstr, index)); 02348 cpl_propertylist_update_string( 02349 header_data[cube_counter_data], 02350 "ESO PRO FRNAME", fn_reconstr); 02351 cpl_propertylist_update_int( 02352 header_data[cube_counter_data], 02353 "ESO PRO IFUNR", ifu_nr); 02354 cube_counter_data++; 02355 } 02356 02357 // load noise & subheader (if existing) 02358 if (desc1.ex_noise) { 02359 index = kmo_identify_index(fn_reconstr,ifu_nr,TRUE); 02360 KMO_TRY_CHECK_ERROR_STATE(); 02361 if (desc1.sub_desc[index-1].valid_data) { 02362 KMO_TRY_EXIT_IF_NULL( 02363 cube_noise[cube_counter_noise] = 02364 kmclipm_imagelist_load(fn_reconstr, 02365 CPL_TYPE_FLOAT, index)); 02366 02367 if (edge_nan) { 02368 KMO_TRY_EXIT_IF_ERROR(kmo_edge_nan( 02369 cube_noise[cube_counter_noise], 02370 ifu_nr)); 02371 } 02372 02373 if (fast_mode) { 02374 KMO_TRY_EXIT_IF_NULL(tmpImg = 02375 cpl_imagelist_collapse_median_create(cube_noise[cube_counter_noise])); 02376 KMO_TRY_EXIT_IF_NULL( 02377 tmpCube = cpl_imagelist_new()); 02378 KMO_TRY_EXIT_IF_ERROR( 02379 cpl_imagelist_set(tmpCube, tmpImg, 0)); 02380 cpl_imagelist_delete(cube_noise[cube_counter_noise]); 02381 cube_noise[cube_counter_noise] = tmpCube; 02382 } 02383 KMO_TRY_EXIT_IF_NULL( 02384 header_noise[cube_counter_noise] = 02385 kmclipm_propertylist_load(fn_reconstr, 02386 index)); 02387 cube_counter_noise++; 02388 } 02389 } 02390 cpl_error_reset(); 02391 } // end for ifu_nr 02392 02393 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 02394 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 02395 KMO_TRY_CHECK_ERROR_STATE(); 02396 } // end while-loop RECONSTRUCTED_CUBE frames 02397 02398 if (cube_counter_data > 1) { 02399 if (cube_counter_data == cube_counter_noise) { 02400 KMO_TRY_EXIT_IF_ERROR( 02401 kmo_priv_combine(cube_data, 02402 cube_noise, 02403 header_data, 02404 header_noise, 02405 cube_counter_data, 02406 cube_counter_noise, 02407 mapping_mode, 02408 "", 02409 comb_method, 02410 smethod, 02411 fmethod, 02412 filename, 02413 cmethod, 02414 cpos_rej, 02415 cneg_rej, 02416 citer, 02417 cmin, 02418 cmax, 02419 extrapol_enum, 02420 flux, 02421 &combined_data, 02422 &combined_noise, 02423 NULL)); 02424 } else if (cube_counter_noise == 0) { 02425 KMO_TRY_EXIT_IF_ERROR( 02426 kmo_priv_combine(cube_data, 02427 NULL, 02428 header_data, 02429 header_noise, 02430 cube_counter_data, 02431 cube_counter_noise, 02432 mapping_mode, 02433 "", 02434 comb_method, 02435 smethod, 02436 fmethod, 02437 filename, 02438 cmethod, 02439 cpos_rej, 02440 cneg_rej, 02441 citer, 02442 cmin, 02443 cmax, 02444 extrapol_enum, 02445 flux, 02446 &combined_data, 02447 &combined_noise, 02448 NULL)); 02449 } else { 02450 KMO_TRY_ASSURE(1 == 0, CPL_ERROR_ILLEGAL_INPUT, 02451 "The number of cube-data and cube-noise " 02452 "isn't the same (%d vs. %d)!", 02453 cube_counter_data, cube_counter_noise); 02454 } 02455 } else { 02456 cpl_msg_warning(__func__, 02457 "There is only one reconstructed cube - Save it"); 02458 KMO_TRY_EXIT_IF_NULL( 02459 combined_data = cpl_imagelist_duplicate(cube_data[0])); 02460 02461 if (cube_noise[0] != NULL) { 02462 KMO_TRY_EXIT_IF_NULL( 02463 combined_noise = cpl_imagelist_duplicate( 02464 cube_noise[0])); 02465 } 02466 } 02467 02468 fn_out = COMBINED_CUBE; 02469 KMO_TRY_EXIT_IF_NULL( 02470 fn_suffix = cpl_sprintf("_%s", mapping_mode)); 02471 02472 // save combined cube 02473 KMO_TRY_EXIT_IF_NULL(tmp_frame = kmo_dfs_get_frame(frameset, 02474 RECONSTRUCTED_CUBE)); 02475 KMO_TRY_EXIT_IF_ERROR( 02476 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, 02477 tmp_frame, NULL, parlist, cpl_func)); 02478 02479 KMO_TRY_EXIT_IF_ERROR( 02480 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, 02481 header_data[0], 0./0.)); 02482 02483 if (header_noise[0] == NULL) { 02484 KMO_TRY_EXIT_IF_NULL( 02485 header_noise[0] = 02486 cpl_propertylist_duplicate(header_data[0])); 02487 02488 KMO_TRY_EXIT_IF_NULL( 02489 tmp_str = cpl_propertylist_get_string(header_data[0], 02490 EXTNAME)); 02491 KMO_TRY_EXIT_IF_ERROR( 02492 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content)); 02493 KMO_TRY_EXIT_IF_NULL( 02494 extname = kmo_extname_creator(ifu_frame, tmp_int, 02495 EXT_NOISE)); 02496 KMO_TRY_EXIT_IF_ERROR( 02497 kmclipm_update_property_string(header_noise[0], EXTNAME, 02498 extname, "FITS extension name")); 02499 cpl_free(extname); extname = NULL; 02500 } 02501 KMO_TRY_EXIT_IF_ERROR( 02502 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix, 02503 header_noise[0], 0./0.)); 02504 02505 for (i = 0; i < nr_data_alloc; i++) { 02506 cpl_imagelist_delete(cube_data[i]); cube_data[i] = NULL; 02507 cpl_imagelist_delete(cube_noise[i]); cube_noise[i] = NULL; 02508 cpl_propertylist_delete(header_data[i]); 02509 header_data[i] = NULL; 02510 cpl_propertylist_delete(header_noise[i]); 02511 header_noise[i] = NULL; 02512 } 02513 cpl_free(cube_data); cube_data = NULL; 02514 cpl_free(cube_noise); cube_noise = NULL; 02515 cpl_free(header_data); header_data = NULL; 02516 cpl_free(header_noise); header_noise = NULL; 02517 cpl_free(fn_suffix); fn_suffix = NULL; 02518 cpl_imagelist_delete(combined_data); combined_data = NULL; 02519 cpl_imagelist_delete(combined_noise); combined_noise = NULL; 02520 } // if mapping_mode 02521 } else { 02522 cpl_msg_info("", "Reconstructed objects are not combined"); 02523 } // if (!no_combine) 02524 cpl_msg_info("", "-------------------------------------------"); 02525 } 02526 KMO_CATCH 02527 { 02528 KMO_CATCH_MSG(); 02529 ret_val = -1; 02530 } 02531 if (cube_data != NULL) { 02532 for (ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02533 cpl_imagelist_delete(cube_data[ifu_nr-1]); 02534 cube_data[ifu_nr-1] = NULL; 02535 } 02536 } 02537 cpl_free(cube_data); cube_data = NULL; 02538 if (cube_noise != NULL) { 02539 for (ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02540 cpl_imagelist_delete(cube_noise[ifu_nr-1]); 02541 cube_noise[ifu_nr-1] = NULL; 02542 } 02543 } 02544 cpl_free(cube_noise); cube_noise = NULL; 02545 if (header_data != NULL) { 02546 for (ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02547 cpl_propertylist_delete(header_data[ifu_nr-1]); 02548 header_data[ifu_nr-1] = NULL; 02549 } 02550 } 02551 cpl_free(header_data); header_data = NULL; 02552 if (header_noise != NULL) { 02553 for (ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02554 cpl_propertylist_delete(header_noise[ifu_nr-1]); 02555 header_noise[ifu_nr-1] = NULL; 02556 } 02557 } 02558 cpl_free(header_noise); header_noise = NULL; 02559 02560 02561 kmo_free_fits_desc(&desc1); 02562 kmo_free_fits_desc(&desc2); 02563 kmo_free_fits_desc(&desc_telluric); 02564 02565 cpl_vector_delete(ifus); ifus = NULL; 02566 cpl_free(mapping_mode); mapping_mode = NULL; 02567 if (unused_ifus_before != NULL) { 02568 kmo_free_unused_ifus(unused_ifus_before); unused_ifus_before = NULL; 02569 } 02570 if (unused_ifus_after != NULL) { 02571 kmo_free_unused_ifus(unused_ifus_after); unused_ifus_after = NULL; 02572 } 02573 if (bounds != NULL) { 02574 cpl_free(bounds); bounds = NULL; 02575 } 02576 02577 // frees for the case of errors 02578 kmclipm_vector_delete(telluric_data); telluric_data = NULL; 02579 kmclipm_vector_delete(telluric_noise); telluric_noise = NULL; 02580 cpl_image_delete(illum_data); illum_data = NULL; 02581 cpl_image_delete(illum_noise); illum_noise = NULL; 02582 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 02583 cpl_table_delete(band_table); band_table = NULL; 02584 cpl_propertylist_delete(main_header); main_header = NULL; 02585 if (lcal != NULL) { 02586 for (i = 0; i < KMOS_NR_DETECTORS; i++) { 02587 cpl_image_delete(lcal[i]); 02588 } 02589 } 02590 cpl_free(lcal); lcal = NULL; 02591 cpl_free(fn_suffix); fn_suffix = NULL; 02592 cpl_free(suffix); suffix = NULL; 02593 02594 kmo_delete_armNameStruct(arm_name_struct); 02595 02596 return ret_val; 02597 } 02598
1.7.6.1