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