|
KMOS Pipeline Reference Manual
1.1.2
|
00001 /* $Id: kmo_sci_red.c,v 1.56 2013/05/08 10:05:25 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/08 10:05:25 $ 00024 * $Revision: 1.56 $ 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 // 01189 // load lcal-frames 01190 // 01191 KMO_TRY_EXIT_IF_NULL( 01192 lcal = (cpl_image**) 01193 cpl_calloc(KMOS_NR_DETECTORS, sizeof(cpl_image*))); 01194 for (int i = 0; i < KMOS_NR_DETECTORS; i++) { 01195 KMO_TRY_EXIT_IF_NULL( 01196 lcal[i] = kmo_dfs_load_image(frameset, LCAL, i+1, FALSE, FALSE, NULL)); 01197 } 01198 01199 // 01200 // allocate intermediate memory 01201 // 01202 KMO_TRY_EXIT_IF_NULL( 01203 all_obj = (allObjStruct*)cpl_calloc(nr_science_frames * KMOS_NR_IFUS, sizeof(allObjStruct))); 01204 01205 // initialize intermediate memory 01206 for (int i = 0; i < nr_science_frames * KMOS_NR_IFUS; i++) { 01207 all_obj[i].name = NULL; 01208 all_obj[i].count = 0; 01209 } 01210 01211 nr_data_alloc = KMOS_NR_IFUS; 01212 KMO_TRY_EXIT_IF_NULL( 01213 cube_data = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01214 sizeof(cpl_imagelist*))); 01215 KMO_TRY_EXIT_IF_NULL( 01216 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01217 sizeof(cpl_imagelist*))); 01218 KMO_TRY_EXIT_IF_NULL( 01219 header_data = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01220 sizeof(cpl_propertylist*))); 01221 KMO_TRY_EXIT_IF_NULL( 01222 header_noise = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01223 sizeof(cpl_propertylist*))); 01224 01225 if (cpl_frameset_count_tags(frameset, SCIENCE) == 1) { 01226 no_combine = TRUE; 01227 cpl_msg_info("", "--no_combine has been set to TRUE since there is only one SCIENCE frame!"); 01228 } 01229 01230 if (no_subtract) { 01231 no_combine = TRUE; 01232 cpl_msg_info("", "--no_combine has been set to TRUE since --no_subtract has been specified by the user!"); 01233 cpl_msg_info("", "Combining cubes would combine skies and obejcts which is meaningless."); 01234 cpl_msg_info("", "This can be done manually with the recipe kmo_combine afterwards!"); 01235 } 01236 01237 // 01238 // loop all science frames containing at least one object 01239 // 01240 cpl_msg_info("", "-------------------------------------------"); 01241 cpl_msg_info("", "Reconstructing & saving cubes containing objects"); 01242 cpl_msg_info("", " "); 01243 for (int sf = 0; sf < nr_science_frames; sf++) { 01244 KMO_TRY_EXIT_IF_NULL( 01245 fn_obj = cpl_frame_get_filename( 01246 obj_sky_struct[sf].objectFrame)); 01247 01248 KMO_TRY_EXIT_IF_NULL( 01249 main_header = kmclipm_propertylist_load(fn_obj, 0)); 01250 01251 // get ifu and detector number to work at 01252 actual_msg_level = cpl_msg_get_level(); 01253 user_defined_ifu = 0; 01254 if ((ifus != NULL) || (strcmp(name, "") != 0)) { 01255 if (ifus != NULL) { 01256 // user specified IFUs 01257 user_defined_ifu = cpl_vector_get(ifus, sf); 01258 KMO_TRY_CHECK_ERROR_STATE(); 01259 01260 if (user_defined_ifu < 1) { 01261 user_defined_ifu = -1; 01262 } 01263 } else { 01264 // user specified an object name 01265 cpl_msg_set_level(CPL_MSG_OFF); 01266 user_defined_ifu = 01267 kmo_get_index_from_ocs_name(obj_sky_struct[sf].objectFrame, 01268 name); 01269 cpl_msg_set_level(actual_msg_level); 01270 if (user_defined_ifu == -1) { 01271 cpl_error_reset(); 01272 } 01273 KMO_TRY_CHECK_ERROR_STATE(); 01274 } 01275 } 01276 01277 // 01278 // reconstruct science frame 01279 // 01280 cpl_msg_info("", " > processing frame: %s", fn_obj); 01281 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) 01282 { 01283 det_nr = (ifu_nr - 1)/KMOS_IFUS_PER_DETECTOR + 1; 01284 01285 KMO_TRY_ASSURE((det_nr >= 1) && 01286 (det_nr <= KMOS_NR_DETECTORS), 01287 CPL_ERROR_ILLEGAL_INPUT, 01288 "The provided ifu-numbers are incorrect! They " 01289 "must be between 1 and %d", KMOS_NR_IFUS); 01290 01291 KMO_TRY_EXIT_IF_NULL( 01292 punused_ifus = cpl_array_get_data_int_const( 01293 unused_ifus[det_nr-1])); 01294 01295 // get subheader data 01296 KMO_TRY_EXIT_IF_NULL( 01297 header_data[ifu_nr-1] = kmclipm_propertylist_load(fn_obj, 01298 det_nr)); 01299 KMO_TRY_EXIT_IF_NULL( 01300 extname = kmo_extname_creator(ifu_frame, ifu_nr, 01301 EXT_DATA)); 01302 KMO_TRY_EXIT_IF_ERROR( 01303 kmclipm_update_property_string(header_data[ifu_nr-1], 01304 EXTNAME, extname, 01305 "FITS extension name")); 01306 cpl_free(extname); extname = NULL; 01307 01308 // Search for keyword ESO OCS ARMi NOTUSED 01309 // If not present (CPL_ERROR_DATA_NOT_FOUND), do nothing 01310 KMO_TRY_EXIT_IF_NULL( 01311 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, 01312 IFU_VALID_POSTFIX)); 01313 tmp_str = cpl_propertylist_get_string(main_header, keyword); 01314 cpl_free(keyword); keyword = NULL; 01315 01316 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 01317 (bounds[2*(ifu_nr-1)] != -1) && 01318 (bounds[2*(ifu_nr-1)+1] != -1) && 01319 ((obj_sky_struct[sf].skyframes[ifu_nr-1] != NULL) || (cpl_frameset_count_tags(frameset, SCIENCE) == 1) || no_subtract) && 01320 (punused_ifus[(ifu_nr-1) % KMOS_IFUS_PER_DETECTOR] == 0) && 01321 ((user_defined_ifu == 0) || (user_defined_ifu == ifu_nr))) 01322 { 01323 // IFU is valid 01324 cpl_error_reset(); 01325 01326 if ((obj_sky_struct[sf].skyframes[ifu_nr-1] != NO_CORRESPONDING_SKYFRAME) && 01327 (cpl_frameset_count_tags(frameset, SCIENCE) != 1) && 01328 !no_subtract) 01329 { 01330 if (no_subtract) { 01331 sky_frame = NULL; 01332 cpl_msg_warning("", " > Omit sky subtraction on IFU %d", ifu_nr); 01333 } else { 01334 sky_frame = obj_sky_struct[sf].skyframes[ifu_nr-1]; 01335 KMO_TRY_EXIT_IF_NULL( 01336 fn_sky = cpl_frame_get_filename(sky_frame)); 01337 cpl_msg_info("", " > IFU %d (with sky in frame: %s)", ifu_nr, fn_sky); 01338 } 01339 } else { 01340 sky_frame = NULL; 01341 if ((cpl_frameset_count_tags(frameset, SCIENCE) != 1) && (!no_subtract)) { 01342 cpl_msg_warning("", " > IFU %d with no corresponding sky frame", ifu_nr); 01343 } 01344 } 01345 01346 // get filter for this detector and setup grid definition 01347 // ESO INS FILTi ID 01348 char *tmp_band_method = getenv("KMO_BAND_METHOD"); 01349 int band_method = 0; 01350 if (tmp_band_method != NULL) { 01351 band_method = atoi(tmp_band_method); 01352 } 01353 01354 KMO_TRY_EXIT_IF_NULL( 01355 keyword = cpl_sprintf("%s%d%s", 01356 IFU_FILTID_PREFIX, det_nr, 01357 IFU_FILTID_POSTFIX)); 01358 KMO_TRY_EXIT_IF_NULL( 01359 filter_id = cpl_propertylist_get_string(main_header, 01360 keyword)); 01361 cpl_free(keyword); keyword = NULL; 01362 01363 if (print_once) { 01364 cpl_msg_set_level(CPL_MSG_WARNING); 01365 } 01366 01367 KMO_TRY_EXIT_IF_NULL( 01368 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 01369 1, 0)); 01370 KMO_TRY_EXIT_IF_ERROR( 01371 kmclipm_setup_grid_band_lcal(&gd, lcal[det_nr-1], 01372 filter_id, band_method, 01373 band_table)); 01374 cpl_table_delete(band_table); band_table = NULL; 01375 01376 print_once = TRUE; 01377 cpl_msg_set_level(actual_msg_level); 01378 01379 // 01380 // reconstruct 01381 // 01382 KMO_TRY_EXIT_IF_ERROR( 01383 kmo_reconstruct_sci(ifu_nr, 01384 bounds[2*(ifu_nr-1)], 01385 bounds[2*(ifu_nr-1)+1], 01386 obj_sky_struct[sf].objectFrame, 01387 SCIENCE, 01388 sky_frame, 01389 SCIENCE, 01390 flat_frame, 01391 xcal_frame, 01392 ycal_frame, 01393 lcal_frame, 01394 NULL, 01395 &gd, 01396 &cube_data[ifu_nr-1], 01397 &cube_noise[ifu_nr-1], 01398 flux, 01399 background)); 01400 01401 // 01402 // divide cube by telluric correction 01403 // 01404 if (has_telluric) { 01405 telluric_data = kmo_tweak_load_telluric(frameset, ifu_nr, FALSE, 01406 cube_noise[ifu_nr-1] != NULL); 01407 KMO_TRY_CHECK_ERROR_STATE(); 01408 if (telluric_data != NULL) { 01409 // load noise if present 01410 telluric_noise = kmo_tweak_load_telluric(frameset, ifu_nr, TRUE, 01411 cube_noise[ifu_nr-1] != NULL); 01412 KMO_TRY_CHECK_ERROR_STATE(); 01413 01414 KMO_TRY_EXIT_IF_ERROR( 01415 kmo_arithmetic_3D_1D( 01416 cube_data[ifu_nr-1], telluric_data, 01417 cube_noise[ifu_nr-1], telluric_noise, "/")); 01418 01419 kmclipm_vector_delete(telluric_data); 01420 telluric_data = NULL; 01421 kmclipm_vector_delete(telluric_noise); 01422 telluric_noise = NULL; 01423 } 01424 } 01425 01426 // 01427 // divide cube by illumination correction 01428 // 01429 if (has_illum_corr) { 01430 cpl_msg_set_level(CPL_MSG_OFF); 01431 illum_data = kmo_dfs_load_image(frameset, ILLUM_CORR, 01432 ifu_nr, FALSE, FALSE, NULL); 01433 cpl_msg_set_level(actual_msg_level); 01434 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01435 cpl_msg_warning("","No illumination correction for IFU %d available! " 01436 "Proceeding anyway.", ifu_nr); 01437 cpl_error_reset(); 01438 } else { 01439 cpl_msg_set_level(CPL_MSG_OFF); 01440 illum_noise = kmo_dfs_load_image(frameset, 01441 ILLUM_CORR, 01442 ifu_nr, TRUE, 01443 FALSE, NULL); 01444 cpl_msg_set_level(actual_msg_level); 01445 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01446 cpl_msg_warning("","No illumination correction for IFU %d " 01447 "available! Proceeding anyway.", ifu_nr); 01448 cpl_image_delete(illum_data); illum_data = NULL; 01449 cpl_error_reset(); 01450 } 01451 } 01452 01453 if (illum_data != NULL) { 01454 KMO_TRY_EXIT_IF_ERROR( 01455 kmo_arithmetic_3D_2D( 01456 cube_data[ifu_nr-1], illum_data, 01457 cube_noise[ifu_nr-1], illum_noise, "/")); 01458 cpl_image_delete(illum_data); illum_data = NULL; 01459 cpl_image_delete(illum_noise); illum_noise = NULL; 01460 } 01461 } 01462 01463 // 01464 // calc WCS & update subheader 01465 // 01466 KMO_TRY_EXIT_IF_ERROR( 01467 kmo_calc_wcs_gd(main_header, header_data[ifu_nr-1], ifu_nr, gd)); 01468 01469 KMO_TRY_EXIT_IF_ERROR( 01470 kmclipm_update_property_int(header_data[ifu_nr-1], 01471 NAXIS, 3, 01472 "number of data axes")); 01473 KMO_TRY_EXIT_IF_ERROR( 01474 kmclipm_update_property_int(header_data[ifu_nr-1], 01475 NAXIS1, gd.x.dim, 01476 "length of data axis 1")); 01477 KMO_TRY_EXIT_IF_ERROR( 01478 kmclipm_update_property_int(header_data[ifu_nr-1], 01479 NAXIS2, gd.y.dim, 01480 "length of data axis 2")); 01481 KMO_TRY_EXIT_IF_ERROR( 01482 kmclipm_update_property_int(header_data[ifu_nr-1], 01483 NAXIS3, gd.l.dim, 01484 "length of data axis 3")); 01485 01486 // get object name and store if not already present 01487 KMO_TRY_EXIT_IF_NULL( 01488 keyword = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, ifu_nr, 01489 IFU_NAME_POSTFIX)); 01490 KMO_TRY_EXIT_IF_NULL( 01491 tmp_str = cpl_propertylist_get_string(header_data[ifu_nr-1], 01492 keyword)); 01493 cpl_free(keyword); keyword = NULL; 01494 01495 // found keyword, check if it is already in all_obj 01496 found_name = 0; 01497 for(int i = 0; i < nr_avail_obj_names; i++) { 01498 if (strcmp(all_obj[i].name, tmp_str) == 0) { 01499 found_name = TRUE; 01500 all_obj[i].count++; 01501 break; 01502 } 01503 } 01504 if (!found_name) { 01505 all_obj[nr_avail_obj_names].count++; 01506 KMO_TRY_EXIT_IF_NULL( 01507 all_obj[nr_avail_obj_names++].name = 01508 cpl_sprintf("%s", tmp_str)); 01509 } 01510 } else { 01511 cpl_error_reset(); 01512 01513 // IFU is invalid 01514 } 01515 01516 // duplicate subheader data 01517 KMO_TRY_EXIT_IF_NULL( 01518 header_noise[ifu_nr-1] = 01519 cpl_propertylist_duplicate(header_data[ifu_nr-1])); 01520 01521 KMO_TRY_EXIT_IF_NULL( 01522 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE)); 01523 KMO_TRY_EXIT_IF_ERROR( 01524 kmclipm_update_property_string(header_noise[ifu_nr-1], 01525 EXTNAME, extname, 01526 "FITS extension name")); 01527 cpl_free(extname); extname = NULL; 01528 } // end for ifu_nr 01529 01530 // 01531 // count number of reconstructed data- and noise-cubes 01532 // 01533 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 01534 if (cube_data[ifu_nr-1] != NULL) { 01535 cube_counter_data++; 01536 } 01537 if (cube_noise[ifu_nr-1] != NULL) { 01538 cube_counter_noise++; 01539 } 01540 } 01541 01542 // 01543 // save reconstructed cubes of science frame 01544 // 01545 if (cube_counter_data > 0) { 01546 cpl_msg_info("", " > saving..."); 01547 01548 fn_out = fn_obj; 01549 01550 int nr_found = 0; 01551 // remove any path-elements from filename and use it as 01552 // suffix 01553 split = kmo_strsplit(fn_out, "/", &nr_found); 01554 01555 fn_suffix = cpl_sprintf("_%s", split[nr_found-1]); 01556 kmo_strfreev(split); 01557 01558 // remove '.fits' at the end if there is any 01559 char *fff = fn_suffix; 01560 fff += strlen(fn_suffix)-5; 01561 if (strcmp(fff, ".fits") == 0) { 01562 fn_suffix[strlen(fn_suffix)-5] = '\0'; 01563 } 01564 01565 fn_out = RECONSTRUCTED_CUBE; 01566 01567 KMO_TRY_EXIT_IF_ERROR( 01568 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, 01569 obj_sky_struct[sf].objectFrame, 01570 NULL, parlist, cpl_func)); 01571 01572 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01573 KMO_TRY_EXIT_IF_ERROR( 01574 kmo_dfs_save_cube(cube_data[ifu_nr-1], fn_out, 01575 fn_suffix, header_data[ifu_nr-1], 0./0.)); 01576 01577 if (cube_counter_noise > 0) { 01578 KMO_TRY_EXIT_IF_ERROR( 01579 kmo_dfs_save_cube(cube_noise[ifu_nr-1], fn_out, 01580 fn_suffix, header_noise[ifu_nr-1], 01581 0./0.)); 01582 } 01583 01584 cpl_imagelist_delete(cube_data[ifu_nr-1]); cube_data[ifu_nr-1] = NULL; 01585 cpl_imagelist_delete(cube_noise[ifu_nr-1]); cube_noise[ifu_nr-1] = NULL; 01586 cpl_propertylist_delete(header_data[ifu_nr-1]); header_data[ifu_nr-1] = NULL; 01587 cpl_propertylist_delete(header_noise[ifu_nr-1]); header_noise[ifu_nr-1] = NULL; 01588 } // end for ifu_nr 01589 cpl_free(fn_suffix); fn_suffix = NULL; 01590 } else { 01591 cpl_msg_info("", " > all IFUs invalid, don't save"); 01592 } // if (cube_counter_data > 0) { 01593 01594 cpl_propertylist_delete(main_header); main_header = NULL; 01595 } // end for sf (nr_science_frames) 01596 cpl_free(cube_data); cube_data = NULL; 01597 cpl_free(cube_noise); cube_noise = NULL; 01598 cpl_free(header_data); header_data = NULL; 01599 cpl_free(header_noise); header_noise = NULL; 01600 cpl_msg_info("", "-------------------------------------------"); 01601 01602 if (lcal != NULL) { 01603 for (int i = 0; i < KMOS_NR_DETECTORS; i++) { 01604 cpl_image_delete(lcal[i]); 01605 } 01606 } 01607 cpl_free(lcal); lcal = NULL; 01608 01609 // 01610 // combine 01611 // 01612 if (!no_combine) { 01613 cpl_msg_info("", "Combining reconstructed objects"); 01614 cpl_msg_info("", " "); 01615 01616 nr_reconstructed_frames = cpl_frameset_count_tags(frameset, RECONSTRUCTED_CUBE); 01617 01618 if ( (mapping_mode == NULL) || ((mapping_mode != NULL) && 01619 ((ifus != NULL) || (strcmp(name, "") != 0))) 01620 ) 01621 { 01622 // loop all available objects 01623 for (int i = 0; i < nr_avail_obj_names; i++) { 01624 cpl_msg_info("", " > object: %s", all_obj[i].name); 01625 nr_data_alloc = all_obj[i].count; 01626 KMO_TRY_EXIT_IF_NULL( 01627 cube_data = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01628 sizeof(cpl_imagelist*))); 01629 KMO_TRY_EXIT_IF_NULL( 01630 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01631 sizeof(cpl_imagelist*))); 01632 KMO_TRY_EXIT_IF_NULL( 01633 header_data = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01634 sizeof(cpl_propertylist*))); 01635 KMO_TRY_EXIT_IF_NULL( 01636 header_noise = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01637 sizeof(cpl_propertylist*))); 01638 01639 // setup cube-list and header-list for kmo_priv_combine() 01640 cube_counter_data = 0; 01641 cube_counter_noise = 0; 01642 KMO_TRY_EXIT_IF_NULL( 01643 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01644 while (tmp_frame != NULL ) { 01645 KMO_TRY_EXIT_IF_NULL( 01646 fn_reconstr = cpl_frame_get_filename(tmp_frame)); 01647 01648 KMO_TRY_EXIT_IF_NULL( 01649 tmp_header = kmclipm_propertylist_load(fn_reconstr, 0)); 01650 01651 kmo_free_fits_desc(&desc1); 01652 kmo_init_fits_desc(&desc1); 01653 desc1 = kmo_identify_fits_header(fn_reconstr); 01654 01655 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01656 // check if object-name equals the one in our list 01657 KMO_TRY_EXIT_IF_NULL( 01658 keyword = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, 01659 ifu_nr, IFU_NAME_POSTFIX)); 01660 KMO_TRY_EXIT_IF_NULL( 01661 tmp_str = cpl_propertylist_get_string(tmp_header, 01662 keyword)); 01663 cpl_free(keyword); keyword = NULL; 01664 01665 if (strcmp(all_obj[i].name, tmp_str) == 0) { 01666 // found object-IFU with matching name 01667 // load data & subheader 01668 index = kmo_identify_index(fn_reconstr, ifu_nr, FALSE); 01669 KMO_TRY_CHECK_ERROR_STATE(); 01670 01671 if (desc1.sub_desc[index-1].valid_data) { 01672 KMO_TRY_EXIT_IF_NULL( 01673 cube_data[cube_counter_data] = 01674 kmclipm_imagelist_load(fn_reconstr, 01675 CPL_TYPE_FLOAT, 01676 index)); 01677 if (edge_nan) { 01678 KMO_TRY_EXIT_IF_ERROR( 01679 kmo_edge_nan(cube_data[cube_counter_data], ifu_nr)); 01680 } 01681 01682 KMO_TRY_EXIT_IF_NULL( 01683 header_data[cube_counter_data] = 01684 kmclipm_propertylist_load(fn_reconstr, 01685 index)); 01686 cpl_propertylist_update_string(header_data[cube_counter_data], 01687 "ESO PRO FRNAME", 01688 fn_reconstr); 01689 cpl_propertylist_update_int(header_data[cube_counter_data], 01690 "ESO PRO IFUNR", 01691 index); 01692 cube_counter_data++; 01693 } 01694 01695 // load noise & subheader (if existing) 01696 if (desc1.ex_noise) { 01697 index = kmo_identify_index(fn_reconstr, ifu_nr, TRUE); 01698 KMO_TRY_CHECK_ERROR_STATE(); 01699 01700 if (desc1.sub_desc[index-1].valid_data) { 01701 KMO_TRY_EXIT_IF_NULL( 01702 cube_noise[cube_counter_noise] = 01703 kmclipm_imagelist_load(fn_reconstr, 01704 CPL_TYPE_FLOAT, 01705 index)); 01706 if (edge_nan) { 01707 KMO_TRY_EXIT_IF_ERROR( 01708 kmo_edge_nan(cube_noise[cube_counter_noise], ifu_nr)); 01709 } 01710 KMO_TRY_EXIT_IF_NULL( 01711 header_noise[cube_counter_noise] = 01712 kmclipm_propertylist_load(fn_reconstr, 01713 index)); 01714 cube_counter_noise++; 01715 } 01716 } 01717 cpl_error_reset(); 01718 } // end if found obj 01719 } // end for ifu_nr 01720 01721 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01722 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01723 KMO_TRY_CHECK_ERROR_STATE(); 01724 } // end while-loop RECONSTRUCTED_CUBE frames 01725 01726 if (cube_counter_data > 1) { 01727 if (cube_counter_data == cube_counter_noise) { 01728 KMO_TRY_EXIT_IF_ERROR( 01729 kmo_priv_combine(cube_data, 01730 cube_noise, 01731 header_data, 01732 header_noise, 01733 cube_counter_data, 01734 cube_counter_noise, 01735 all_obj[i].name, 01736 "", 01737 comb_method, 01738 smethod, 01739 fmethod, 01740 filename, 01741 cmethod, 01742 cpos_rej, 01743 cneg_rej, 01744 citer, 01745 cmin, 01746 cmax, 01747 extrapol_enum, 01748 flux, 01749 &combined_data, 01750 &combined_noise)); 01751 } else if (cube_counter_noise == 0) { 01752 // if imethod == "CS" 01753 KMO_TRY_EXIT_IF_ERROR( 01754 kmo_priv_combine(cube_data, 01755 NULL, 01756 header_data, 01757 header_noise, 01758 cube_counter_data, 01759 cube_counter_noise, 01760 all_obj[i].name, 01761 "", 01762 comb_method, 01763 smethod, 01764 fmethod, 01765 filename, 01766 cmethod, 01767 cpos_rej, 01768 cneg_rej, 01769 citer, 01770 cmin, 01771 cmax, 01772 extrapol_enum, 01773 flux, 01774 &combined_data, 01775 &combined_noise)); 01776 } else { 01777 KMO_TRY_ASSURE(1 == 0, 01778 CPL_ERROR_ILLEGAL_INPUT, 01779 "The number of cube-data and cube-noise " 01780 "isn't the same (%d vs. %d)!", 01781 cube_counter_data, cube_counter_noise); 01782 } 01783 } else { 01784 cpl_msg_warning("", "There is only one reconstructed cube with " 01785 "this object! Saving it as it is."); 01786 KMO_TRY_EXIT_IF_NULL( 01787 combined_data = cpl_imagelist_duplicate(cube_data[0])); 01788 01789 if (cube_noise[0] != NULL) { 01790 KMO_TRY_EXIT_IF_NULL( 01791 combined_noise = cpl_imagelist_duplicate(cube_noise[0])); 01792 } 01793 } // end if (cube_counter_data > 1) 01794 01795 fn_out = COMBINED_CUBE; 01796 KMO_TRY_EXIT_IF_NULL( 01797 fn_suffix = cpl_sprintf("_%s", all_obj[i].name)); 01798 01799 // save combined cube 01800 KMO_TRY_EXIT_IF_NULL( 01801 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01802 KMO_TRY_EXIT_IF_ERROR( 01803 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, 01804 tmp_frame, NULL, parlist, cpl_func)); 01805 01806 KMO_TRY_EXIT_IF_ERROR( 01807 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, 01808 header_data[0], 0./0.)); 01809 01810 // if (combined_noise != NULL) { 01811 if (header_noise[0] == NULL) { 01812 KMO_TRY_EXIT_IF_NULL( 01813 header_noise[0] = 01814 cpl_propertylist_duplicate(header_data[0])); 01815 01816 KMO_TRY_EXIT_IF_NULL( 01817 tmp_str = cpl_propertylist_get_string(header_data[0], 01818 EXTNAME)); 01819 KMO_TRY_EXIT_IF_ERROR( 01820 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content)); 01821 KMO_TRY_EXIT_IF_NULL( 01822 extname = kmo_extname_creator(ifu_frame, tmp_int, 01823 EXT_NOISE)); 01824 KMO_TRY_EXIT_IF_ERROR( 01825 kmclipm_update_property_string(header_noise[0], 01826 EXTNAME, extname, 01827 "FITS extension name")); 01828 cpl_free(extname); extname = NULL; 01829 } 01830 KMO_TRY_EXIT_IF_ERROR( 01831 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix, 01832 header_noise[0], 0./0.)); 01833 // } 01834 01835 for (int jj = 0; jj < nr_data_alloc; jj++) { 01836 cpl_imagelist_delete(cube_data[jj]); cube_data[jj] = NULL; 01837 cpl_imagelist_delete(cube_noise[jj]); cube_noise[jj] = NULL; 01838 cpl_propertylist_delete(header_data[jj]); header_data[jj] = NULL; 01839 cpl_propertylist_delete(header_noise[jj]); header_noise[jj] = NULL; 01840 } 01841 cpl_free(cube_data); cube_data = NULL; 01842 cpl_free(cube_noise); cube_noise = NULL; 01843 cpl_free(header_data); header_data = NULL; 01844 cpl_free(header_noise); header_noise = NULL; 01845 cpl_free(fn_suffix); fn_suffix = NULL; 01846 cpl_imagelist_delete(combined_data); combined_data = NULL; 01847 cpl_imagelist_delete(combined_noise); combined_noise = NULL; 01848 } // for i = nr_avail_obj_names 01849 } else { 01850 // we are in mapping_mode 01851 nr_data_alloc = nr_reconstructed_frames*KMOS_NR_IFUS; 01852 KMO_TRY_EXIT_IF_NULL( 01853 cube_data = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01854 sizeof(cpl_imagelist*))); 01855 KMO_TRY_EXIT_IF_NULL( 01856 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data_alloc, 01857 sizeof(cpl_imagelist*))); 01858 KMO_TRY_EXIT_IF_NULL( 01859 header_data = (cpl_propertylist**)cpl_calloc( nr_data_alloc, 01860 sizeof(cpl_propertylist*))); 01861 KMO_TRY_EXIT_IF_NULL( 01862 header_noise = (cpl_propertylist**)cpl_calloc(nr_data_alloc, 01863 sizeof(cpl_propertylist*))); 01864 01865 cube_counter_data = 0; 01866 cube_counter_noise = 0; 01867 KMO_TRY_EXIT_IF_NULL( 01868 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 01869 while (tmp_frame != NULL ) { 01870 KMO_TRY_EXIT_IF_NULL( 01871 fn_reconstr = cpl_frame_get_filename(tmp_frame)); 01872 01873 KMO_TRY_EXIT_IF_NULL( 01874 tmp_header = kmclipm_propertylist_load(fn_reconstr, 0)); 01875 01876 kmo_free_fits_desc(&desc1); 01877 kmo_init_fits_desc(&desc1); 01878 desc1 = kmo_identify_fits_header(fn_reconstr); 01879 for (int ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01880 index = kmo_identify_index(fn_reconstr, ifu_nr, FALSE); 01881 KMO_TRY_CHECK_ERROR_STATE(); 01882 01883 if (desc1.sub_desc[index-1].valid_data) { 01884 KMO_TRY_EXIT_IF_NULL( 01885 cube_data[cube_counter_data] = 01886 kmclipm_imagelist_load(fn_reconstr, CPL_TYPE_FLOAT, 01887 index)); 01888 if (edge_nan) { 01889 KMO_TRY_EXIT_IF_ERROR( 01890 kmo_edge_nan(cube_data[cube_counter_data], ifu_nr)); 01891 } 01892 01893 if (fast_mode) { 01894 KMO_TRY_EXIT_IF_NULL( 01895 tmpImg = cpl_imagelist_collapse_median_create(cube_data[cube_counter_data])); 01896 KMO_TRY_EXIT_IF_NULL( 01897 tmpCube = cpl_imagelist_new()); 01898 KMO_TRY_EXIT_IF_ERROR( 01899 cpl_imagelist_set(tmpCube, tmpImg, 0)); 01900 cpl_imagelist_delete(cube_data[cube_counter_data]); 01901 cube_data[cube_counter_data] = tmpCube; 01902 } 01903 01904 KMO_TRY_EXIT_IF_NULL( 01905 header_data[cube_counter_data] = 01906 kmclipm_propertylist_load(fn_reconstr, index)); 01907 cpl_propertylist_update_string(header_data[cube_counter_data], 01908 "ESO PRO FRNAME", 01909 fn_reconstr); 01910 cpl_propertylist_update_int(header_data[cube_counter_data], 01911 "ESO PRO IFUNR", 01912 index); 01913 cube_counter_data++; 01914 } 01915 01916 // load noise & subheader (if existing) 01917 if (desc1.ex_noise) { 01918 index = kmo_identify_index(fn_reconstr, ifu_nr, TRUE); 01919 KMO_TRY_CHECK_ERROR_STATE(); 01920 if (desc1.sub_desc[index-1].valid_data) { 01921 KMO_TRY_EXIT_IF_NULL( 01922 cube_noise[cube_counter_noise] = 01923 kmclipm_imagelist_load(fn_reconstr, CPL_TYPE_FLOAT, 01924 index)); 01925 01926 if (edge_nan) { 01927 KMO_TRY_EXIT_IF_ERROR( 01928 kmo_edge_nan(cube_noise[cube_counter_noise], ifu_nr)); 01929 } 01930 01931 if (fast_mode) { 01932 KMO_TRY_EXIT_IF_NULL( 01933 tmpImg = cpl_imagelist_collapse_median_create(cube_noise[cube_counter_noise])); 01934 KMO_TRY_EXIT_IF_NULL( 01935 tmpCube = cpl_imagelist_new()); 01936 KMO_TRY_EXIT_IF_ERROR( 01937 cpl_imagelist_set(tmpCube, tmpImg, 0)); 01938 cpl_imagelist_delete(cube_noise[cube_counter_noise]); 01939 cube_noise[cube_counter_noise] = tmpCube; 01940 } 01941 KMO_TRY_EXIT_IF_NULL( 01942 header_noise[cube_counter_noise] = 01943 kmclipm_propertylist_load(fn_reconstr, index)); 01944 cube_counter_noise++; 01945 } 01946 } 01947 cpl_error_reset(); 01948 } // end for ifu_nr 01949 01950 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01951 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01952 KMO_TRY_CHECK_ERROR_STATE(); 01953 } // end while-loop RECONSTRUCTED_CUBE frames 01954 01955 if (cube_counter_data > 1) { 01956 if (cube_counter_data == cube_counter_noise) { 01957 KMO_TRY_EXIT_IF_ERROR( 01958 kmo_priv_combine(cube_data, 01959 cube_noise, 01960 header_data, 01961 header_noise, 01962 cube_counter_data, 01963 cube_counter_noise, 01964 mapping_mode, 01965 "", 01966 comb_method, 01967 smethod, 01968 fmethod, 01969 filename, 01970 cmethod, 01971 cpos_rej, 01972 cneg_rej, 01973 citer, 01974 cmin, 01975 cmax, 01976 extrapol_enum, 01977 flux, 01978 &combined_data, 01979 &combined_noise)); 01980 } else if (cube_counter_noise == 0) { 01981 // if imethod == "CS" 01982 KMO_TRY_EXIT_IF_ERROR( 01983 kmo_priv_combine(cube_data, 01984 NULL, 01985 header_data, 01986 header_noise, 01987 cube_counter_data, 01988 cube_counter_noise, 01989 mapping_mode, 01990 "", 01991 comb_method, 01992 smethod, 01993 fmethod, 01994 filename, 01995 cmethod, 01996 cpos_rej, 01997 cneg_rej, 01998 citer, 01999 cmin, 02000 cmax, 02001 extrapol_enum, 02002 flux, 02003 &combined_data, 02004 &combined_noise)); 02005 } else { 02006 KMO_TRY_ASSURE(1 == 0, 02007 CPL_ERROR_ILLEGAL_INPUT, 02008 "The number of cube-data and cube-noise " 02009 "isn't the same (%d vs. %d)!", 02010 cube_counter_data, cube_counter_noise); 02011 } 02012 } else { 02013 cpl_msg_warning("", "There is only one reconstructed cube! " 02014 "Saving it as it is."); 02015 KMO_TRY_EXIT_IF_NULL( 02016 combined_data = cpl_imagelist_duplicate(cube_data[0])); 02017 02018 if (cube_noise[0] != NULL) { 02019 KMO_TRY_EXIT_IF_NULL( 02020 combined_noise = cpl_imagelist_duplicate(cube_noise[0])); 02021 } 02022 } 02023 02024 fn_out = COMBINED_CUBE; 02025 KMO_TRY_EXIT_IF_NULL( 02026 fn_suffix = cpl_sprintf("_%s", mapping_mode)); 02027 02028 // save combined cube 02029 KMO_TRY_EXIT_IF_NULL( 02030 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE)); 02031 KMO_TRY_EXIT_IF_ERROR( 02032 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, tmp_frame, 02033 NULL, parlist, cpl_func)); 02034 02035 KMO_TRY_EXIT_IF_ERROR( 02036 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, 02037 header_data[0], 0./0.)); 02038 02039 // if (combined_noise != NULL) { 02040 if (header_noise[0] == NULL) { 02041 KMO_TRY_EXIT_IF_NULL( 02042 header_noise[0] = 02043 cpl_propertylist_duplicate(header_data[0])); 02044 02045 KMO_TRY_EXIT_IF_NULL( 02046 tmp_str = cpl_propertylist_get_string(header_data[0], 02047 EXTNAME)); 02048 KMO_TRY_EXIT_IF_ERROR( 02049 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content)); 02050 KMO_TRY_EXIT_IF_NULL( 02051 extname = kmo_extname_creator(ifu_frame, tmp_int, 02052 EXT_NOISE)); 02053 KMO_TRY_EXIT_IF_ERROR( 02054 kmclipm_update_property_string(header_noise[0], 02055 EXTNAME, extname, 02056 "FITS extension name")); 02057 cpl_free(extname); extname = NULL; 02058 } 02059 KMO_TRY_EXIT_IF_ERROR( 02060 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix, 02061 header_noise[0], 0./0.)); 02062 // } 02063 02064 for (int i = 0; i < nr_data_alloc; i++) { 02065 cpl_imagelist_delete(cube_data[i]); cube_data[i] = NULL; 02066 cpl_imagelist_delete(cube_noise[i]); cube_noise[i] = NULL; 02067 cpl_propertylist_delete(header_data[i]); header_data[i] = NULL; 02068 cpl_propertylist_delete(header_noise[i]); header_noise[i] = NULL; 02069 } 02070 cpl_free(cube_data); cube_data = NULL; 02071 cpl_free(cube_noise); cube_noise = NULL; 02072 cpl_free(header_data); header_data = NULL; 02073 cpl_free(header_noise); header_noise = NULL; 02074 cpl_free(fn_suffix); fn_suffix = NULL; 02075 cpl_imagelist_delete(combined_data); combined_data = NULL; 02076 cpl_imagelist_delete(combined_noise); combined_noise = NULL; 02077 } // if mapping_mode 02078 } else { 02079 cpl_msg_info("", "NOT combining reconstructed objects (--no_combine is set)"); 02080 } // if (!no_combine) 02081 02082 cpl_msg_info("", "-------------------------------------------"); 02083 } 02084 KMO_CATCH 02085 { 02086 KMO_CATCH_MSG(); 02087 ret_val = -1; 02088 } 02089 02090 if (cube_data != NULL) { 02091 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02092 cpl_imagelist_delete(cube_data[ifu_nr-1]); cube_data[ifu_nr-1] = NULL; 02093 } 02094 } 02095 cpl_free(cube_data); cube_data = NULL; 02096 if (cube_noise != NULL) { 02097 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02098 cpl_imagelist_delete(cube_noise[ifu_nr-1]); cube_noise[ifu_nr-1] = NULL; 02099 } 02100 } 02101 cpl_free(cube_noise); cube_noise = NULL; 02102 if (header_data != NULL) { 02103 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02104 cpl_propertylist_delete(header_data[ifu_nr-1]); header_data[ifu_nr-1] = NULL; 02105 } 02106 } 02107 cpl_free(header_data); header_data = NULL; 02108 if (header_noise != NULL) { 02109 for (int ifu_nr = 1; ifu_nr <= nr_data_alloc; ifu_nr++) { 02110 cpl_propertylist_delete(header_noise[ifu_nr-1]); header_noise[ifu_nr-1] = NULL; 02111 } 02112 } 02113 cpl_free(header_noise); header_noise = NULL; 02114 02115 02116 kmo_free_fits_desc(&desc1); 02117 kmo_free_fits_desc(&desc2); 02118 cpl_vector_delete(ifus); ifus = NULL; 02119 cpl_free(mapping_mode); mapping_mode = NULL; 02120 if (unused_ifus != NULL) { 02121 kmo_free_unused_ifus(unused_ifus); unused_ifus = NULL; 02122 } 02123 if (bounds != NULL) { 02124 cpl_free(bounds); bounds = NULL; 02125 } 02126 if (obj_sky_struct != NULL) { 02127 cpl_free(obj_sky_struct); obj_sky_struct = NULL; 02128 } 02129 02130 // frees for the case of errors 02131 kmclipm_vector_delete(telluric_data); telluric_data = NULL; 02132 kmclipm_vector_delete(telluric_noise); telluric_noise = NULL; 02133 cpl_image_delete(illum_data); illum_data = NULL; 02134 cpl_image_delete(illum_noise); illum_noise = NULL; 02135 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 02136 cpl_table_delete(band_table); band_table = NULL; 02137 cpl_propertylist_delete(main_header); main_header = NULL; 02138 if (lcal != NULL) { 02139 for (int i = 0; i < KMOS_NR_DETECTORS; i++) { 02140 cpl_image_delete(lcal[i]); 02141 } 02142 } 02143 cpl_free(lcal); lcal = NULL; 02144 cpl_free(fn_suffix); fn_suffix = NULL; 02145 cpl_free(suffix); suffix = NULL; 02146 02147 if (all_obj != NULL) { 02148 for (int i = 0; i < nr_science_frames*KMOS_NR_IFUS; i++) { 02149 cpl_free(all_obj[i].name); 02150 } 02151 } 02152 cpl_free(all_obj); all_obj = NULL; 02153 02154 return ret_val; 02155 } 02156
1.7.6.1