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