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