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