|
KMOS Pipeline Reference Manual
1.1.3
|
00001 /* $Id: kmo_sci_red.c,v 1.58 2013/05/13 13:20:27 aagudo Exp $ 00002 * 00003 * This file is part of the KMOS Pipeline 00004 * Copyright (C) 2002,2003 European Southern Observatory 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 */ 00020 00021 /* 00022 * $Author: aagudo $ 00023 * $Date: 2013/05/13 13:20:27 $ 00024 * $Revision: 1.58 $ 00025 * $Name: HEAD $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 * Includes 00034 *----------------------------------------------------------------------------*/ 00035 #include <string.h> 00036 #include <math.h> 00037 00038 #include <cpl.h> 00039 #include "kmclipm_constants.h" 00040 #include "kmclipm_functions.h" 00041 00042 #include "kmo_debug.h" 00043 #include "kmo_constants.h" 00044 #include "kmo_utils.h" 00045 #include "kmo_error.h" 00046 #include "kmo_dfs.h" 00047 #include "kmo_functions.h" 00048 #include "kmo_priv_arithmetic.h" 00049 #include "kmo_priv_combine.h" 00050 #include "kmo_priv_functions.h" 00051 #include "kmo_priv_reconstruct.h" 00052 #include "kmo_priv_std_star.h" 00053 00054 /*----------------------------------------------------------------------------- 00055 * Types 00056 *-----------------------------------------------------------------------------*/ 00057 typedef struct { 00058 char *name; 00059 int count; 00060 } allObjStruct; 00061 00062 /*----------------------------------------------------------------------------- 00063 * Functions prototypes 00064 *----------------------------------------------------------------------------*/ 00065 00066 static int kmo_sci_red_create(cpl_plugin *); 00067 static int kmo_sci_red_exec(cpl_plugin *); 00068 static int kmo_sci_red_destroy(cpl_plugin *); 00069 static int kmo_sci_red(cpl_parameterlist *, cpl_frameset *); 00070 00071 /*----------------------------------------------------------------------------- 00072 * Static variables 00073 *----------------------------------------------------------------------------*/ 00074 00075 static char kmo_sci_red_description[] = 00076 "At least two data frames have to be provided since we need for each IFU poin-\n" 00077 "ting to an object also a sky frame from the same IFU.\n" 00078 "Every IFU containing an object will be reconstructed and divided by telluric\n" 00079 "and illumination correction. By default these intermediate cubes are saved to\n" 00080 "disk. Frames just containing skies won’t produce an output here, so the number\n" 00081 "of output frames can be smaller than the number of input frames.\n" 00082 "Then the reconstructed objects with the same object name are combined. These\n" 00083 "outputs are also saved to disk, the number of created files depends on the\n" 00084 "number of reconstructed objects of different name. If the user just wants to\n" 00085 "combine a certain object, the parameters --name or --ifus can be used.\n" 00086 "For exposures taken with the templates KMOS_spec_obs_mapping8 and\n" 00087 "KMOS_spec_obs_mapping24 the recipe behaves a bit different: All active IFUs\n" 00088 "will be combined, regardless of the object names.\n" 00089 "This recipe must be called after the kmo_std_star-recipe.\n" 00090 "\n" 00091 "BASIC PARAMETERS:\n" 00092 "-----------------\n" 00093 "--imethod\n" 00094 "The interpolation method used for reconstruction.\n" 00095 "\n" 00096 "--smethod\n" 00097 "The interpolation method used for shifting.\n" 00098 "\n" 00099 "ADVANCED PARAMETERS\n" 00100 "-------------------\n" 00101 "--flux\n" 00102 "Specify if flux conservation should be applied.\n" 00103 "\n" 00104 "--background\n" 00105 "Specify if background removal should be applied.\n" 00106 "\n" 00107 " Advanced reconstruction parameters\n" 00108 " ----------------------------------\n" 00109 "--neighborhoodRange\n" 00110 "Defines the range to search for neighbors during reconstruction\n" 00111 "\n" 00112 "--b_samples\n" 00113 "The number of samples in spectral direction for the reconstructed cube.\n" 00114 "Ideally this number should be greater than 2048, the detector size.\n" 00115 "\n" 00116 "--b_start\n" 00117 "--b_end\n" 00118 "Used to define manually the start and end wavelength for the reconstructed\n" 00119 "cube. By default the internally defined values are used.\n" 00120 "\n" 00121 "--fast_mode\n" 00122 "If set to TRUE, the reconstructed cubes will be collapsed (using median) and\n" 00123 "only then be shifted and combined.\n" 00124 "\n" 00125 "--pix_scale" 00126 "Change the pixel scale [arcsec]. Default of 0.2\" results into cubes of\n" 00127 "14x14pix, a scale of 0.1\" results into cubes of 28x28pix, etc.\n" 00128 "\n" 00129 " Advanced combining parameters\n" 00130 " ----------------------------------\n" 00131 "--edge_nan\n" 00132 "Set borders of two sides of the cubes to NaN before combining them. This minimises\n" 00133 "unwanted border effects when dithering.\n" 00134 "\n" 00135 "--no_combine\n" 00136 "If set to TRUE, the reconstructed cubes will not be combined.\n" 00137 "\n" 00138 "--no_subtract\n" 00139 "If set to TRUE, the found objects and references won't be sky subtracted.\n" 00140 "\n" 00141 "--name\n" 00142 "--ifus\n" 00143 "Since an object can be present only once per exposure and since it can be\n" 00144 "located in different IFUs for the existing exposures, there are two modes to\n" 00145 "identify the objects:\n" 00146 " * Combine by object names (default)\n" 00147 " In this case the object name must be provided via the --name parameter. The\n" 00148 " object name will be searched for in all primary headers of all provided\n" 00149 " frames in the keyword ESO OCS ARMx NAME.\n" 00150 "\n" 00151 " * Combine by index (advanced)\n" 00152 " In this case the --ifus parameter must be provided. The parameter must have\n" 00153 " the same number of entries as frames are provided, e.g. \"3;1;24\" for 3\n" 00154 " exposures. The index doesn't reference the extension in the frame but the\n" 00155 " real index of the IFU as defined in the EXTNAME keyword.\n" 00156 " (e.g. 'IFU.3.DATA')\n" 00157 "\n" 00158 "--method\n" 00159 "There are following sources to get the shift parameters from:\n" 00160 " * 'header' (default)\n" 00161 " The shifts are calculated according to the WCS information stored in the\n" 00162 " header of every IFU. The output frame will get larger, except the object is\n" 00163 " at the exact same position for all exposures. The size of the exposures can\n" 00164 " differ, but the orientation must be the same for all exposures.\n" 00165 "\n" 00166 " * 'none'\n" 00167 " The cubes are directly recombined, not shifting at all. The ouput frame\n" 00168 " will have the same dimensions as the input cubes.\n" 00169 " If the size differs a warning will be emitted and the cubes will be aligned\n" 00170 " to the lower left corner. If the orientation differs a warning will be\n" 00171 " emitted, but the cubes are combined anyway.\n" 00172 "\n" 00173 " * 'center'\n" 00174 " The shifts are calculated using a centering algorithm. The cube will be\n" 00175 " collapsed and a 2D profile will be fitted to it to identify the centre.\n" 00176 " With the parameter --fmethod the function to fit can be provided. The size\n" 00177 " of the exposures can differ, but the orientation must be the same for all\n" 00178 " exposures.\n" 00179 "\n" 00180 " * 'user'\n" 00181 " Read the shifts from a user specified file. The path of the file must be\n" 00182 " provided using the --filename parameter. For every exposure (except the\n" 00183 " first one) two shift values are expected per line, they have to be separa-\n" 00184 " ted with simple spaces. The values indicate pixel shifts and are referenced\n" 00185 " to the first frame. The 1st value is the shift in x-direction to the left,\n" 00186 " the 2nd the shift in y-direction upwards. The size of the exposures can\n" 00187 " differ, but the orientation must be the same for all exposures.\n" 00188 "\n" 00189 "--fmethod\n" 00190 "see --method='center'\n" 00191 "The type of function that should be fitted spatially to the collapsed image.\n" 00192 "This fit is used to create a mask to extract the spectrum of the object. Valid\n" 00193 "values are 'gauss' and 'moffat'.\n" 00194 "\n" 00195 "--filename\n" 00196 "see --method='user'\n" 00197 "\n" 00198 "--cpos_rej\n" 00199 "--cneg_rej\n" 00200 "--citer\n" 00201 "see --cmethod='ksigma'\n" 00202 "\n" 00203 "--cmax\n" 00204 "--cmin\n" 00205 "see --cmethod='min_max'\n" 00206 "\n" 00207 "--extrapolate\n" 00208 "By default no extrapolation is applied. This means that the intermediate\n" 00209 "reconstructed cubes will shrink at most one pixel, which is ok for templates\n" 00210 "like KMOS_spec_obs_nodtosky or KMOS_spec_obs_freedither. When the cubes will be\n" 00211 "arranged as a map, a grid is likely to occur between the IFUs. Therefore extra-\n" 00212 "polation during the shifting process can be switched on in order to get IFUs of\n" 00213 "original size. For frames taken with mapping templates, extrapolation is\n" 00214 "switched on automatically.\n" 00215 "\n" 00216 "------------------------------------------------------------------------------\n" 00217 " Input files:\n" 00218 "\n" 00219 " DO KMOS \n" 00220 " category Type Explanation Required #Frames\n" 00221 " -------- ----- ----------- -------- -------\n" 00222 " SCIENCE RAW The science frames Y >=1 \n" 00223 " XCAL F2D x calibration frame Y 1 \n" 00224 " YCAL F2D y calibration frame Y 1 \n" 00225 " LCAL F2D Wavelength calib. frame Y 1 \n" 00226 " MASTER_FLAT F2D Master flat Y 1 \n" 00227 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00228 " ILLUM_CORR F2I Illumination correction N 0,1 \n" 00229 " TELLURIC F1I normalised telluric spectrum N 0,1 \n" 00230 "\n" 00231 " Output files:\n" 00232 "\n" 00233 " DO KMOS\n" 00234 " category Type Explanation\n" 00235 " -------- ----- -----------\n" 00236 " SCI_COMBINED F3I Combined cubes with noise\n" 00237 " SCI_RECONSTRUCTED F3I Reconstructed cube with noise\n" 00238 "------------------------------------------------------------------------------\n" 00239 "\n"; 00240 00241 /*----------------------------------------------------------------------------- 00242 * Functions code 00243 *----------------------------------------------------------------------------*/ 00244 00261 int cpl_plugin_get_info(cpl_pluginlist *list) 00262 { 00263 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00264 cpl_plugin *plugin = &recipe->interface; 00265 00266 cpl_plugin_init(plugin, 00267 CPL_PLUGIN_API, 00268 KMOS_BINARY_VERSION, 00269 CPL_PLUGIN_TYPE_RECIPE, 00270 "kmo_sci_red", 00271 "Reconstruct and combine data frames dividing " 00272 "illumination and telluric correction.", 00273 kmo_sci_red_description, 00274 "Alex Agudo Berbel", 00275 "agudo@mpe.mpg.de", 00276 kmos_get_license(), 00277 kmo_sci_red_create, 00278 kmo_sci_red_exec, 00279 kmo_sci_red_destroy); 00280 00281 cpl_pluginlist_append(list, plugin); 00282 00283 return 0; 00284 } 00285 00293 static int kmo_sci_red_create(cpl_plugin *plugin) 00294 { 00295 cpl_recipe *recipe; 00296 cpl_parameter *p; 00297 00298 /* Check that the plugin is part of a valid recipe */ 00299 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00300 recipe = (cpl_recipe *)plugin; 00301 else 00302 return -1; 00303 00304 /* Create the parameters list in the cpl_recipe object */ 00305 recipe->parameters = cpl_parameterlist_new(); 00306 00307 /* --imethod */ 00308 p = cpl_parameter_new_value("kmos.kmo_sci_red.imethod", 00309 CPL_TYPE_STRING, 00310 "Method to use for interpolation during reconstruction. " 00311 "[\"NN\" (nearest neighbour), " 00312 "\"lwNN\" (linear weighted nearest neighbor), " 00313 "\"swNN\" (square weighted nearest neighbor), " 00314 "\"MS\" (Modified Shepard's method)" 00315 "\"CS\" (Cubic spline)]", 00316 "kmos.kmo_sci_red", 00317 "CS"); 00318 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00319 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00320 cpl_parameterlist_append(recipe->parameters, p); 00321 00322 /* --smethod */ 00323 p = cpl_parameter_new_value("kmos.kmo_sci_red.smethod", 00324 CPL_TYPE_STRING, 00325 "Method to use for interpolation during shifting. " 00326 "[\"NN\" (nearest neighbour), " 00327 "\"CS\" (Cubic spline)]", 00328 "kmos.kmo_sci_red", 00329 "CS"); 00330 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "smethod"); 00331 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00332 cpl_parameterlist_append(recipe->parameters, p); 00333 00334 /* --neighborhoodRange */ 00335 p = cpl_parameter_new_value("kmos.kmo_sci_red.neighborhoodRange", 00336 CPL_TYPE_DOUBLE, 00337 "Defines the range to search for neighbors " 00338 "in pixels", 00339 "kmos.kmo_sci_red", 00340 1.001); 00341 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00342 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00343 cpl_parameterlist_append(recipe->parameters, p); 00344 00345 /* --name */ 00346 p = cpl_parameter_new_value("kmos.kmo_sci_red.name", 00347 CPL_TYPE_STRING, 00348 "Name of the object to combine.", 00349 "kmos.kmo_sci_red", 00350 ""); 00351 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00352 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00353 cpl_parameterlist_append(recipe->parameters, p); 00354 00355 /* --ifus */ 00356 p = cpl_parameter_new_value("kmos.kmo_sci_red.ifus", 00357 CPL_TYPE_STRING, 00358 "The indices of the IFUs to combine. " 00359 "\"ifu1;ifu2;...\"", 00360 "kmos.kmo_sci_red", 00361 ""); 00362 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00363 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00364 cpl_parameterlist_append(recipe->parameters, p); 00365 00366 /* --method */ 00367 p = cpl_parameter_new_value("kmos.kmo_sci_red.method", 00368 CPL_TYPE_STRING, 00369 "The shifting method: " 00370 "'none': no shifting, combined directly, " 00371 "'header': shift according to WCS (default), " 00372 "'center': centering algorithm, " 00373 "'user': read shifts from file", 00374 "kmos.kmo_sci_red", 00375 "header"); 00376 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method"); 00377 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00378 cpl_parameterlist_append(recipe->parameters, p); 00379 00380 /* --fmethod */ 00381 p = cpl_parameter_new_value("kmos.kmo_sci_red.fmethod", 00382 CPL_TYPE_STRING, 00383 "The fitting method (applies only when " 00384 "method='center'): " 00385 "'gauss': fit a gauss function to collapsed " 00386 "image (default), " 00387 "'moffat': fit a moffat function to collapsed" 00388 " image", 00389 "kmos.kmo_sci_red", 00390 "gauss"); 00391 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00392 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00393 cpl_parameterlist_append(recipe->parameters, p); 00394 00395 /* --filename */ 00396 p = cpl_parameter_new_value("kmos.kmo_sci_red.filename", 00397 CPL_TYPE_STRING, 00398 "The path to the file with the shift vectors." 00399 "(Applies only to method='user')", 00400 "kmos.kmo_sci_red", 00401 ""); 00402 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filename"); 00403 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00404 cpl_parameterlist_append(recipe->parameters, p); 00405 00406 /* --flux */ 00407 p = cpl_parameter_new_value("kmos.kmo_sci_red.flux", 00408 CPL_TYPE_BOOL, 00409 "TRUE: Apply flux conservation. FALSE: otherwise", 00410 "kmos.kmo_sci_red", 00411 FALSE); 00412 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00413 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00414 cpl_parameterlist_append(recipe->parameters, p); 00415 00416 /* --background */ 00417 p = cpl_parameter_new_value("kmos.kmo_sci_red.background", 00418 CPL_TYPE_BOOL, 00419 "TRUE: Apply background removal. FALSE: otherwise", 00420 "kmos.kmo_sci_red", 00421 FALSE); 00422 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "background"); 00423 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00424 cpl_parameterlist_append(recipe->parameters, p); 00425 00426 /* --extrapolate */ 00427 p = cpl_parameter_new_value("kmos.kmo_sci_red.extrapolate", 00428 CPL_TYPE_BOOL, 00429 "Applies only to 'method=CS' when doing sub-" 00430 "pixel shifts: " 00431 "FALSE: shifted IFU will be filled with NaN's " 00432 "at the borders," 00433 "TRUE: shifted IFU will be extrapolated at " 00434 "the borders", 00435 "kmos.kmo_sci_red", 00436 FALSE); 00437 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extrapolate"); 00438 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00439 cpl_parameterlist_append(recipe->parameters, p); 00440 00441 /* --fast_mode */ 00442 p = cpl_parameter_new_value("kmos.kmo_sci_red.fast_mode", 00443 CPL_TYPE_BOOL, 00444 "FALSE: cubes are shifted and combined," 00445 "TRUE: cubes are collapsed and then shifted and combined", 00446 "kmos.kmo_sci_red", 00447 FALSE); 00448 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fast_mode"); 00449 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00450 cpl_parameterlist_append(recipe->parameters, p); 00451 00452 /* --edge_nan */ 00453 p = cpl_parameter_new_value("kmos.kmo_sci_red.edge_nan", 00454 CPL_TYPE_BOOL, 00455 "Set borders of cubes to NaN before combining them." 00456 "(TRUE (apply) or " 00457 "FALSE (don't apply)", 00458 "kmos.kmo_sci_red", 00459 FALSE); 00460 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "edge_nan"); 00461 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00462 cpl_parameterlist_append(recipe->parameters, p); 00463 00464 /* --no_combine */ 00465 p = cpl_parameter_new_value("kmos.kmo_sci_red.no_combine", 00466 CPL_TYPE_BOOL, 00467 "Don't combine cubes after reconstruction." 00468 "(TRUE (apply) or " 00469 "FALSE (don't apply)", 00470 "kmos.kmo_sci_red", 00471 FALSE); 00472 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "no_combine"); 00473 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00474 cpl_parameterlist_append(recipe->parameters, p); 00475 00476 /* --no_subtract */ 00477 p = cpl_parameter_new_value("kmos.kmo_sci_red.no_subtract", 00478 CPL_TYPE_BOOL, 00479 "Don't sky subtract object and references." 00480 "(TRUE (apply) or " 00481 "FALSE (don't apply)", 00482 "kmos.kmo_sci_red", 00483 FALSE); 00484 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "no_subtract"); 00485 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00486 cpl_parameterlist_append(recipe->parameters, p); 00487 00488 /* --pix_scale */ 00489 p = cpl_parameter_new_value("kmos.kmo_sci_red.pix_scale", 00490 CPL_TYPE_DOUBLE, 00491 "Change the pixel scale [arcsec]. " 00492 "Default of 0.2\" results into cubes of 14x14pix, " 00493 "a scale of 0.1\" results into cubes of 28x28pix, " 00494 "etc.", 00495 "kmos.kmo_sci_red", 00496 KMOS_PIX_RESOLUTION); 00497 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pix_scale"); 00498 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00499 cpl_parameterlist_append(recipe->parameters, p); 00500 00501 00502 00503 // add parameters for band-definition 00504 kmo_band_pars_create(recipe->parameters, 00505 "kmos.kmo_sci_red"); 00506 00507 return kmo_combine_pars_create(recipe->parameters, 00508 "kmos.kmo_sci_red", 00509 DEF_REJ_METHOD, 00510 FALSE); 00511 } 00512 00518 static int kmo_sci_red_exec(cpl_plugin *plugin) 00519 { 00520 cpl_recipe *recipe; 00521 00522 /* Get the recipe out of the plugin */ 00523 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00524 recipe = (cpl_recipe *)plugin; 00525 else return -1 ; 00526 00527 return kmo_sci_red(recipe->parameters, recipe->frames); 00528 } 00529 00535 static int kmo_sci_red_destroy(cpl_plugin *plugin) 00536 { 00537 cpl_recipe *recipe; 00538 00539 /* Get the recipe out of the plugin */ 00540 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00541 recipe = (cpl_recipe *)plugin; 00542 else return -1 ; 00543 00544 cpl_parameterlist_delete(recipe->parameters); 00545 return 0 ; 00546 } 00547 00548 00549 00564 static int kmo_sci_red(cpl_parameterlist *parlist, cpl_frameset *frameset) 00565 { 00566 int ret_val = 0, 00567 nr_science_frames = 0, 00568 nr_reconstructed_frames = 0, 00569 has_illum_corr = 0, 00570 has_telluric = 0, 00571 *bounds = NULL, 00572 det_nr = 0, 00573 actual_msg_level = 0, 00574 print_once = FALSE, 00575 nr_avail_obj_names = 0, 00576 found_name = FALSE, 00577 cube_counter_data = 0, 00578 cube_counter_noise = 0, 00579 citer = 0, 00580 cmin = 0, 00581 cmax = 0, 00582 user_defined_ifu = 0, 00583 extrapolate = 0, 00584 flux = FALSE, 00585 background = FALSE, 00586 index = 0, 00587 nr_data_alloc = 0, 00588 tmp_int = 0, 00589 fast_mode = FALSE, 00590 edge_nan = FALSE, 00591 no_combine = FALSE, 00592 no_subtract = FALSE; 00593 const int *punused_ifus = NULL; 00594 double neighborhoodRange = 1.001, 00595 cpos_rej = 0.0, 00596 cneg_rej = 0.0, 00597 pix_scale = 0.0; 00598 char *suffix = NULL, 00599 *keyword = NULL, 00600 *extname = NULL, 00601 *fn_suffix = NULL, 00602 *mapping_mode = NULL, 00603 **split = NULL, 00604 content[256]; 00605 const char *imethod = NULL, 00606 *smethod = NULL, 00607 *ifus_txt = NULL, 00608 *name = NULL, 00609 *filter_id = NULL, 00610 *tmp_str = NULL, 00611 *filename = NULL, 00612 *fn_out = NULL, 00613 *fn_obj = NULL, 00614 *fn_sky = NULL, 00615 *fn_reconstr = NULL, 00616 *comb_method = NULL, 00617 *cmethod = NULL, 00618 *fmethod = NULL; 00619 cpl_array **unused_ifus = NULL; 00620 cpl_frame *xcal_frame = NULL, 00621 *ycal_frame = NULL, 00622 *lcal_frame = NULL, 00623 *flat_frame = NULL, 00624 *illum_frame = NULL, 00625 *telluric_frame = NULL, 00626 *tmp_frame = NULL; 00627 cpl_propertylist *tmp_header = NULL, 00628 *main_header = NULL, 00629 **header_data = NULL, 00630 **header_noise = NULL; 00631 cpl_vector *ifus = NULL; 00632 kmclipm_vector *telluric_data = NULL, 00633 *telluric_noise = NULL; 00634 cpl_image **lcal = NULL, 00635 *illum_data = NULL, 00636 *illum_noise = NULL, 00637 *tmpImg = NULL; 00638 cpl_imagelist **cube_data = NULL, 00639 **cube_noise = NULL, 00640 *combined_data = NULL, 00641 *combined_noise = NULL, 00642 *tmpCube = NULL; 00643 cpl_table *band_table = NULL; 00644 cpl_frame *sky_frame = NULL; 00645 main_fits_desc desc1, 00646 desc2; 00647 gridDefinition gd; 00648 objSkyFrameTableStruct *obj_sky_struct = NULL; 00649 allObjStruct *all_obj = NULL; 00650 enum extrapolationType extrapol_enum = 0; 00651 enum kmo_frame_type ft = 0; 00652 00653 KMO_TRY 00654 { 00655 00656 kmo_init_fits_desc(&desc1); 00657 kmo_init_fits_desc(&desc2); 00658 00659 // 00660 // check frameset 00661 // 00662 KMO_TRY_ASSURE((parlist != NULL) && 00663 (frameset != NULL), 00664 CPL_ERROR_NULL_INPUT, 00665 "Not all input data is provided!"); 00666 00667 nr_science_frames = cpl_frameset_count_tags(frameset, SCIENCE); 00668 KMO_TRY_ASSURE(nr_science_frames >= 1, 00669 CPL_ERROR_ILLEGAL_INPUT, 00670 "At least one SCIENCE frame is required!"); 00671 if (nr_science_frames == 1) { 00672 cpl_msg_warning("", "At least two SCIENCE frames should be provided " 00673 "in order to apply sky subtraction!"); 00674 cpl_msg_warning("", "All IFUs will be reconstructed regardless if " 00675 "they contain object, reference or sky!"); 00676 } 00677 00678 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00679 CPL_ERROR_FILE_NOT_FOUND, 00680 "Exactly one XCAL frame is required!"); 00681 00682 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00683 CPL_ERROR_FILE_NOT_FOUND, 00684 "Exactly one YCAL frame is required!"); 00685 00686 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00687 CPL_ERROR_FILE_NOT_FOUND, 00688 "Exactly one LCAL frame is required!"); 00689 00690 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, MASTER_FLAT) == 1, 00691 CPL_ERROR_FILE_NOT_FOUND, 00692 "Exactly one MASTER_FLAT frame is required!"); 00693 00694 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00695 CPL_ERROR_FILE_NOT_FOUND, 00696 "Exactly one WAVE_BAND frame is required!"); 00697 00698 has_illum_corr = cpl_frameset_count_tags(frameset, ILLUM_CORR); 00699 KMO_TRY_ASSURE((has_illum_corr == 0) || (has_illum_corr == 1), 00700 CPL_ERROR_FILE_NOT_FOUND, 00701 "At most one ILLUM_CORR frame can be provided!"); 00702 00703 has_telluric = cpl_frameset_count_tags(frameset, TELLURIC); 00704 KMO_TRY_ASSURE((has_telluric == 0) || (has_telluric == 1), 00705 CPL_ERROR_FILE_NOT_FOUND, 00706 "At most one TELLURIC frame can be provided!"); 00707 00708 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_sci_red") == 1, 00709 CPL_ERROR_ILLEGAL_INPUT, 00710 "Cannot identify RAW and CALIB frames!"); 00711 00712 // 00713 // get parameters 00714 // 00715 cpl_msg_info("", "--- Parameter setup for kmo_sci_red ------"); 00716 00717 flux = kmo_dfs_get_parameter_bool(parlist, 00718 "kmos.kmo_sci_red.flux"); 00719 00720 KMO_TRY_ASSURE((flux == 0) || 00721 (flux == 1), 00722 CPL_ERROR_ILLEGAL_INPUT, 00723 "flux must be either FALSE or TRUE! %d", flux); 00724 00725 KMO_TRY_EXIT_IF_ERROR( 00726 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.flux")); 00727 00728 background = kmo_dfs_get_parameter_bool(parlist, 00729 "kmos.kmo_sci_red.background"); 00730 00731 KMO_TRY_ASSURE((background == 0) || 00732 (background == 1), 00733 CPL_ERROR_ILLEGAL_INPUT, 00734 "background must be either FALSE or TRUE! %d", background); 00735 00736 KMO_TRY_EXIT_IF_ERROR( 00737 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.background")); 00738 00739 KMO_TRY_EXIT_IF_NULL( 00740 imethod = kmo_dfs_get_parameter_string(parlist, 00741 "kmos.kmo_sci_red.imethod")); 00742 00743 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00744 (strcmp(imethod, "lwNN") == 0) || 00745 (strcmp(imethod, "swNN") == 0) || 00746 (strcmp(imethod, "MS") == 0) || 00747 (strcmp(imethod, "CS") == 0), 00748 CPL_ERROR_ILLEGAL_INPUT, 00749 "imethod must be either \"NN\", \"lwNN\", " 00750 "\"swNN\", \"MS\" or \"CS\"!"); 00751 00752 KMO_TRY_EXIT_IF_ERROR( 00753 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.imethod")); 00754 00755 KMO_TRY_EXIT_IF_NULL( 00756 smethod = kmo_dfs_get_parameter_string(parlist, 00757 "kmos.kmo_sci_red.smethod")); 00758 00759 KMO_TRY_ASSURE((strcmp(smethod, "NN") == 0) || 00760 (strcmp(smethod, "CS") == 0), 00761 CPL_ERROR_ILLEGAL_INPUT, 00762 "smethod must be either \"NN\" or \"CS\"!"); 00763 00764 KMO_TRY_EXIT_IF_ERROR( 00765 kmo_dfs_print_parameter_help(parlist, 00766 "kmos.kmo_sci_red.smethod")); 00767 00768 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00769 "kmos.kmo_sci_red.neighborhoodRange"); 00770 KMO_TRY_CHECK_ERROR_STATE(); 00771 00772 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00773 CPL_ERROR_ILLEGAL_INPUT, 00774 "neighborhoodRange must be greater than 0.0"); 00775 00776 KMO_TRY_EXIT_IF_ERROR( 00777 kmo_dfs_print_parameter_help(parlist, 00778 "kmos.kmo_sci_red.neighborhoodRange")); 00779 00780 KMO_TRY_EXIT_IF_NULL( 00781 comb_method = kmo_dfs_get_parameter_string(parlist, 00782 "kmos.kmo_sci_red.method")); 00783 00784 KMO_TRY_EXIT_IF_NULL( 00785 fmethod = kmo_dfs_get_parameter_string(parlist, 00786 "kmos.kmo_sci_red.fmethod")); 00787 00788 KMO_TRY_ASSURE((strcmp(comb_method, "none") == 0) || 00789 (strcmp(comb_method, "header") == 0) || 00790 (strcmp(comb_method, "center") == 0) || 00791 (strcmp(comb_method, "user") == 0), 00792 CPL_ERROR_ILLEGAL_INPUT, 00793 "Following shift methods are available : 'none', " 00794 "'header', 'center' or 'user'"); 00795 00796 if (strcmp(comb_method, "user") == 0) { 00797 filename = kmo_dfs_get_parameter_string(parlist, 00798 "kmos.kmo_sci_red.filename"); 00799 KMO_TRY_CHECK_ERROR_STATE(); 00800 00801 KMO_TRY_ASSURE(strcmp(filename, "") != 0, 00802 CPL_ERROR_ILLEGAL_INPUT, 00803 "path of file with shift information must be " 00804 "provided!"); 00805 00806 KMO_TRY_EXIT_IF_ERROR( 00807 kmo_dfs_print_parameter_help(parlist, 00808 "kmos.kmo_sci_red.filename")); 00809 } 00810 00811 KMO_TRY_EXIT_IF_ERROR( 00812 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.method")); 00813 00814 ifus_txt = kmo_dfs_get_parameter_string(parlist, 00815 "kmos.kmo_sci_red.ifus"); 00816 KMO_TRY_CHECK_ERROR_STATE(); 00817 00818 name = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_sci_red.name"); 00819 KMO_TRY_CHECK_ERROR_STATE(); 00820 00821 if (strcmp(ifus_txt, "") != 0) { 00822 KMO_TRY_ASSURE(strcmp(name, "") == 0, 00823 CPL_ERROR_ILLEGAL_INPUT, 00824 "name parameter must be NULL if IFU indices are " 00825 "provided!"); 00826 00827 KMO_TRY_EXIT_IF_NULL( 00828 ifus = kmo_identify_values(ifus_txt)); 00829 00830 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_science_frames, 00831 CPL_ERROR_ILLEGAL_INPUT, 00832 "ifus parameter must have the same number of values " 00833 "than frames provided (for frames just containing " 00834 "skies insert 0)) (%lld!=%d)", 00835 cpl_vector_get_size(ifus), nr_science_frames); 00836 } 00837 00838 if (strcmp(name, "") != 0) { 00839 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, 00840 CPL_ERROR_ILLEGAL_INPUT, 00841 "ifus parameter must be NULL if name is provided!"); 00842 } 00843 00844 KMO_TRY_EXIT_IF_ERROR( 00845 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.ifus")); 00846 00847 KMO_TRY_EXIT_IF_ERROR( 00848 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.name")); 00849 00850 kmo_band_pars_load(parlist, "kmos.kmo_sci_red"); 00851 00852 extrapolate = kmo_dfs_get_parameter_bool(parlist, 00853 "kmos.kmo_sci_red.extrapolate"); 00854 KMO_TRY_CHECK_ERROR_STATE(); 00855 00856 if (strcmp(smethod, "NN") == 0) { 00857 if (extrapolate == TRUE) { 00858 cpl_msg_warning("", "extrapolation for smethod='NN' not available!"); 00859 } 00860 extrapol_enum = NONE_NANS; 00861 } else if (strcmp(smethod, "CS") == 0) { 00862 if (extrapolate == FALSE) { 00863 extrapol_enum = NONE_NANS; 00864 } else if (extrapolate == TRUE) { 00865 extrapol_enum = BCS_NATURAL; 00866 } else { 00867 KMO_TRY_ASSURE(1 == 0, 00868 CPL_ERROR_ILLEGAL_INPUT, 00869 "extrapolate must be either FALSE or TRUE!"); 00870 } 00871 smethod = "BCS"; 00872 } else { 00873 KMO_TRY_ASSURE(1 == 0, 00874 CPL_ERROR_ILLEGAL_INPUT, 00875 "method must be either \"CS\" or \"NN\" !"); 00876 } 00877 KMO_TRY_CHECK_ERROR_STATE(); 00878 00879 KMO_TRY_EXIT_IF_ERROR( 00880 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.extrapolate")); 00881 00882 fast_mode = kmo_dfs_get_parameter_bool(parlist, 00883 "kmos.kmo_sci_red.fast_mode"); 00884 KMO_TRY_CHECK_ERROR_STATE(); 00885 KMO_TRY_ASSURE((fast_mode == TRUE) || 00886 (fast_mode == FALSE), 00887 CPL_ERROR_ILLEGAL_INPUT, 00888 "fast_mode must be either FALSE or TRUE!"); 00889 KMO_TRY_EXIT_IF_ERROR( 00890 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.fast_mode")); 00891 00892 edge_nan = kmo_dfs_get_parameter_bool(parlist, 00893 "kmos.kmo_sci_red.edge_nan"); 00894 KMO_TRY_CHECK_ERROR_STATE(); 00895 KMO_TRY_EXIT_IF_ERROR( 00896 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.edge_nan")); 00897 00898 KMO_TRY_ASSURE((edge_nan == TRUE) || (edge_nan == FALSE), 00899 CPL_ERROR_ILLEGAL_INPUT, 00900 "edge_nan must be TRUE or FALSE!"); 00901 00902 no_combine = kmo_dfs_get_parameter_bool(parlist, 00903 "kmos.kmo_sci_red.no_combine"); 00904 KMO_TRY_CHECK_ERROR_STATE(); 00905 00906 KMO_TRY_EXIT_IF_ERROR( 00907 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.no_combine")); 00908 00909 KMO_TRY_ASSURE((no_combine == TRUE) || (no_combine == FALSE), 00910 CPL_ERROR_ILLEGAL_INPUT, 00911 "no_combine must be TRUE or FALSE!"); 00912 00913 no_subtract = kmo_dfs_get_parameter_bool(parlist, 00914 "kmos.kmo_sci_red.no_subtract"); 00915 KMO_TRY_CHECK_ERROR_STATE(); 00916 00917 KMO_TRY_EXIT_IF_ERROR( 00918 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_sci_red.no_subtract")); 00919 00920 KMO_TRY_ASSURE((no_subtract == TRUE) || (no_subtract == FALSE), 00921 CPL_ERROR_ILLEGAL_INPUT, 00922 "no_subtract must be TRUE or FALSE!"); 00923 00924 pix_scale = kmo_dfs_get_parameter_double(parlist, 00925 "kmos.kmo_sci_red.pix_scale"); 00926 KMO_TRY_CHECK_ERROR_STATE(); 00927 KMO_TRY_EXIT_IF_ERROR( 00928 kmo_dfs_print_parameter_help(parlist, 00929 "kmos.kmo_sci_red.pix_scale")); 00930 KMO_TRY_ASSURE((pix_scale >= 0.01) && 00931 (pix_scale <= 0.4), 00932 CPL_ERROR_ILLEGAL_INPUT, 00933 "pix_scale must be between 0.01 and 0.4 (results in cubes " 00934 "with 7x7 to 280x280 pixels)!"); 00935 00936 00937 KMO_TRY_EXIT_IF_ERROR( 00938 kmo_combine_pars_load(parlist, 00939 "kmos.kmo_sci_red", 00940 &cmethod, 00941 &cpos_rej, 00942 &cneg_rej, 00943 &citer, 00944 &cmin, 00945 &cmax, 00946 FALSE)); 00947 00948 cpl_msg_info("", "-------------------------------------------"); 00949 00950 // 00951 // assure that filters, grating and rotation offsets match for 00952 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 00953 // frames) 00954 // 00955 00956 // check if filter_id and grating_id match for all detectors 00957 KMO_TRY_EXIT_IF_ERROR( 00958 kmo_check_frameset_setup(frameset, SCIENCE, 00959 TRUE, FALSE, TRUE)); 00960 KMO_TRY_EXIT_IF_ERROR( 00961 kmo_check_frame_setup(frameset, SCIENCE, YCAL, 00962 TRUE, FALSE, TRUE)); 00963 KMO_TRY_EXIT_IF_ERROR( 00964 kmo_check_frame_setup(frameset, XCAL, YCAL, 00965 TRUE, FALSE, TRUE)); 00966 KMO_TRY_EXIT_IF_ERROR( 00967 kmo_check_frame_setup(frameset, XCAL, LCAL, 00968 TRUE, FALSE, TRUE)); 00969 // KMO_TRY_EXIT_IF_ERROR( 00970 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00971 // KMO_TRY_EXIT_IF_ERROR( 00972 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00973 KMO_TRY_EXIT_IF_ERROR( 00974 kmo_check_frame_setup(frameset, XCAL, MASTER_FLAT, 00975 TRUE, FALSE, TRUE)); 00976 // omit this check because ILLUM_CORR is band-independend 00977 // if (has_illum_corr) { 00978 // KMO_TRY_EXIT_IF_ERROR( 00979 // kmo_check_frame_setup(frameset, XCAL, ILLUM_CORR, 00980 // TRUE, FALSE, TRUE)); 00981 // } 00982 00983 if (has_telluric) { 00984 KMO_TRY_EXIT_IF_ERROR( 00985 kmo_check_frame_setup(frameset, XCAL, TELLURIC, 00986 TRUE, FALSE, TRUE)); 00987 } 00988 00989 // check descriptors of all frames 00990 KMO_TRY_EXIT_IF_NULL( 00991 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 00992 00993 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 00994 KMO_TRY_CHECK_ERROR_STATE(); 00995 00996 KMO_TRY_ASSURE((desc1.nr_ext % 3 == 0) && 00997 (desc1.ex_badpix == FALSE) && 00998 (desc1.fits_type == f2d_fits) && 00999 (desc1.frame_type == detector_frame), 01000 CPL_ERROR_ILLEGAL_INPUT, 01001 "XCAL isn't in the correct format!!!"); 01002 01003 KMO_TRY_EXIT_IF_NULL( 01004 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 01005 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 01006 KMO_TRY_CHECK_ERROR_STATE(); 01007 01008 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 01009 (desc1.ex_badpix == desc2.ex_badpix) && 01010 (desc1.fits_type == desc2.fits_type) && 01011 (desc1.frame_type == desc2.frame_type), 01012 CPL_ERROR_ILLEGAL_INPUT, 01013 "YCAL isn't in the correct format!!!"); 01014 kmo_free_fits_desc(&desc2); 01015 kmo_init_fits_desc(&desc2); 01016 01017 KMO_TRY_EXIT_IF_NULL( 01018 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 01019 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 01020 KMO_TRY_CHECK_ERROR_STATE(); 01021 01022 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 01023 (desc1.ex_badpix == desc2.ex_badpix) && 01024 (desc1.fits_type == desc2.fits_type) && 01025 (desc1.frame_type == desc2.frame_type), 01026 CPL_ERROR_ILLEGAL_INPUT, 01027 "YCAL isn't in the correct format!!!"); 01028 kmo_free_fits_desc(&desc2); 01029 kmo_init_fits_desc(&desc2); 01030 01031 KMO_TRY_EXIT_IF_NULL( 01032 flat_frame = kmo_dfs_get_frame(frameset, MASTER_FLAT)); 01033 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(flat_frame)); 01034 KMO_TRY_CHECK_ERROR_STATE(); 01035 01036 KMO_TRY_ASSURE((desc2.nr_ext % 6 == 0) && 01037 (desc1.ex_badpix == desc2.ex_badpix) && 01038 (desc1.fits_type == desc2.fits_type) && 01039 (desc1.frame_type == desc2.frame_type), 01040 CPL_ERROR_ILLEGAL_INPUT, 01041 "MASTER_FLAT isn't in the correct format!!!"); 01042 kmo_free_fits_desc(&desc2); 01043 kmo_init_fits_desc(&desc2); 01044 01045 if (has_illum_corr) { 01046 KMO_TRY_EXIT_IF_NULL( 01047 illum_frame = kmo_dfs_get_frame(frameset, ILLUM_CORR)); 01048 desc2 = kmo_identify_fits_header( 01049 cpl_frame_get_filename(illum_frame)); 01050 KMO_TRY_CHECK_ERROR_STATE(); 01051 KMO_TRY_ASSURE(((desc2.nr_ext == 24) || (desc2.nr_ext == 48)) && 01052 (desc2.ex_badpix == FALSE) && 01053 (desc2.fits_type == f2i_fits) && 01054 (desc2.frame_type == ifu_frame), 01055 CPL_ERROR_ILLEGAL_INPUT, 01056 "ILLUM_CORR isn't in the correct format!!!"); 01057 kmo_free_fits_desc(&desc2); 01058 kmo_init_fits_desc(&desc2); 01059 } 01060 01061 if (has_telluric) { 01062 KMO_TRY_EXIT_IF_NULL( 01063 telluric_frame = kmo_dfs_get_frame(frameset, TELLURIC)); 01064 desc2 = kmo_identify_fits_header( 01065 cpl_frame_get_filename(telluric_frame)); 01066 KMO_TRY_CHECK_ERROR_STATE(); 01067 KMO_TRY_ASSURE(((desc2.nr_ext == 24) || (desc2.nr_ext == 48)) && 01068 (desc2.ex_badpix == FALSE) && 01069 (desc2.fits_type == f1i_fits) && 01070 (desc2.frame_type == ifu_frame), 01071 CPL_ERROR_ILLEGAL_INPUT, 01072 "TELLURIC isn't in the correct format!!!"); 01073 kmo_free_fits_desc(&desc2); 01074 kmo_init_fits_desc(&desc2); 01075 } 01076 01077 KMO_TRY_EXIT_IF_NULL( 01078 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 01079 while (tmp_frame != NULL ) { 01080 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01081 KMO_TRY_CHECK_ERROR_STATE(); 01082 KMO_TRY_ASSURE((desc2.nr_ext == 3) && 01083 (desc2.ex_badpix == FALSE) && 01084 (desc2.fits_type == raw_fits) && 01085 (desc2.frame_type == detector_frame), 01086 CPL_ERROR_ILLEGAL_INPUT, 01087 "SCIENCE isn't in the correct format!!!"); 01088 kmo_free_fits_desc(&desc2); 01089 kmo_init_fits_desc(&desc2); 01090 01091 if (mapping_mode == NULL) { 01092 KMO_TRY_EXIT_IF_NULL( 01093 tmp_header = 01094 kmclipm_propertylist_load( 01095 cpl_frame_get_filename(tmp_frame), 0)); 01096 if (cpl_propertylist_has(tmp_header, TPL_ID)) { 01097 KMO_TRY_EXIT_IF_NULL( 01098 tmp_str = cpl_propertylist_get_string(tmp_header, 01099 TPL_ID)); 01100 01101 if (strcmp(tmp_str, MAPPING8) == 0) 01102 { 01103 mapping_mode = cpl_sprintf("%s", "mapping8"); 01104 } 01105 if (strcmp(tmp_str, MAPPING24) == 0) 01106 { 01107 mapping_mode = cpl_sprintf("%s", "mapping24"); 01108 } 01109 } 01110 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01111 } 01112 01113 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01114 KMO_TRY_CHECK_ERROR_STATE(); 01115 } 01116 01117 if (mapping_mode != NULL) { 01118 // we are in mapping mode 01119 if ((ifus != NULL) || (strcmp(name, "") != 0)) 01120 { 01121 cpl_msg_warning("","The SCIENCE frames have been taken in one of the " 01122 "mapping modes AND specific IFUs have been " 01123 "specified! --> Only processing these!"); 01124 } else { 01125 if (strcmp(smethod, "BCS") == 0) { 01126 extrapol_enum = BCS_NATURAL; 01127 cpl_msg_info("","Detected frames taken in mapping mode. " 01128 "Changing extrapolation mode to TRUE."); 01129 } 01130 } 01131 if (fast_mode) { 01132 cpl_msg_info("", "Creating map in fast_mode."); 01133 } 01134 } else { 01135 if (fast_mode) { 01136 cpl_msg_info("", "fast_mode has been selected but we aren't in " 01137 "mapping mode. So your choise for fast_mode is ignored."); 01138 } 01139 } 01140 01141 KMO_TRY_EXIT_IF_NULL( 01142 suffix = kmo_dfs_get_suffix(xcal_frame, TRUE, TRUE)); 01143 01144 KMO_TRY_EXIT_IF_ERROR( 01145 kmo_check_frame_setup_md5_xycal(frameset)); 01146 KMO_TRY_EXIT_IF_ERROR( 01147 kmo_check_frame_setup_md5(frameset)); 01148 KMO_TRY_EXIT_IF_ERROR( 01149 kmo_check_frame_setup_sampling(frameset)); 01150 01151 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 01152 cpl_msg_info("", "(grating 1, 2 & 3, rotation angle)"); 01153 01154 // 01155 // check which IFUs are active for all frames 01156 // 01157 KMO_TRY_EXIT_IF_NULL( 01158 unused_ifus = kmo_get_unused_ifus(frameset, 1, 1)); 01159 01160 // KMO_TRY_EXIT_IF_NULL( 01161 // unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before)); 01162 01163 kmo_print_unused_ifus(unused_ifus, FALSE); 01164 01165 // 01166 // get bounds, setup grid, setup obj_sky-struct 01167 // 01168 01169 // get left and right bounds of IFUs 01170 KMO_TRY_EXIT_IF_NULL( 01171 tmp_header = 01172 kmclipm_propertylist_load(cpl_frame_get_filename(xcal_frame), 01173 0)); 01174 KMO_TRY_EXIT_IF_NULL( 01175 bounds = kmclipm_extract_bounds(tmp_header)); 01176 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01177 01178 // setup grid definition, wavelength start and end points will be set 01179 // in the detector loop 01180 KMO_TRY_EXIT_IF_ERROR( 01181 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale)); 01182 01183 // get valid STD frames with objects in it and associated sky exposures 01184 KMO_TRY_EXIT_IF_NULL( 01185 obj_sky_struct = kmo_get_obj_sky_frame_table(frameset, 01186 &nr_science_frames, 01187 SCIENCE, 01188 no_subtract)); 01189 // 01190 // load lcal-frames 01191 // 01192 KMO_TRY_EXIT_IF_NULL( 01193 lcal = (cpl_image**) 01194 cpl_calloc(KMOS_NR_DETECTORS, sizeof(cpl_image*))); 01195 for (int i = 0; i < KMOS_NR_DETECTORS; i++) { 01196 KMO_TRY_EXIT_IF_NULL( 01197 lcal[i] = kmo_dfs_load_image(frameset, LCAL, i+1, FALSE, FALSE, NULL)); 01198 } 01199 01200 // 01201 // allocate intermediate memory 01202 // 01203 KMO_TRY_EXIT_IF_NULL( 01204 all_obj = (allObjStruct*)cpl_calloc(nr_science_frames * KMOS_NR_IFUS, sizeof(allObjStruct))); 01205 01206 // initialize intermediate memory 01207 for (int i = 0; i < nr_science_frames * KMOS_NR_IFUS; i++) { 01208 all_obj[i].name = NULL; 01209 all_obj[i].count = 0; 01210 } 01211 01212 nr_data_alloc = KMOS_NR_IFUS; 01213 KMO_TRY_EXIT_IF_NULL( 01214 cube_data = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01215 sizeof(cpl_imagelist*))); 01216 KMO_TRY_EXIT_IF_NULL( 01217 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01218 sizeof(cpl_imagelist*))); 01219 KMO_TRY_EXIT_IF_NULL( 01220 header_data = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01221 sizeof(cpl_propertylist*))); 01222 KMO_TRY_EXIT_IF_NULL( 01223 header_noise = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01224 sizeof(cpl_propertylist*))); 01225 01226 if (cpl_frameset_count_tags(frameset, SCIENCE) == 1) { 01227 no_combine = TRUE; 01228 cpl_msg_info("", "--no_combine has been set to TRUE since there is only one SCIENCE frame!"); 01229 } 01230 01231 if (no_subtract) { 01232 no_combine = TRUE; 01233 cpl_msg_info("", "--no_combine has been set to TRUE since --no_subtract has been specified by the user!"); 01234 cpl_msg_info("", "Combining cubes would combine skies and obejcts which is meaningless."); 01235 cpl_msg_info("", "This can be done manually with the recipe kmo_combine afterwards!"); 01236 } 01237 01238 // 01239 // loop all science frames containing at least one object 01240 // 01241 cpl_msg_info("", "-------------------------------------------"); 01242 cpl_msg_info("", "Reconstructing & saving cubes containing objects"); 01243 cpl_msg_info("", " "); 01244 for (int sf = 0; sf < nr_science_frames; sf++) { 01245 KMO_TRY_EXIT_IF_NULL( 01246 fn_obj = cpl_frame_get_filename( 01247 obj_sky_struct[sf].objectFrame)); 01248 01249 KMO_TRY_EXIT_IF_NULL( 01250 main_header = kmclipm_propertylist_load(fn_obj, 0)); 01251 01252 // get ifu and detector number to work at 01253 actual_msg_level = cpl_msg_get_level(); 01254 user_defined_ifu = 0; 01255 if ((ifus != NULL) || (strcmp(name, "") != 0)) { 01256 if (ifus != NULL) { 01257 // user specified IFUs 01258 user_defined_ifu = cpl_vector_get(ifus, sf); 01259 KMO_TRY_CHECK_ERROR_STATE(); 01260 01261 if (user_defined_ifu < 1) { 01262 user_defined_ifu = -1; 01263 } 01264 } else { 01265 // user specified an object name 01266 cpl_msg_set_level(CPL_MSG_OFF); 01267 user_defined_ifu = 01268 kmo_get_index_from_ocs_name(obj_sky_struct[sf].objectFrame, 01269 name); 01270 cpl_msg_set_level(actual_msg_level); 01271 if (user_defined_ifu == -1) { 01272 cpl_error_reset(); 01273 } 01274 KMO_TRY_CHECK_ERROR_STATE(); 01275 } 01276 } 01277 01278 // 01279 // reconstruct science frame 01280 // 01281 cpl_msg_info("", " > processing frame: %s", fn_obj); 01282 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) 01283 { 01284 det_nr = (ifu_nr - 1)/KMOS_IFUS_PER_DETECTOR + 1; 01285 01286 KMO_TRY_ASSURE((det_nr >= 1) && 01287 (det_nr <= KMOS_NR_DETECTORS), 01288 CPL_ERROR_ILLEGAL_INPUT, 01289 "The provided ifu-numbers are incorrect! They " 01290 "must be between 1 and %d", KMOS_NR_IFUS); 01291 01292 KMO_TRY_EXIT_IF_NULL( 01293 punused_ifus = cpl_array_get_data_int_const( 01294 unused_ifus[det_nr-1])); 01295 01296 // get subheader data 01297 KMO_TRY_EXIT_IF_NULL( 01298 header_data[ifu_nr-1] = kmclipm_propertylist_load(fn_obj, 01299 det_nr)); 01300 KMO_TRY_EXIT_IF_NULL( 01301 extname = kmo_extname_creator(ifu_frame, ifu_nr, 01302 EXT_DATA)); 01303 KMO_TRY_EXIT_IF_ERROR( 01304 kmclipm_update_property_string(header_data[ifu_nr-1], 01305 EXTNAME, extname, 01306 "FITS extension name")); 01307 cpl_free(extname); extname = NULL; 01308 01309 // Search for keyword ESO OCS ARMi NOTUSED 01310 // If not present (CPL_ERROR_DATA_NOT_FOUND), do nothing 01311 KMO_TRY_EXIT_IF_NULL( 01312 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, 01313 IFU_VALID_POSTFIX)); 01314 tmp_str = cpl_propertylist_get_string(main_header, keyword); 01315 cpl_free(keyword); keyword = NULL; 01316 01317 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 01318 (bounds[2*(ifu_nr-1)] != -1) && 01319 (bounds[2*(ifu_nr-1)+1] != -1) && 01320 ((obj_sky_struct[sf].skyframes[ifu_nr-1] != NULL) || (cpl_frameset_count_tags(frameset, SCIENCE) == 1) || no_subtract) && 01321 (punused_ifus[(ifu_nr-1) % KMOS_IFUS_PER_DETECTOR] == 0) && 01322 ((user_defined_ifu == 0) || (user_defined_ifu == ifu_nr))) 01323 { 01324 // IFU is valid 01325 cpl_error_reset(); 01326 01327 if ((obj_sky_struct[sf].skyframes[ifu_nr-1] != NO_CORRESPONDING_SKYFRAME) && 01328 (cpl_frameset_count_tags(frameset, SCIENCE) != 1) && 01329 !no_subtract) 01330 { 01331 if (no_subtract) { 01332 sky_frame = NULL; 01333 cpl_msg_warning("", " > Omit sky subtraction on IFU %d", ifu_nr); 01334 } else { 01335 sky_frame = obj_sky_struct[sf].skyframes[ifu_nr-1]; 01336 KMO_TRY_EXIT_IF_NULL( 01337 fn_sky = cpl_frame_get_filename(sky_frame)); 01338 cpl_msg_info("", " > IFU %d (with sky in frame: %s)", ifu_nr, fn_sky); 01339 } 01340 } else { 01341 sky_frame = NULL; 01342 if ((cpl_frameset_count_tags(frameset, SCIENCE) != 1) && (!no_subtract)) { 01343 cpl_msg_warning("", " > IFU %d with no corresponding sky frame", ifu_nr); 01344 } 01345 } 01346 01347 // get filter for this detector and setup grid definition 01348 // ESO INS FILTi ID 01349 char *tmp_band_method = getenv("KMO_BAND_METHOD"); 01350 int band_method = 0; 01351 if (tmp_band_method != NULL) { 01352 band_method = atoi(tmp_band_method); 01353 } 01354 01355 KMO_TRY_EXIT_IF_NULL( 01356 keyword = cpl_sprintf("%s%d%s", 01357 IFU_FILTID_PREFIX, det_nr, 01358 IFU_FILTID_POSTFIX)); 01359 KMO_TRY_EXIT_IF_NULL( 01360 filter_id = cpl_propertylist_get_string(main_header, 01361 keyword)); 01362 cpl_free(keyword); keyword = NULL; 01363 01364 if (print_once) { 01365 cpl_msg_set_level(CPL_MSG_WARNING); 01366 } 01367 01368 KMO_TRY_EXIT_IF_NULL( 01369 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 01370 1, 0)); 01371 KMO_TRY_EXIT_IF_ERROR( 01372 kmclipm_setup_grid_band_lcal(&gd, lcal[det_nr-1], 01373 filter_id, band_method, 01374 band_table)); 01375 cpl_table_delete(band_table); band_table = NULL; 01376 01377 print_once = TRUE; 01378 cpl_msg_set_level(actual_msg_level); 01379 01380 // 01381 // reconstruct 01382 // 01383 KMO_TRY_EXIT_IF_ERROR( 01384 kmo_reconstruct_sci(ifu_nr, 01385 bounds[2*(ifu_nr-1)], 01386 bounds[2*(ifu_nr-1)+1], 01387 obj_sky_struct[sf].objectFrame, 01388 SCIENCE, 01389 sky_frame, 01390 SCIENCE, 01391 flat_frame, 01392 xcal_frame, 01393 ycal_frame, 01394 lcal_frame, 01395 NULL, 01396 &gd, 01397 &cube_data[ifu_nr-1], 01398 &cube_noise[ifu_nr-1], 01399 flux, 01400 background)); 01401 01402 // scale flux according to pixel_scale 01403 KMO_TRY_EXIT_IF_NULL( 01404 tmpImg = cpl_imagelist_get(cube_data[ifu_nr-1], 0)); 01405 double scaling = (cpl_image_get_size_x(tmpImg)*cpl_image_get_size_y(tmpImg)) / 01406 (KMOS_SLITLET_X*KMOS_SLITLET_Y); 01407 KMO_TRY_EXIT_IF_ERROR( 01408 cpl_imagelist_divide_scalar(cube_data[ifu_nr-1], scaling)); 01409 if (cube_noise[ifu_nr-1] != NULL) { 01410 KMO_TRY_EXIT_IF_ERROR( 01411 cpl_imagelist_divide_scalar(cube_noise[ifu_nr-1], scaling)); 01412 } 01413 01414 // 01415 // divide cube by telluric correction 01416 // 01417 if (has_telluric) { 01418 telluric_data = kmo_tweak_load_telluric(frameset, ifu_nr, FALSE, 01419 cube_noise[ifu_nr-1] != NULL); 01420 KMO_TRY_CHECK_ERROR_STATE(); 01421 if (telluric_data != NULL) { 01422 // load noise if present 01423 telluric_noise = kmo_tweak_load_telluric(frameset, ifu_nr, TRUE, 01424 cube_noise[ifu_nr-1] != NULL); 01425 KMO_TRY_CHECK_ERROR_STATE(); 01426 01427 KMO_TRY_EXIT_IF_ERROR( 01428 kmo_arithmetic_3D_1D( 01429 cube_data[ifu_nr-1], telluric_data, 01430 cube_noise[ifu_nr-1], telluric_noise, "/")); 01431 01432 kmclipm_vector_delete(telluric_data); 01433 telluric_data = NULL; 01434 kmclipm_vector_delete(telluric_noise); 01435 telluric_noise = NULL; 01436 } 01437 } 01438 01439 // 01440 // divide cube by illumination correction 01441 // 01442 if (has_illum_corr) { 01443 cpl_msg_set_level(CPL_MSG_OFF); 01444 illum_data = kmo_dfs_load_image(frameset, ILLUM_CORR, 01445 ifu_nr, FALSE, FALSE, NULL); 01446 cpl_msg_set_level(actual_msg_level); 01447 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01448 cpl_msg_warning("","No illumination correction for IFU %d available! " 01449 "Proceeding anyway.", ifu_nr); 01450 cpl_error_reset(); 01451 } else { 01452 cpl_msg_set_level(CPL_MSG_OFF); 01453 illum_noise = kmo_dfs_load_image(frameset, 01454 ILLUM_CORR, 01455 ifu_nr, TRUE, 01456 FALSE, NULL); 01457 cpl_msg_set_level(actual_msg_level); 01458 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01459 cpl_msg_warning("","No illumination correction for IFU %d " 01460 "available! Proceeding anyway.", ifu_nr); 01461 cpl_image_delete(illum_data); illum_data = NULL; 01462 cpl_error_reset(); 01463 } 01464 } 01465 01466 if (illum_data != NULL) { 01467 KMO_TRY_EXIT_IF_ERROR( 01468 kmo_arithmetic_3D_2D( 01469 cube_data[ifu_nr-1], illum_data, 01470 cube_noise[ifu_nr-1], illum_noise, "/")); 01471 cpl_image_delete(illum_data); illum_data = NULL; 01472 cpl_image_delete(illum_noise); illum_noise = NULL; 01473 } 01474 } 01475 01476 // 01477 // calc WCS & update subheader 01478 // 01479 KMO_TRY_EXIT_IF_ERROR( 01480 kmo_calc_wcs_gd(main_header, header_data[ifu_nr-1], ifu_nr, gd)); 01481 01482 KMO_TRY_EXIT_IF_ERROR( 01483 kmclipm_update_property_int(header_data[ifu_nr-1], 01484 NAXIS, 3, 01485 "number of data axes")); 01486 KMO_TRY_EXIT_IF_ERROR( 01487 kmclipm_update_property_int(header_data[ifu_nr-1], 01488 NAXIS1, gd.x.dim, 01489 "length of data axis 1")); 01490 KMO_TRY_EXIT_IF_ERROR( 01491 kmclipm_update_property_int(header_data[ifu_nr-1], 01492 NAXIS2, gd.y.dim, 01493 "length of data axis 2")); 01494 KMO_TRY_EXIT_IF_ERROR( 01495 kmclipm_update_property_int(header_data[ifu_nr-1], 01496 NAXIS3, gd.l.dim, 01497 "length of data axis 3")); 01498 01499 // get object name and store if not already present 01500 KMO_TRY_EXIT_IF_NULL( 01501 keyword = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, ifu_nr, 01502 IFU_NAME_POSTFIX)); 01503 KMO_TRY_EXIT_IF_NULL( 01504 tmp_str = cpl_propertylist_get_string(header_data[ifu_nr-1], 01505 keyword)); 01506 cpl_free(keyword); keyword = NULL; 01507 01508 // found keyword, check if it is already in all_obj 01509 found_name = 0; 01510 for(int i = 0; i < nr_avail_obj_names; i++) { 01511 if (strcmp(all_obj[i].name, tmp_str) == 0) { 01512 found_name = TRUE; 01513 all_obj[i].count++; 01514 break; 01515 } 01516 } 01517 if (!found_name) { 01518 all_obj[nr_avail_obj_names].count++; 01519 KMO_TRY_EXIT_IF_NULL( 01520 all_obj[nr_avail_obj_names++].name = 01521 cpl_sprintf("%s", tmp_str)); 01522 } 01523 } else { 01524 cpl_error_reset(); 01525 01526 // IFU is invalid 01527 } 01528 01529 // duplicate subheader data 01530 KMO_TRY_EXIT_IF_NULL( 01531 header_noise[ifu_nr-1] = 01532 cpl_propertylist_duplicate(header_data[ifu_nr-1])); 01533 01534 KMO_TRY_EXIT_IF_NULL( 01535 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE)); 01536 KMO_TRY_EXIT_IF_ERROR( 01537 kmclipm_update_property_string(header_noise[ifu_nr-1], 01538 EXTNAME, extname, 01539 "FITS extension name")); 01540 cpl_free(extname); extname = NULL; 01541 } // end for ifu_nr 01542 01543 // 01544 // count number of reconstructed data- and noise-cubes 01545 // 01546 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 01547 if (cube_data[ifu_nr-1] != NULL) { 01548 cube_counter_data++; 01549 } 01550 if (cube_noise[ifu_nr-1] != NULL) { 01551 cube_counter_noise++; 01552 } 01553 } 01554 01555 // 01556 // save reconstructed cubes of science frame 01557 // 01558 if (cube_counter_data > 0) { 01559 cpl_msg_info("", " > saving..."); 01560 01561 fn_out = fn_obj; 01562 01563 int nr_found = 0; 01564 // remove any path-elements from filename and use it as 01565 // suffix 01566 split = kmo_strsplit(fn_out, "/", &nr_found); 01567 01568 fn_suffix = cpl_sprintf("_%s", split[nr_found-1]); 01569 kmo_strfreev(split); 01570 01571 // remove '.fits' at the end if there is any 01572 char *fff = fn_suffix; 01573 fff += strlen(fn_suffix)-5; 01574 if (strcmp(fff, ".fits") == 0) { 01575 fn_suffix[strlen(fn_suffix)-5] = '\0'; 01576 } 01577 01578 fn_out = RECONSTRUCTED_CUBE; 01579 01580 KMO_TRY_EXIT_IF_ERROR( 01581 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, 01582 obj_sky_struct[sf].objectFrame, 01583 NULL, parlist, cpl_func)); 01584 01585 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01586 KMO_TRY_EXIT_IF_ERROR( 01587 kmo_dfs_save_cube(cube_data[ifu_nr-1], fn_out, 01588 fn_suffix, header_data[ifu_nr-1], 0./0.)); 01589 01590 if (cube_counter_noise > 0) { 01591 KMO_TRY_EXIT_IF_ERROR( 01592 kmo_dfs_save_cube(cube_noise[ifu_nr-1], fn_out, 01593 fn_suffix, header_noise[ifu_nr-1], 01594 0./0.)); 01595 } 01596 01597 cpl_imagelist_delete(cube_data[ifu_nr-1]); cube_data[ifu_nr-1] = NULL; 01598 cpl_imagelist_delete(cube_noise[ifu_nr-1]); cube_noise[ifu_nr-1] = NULL; 01599 cpl_propertylist_delete(header_data[ifu_nr-1]); header_data[ifu_nr-1] = NULL; 01600 cpl_propertylist_delete(header_noise[ifu_nr-1]); header_noise[ifu_nr-1] = NULL; 01601 } // end for ifu_nr 01602 cpl_free(fn_suffix); fn_suffix = NULL; 01603 } else { 01604 cpl_msg_info("", " > all IFUs invalid, don't save"); 01605 } // if (cube_counter_data > 0) { 01606 01607 cpl_propertylist_delete(main_header); main_header = NULL; 01608 } // end for sf (nr_science_frames) 01609 cpl_free(cube_data); cube_data = NULL; 01610 cpl_free(cube_noise); cube_noise = NULL; 01611 cpl_free(header_data); header_data = NULL; 01612 cpl_free(header_noise); header_noise = NULL; 01613 cpl_msg_info("", "-------------------------------------------"); 01614 01615 if (lcal != NULL) { 01616 for (int i = 0; i < KMOS_NR_DETECTORS; i++) { 01617 cpl_image_delete(lcal[i]); 01618 } 01619 } 01620 cpl_free(lcal); lcal = NULL; 01621 01622 // 01623 // combine 01624 // 01625 if (!no_combine) { 01626 cpl_msg_info("", "Combining reconstructed objects"); 01627 cpl_msg_info("", " "); 01628 01629 nr_reconstructed_frames = cpl_frameset_count_tags(frameset, RECONSTRUCTED_CUBE); 01630 01631 if ( (mapping_mode == NULL) || ((mapping_mode != NULL) && 01632 ((ifus != NULL) || (strcmp(name, "") != 0))) 01633 ) 01634 { 01635 // loop all available objects 01636 for (int i = 0; i < nr_avail_obj_names; i++) { 01637 cpl_msg_info("", " > object: %s", all_obj[i].name); 01638 nr_data_alloc = all_obj[i].count; 01639 KMO_TRY_EXIT_IF_NULL( 01640 cube_data = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01641 sizeof(cpl_imagelist*))); 01642 KMO_TRY_EXIT_IF_NULL( 01643 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01644 sizeof(cpl_imagelist*))); 01645 KMO_TRY_EXIT_IF_NULL( 01646 header_data = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01647 sizeof(cpl_propertylist*))); 01648 KMO_TRY_EXIT_IF_NULL( 01649 header_noise = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01650 sizeof(cpl_propertylist*))); 01651 01652 // setup cube-list and header-list for kmo_priv_combine() 01653 cube_counter_data = 0; 01654 cube_counter_noise = 0; 01655 KMO_TRY_EXIT_IF_NULL( 01656 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01657 while (tmp_frame != NULL ) { 01658 KMO_TRY_EXIT_IF_NULL( 01659 fn_reconstr = cpl_frame_get_filename(tmp_frame)); 01660 01661 KMO_TRY_EXIT_IF_NULL( 01662 tmp_header = kmclipm_propertylist_load(fn_reconstr, 0)); 01663 01664 kmo_free_fits_desc(&desc1); 01665 kmo_init_fits_desc(&desc1); 01666 desc1 = kmo_identify_fits_header(fn_reconstr); 01667 01668 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01669 // check if object-name equals the one in our list 01670 KMO_TRY_EXIT_IF_NULL( 01671 keyword = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, 01672 ifu_nr, IFU_NAME_POSTFIX)); 01673 KMO_TRY_EXIT_IF_NULL( 01674 tmp_str = cpl_propertylist_get_string(tmp_header, 01675 keyword)); 01676 cpl_free(keyword); keyword = NULL; 01677 01678 if (strcmp(all_obj[i].name, tmp_str) == 0) { 01679 // found object-IFU with matching name 01680 // load data & subheader 01681 index = kmo_identify_index(fn_reconstr, ifu_nr, FALSE); 01682 KMO_TRY_CHECK_ERROR_STATE(); 01683 01684 if (desc1.sub_desc[index-1].valid_data) { 01685 KMO_TRY_EXIT_IF_NULL( 01686 cube_data[cube_counter_data] = 01687 kmclipm_imagelist_load(fn_reconstr, 01688 CPL_TYPE_FLOAT, 01689 index)); 01690 if (edge_nan) { 01691 KMO_TRY_EXIT_IF_ERROR( 01692 kmo_edge_nan(cube_data[cube_counter_data], ifu_nr)); 01693 } 01694 01695 KMO_TRY_EXIT_IF_NULL( 01696 header_data[cube_counter_data] = 01697 kmclipm_propertylist_load(fn_reconstr, 01698 index)); 01699 cpl_propertylist_update_string(header_data[cube_counter_data], 01700 "ESO PRO FRNAME", 01701 fn_reconstr); 01702 cpl_propertylist_update_int(header_data[cube_counter_data], 01703 "ESO PRO IFUNR", 01704 index); 01705 cube_counter_data++; 01706 } 01707 01708 // load noise & subheader (if existing) 01709 if (desc1.ex_noise) { 01710 index = kmo_identify_index(fn_reconstr, ifu_nr, TRUE); 01711 KMO_TRY_CHECK_ERROR_STATE(); 01712 01713 if (desc1.sub_desc[index-1].valid_data) { 01714 KMO_TRY_EXIT_IF_NULL( 01715 cube_noise[cube_counter_noise] = 01716 kmclipm_imagelist_load(fn_reconstr, 01717 CPL_TYPE_FLOAT, 01718 index)); 01719 if (edge_nan) { 01720 KMO_TRY_EXIT_IF_ERROR( 01721 kmo_edge_nan(cube_noise[cube_counter_noise], ifu_nr)); 01722 } 01723 KMO_TRY_EXIT_IF_NULL( 01724 header_noise[cube_counter_noise] = 01725 kmclipm_propertylist_load(fn_reconstr, 01726 index)); 01727 cube_counter_noise++; 01728 } 01729 } 01730 cpl_error_reset(); 01731 } // end if found obj 01732 } // end for ifu_nr 01733 01734 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01735 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01736 KMO_TRY_CHECK_ERROR_STATE(); 01737 } // end while-loop RECONSTRUCTED_CUBE frames 01738 01739 if (cube_counter_data > 1) { 01740 if (cube_counter_data == cube_counter_noise) { 01741 KMO_TRY_EXIT_IF_ERROR( 01742 kmo_priv_combine(cube_data, 01743 cube_noise, 01744 header_data, 01745 header_noise, 01746 cube_counter_data, 01747 cube_counter_noise, 01748 all_obj[i].name, 01749 "", 01750 comb_method, 01751 smethod, 01752 fmethod, 01753 filename, 01754 cmethod, 01755 cpos_rej, 01756 cneg_rej, 01757 citer, 01758 cmin, 01759 cmax, 01760 extrapol_enum, 01761 flux, 01762 &combined_data, 01763 &combined_noise)); 01764 } else if (cube_counter_noise == 0) { 01765 // if imethod == "CS" 01766 KMO_TRY_EXIT_IF_ERROR( 01767 kmo_priv_combine(cube_data, 01768 NULL, 01769 header_data, 01770 header_noise, 01771 cube_counter_data, 01772 cube_counter_noise, 01773 all_obj[i].name, 01774 "", 01775 comb_method, 01776 smethod, 01777 fmethod, 01778 filename, 01779 cmethod, 01780 cpos_rej, 01781 cneg_rej, 01782 citer, 01783 cmin, 01784 cmax, 01785 extrapol_enum, 01786 flux, 01787 &combined_data, 01788 &combined_noise)); 01789 } else { 01790 KMO_TRY_ASSURE(1 == 0, 01791 CPL_ERROR_ILLEGAL_INPUT, 01792 "The number of cube-data and cube-noise " 01793 "isn't the same (%d vs. %d)!", 01794 cube_counter_data, cube_counter_noise); 01795 } 01796 } else { 01797 cpl_msg_warning("", "There is only one reconstructed cube with " 01798 "this object! Saving it as it is."); 01799 KMO_TRY_EXIT_IF_NULL( 01800 combined_data = cpl_imagelist_duplicate(cube_data[0])); 01801 01802 if (cube_noise[0] != NULL) { 01803 KMO_TRY_EXIT_IF_NULL( 01804 combined_noise = cpl_imagelist_duplicate(cube_noise[0])); 01805 } 01806 } // end if (cube_counter_data > 1) 01807 01808 fn_out = COMBINED_CUBE; 01809 KMO_TRY_EXIT_IF_NULL( 01810 fn_suffix = cpl_sprintf("_%s", all_obj[i].name)); 01811 01812 // save combined cube 01813 KMO_TRY_EXIT_IF_NULL( 01814 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01815 KMO_TRY_EXIT_IF_ERROR( 01816 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, 01817 tmp_frame, NULL, parlist, cpl_func)); 01818 01819 KMO_TRY_EXIT_IF_ERROR( 01820 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, 01821 header_data[0], 0./0.)); 01822 01823 // if (combined_noise != NULL) { 01824 if (header_noise[0] == NULL) { 01825 KMO_TRY_EXIT_IF_NULL( 01826 header_noise[0] = 01827 cpl_propertylist_duplicate(header_data[0])); 01828 01829 KMO_TRY_EXIT_IF_NULL( 01830 tmp_str = cpl_propertylist_get_string(header_data[0], 01831 EXTNAME)); 01832 KMO_TRY_EXIT_IF_ERROR( 01833 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content)); 01834 KMO_TRY_EXIT_IF_NULL( 01835 extname = kmo_extname_creator(ifu_frame, tmp_int, 01836 EXT_NOISE)); 01837 KMO_TRY_EXIT_IF_ERROR( 01838 kmclipm_update_property_string(header_noise[0], 01839 EXTNAME, extname, 01840 "FITS extension name")); 01841 cpl_free(extname); extname = NULL; 01842 } 01843 KMO_TRY_EXIT_IF_ERROR( 01844 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix, 01845 header_noise[0], 0./0.)); 01846 // } 01847 01848 for (int jj = 0; jj < nr_data_alloc; jj++) { 01849 cpl_imagelist_delete(cube_data[jj]); cube_data[jj] = NULL; 01850 cpl_imagelist_delete(cube_noise[jj]); cube_noise[jj] = NULL; 01851 cpl_propertylist_delete(header_data[jj]); header_data[jj] = NULL; 01852 cpl_propertylist_delete(header_noise[jj]); header_noise[jj] = NULL; 01853 } 01854 cpl_free(cube_data); cube_data = NULL; 01855 cpl_free(cube_noise); cube_noise = NULL; 01856 cpl_free(header_data); header_data = NULL; 01857 cpl_free(header_noise); header_noise = NULL; 01858 cpl_free(fn_suffix); fn_suffix = NULL; 01859 cpl_imagelist_delete(combined_data); combined_data = NULL; 01860 cpl_imagelist_delete(combined_noise); combined_noise = NULL; 01861 } // for i = nr_avail_obj_names 01862 } else { 01863 // we are in mapping_mode 01864 nr_data_alloc = nr_reconstructed_frames*KMOS_NR_IFUS; 01865 KMO_TRY_EXIT_IF_NULL( 01866 cube_data = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01867 sizeof(cpl_imagelist*))); 01868 KMO_TRY_EXIT_IF_NULL( 01869 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01870 sizeof(cpl_imagelist*))); 01871 KMO_TRY_EXIT_IF_NULL( 01872 header_data = (cpl_propertylist**)cpl_calloc( nr_data_alloc, 01873 sizeof(cpl_propertylist*))); 01874 KMO_TRY_EXIT_IF_NULL( 01875 header_noise = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01876 sizeof(cpl_propertylist*))); 01877 01878 cube_counter_data = 0; 01879 cube_counter_noise = 0; 01880 KMO_TRY_EXIT_IF_NULL( 01881 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01882 while (tmp_frame != NULL ) { 01883 KMO_TRY_EXIT_IF_NULL( 01884 fn_reconstr = cpl_frame_get_filename(tmp_frame)); 01885 01886 KMO_TRY_EXIT_IF_NULL( 01887 tmp_header = kmclipm_propertylist_load(fn_reconstr, 0)); 01888 01889 kmo_free_fits_desc(&desc1); 01890 kmo_init_fits_desc(&desc1); 01891 desc1 = kmo_identify_fits_header(fn_reconstr); 01892 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01893 index = kmo_identify_index(fn_reconstr, ifu_nr, FALSE); 01894 KMO_TRY_CHECK_ERROR_STATE(); 01895 01896 if (desc1.sub_desc[index-1].valid_data) { 01897 KMO_TRY_EXIT_IF_NULL( 01898 cube_data[cube_counter_data] = 01899 kmclipm_imagelist_load(fn_reconstr, CPL_TYPE_FLOAT, 01900 index)); 01901 if (edge_nan) { 01902 KMO_TRY_EXIT_IF_ERROR( 01903 kmo_edge_nan(cube_data[cube_counter_data], ifu_nr)); 01904 } 01905 01906 if (fast_mode) { 01907 KMO_TRY_EXIT_IF_NULL( 01908 tmpImg = cpl_imagelist_collapse_median_create(cube_data[cube_counter_data])); 01909 KMO_TRY_EXIT_IF_NULL( 01910 tmpCube = cpl_imagelist_new()); 01911 KMO_TRY_EXIT_IF_ERROR( 01912 cpl_imagelist_set(tmpCube, tmpImg, 0)); 01913 cpl_imagelist_delete(cube_data[cube_counter_data]); 01914 cube_data[cube_counter_data] = tmpCube; 01915 } 01916 01917 KMO_TRY_EXIT_IF_NULL( 01918 header_data[cube_counter_data] = 01919 kmclipm_propertylist_load(fn_reconstr, index)); 01920 cpl_propertylist_update_string(header_data[cube_counter_data], 01921 "ESO PRO FRNAME", 01922 fn_reconstr); 01923 cpl_propertylist_update_int(header_data[cube_counter_data], 01924 "ESO PRO IFUNR", 01925 index); 01926 cube_counter_data++; 01927 } 01928 01929 // load noise & subheader (if existing) 01930 if (desc1.ex_noise) { 01931 index = kmo_identify_index(fn_reconstr, ifu_nr, TRUE); 01932 KMO_TRY_CHECK_ERROR_STATE(); 01933 if (desc1.sub_desc[index-1].valid_data) { 01934 KMO_TRY_EXIT_IF_NULL( 01935 cube_noise[cube_counter_noise] = 01936 kmclipm_imagelist_load(fn_reconstr, CPL_TYPE_FLOAT, 01937 index)); 01938 01939 if (edge_nan) { 01940 KMO_TRY_EXIT_IF_ERROR( 01941 kmo_edge_nan(cube_noise[cube_counter_noise], ifu_nr)); 01942 } 01943 01944 if (fast_mode) { 01945 KMO_TRY_EXIT_IF_NULL( 01946 tmpImg = cpl_imagelist_collapse_median_create(cube_noise[cube_counter_noise])); 01947 KMO_TRY_EXIT_IF_NULL( 01948 tmpCube = cpl_imagelist_new()); 01949 KMO_TRY_EXIT_IF_ERROR( 01950 cpl_imagelist_set(tmpCube, tmpImg, 0)); 01951 cpl_imagelist_delete(cube_noise[cube_counter_noise]); 01952 cube_noise[cube_counter_noise] = tmpCube; 01953 } 01954 KMO_TRY_EXIT_IF_NULL( 01955 header_noise[cube_counter_noise] = 01956 kmclipm_propertylist_load(fn_reconstr, index)); 01957 cube_counter_noise++; 01958 } 01959 } 01960 cpl_error_reset(); 01961 } // end for ifu_nr 01962 01963 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01964 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01965 KMO_TRY_CHECK_ERROR_STATE(); 01966 } // end while-loop RECONSTRUCTED_CUBE frames 01967 01968 if (cube_counter_data > 1) { 01969 if (cube_counter_data == cube_counter_noise) { 01970 KMO_TRY_EXIT_IF_ERROR( 01971 kmo_priv_combine(cube_data, 01972 cube_noise, 01973 header_data, 01974 header_noise, 01975 cube_counter_data, 01976 cube_counter_noise, 01977 mapping_mode, 01978 "", 01979 comb_method, 01980 smethod, 01981 fmethod, 01982 filename, 01983 cmethod, 01984 cpos_rej, 01985 cneg_rej, 01986 citer, 01987 cmin, 01988 cmax, 01989 extrapol_enum, 01990 flux, 01991 &combined_data, 01992 &combined_noise)); 01993 } else if (cube_counter_noise == 0) { 01994 // if imethod == "CS" 01995 KMO_TRY_EXIT_IF_ERROR( 01996 kmo_priv_combine(cube_data, 01997 NULL, 01998 header_data, 01999 header_noise, 02000 cube_counter_data, 02001 cube_counter_noise, 02002 mapping_mode, 02003 "", 02004 comb_method, 02005 smethod, 02006 fmethod, 02007 filename, 02008 cmethod, 02009 cpos_rej, 02010 cneg_rej, 02011 citer, 02012 cmin, 02013 cmax, 02014 extrapol_enum, 02015 flux, 02016 &combined_data, 02017 &combined_noise)); 02018 } else { 02019 KMO_TRY_ASSURE(1 == 0, 02020 CPL_ERROR_ILLEGAL_INPUT, 02021 "The number of cube-data and cube-noise " 02022 "isn't the same (%d vs. %d)!", 02023 cube_counter_data, cube_counter_noise); 02024 } 02025 } else { 02026 cpl_msg_warning("", "There is only one reconstructed cube! " 02027 "Saving it as it is."); 02028 KMO_TRY_EXIT_IF_NULL( 02029 combined_data = cpl_imagelist_duplicate(cube_data[0])); 02030 02031 if (cube_noise[0] != NULL) { 02032 KMO_TRY_EXIT_IF_NULL( 02033 combined_noise = cpl_imagelist_duplicate(cube_noise[0])); 02034 } 02035 } 02036 02037 fn_out = COMBINED_CUBE; 02038 KMO_TRY_EXIT_IF_NULL( 02039 fn_suffix = cpl_sprintf("_%s", mapping_mode)); 02040 02041 // save combined cube 02042 KMO_TRY_EXIT_IF_NULL( 02043 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 02044 KMO_TRY_EXIT_IF_ERROR( 02045 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, tmp_frame, 02046 NULL, parlist, cpl_func)); 02047 02048 KMO_TRY_EXIT_IF_ERROR( 02049 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, 02050 header_data[0], 0./0.)); 02051 02052 // if (combined_noise != NULL) { 02053 if (header_noise[0] == NULL) { 02054 KMO_TRY_EXIT_IF_NULL( 02055 header_noise[0] = 02056 cpl_propertylist_duplicate(header_data[0])); 02057 02058 KMO_TRY_EXIT_IF_NULL( 02059 tmp_str = cpl_propertylist_get_string(header_data[0], 02060 EXTNAME)); 02061 KMO_TRY_EXIT_IF_ERROR( 02062 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content)); 02063 KMO_TRY_EXIT_IF_NULL( 02064 extname = kmo_extname_creator(ifu_frame, tmp_int, 02065 EXT_NOISE)); 02066 KMO_TRY_EXIT_IF_ERROR( 02067 kmclipm_update_property_string(header_noise[0], 02068 EXTNAME, extname, 02069 "FITS extension name")); 02070 cpl_free(extname); extname = NULL; 02071 } 02072 KMO_TRY_EXIT_IF_ERROR( 02073 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix, 02074 header_noise[0], 0./0.)); 02075 // } 02076 02077 for (int i = 0; i < nr_data_alloc; i++) { 02078 cpl_imagelist_delete(cube_data[i]); cube_data[i] = NULL; 02079 cpl_imagelist_delete(cube_noise[i]); cube_noise[i] = NULL; 02080 cpl_propertylist_delete(header_data[i]); header_data[i] = NULL; 02081 cpl_propertylist_delete(header_noise[i]); header_noise[i] = NULL; 02082 } 02083 cpl_free(cube_data); cube_data = NULL; 02084 cpl_free(cube_noise); cube_noise = NULL; 02085 cpl_free(header_data); header_data = NULL; 02086 cpl_free(header_noise); header_noise = NULL; 02087 cpl_free(fn_suffix); fn_suffix = NULL; 02088 cpl_imagelist_delete(combined_data); combined_data = NULL; 02089 cpl_imagelist_delete(combined_noise); combined_noise = NULL; 02090 } // if mapping_mode 02091 } else { 02092 cpl_msg_info("", "NOT combining reconstructed objects (--no_combine is set)"); 02093 } // if (!no_combine) 02094 02095 cpl_msg_info("", "-------------------------------------------"); 02096 } 02097 KMO_CATCH 02098 { 02099 KMO_CATCH_MSG(); 02100 ret_val = -1; 02101 } 02102 02103 if (cube_data != NULL) { 02104 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02105 cpl_imagelist_delete(cube_data[ifu_nr-1]); cube_data[ifu_nr-1] = NULL; 02106 } 02107 } 02108 cpl_free(cube_data); cube_data = NULL; 02109 if (cube_noise != NULL) { 02110 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02111 cpl_imagelist_delete(cube_noise[ifu_nr-1]); cube_noise[ifu_nr-1] = NULL; 02112 } 02113 } 02114 cpl_free(cube_noise); cube_noise = NULL; 02115 if (header_data != NULL) { 02116 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02117 cpl_propertylist_delete(header_data[ifu_nr-1]); header_data[ifu_nr-1] = NULL; 02118 } 02119 } 02120 cpl_free(header_data); header_data = NULL; 02121 if (header_noise != NULL) { 02122 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02123 cpl_propertylist_delete(header_noise[ifu_nr-1]); header_noise[ifu_nr-1] = NULL; 02124 } 02125 } 02126 cpl_free(header_noise); header_noise = NULL; 02127 02128 02129 kmo_free_fits_desc(&desc1); 02130 kmo_free_fits_desc(&desc2); 02131 cpl_vector_delete(ifus); ifus = NULL; 02132 cpl_free(mapping_mode); mapping_mode = NULL; 02133 if (unused_ifus != NULL) { 02134 kmo_free_unused_ifus(unused_ifus); unused_ifus = NULL; 02135 } 02136 if (bounds != NULL) { 02137 cpl_free(bounds); bounds = NULL; 02138 } 02139 if (obj_sky_struct != NULL) { 02140 cpl_free(obj_sky_struct); obj_sky_struct = NULL; 02141 } 02142 02143 // frees for the case of errors 02144 kmclipm_vector_delete(telluric_data); telluric_data = NULL; 02145 kmclipm_vector_delete(telluric_noise); telluric_noise = NULL; 02146 cpl_image_delete(illum_data); illum_data = NULL; 02147 cpl_image_delete(illum_noise); illum_noise = NULL; 02148 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 02149 cpl_table_delete(band_table); band_table = NULL; 02150 cpl_propertylist_delete(main_header); main_header = NULL; 02151 if (lcal != NULL) { 02152 for (int i = 0; i < KMOS_NR_DETECTORS; i++) { 02153 cpl_image_delete(lcal[i]); 02154 } 02155 } 02156 cpl_free(lcal); lcal = NULL; 02157 cpl_free(fn_suffix); fn_suffix = NULL; 02158 cpl_free(suffix); suffix = NULL; 02159 02160 if (all_obj != NULL) { 02161 for (int i = 0; i < nr_science_frames*KMOS_NR_IFUS; i++) { 02162 cpl_free(all_obj[i].name); 02163 } 02164 } 02165 cpl_free(all_obj); all_obj = NULL; 02166 02167 return ret_val; 02168 } 02169
1.7.6.1