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