|
KMOS Pipeline Reference Manual
1.2.7
|
00001 /* $Id: kmo_multi_reconstruct.c,v 1.55 2013-10-08 14:55:01 erw Exp $ 00002 * 00003 * This file is part of the KMOS Pipeline 00004 * Copyright (C) 2002,2003 European Southern Observatory 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 */ 00020 00021 /* 00022 * $Author: erw $ 00023 * $Date: 2013-10-08 14:55:01 $ 00024 * $Revision: 1.55 $ 00025 * $Name: not supported by cvs2svn $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 * Includes 00034 *----------------------------------------------------------------------------*/ 00035 #include <string.h> 00036 #include <math.h> 00037 00038 #include <cpl.h> 00039 #include "kmclipm_constants.h" 00040 #include "kmclipm_functions.h" 00041 00042 #include "kmo_debug.h" 00043 #include "kmo_constants.h" 00044 #include "kmo_cpl_extensions.h" 00045 #include "kmo_priv_lcorr.h" 00046 #include "kmo_utils.h" 00047 #include "kmo_error.h" 00048 #include "kmo_dfs.h" 00049 #include "kmo_functions.h" 00050 #include "kmo_priv_arithmetic.h" 00051 #include "kmo_priv_combine.h" 00052 #include "kmo_priv_functions.h" 00053 #include "kmo_priv_reconstruct.h" 00054 #include "kmo_priv_multi_reconstruct.h" 00055 00056 /*----------------------------------------------------------------------------- 00057 * Types 00058 *-----------------------------------------------------------------------------*/ 00059 00060 /*----------------------------------------------------------------------------- 00061 * Functions prototypes 00062 *----------------------------------------------------------------------------*/ 00063 00064 static int kmo_multi_reconstruct_create(cpl_plugin *); 00065 static int kmo_multi_reconstruct_exec(cpl_plugin *); 00066 static int kmo_multi_reconstruct_destroy(cpl_plugin *); 00067 static int kmo_multi_reconstruct(cpl_parameterlist *, cpl_frameset *); 00068 00069 /*----------------------------------------------------------------------------- 00070 * Static variables 00071 *----------------------------------------------------------------------------*/ 00072 00073 static char kmo_multi_reconstruct_description[] = 00074 "Ideally at least two data frames have to be provided since we need for each IFU\n" 00075 "pointing to an object as well a sky frame for the same IFU.\n" 00076 "If an OH spectrum is given in the SOF file the lambda axis will be corrected\n" 00077 "using the OH lines as reference.\n" 00078 "All IFUs with the same object name will be reconstructed and combined in one step\n" 00079 "Telluric correction is only supported if the objects have been observed with\n" 00080 "the same IFU on all exposures (dithering).\n" 00081 "The number of created files depends on the number of objects of different name.\n" 00082 "If the user just wants to combine a certain object, the parameters --name or\n" 00083 "--ifus can be used.\n" 00084 "\n" 00085 "Exposures taken with the templates KMOS_spec_obs_mapping8 and\n" 00086 "KMOS_spec_obs_mapping24 can't be processed with this recipe! Use kmo_sci_red\n" 00087 "instead.\n" 00088 "\n" 00089 "BASIC PARAMETERS:\n" 00090 "-----------------\n" 00091 "--imethod\n" 00092 "The interpolation method used for reconstruction.\n" 00093 "\n" 00094 "--name\n" 00095 "--ifus\n" 00096 "Since an object can be present only once per exposure and since it can be\n" 00097 "located in different IFUs for the existing exposures, there are two modes to\n" 00098 "identify the objects:\n" 00099 " * Combine by object names (default)\n" 00100 " In this case the object name must be provided via the --name parameter. The\n" 00101 " object name will be searched for in all primary headers of all provided\n" 00102 " frames in the keyword ESO OCS ARMx NAME.\n" 00103 "\n" 00104 " * Combine by index (advanced)\n" 00105 " In this case the --ifus parameter must be provided. The parameter must have\n" 00106 " the same number of entries as frames are provided, e.g. \"3;1;24\" for 3\n" 00107 " exposures. The index doesn't reference the extension in the frame but the\n" 00108 " real index of the IFU as defined in the EXTNAME keyword.\n" 00109 " (e.g. 'IFU.3.DATA')\n" 00110 "\n" 00111 "ADVANCED PARAMETERS\n" 00112 "-------------------\n" 00113 "--flux\n" 00114 "Specify if flux conservation should be applied.\n" 00115 "\n" 00116 "--background\n" 00117 "Specify if background removal should be applied.\n" 00118 "\n" 00119 "--suppress_extension\n" 00120 "If set to TRUE, the arbitrary filename extensions are supressed. If multiple\n" 00121 "products with the same category are produced, they will be numered consecutively\n" 00122 "starting from 0.\n" 00123 "\n" 00124 "--obj_sky_table\n" 00125 "The automatic obj-sky-associations can be modified by indicating a file with\n" 00126 "the desired associations. Therefore the file written to disk by default\n" 00127 "(without setting this option) can be edited manually. The formatting must\n" 00128 "absolutely be retained, just the type codes ('O' and'S') and the associated\n" 00129 "frame indices should be altered\n" 00130 "\n" 00131 " Advanced reconstruction parameters\n" 00132 " ----------------------------------\n" 00133 "--neighborhoodRange\n" 00134 "Defines the range to search for neighbors during reconstruction\n" 00135 "\n" 00136 "--b_samples\n" 00137 "The number of samples in spectral direction for the reconstructed cube.\n" 00138 "Ideally this number should be greater than 2048, the detector size.\n" 00139 "\n" 00140 "--b_start\n" 00141 "--b_end\n" 00142 "Used to define manually the start and end wavelength for the reconstructed\n" 00143 "cube. By default the internally defined values are used.\n" 00144 "\n" 00145 "--pix_scale\n" 00146 "Change the pixel scale [arcsec]. Default of 0.2\" results into cubes of\n" 00147 "14x14pix, a scale of 0.1\" results into cubes of 28x28pix, etc.\n" 00148 "\n" 00149 "--no_subtract\n" 00150 "If set to TRUE, the found objects and references won't be sky subtracted. \n" 00151 "Additionally all IFUs will be reconstructed, even the ones containing skies. \n" 00152 "\n" 00153 "--xcal_interpolation\n" 00154 "If true interpolate the pixel position in the slitlet (xcal) using the two\n" 00155 "closest rotator angles in the calibration file. Otherwise take the values\n" 00156 "of the closest rotator angle\n" 00157 "\n" 00158 " Advanced combining parameters\n" 00159 " ----------------------------------\n" 00160 "--method\n" 00161 "There are following sources to get the shift parameters from:\n" 00162 " * 'header' (default)\n" 00163 " The shifts are calculated according to the WCS information stored in the\n" 00164 " header of every IFU. The output frame will get larger, except the object is\n" 00165 " at the exact same position for all exposures. The size of the exposures can\n" 00166 " differ, but the orientation must be the same for all exposures.\n" 00167 "\n" 00168 " * 'none'\n" 00169 " The cubes are directly recombined, not shifting at all. The ouput frame\n" 00170 " will have the same dimensions as the input cubes.\n" 00171 " If the size differs a warning will be emitted and the cubes will be aligned\n" 00172 " to the lower left corner. If the orientation differs a warning will be\n" 00173 " emitted, but the cubes are combined anyway.\n" 00174 "\n" 00175 " * 'center'\n" 00176 " The shifts are calculated using a centering algorithm. The cube will be\n" 00177 " collapsed and a 2D profile will be fitted to it to identify the centre.\n" 00178 " With the parameter --fmethod the function to fit can be provided. The size\n" 00179 " of the exposures can differ, but the orientation must be the same for all\n" 00180 " exposures.\n" 00181 "\n" 00182 " * 'user'\n" 00183 " Read the shifts from a user specified file. The path of the file must be\n" 00184 " provided using the --filename parameter. For every exposure (except the\n" 00185 " first one) two shift values are expected per line, they have to be separa-\n" 00186 " ted with simple spaces. The values indicate pixel shifts and are referenced\n" 00187 " to the first frame. The 1st value is the shift in x-direction to the left,\n" 00188 " the 2nd the shift in y-direction upwards. The size of the exposures can\n" 00189 " differ, but the orientation must be the same for all exposures.\n" 00190 "\n" 00191 "--fmethod\n" 00192 "see --method='center'\n" 00193 "The type of function that should be fitted spatially to the collapsed image.\n" 00194 "This fit is used to create a mask to extract the spectrum of the object. Valid\n" 00195 "values are 'gauss' and 'moffat'.\n" 00196 "\n" 00197 "--filename\n" 00198 "see --method='user'\n" 00199 "\n" 00200 "--cmethod\n" 00201 "Following methods of frame combination are available:\n" 00202 " * 'ksigma' (Default)\n" 00203 " An iterative sigma clipping. For each position all pixels in the spectrum\n" 00204 " are examined. If they deviate significantly, they will be rejected according\n" 00205 " to the conditions:\n" 00206 " val > mean + stdev * cpos_rej\n" 00207 " and\n" 00208 " val < mean - stdev * cneg_rej\n" 00209 " where --cpos_rej, --cneg_rej and --citer are the corresponding configuration\n" 00210 " parameters. In the first iteration median and percentile level are used.\n" 00211 "\n" 00212 " * 'median'\n" 00213 " At each pixel position the median is calculated.\n" 00214 "\n" 00215 " * 'average'\n" 00216 " At each pixel position the average is calculated.\n" 00217 "\n" 00218 " * 'sum'\n" 00219 " At each pixel position the sum is calculated.\n" 00220 "\n" 00221 " * 'min_max'\n" 00222 " The specified number of minimum and maximum pixel values will be rejected.\n" 00223 " --cmax and --cmin apply to this method.\n" 00224 "\n" 00225 "--cpos_rej\n" 00226 "--cneg_rej\n" 00227 "--citer\n" 00228 "see --cmethod='ksigma'\n" 00229 "\n" 00230 "--cmax\n" 00231 "--cmin\n" 00232 "see --cmethod='min_max'\n" 00233 "\n" 00234 "------------------------------------------------------------------------------\n" 00235 " Input files:\n" 00236 "\n" 00237 " DO KMOS \n" 00238 " category Type Explanation Required #Frames\n" 00239 " -------- ----- ----------- -------- -------\n" 00240 " SCIENCE RAW The science frames Y >=1 \n" 00241 " XCAL F2D x calibration frame Y 1 \n" 00242 " YCAL F2D y calibration frame Y 1 \n" 00243 " LCAL F2D Wavelength calib. frame Y 1 \n" 00244 " MASTER_FLAT F2D Master flat Y 0,1 \n" 00245 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00246 " TELLURIC F1I normalised telluric spectrum N 0,1 \n" 00247 " OH_SPEC F1S Vector holding OH lines N 0,1 \n" 00248 "\n" 00249 " Output files:\n" 00250 "\n" 00251 " DO KMOS\n" 00252 " category Type Explanation\n" 00253 " -------- ----- -----------\n" 00254 " CUBE_MULTI F3I Combined cubes with noise\n" 00255 "------------------------------------------------------------------------------\n" 00256 "\n"; 00257 00258 /*----------------------------------------------------------------------------- 00259 * Functions code 00260 *----------------------------------------------------------------------------*/ 00261 00279 int cpl_plugin_get_info(cpl_pluginlist *list) 00280 { 00281 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00282 cpl_plugin *plugin = &recipe->interface; 00283 00284 cpl_plugin_init(plugin, 00285 CPL_PLUGIN_API, 00286 KMOS_BINARY_VERSION, 00287 CPL_PLUGIN_TYPE_RECIPE, 00288 "kmo_multi_reconstruct", 00289 "Reconstruct and combine obj/sky-pairs in one step.", 00290 kmo_multi_reconstruct_description, 00291 "Alex Agudo Berbel", 00292 "kmos-spark@mpe.mpg.de", 00293 kmos_get_license(), 00294 kmo_multi_reconstruct_create, 00295 kmo_multi_reconstruct_exec, 00296 kmo_multi_reconstruct_destroy); 00297 00298 cpl_pluginlist_append(list, plugin); 00299 00300 return 0; 00301 } 00302 00310 static int kmo_multi_reconstruct_create(cpl_plugin *plugin) 00311 { 00312 cpl_recipe *recipe; 00313 cpl_parameter *p; 00314 00315 /* Check that the plugin is part of a valid recipe */ 00316 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00317 recipe = (cpl_recipe *)plugin; 00318 else 00319 return -1; 00320 00321 /* Create the parameters list in the cpl_recipe object */ 00322 recipe->parameters = cpl_parameterlist_new(); 00323 00324 /* --imethod (interpolation method) */ 00325 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.imethod", 00326 CPL_TYPE_STRING, 00327 "Method to use for interpolation during reconstruction. " 00328 "[\"NN\" (nearest neighbour), " 00329 "\"lwNN\" (linear weighted nearest neighbor), " 00330 "\"swNN\" (square weighted nearest neighbor), " 00331 "\"MS\" (Modified Shepard's method)", 00332 "kmos.kmo_multi_reconstruct", 00333 "MS"); 00334 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00335 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00336 cpl_parameterlist_append(recipe->parameters, p); 00337 00338 /* --method (shift method) */ 00339 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.method", 00340 CPL_TYPE_STRING, 00341 "The shifting method: " 00342 "'none': no shifting, combined directly, " 00343 "'header': shift according to WCS (default), " 00344 "'center': centering algorithm, " 00345 "'user': read shifts from file", 00346 "kmos.kmo_multi_reconstruct", 00347 "header"); 00348 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method"); 00349 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00350 cpl_parameterlist_append(recipe->parameters, p); 00351 00352 /* --fmethod */ 00353 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.fmethod", 00354 CPL_TYPE_STRING, 00355 "The fitting method (applies only when " 00356 "method='center'): " 00357 "'gauss': fit a gauss function to collapsed " 00358 "image (default), " 00359 "'moffat': fit a moffat function to collapsed" 00360 " image", 00361 "kmos.kmo_multi_reconstruct", 00362 "gauss"); 00363 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00364 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00365 cpl_parameterlist_append(recipe->parameters, p); 00366 00367 /* --name */ 00368 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.name", 00369 CPL_TYPE_STRING, 00370 "Name of the object to combine.", 00371 "kmos.kmo_multi_reconstruct", 00372 ""); 00373 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00374 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00375 cpl_parameterlist_append(recipe->parameters, p); 00376 00377 /* --ifus */ 00378 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.ifus", 00379 CPL_TYPE_STRING, 00380 "The indices of the IFUs to combine. " 00381 "\"ifu1;ifu2;...\"", 00382 "kmos.kmo_multi_reconstruct", 00383 ""); 00384 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00385 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00386 cpl_parameterlist_append(recipe->parameters, p); 00387 00388 /* --pix_scale */ 00389 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.pix_scale", 00390 CPL_TYPE_DOUBLE, 00391 "Change the pixel scale [arcsec]. " 00392 "Default of 0.2\" results into cubes of 14x14pix, " 00393 "a scale of 0.1\" results into cubes of 28x28pix, " 00394 "etc.", 00395 "kmos.kmo_multi_reconstruct", 00396 KMOS_PIX_RESOLUTION); 00397 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pix_scale"); 00398 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00399 cpl_parameterlist_append(recipe->parameters, p); 00400 00401 /* --suppress_extension */ 00402 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.suppress_extension", 00403 CPL_TYPE_BOOL, 00404 "Suppress arbitrary filename extension." 00405 "(TRUE (apply) or FALSE (don't apply)", 00406 "kmos.kmo_multi_reconstruct", 00407 FALSE); 00408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00409 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00410 cpl_parameterlist_append(recipe->parameters, p); 00411 00412 /* --neighborhoodRange */ 00413 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.neighborhoodRange", 00414 CPL_TYPE_DOUBLE, 00415 "Defines the range to search for neighbors " 00416 "in pixels", 00417 "kmos.kmo_multi_reconstruct", 00418 1.001); 00419 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00420 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00421 cpl_parameterlist_append(recipe->parameters, p); 00422 00423 /* --filename */ 00424 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.filename", 00425 CPL_TYPE_STRING, 00426 "The path to the file with the shift vectors." 00427 "(Applies only to method='user')", 00428 "kmos.kmo_multi_reconstruct", 00429 ""); 00430 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filename"); 00431 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00432 cpl_parameterlist_append(recipe->parameters, p); 00433 00434 /* --flux */ 00435 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.flux", 00436 CPL_TYPE_BOOL, 00437 "TRUE: Apply flux conservation. FALSE: otherwise", 00438 "kmos.kmo_multi_reconstruct", 00439 FALSE); 00440 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00441 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00442 cpl_parameterlist_append(recipe->parameters, p); 00443 00444 /* --background */ 00445 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.background", 00446 CPL_TYPE_BOOL, 00447 "TRUE: Apply background removal. FALSE: otherwise", 00448 "kmos.kmo_multi_reconstruct", 00449 FALSE); 00450 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "background"); 00451 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00452 cpl_parameterlist_append(recipe->parameters, p); 00453 00454 /* --xcal_interpolation */ 00455 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.xcal_interpolation", 00456 CPL_TYPE_BOOL, 00457 "TRUE: Interpolate xcal between rotator angles. FALSE: otherwise", 00458 "kmos.kmo_multi_reconstruct", 00459 TRUE); 00460 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcal_interpolation"); 00461 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00462 cpl_parameterlist_append(recipe->parameters, p); 00463 00464 /* --no_subtract */ 00465 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.no_subtract", 00466 CPL_TYPE_BOOL, 00467 "Don't sky subtract object and references." 00468 "(TRUE (apply) or " 00469 "FALSE (don't apply)", 00470 "kmos.kmo_multi_reconstruct", 00471 FALSE); 00472 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "no_subtract"); 00473 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00474 cpl_parameterlist_append(recipe->parameters, p); 00475 00476 /* --dev_cal */ 00477 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.dev_cal", 00478 CPL_TYPE_BOOL, 00479 "Development only: If calibration data is to be " 00480 "reconstructed the ALPHA/DELTA keywords are " 00481 "missing. Setting this parameter to TRUE prevents " 00482 "according data check", 00483 "kmos.kmo_multi_reconstruct", 00484 FALSE); 00485 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dev_cal"); 00486 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00487 cpl_parameterlist_append(recipe->parameters, p); 00488 00489 /* --obj_sky_table */ 00490 p = cpl_parameter_new_value("kmos.kmo_multi_reconstruct.obj_sky_table", 00491 CPL_TYPE_STRING, 00492 "The path to the file with the modified obj/sky associations.", 00493 "kmos.kmo_multi_reconstruct", 00494 ""); 00495 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "obj_sky_table"); 00496 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00497 cpl_parameterlist_append(recipe->parameters, p); 00498 00499 00500 // add parameters for band-definition 00501 kmo_band_pars_create(recipe->parameters, 00502 "kmos.kmo_multi_reconstruct"); 00503 00504 return kmo_combine_pars_create(recipe->parameters, 00505 "kmos.kmo_multi_reconstruct", 00506 DEF_REJ_METHOD, 00507 FALSE); 00508 } 00509 00515 static int kmo_multi_reconstruct_exec(cpl_plugin *plugin) 00516 { 00517 cpl_recipe *recipe; 00518 00519 /* Get the recipe out of the plugin */ 00520 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00521 recipe = (cpl_recipe *)plugin; 00522 else return -1 ; 00523 00524 return kmo_multi_reconstruct(recipe->parameters, recipe->frames); 00525 } 00526 00532 static int kmo_multi_reconstruct_destroy(cpl_plugin *plugin) 00533 { 00534 cpl_recipe *recipe; 00535 00536 /* Get the recipe out of the plugin */ 00537 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00538 recipe = (cpl_recipe *)plugin; 00539 else return -1 ; 00540 00541 cpl_parameterlist_delete(recipe->parameters); 00542 return 0 ; 00543 } 00544 00559 static int kmo_multi_reconstruct(cpl_parameterlist *parlist, cpl_frameset *frameset) 00560 { 00561 int ret_val = 0, 00562 nr_science_frames = 0, 00563 has_illum_corr = 0, 00564 has_master_flat = 0, 00565 has_telluric = 0, 00566 *bounds = NULL, 00567 citer = 0, 00568 cmin = 0, 00569 cmax = 0, 00570 flux = FALSE, 00571 background = FALSE, 00572 no_subtract = FALSE, 00573 xcal_interpolation = FALSE, 00574 suppress_extension = FALSE, 00575 dev_cal = 0, 00576 cnt = 0, 00577 arm_index = 0, 00578 suppress_index = 0, 00579 xdim = 0, 00580 ydim = 0, 00581 iy = 0, 00582 ix = 0, 00583 ifu_nr = 0, 00584 nr_frames = 0; 00585 double xmin = DBL_MAX, 00586 xmax = -DBL_MAX, 00587 ymin = DBL_MAX, 00588 ymax = -DBL_MAX, 00589 gxshift = 0., 00590 gyshift = 0., 00591 gxdim = 0., 00592 gydim = 0., 00593 neighborhoodRange = 1.001, 00594 cpos_rej = 0.0, 00595 cneg_rej = 0.0, 00596 pix_scale = 0.0, 00597 *xshifts = NULL, 00598 *yshifts = NULL; 00599 char *suffix = NULL, 00600 *mapping_mode = NULL, 00601 *fn_cube = NULL, 00602 *fn_suffix = NULL, 00603 *filter_id = NULL, 00604 *extname = NULL; 00605 const char *imethod = NULL, 00606 *ifus_txt = NULL, 00607 *name = NULL, 00608 *tmp_str = NULL, 00609 *filename = NULL, 00610 *fn_obj_sky_table = NULL, 00611 *comb_method = NULL, 00612 *cmethod = NULL, 00613 *fmethod = NULL, 00614 *filter_keyword = "ESO INS FILT1 ID"; 00615 cpl_array **unused_ifus_before = NULL, 00616 **unused_ifus_after = NULL; 00617 cpl_frame *xcal_frame = NULL, 00618 *ycal_frame = NULL, 00619 *lcal_frame = NULL, 00620 *flat_frame = NULL, 00621 *illum_frame = NULL, 00622 *telluric_frame = NULL, 00623 *science_frame = NULL, 00624 *ref_spectrum_frame = NULL; 00625 cpl_propertylist *tmp_header = NULL, 00626 *ref_sub_header = NULL, 00627 *science_frame_header = NULL, 00628 **sub_headers = NULL; 00629 cpl_vector *ifus = NULL; 00630 cpl_table *band_table = NULL; 00631 00632 cpl_polynomial **lcorr_coeffs = NULL; 00633 cpl_imagelist *cube_combined_data = NULL, 00634 *cube_combined_noise = NULL, 00635 **pre_data_cube_list = NULL; 00636 kmclipm_vector *telluric_data = NULL, 00637 *telluric_noise = NULL; 00638 main_fits_desc desc1, 00639 desc2, 00640 desc_telluric; 00641 gridDefinition gd, 00642 gd_14x14; 00643 armNameStruct *arm_name_struct = NULL; 00644 00645 KMO_TRY 00646 { 00647 00648 kmo_init_fits_desc(&desc1); 00649 kmo_init_fits_desc(&desc2); 00650 kmo_init_fits_desc(&desc_telluric); 00651 00652 // 00653 // check frameset 00654 // 00655 KMO_TRY_ASSURE((parlist != NULL) && 00656 (frameset != NULL), 00657 CPL_ERROR_NULL_INPUT, 00658 "Not all input data is provided!"); 00659 00660 nr_science_frames = cpl_frameset_count_tags(frameset, SCIENCE); 00661 KMO_TRY_ASSURE(nr_science_frames >= 1, 00662 CPL_ERROR_ILLEGAL_INPUT, 00663 "At least one SCIENCE frame is required!"); 00664 if (nr_science_frames == 1) { 00665 cpl_msg_warning("", "At least two SCIENCE frames should be provided " 00666 "in order to apply sky subtraction!"); 00667 cpl_msg_warning("", "All IFUs will be reconstructed regardless if " 00668 "they contain object, reference or sky!"); 00669 } 00670 00671 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00672 CPL_ERROR_FILE_NOT_FOUND, 00673 "Exactly one XCAL frame is required!"); 00674 00675 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00676 CPL_ERROR_FILE_NOT_FOUND, 00677 "Exactly one YCAL frame is required!"); 00678 00679 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00680 CPL_ERROR_FILE_NOT_FOUND, 00681 "Exactly one LCAL frame is required!"); 00682 00683 has_master_flat = cpl_frameset_count_tags(frameset, MASTER_FLAT); 00684 KMO_TRY_ASSURE((has_master_flat == 0) || (has_master_flat == 1), 00685 CPL_ERROR_FILE_NOT_FOUND, 00686 "At most one MASTER_FLAT frame can be provided!"); 00687 00688 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00689 CPL_ERROR_FILE_NOT_FOUND, 00690 "Exactly one WAVE_BAND frame is required!"); 00691 00692 has_illum_corr = cpl_frameset_count_tags(frameset, ILLUM_CORR); 00693 KMO_TRY_ASSURE((has_illum_corr == 0) || (has_illum_corr == 1), 00694 CPL_ERROR_FILE_NOT_FOUND, 00695 "At most one ILLUM_CORR frame can be provided!"); 00696 00697 has_telluric = cpl_frameset_count_tags(frameset, TELLURIC); 00698 KMO_TRY_ASSURE((has_telluric == 0) || (has_telluric == 1), 00699 CPL_ERROR_FILE_NOT_FOUND, 00700 "At most one TELLURIC frame can be provided!"); 00701 00702 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_multi_reconstruct") == 1, 00703 CPL_ERROR_ILLEGAL_INPUT, 00704 "Cannot identify RAW and CALIB frames!"); 00705 00706 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, OH_SPEC) == 0 || 00707 cpl_frameset_count_tags(frameset, OH_SPEC) == 1, 00708 CPL_ERROR_ILLEGAL_INPUT, 00709 "Only a single reference spectrum can be provided!"); 00710 // 00711 // get parameters 00712 // 00713 cpl_msg_info("", "--- Parameter setup for kmo_multi_reconstruct ------"); 00714 00715 flux = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_multi_reconstruct.flux"); 00716 KMO_TRY_ASSURE((flux == 0) || 00717 (flux == 1), 00718 CPL_ERROR_ILLEGAL_INPUT, 00719 "flux must be either FALSE or TRUE! %d", flux); 00720 KMO_TRY_EXIT_IF_ERROR( 00721 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.flux")); 00722 00723 background = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_multi_reconstruct.background"); 00724 KMO_TRY_ASSURE((background == 0) || 00725 (background == 1), 00726 CPL_ERROR_ILLEGAL_INPUT, 00727 "background must be either FALSE or TRUE! %d", background); 00728 KMO_TRY_EXIT_IF_ERROR( 00729 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.background")); 00730 00731 KMO_TRY_EXIT_IF_NULL( 00732 imethod = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_multi_reconstruct.imethod")); 00733 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00734 (strcmp(imethod, "lwNN") == 0) || 00735 (strcmp(imethod, "swNN") == 0) || 00736 (strcmp(imethod, "MS") == 0), 00737 CPL_ERROR_ILLEGAL_INPUT, 00738 "imethod must be either \"NN\", \"lwNN\", " 00739 "\"swNN\" or \"MS\"!"); 00740 KMO_TRY_EXIT_IF_ERROR( 00741 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.imethod")); 00742 00743 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, "kmos.kmo_multi_reconstruct.neighborhoodRange"); 00744 KMO_TRY_CHECK_ERROR_STATE(); 00745 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00746 CPL_ERROR_ILLEGAL_INPUT, 00747 "neighborhoodRange must be greater than 0.0"); 00748 KMO_TRY_EXIT_IF_ERROR( 00749 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.neighborhoodRange")); 00750 00751 KMO_TRY_EXIT_IF_NULL( 00752 comb_method = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_multi_reconstruct.method")); 00753 KMO_TRY_EXIT_IF_NULL( 00754 fmethod = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_multi_reconstruct.fmethod")); 00755 KMO_TRY_ASSURE((strcmp(comb_method, "none") == 0) || 00756 (strcmp(comb_method, "header") == 0) || 00757 (strcmp(comb_method, "center") == 0) || 00758 (strcmp(comb_method, "user") == 0), 00759 CPL_ERROR_ILLEGAL_INPUT, 00760 "Following shift methods are available : 'none', " 00761 "'header', 'center' or 'user'"); 00762 00763 if (strcmp(comb_method, "user") == 0) { 00764 filename = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_multi_reconstruct.filename"); 00765 KMO_TRY_CHECK_ERROR_STATE(); 00766 KMO_TRY_ASSURE(strcmp(filename, "") != 0, 00767 CPL_ERROR_ILLEGAL_INPUT, 00768 "path of file with shift information must be " 00769 "provided!"); 00770 KMO_TRY_EXIT_IF_ERROR( 00771 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.filename")); 00772 } 00773 00774 KMO_TRY_EXIT_IF_ERROR( 00775 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.method")); 00776 ifus_txt = kmo_dfs_get_parameter_string(parlist, 00777 "kmos.kmo_multi_reconstruct.ifus"); 00778 KMO_TRY_CHECK_ERROR_STATE(); 00779 name = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_multi_reconstruct.name"); 00780 KMO_TRY_CHECK_ERROR_STATE(); 00781 00782 if (strcmp(ifus_txt, "") != 0) { 00783 KMO_TRY_ASSURE(strcmp(name, "") == 0, 00784 CPL_ERROR_ILLEGAL_INPUT, 00785 "name parameter must be NULL if IFU indices are " 00786 "provided!"); 00787 00788 KMO_TRY_EXIT_IF_NULL( 00789 ifus = kmo_identify_values(ifus_txt)); 00790 00791 KMO_TRY_ASSURE(cpl_vector_get_size(ifus) == nr_science_frames, 00792 CPL_ERROR_ILLEGAL_INPUT, 00793 "ifus parameter must have the same number of values " 00794 "than frames provided (for frames just containing " 00795 "skies insert 0)) (%lld=%d)", 00796 cpl_vector_get_size(ifus), nr_science_frames); 00797 } 00798 00799 if (strcmp(name, "") != 0) { 00800 KMO_TRY_ASSURE(strcmp(ifus_txt, "") == 0, 00801 CPL_ERROR_ILLEGAL_INPUT, 00802 "ifus parameter must be NULL if name is provided!"); 00803 } 00804 00805 KMO_TRY_EXIT_IF_ERROR( 00806 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.ifus")); 00807 KMO_TRY_EXIT_IF_ERROR( 00808 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.name")); 00809 00810 kmo_band_pars_load(parlist, "kmos.kmo_multi_reconstruct"); 00811 00812 no_subtract = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_multi_reconstruct.no_subtract"); 00813 KMO_TRY_CHECK_ERROR_STATE(); 00814 KMO_TRY_ASSURE((no_subtract == TRUE) || (no_subtract == FALSE), 00815 CPL_ERROR_ILLEGAL_INPUT, 00816 "no_subtract must be TRUE or FALSE!"); 00817 KMO_TRY_EXIT_IF_ERROR( 00818 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.no_subtract")); 00819 00820 pix_scale = kmo_dfs_get_parameter_double(parlist, "kmos.kmo_multi_reconstruct.pix_scale"); 00821 KMO_TRY_CHECK_ERROR_STATE(); 00822 KMO_TRY_ASSURE((pix_scale >= 0.01) && 00823 (pix_scale <= 0.4), 00824 CPL_ERROR_ILLEGAL_INPUT, 00825 "pix_scale must be between 0.01 and 0.4 (results in cubes " 00826 "with 7x7 to 280x280 pixels)!"); 00827 KMO_TRY_EXIT_IF_ERROR( 00828 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.pix_scale")); 00829 00830 xcal_interpolation = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_multi_reconstruct.xcal_interpolation"); 00831 KMO_TRY_CHECK_ERROR_STATE(); 00832 KMO_TRY_ASSURE((xcal_interpolation == TRUE) || 00833 (xcal_interpolation == FALSE), 00834 CPL_ERROR_ILLEGAL_INPUT, 00835 "xcal_interpolation must be TRUE or FALSE!"); 00836 KMO_TRY_EXIT_IF_ERROR( 00837 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.xcal_interpolation")); 00838 00839 suppress_extension = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_multi_reconstruct.suppress_extension"); 00840 KMO_TRY_CHECK_ERROR_STATE(); 00841 KMO_TRY_ASSURE((suppress_extension == TRUE) || (suppress_extension == FALSE), 00842 CPL_ERROR_ILLEGAL_INPUT, 00843 "suppress_extension must be TRUE or FALSE!"); 00844 KMO_TRY_EXIT_IF_ERROR( 00845 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.suppress_extension")); 00846 00847 dev_cal = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_multi_reconstruct.dev_cal"); 00848 KMO_TRY_CHECK_ERROR_STATE(); 00849 KMO_TRY_ASSURE((dev_cal == TRUE) || (dev_cal == FALSE), 00850 CPL_ERROR_ILLEGAL_INPUT, 00851 "dev_cal must be TRUE or FALSE!"); 00852 KMO_TRY_EXIT_IF_ERROR( 00853 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_multi_reconstruct.dev_cal")); 00854 00855 fn_obj_sky_table = kmo_dfs_get_parameter_string(parlist, 00856 "kmos.kmo_multi_reconstruct.obj_sky_table"); 00857 KMO_TRY_CHECK_ERROR_STATE(); 00858 00859 KMO_TRY_EXIT_IF_ERROR( 00860 kmo_dfs_print_parameter_help(parlist, 00861 "kmos.kmo_multi_reconstruct.obj_sky_table")); 00862 00863 00864 KMO_TRY_EXIT_IF_ERROR( 00865 kmo_combine_pars_load(parlist, 00866 "kmos.kmo_multi_reconstruct", 00867 &cmethod, 00868 &cpos_rej, 00869 &cneg_rej, 00870 &citer, 00871 &cmin, 00872 &cmax, 00873 FALSE)); 00874 00875 cpl_msg_info("", "-------------------------------------------"); 00876 00877 // 00878 // assure that filters, grating and rotation offsets match for 00879 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 00880 // frames) 00881 // 00882 00883 // check if filter_id and grating_id match for all detectors 00884 KMO_TRY_EXIT_IF_ERROR( 00885 kmo_check_frameset_setup(frameset, SCIENCE, TRUE, FALSE, TRUE)); 00886 KMO_TRY_EXIT_IF_ERROR( 00887 kmo_check_frame_setup(frameset, SCIENCE, YCAL, TRUE, FALSE, TRUE)); 00888 KMO_TRY_EXIT_IF_ERROR( 00889 kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE)); 00890 KMO_TRY_EXIT_IF_ERROR( 00891 kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE)); 00892 if (has_master_flat) { 00893 KMO_TRY_EXIT_IF_ERROR( 00894 kmo_check_frame_setup(frameset, XCAL, MASTER_FLAT, TRUE, FALSE, TRUE)); 00895 } 00896 if (has_telluric) { 00897 KMO_TRY_EXIT_IF_ERROR( 00898 kmo_check_frame_setup(frameset, XCAL, TELLURIC, 00899 TRUE, FALSE, TRUE)); 00900 } 00901 00902 // check descriptors of all frames 00903 KMO_TRY_EXIT_IF_NULL( 00904 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 00905 00906 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 00907 KMO_TRY_CHECK_ERROR_STATE(); 00908 00909 KMO_TRY_ASSURE((desc1.nr_ext % KMOS_NR_DETECTORS == 0) && 00910 (desc1.ex_badpix == FALSE) && 00911 (desc1.fits_type == f2d_fits) && 00912 (desc1.frame_type == detector_frame), 00913 CPL_ERROR_ILLEGAL_INPUT, 00914 "XCAL isn't in the correct format!!!"); 00915 00916 KMO_TRY_EXIT_IF_NULL( 00917 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 00918 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 00919 KMO_TRY_CHECK_ERROR_STATE(); 00920 00921 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 00922 (desc1.ex_badpix == desc2.ex_badpix) && 00923 (desc1.fits_type == desc2.fits_type) && 00924 (desc1.frame_type == desc2.frame_type), 00925 CPL_ERROR_ILLEGAL_INPUT, 00926 "YCAL isn't in the correct format!!!"); 00927 kmo_free_fits_desc(&desc2); 00928 kmo_init_fits_desc(&desc2); 00929 00930 KMO_TRY_EXIT_IF_NULL( 00931 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00932 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 00933 KMO_TRY_CHECK_ERROR_STATE(); 00934 00935 KMO_TRY_ASSURE((desc2.nr_ext % KMOS_NR_DETECTORS == 0) && 00936 (desc1.ex_badpix == desc2.ex_badpix) && 00937 (desc1.fits_type == desc2.fits_type) && 00938 (desc1.frame_type == desc2.frame_type), 00939 CPL_ERROR_ILLEGAL_INPUT, 00940 "LCAL isn't in the correct format!!!"); 00941 kmo_free_fits_desc(&desc2); 00942 kmo_init_fits_desc(&desc2); 00943 00944 if (has_master_flat) { 00945 KMO_TRY_EXIT_IF_NULL( 00946 flat_frame = kmo_dfs_get_frame(frameset, MASTER_FLAT)); 00947 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(flat_frame)); 00948 KMO_TRY_CHECK_ERROR_STATE(); 00949 00950 KMO_TRY_ASSURE((desc2.nr_ext % (2*KMOS_NR_DETECTORS) == 0) && 00951 (desc1.ex_badpix == desc2.ex_badpix) && 00952 (desc1.fits_type == desc2.fits_type) && 00953 (desc1.frame_type == desc2.frame_type), 00954 CPL_ERROR_ILLEGAL_INPUT, 00955 "MASTER_FLAT isn't in the correct format!!!"); 00956 kmo_free_fits_desc(&desc2); 00957 kmo_init_fits_desc(&desc2); 00958 } 00959 00960 if (has_illum_corr) { 00961 KMO_TRY_EXIT_IF_NULL( 00962 illum_frame = kmo_dfs_get_frame(frameset, ILLUM_CORR)); 00963 desc2 = kmo_identify_fits_header( 00964 cpl_frame_get_filename(illum_frame)); 00965 KMO_TRY_CHECK_ERROR_STATE(); 00966 KMO_TRY_ASSURE(((desc2.nr_ext == 24) || (desc2.nr_ext == 48)) && 00967 (desc2.ex_badpix == FALSE) && 00968 (desc2.fits_type == f2i_fits) && 00969 (desc2.frame_type == ifu_frame), 00970 CPL_ERROR_ILLEGAL_INPUT, 00971 "ILLUM_CORR isn't in the correct format!!!"); 00972 kmo_free_fits_desc(&desc2); 00973 kmo_init_fits_desc(&desc2); 00974 } 00975 00976 if (has_telluric) { 00977 KMO_TRY_EXIT_IF_NULL( 00978 telluric_frame = kmo_dfs_get_frame(frameset, TELLURIC)); 00979 desc_telluric = kmo_identify_fits_header( 00980 cpl_frame_get_filename(telluric_frame)); 00981 KMO_TRY_CHECK_ERROR_STATE(); 00982 KMO_TRY_ASSURE(((desc_telluric.nr_ext == 24) || (desc_telluric.nr_ext == 48)) && 00983 (desc_telluric.ex_badpix == FALSE) && 00984 (desc_telluric.fits_type == f1i_fits) && 00985 (desc_telluric.frame_type == ifu_frame), 00986 CPL_ERROR_ILLEGAL_INPUT, 00987 "TELLURIC isn't in the correct format!!!"); 00988 } 00989 00990 KMO_TRY_EXIT_IF_NULL( 00991 science_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 00992 while (science_frame != NULL ) { 00993 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(science_frame)); 00994 KMO_TRY_CHECK_ERROR_STATE(); 00995 KMO_TRY_ASSURE((desc2.nr_ext == 3) && 00996 (desc2.ex_badpix == FALSE) && 00997 (desc2.fits_type == raw_fits) && 00998 (desc2.frame_type == detector_frame), 00999 CPL_ERROR_ILLEGAL_INPUT, 01000 "SCIENCE isn't in the correct format!!!"); 01001 kmo_free_fits_desc(&desc2); 01002 kmo_init_fits_desc(&desc2); 01003 01004 if (mapping_mode == NULL) { 01005 KMO_TRY_EXIT_IF_NULL( 01006 tmp_header = 01007 kmclipm_propertylist_load( 01008 cpl_frame_get_filename(science_frame), 0)); 01009 if (cpl_propertylist_has(tmp_header, TPL_ID)) { 01010 KMO_TRY_EXIT_IF_NULL( 01011 tmp_str = cpl_propertylist_get_string(tmp_header, 01012 TPL_ID)); 01013 if (strcmp(tmp_str, MAPPING8) == 0) 01014 { 01015 mapping_mode = cpl_sprintf("%s", "mapping8"); 01016 } 01017 if (strcmp(tmp_str, MAPPING24) == 0) 01018 { 01019 mapping_mode = cpl_sprintf("%s", "mapping24"); 01020 } 01021 } 01022 01023 // when mapping-mode should be supported, remove this if-statement... 01024 if (mapping_mode != NULL) { 01025 cpl_msg_error("", "*******************************************************"); 01026 cpl_msg_error("", "*******************************************************"); 01027 cpl_msg_error("", "*** ***"); 01028 cpl_msg_error("", "*** The provided SCIENCE frames have been produced ***"); 01029 cpl_msg_error("", "*** with template %s ***", tmp_str); 01030 cpl_msg_error("", "*** ***"); 01031 cpl_msg_error("", "*** kmo_multi_reconstruct doesn't support yet this ***"); 01032 cpl_msg_error("", "*** observation mode. Please use recipe kmo_sci_red ***"); 01033 cpl_msg_error("", "*** instead! ***"); 01034 cpl_msg_error("", "*** ***"); 01035 cpl_msg_error("", "*******************************************************"); 01036 cpl_msg_error("", "*******************************************************"); 01037 KMO_TRY_ASSURE(1==0, 01038 CPL_ERROR_ILLEGAL_INPUT, 01039 " "); 01040 } 01041 01042 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01043 } 01044 01045 science_frame = kmo_dfs_get_frame(frameset, NULL); 01046 KMO_TRY_CHECK_ERROR_STATE(); 01047 } 01048 01049 if ((mapping_mode != NULL) && ((ifus != NULL) || (strcmp(name, "") != 0))) { 01050 cpl_msg_warning("","The SCIENCE frames have been taken in one of the " 01051 "mapping modes AND specific IFUs have been " 01052 "specified! --> Only processing these!"); 01053 } 01054 01055 KMO_TRY_EXIT_IF_NULL( 01056 suffix = kmo_dfs_get_suffix(xcal_frame, TRUE, FALSE)); 01057 01058 KMO_TRY_EXIT_IF_ERROR( 01059 kmo_check_frame_setup_md5_xycal(frameset)); 01060 KMO_TRY_EXIT_IF_ERROR( 01061 kmo_check_frame_setup_md5(frameset)); 01062 KMO_TRY_EXIT_IF_ERROR( 01063 kmo_check_frame_setup_sampling(frameset)); 01064 01065 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 01066 cpl_msg_info("", "(grating 1, 2 & 3)"); 01067 cpl_msg_info("", "-------------------------------------------"); 01068 cpl_free(suffix); suffix = NULL; 01069 01070 if (cpl_frameset_count_tags(frameset, OH_SPEC) != 0) { 01071 int is_all_obs = TRUE, 01072 has_all_origfile = TRUE; 01073 cpl_frame *tmp_frame = NULL; 01074 01075 KMO_TRY_EXIT_IF_NULL( 01076 tmp_frame = kmo_dfs_get_frame(frameset, SCIENCE)); 01077 while (tmp_frame != NULL ) { 01078 KMO_TRY_EXIT_IF_NULL( 01079 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 01080 01081 if (cpl_propertylist_has(tmp_header, ORIGFILE)) { 01082 KMO_TRY_EXIT_IF_NULL( 01083 tmp_str = cpl_propertylist_get_string(tmp_header, ORIGFILE)); 01084 if (strstr(tmp_str, "OBS") == NULL) { 01085 is_all_obs = FALSE; 01086 } 01087 } else { 01088 has_all_origfile = FALSE; 01089 } 01090 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01091 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01092 KMO_TRY_CHECK_ERROR_STATE(); 01093 } 01094 01095 if (has_all_origfile) { 01096 if (is_all_obs) { 01097 // we are reconstructing an OBS-frame, allow OH_SPEC correction 01098 KMO_TRY_EXIT_IF_NULL( 01099 ref_spectrum_frame = kmo_dfs_get_frame(frameset, OH_SPEC)); 01100 } else { 01101 cpl_msg_warning("", "Supplied OH_SPEC is ignored since a calibration " 01102 "frame is being used as SCIENCE frame."); 01103 } 01104 } else { 01105 cpl_msg_warning("", "The supplied SCIENCE frames are all assumed to be " 01106 "science frames. If any of them is a calibration frame, " 01107 "omit OH_SPEC from sof-file"); 01108 KMO_TRY_EXIT_IF_NULL( 01109 ref_spectrum_frame = kmo_dfs_get_frame(frameset, OH_SPEC)); 01110 } 01111 } 01112 01113 // 01114 // check which IFUs are active for all frames 01115 // 01116 KMO_TRY_EXIT_IF_NULL( 01117 unused_ifus_before = kmo_get_unused_ifus(frameset, 1, 1)); 01118 01119 KMO_TRY_EXIT_IF_NULL( 01120 unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before)); 01121 01122 kmo_print_unused_ifus(unused_ifus_before, FALSE); 01123 01124 // 01125 // get bounds, setup grid, setup arm_name-struct 01126 // 01127 01128 // get left and right bounds of IFUs 01129 KMO_TRY_EXIT_IF_NULL( 01130 tmp_header = kmo_dfs_load_primary_header(frameset, XCAL)); 01131 KMO_TRY_EXIT_IF_NULL( 01132 bounds = kmclipm_extract_bounds(tmp_header)); 01133 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01134 01135 // setup grid definition, wavelength start and end points will be set 01136 // in the detector loop 01137 KMO_TRY_EXIT_IF_ERROR( 01138 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale, 0.)); 01139 KMO_TRY_EXIT_IF_ERROR( 01140 kmclipm_setup_grid(&gd_14x14, imethod, neighborhoodRange, pix_scale, 0.)); 01141 01142 KMO_TRY_EXIT_IF_NULL( 01143 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0)); 01144 KMO_TRY_EXIT_IF_NULL( 01145 tmp_header = kmo_dfs_load_primary_header(frameset, LCAL)); 01146 KMO_TRY_EXIT_IF_NULL( 01147 filter_id = cpl_sprintf("%s", cpl_propertylist_get_string(tmp_header, filter_keyword))); 01148 KMO_TRY_EXIT_IF_ERROR( 01149 kmclipm_setup_grid_band_lcal(&gd, NULL, filter_id, 0, band_table)); 01150 KMO_TRY_EXIT_IF_ERROR( 01151 kmclipm_setup_grid_band_lcal(&gd_14x14, NULL, filter_id, 0, band_table)); 01152 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01153 cpl_table_delete(band_table); band_table = NULL; 01154 01155 // 01156 // get valid object names to process, either one object name across 01157 // several SCIENCE frames, or all object names 01158 // 01159 if (strcmp(fn_obj_sky_table, "") == 0) { 01160 KMO_TRY_EXIT_IF_NULL( 01161 arm_name_struct = kmo_create_armNameStruct(frameset, 01162 SCIENCE, 01163 ifus, 01164 name, 01165 unused_ifus_after, 01166 bounds, 01167 mapping_mode, 01168 no_subtract)); 01169 KMO_TRY_EXIT_IF_ERROR( 01170 kmo_save_objSkyStruct(arm_name_struct->obj_sky_struct, "obj_sky_table.txt")); 01171 } else { 01172 // read in obj/sky-table 01173 objSkyStruct *obj_sky_struct = NULL; 01174 01175 KMO_TRY_EXIT_IF_NULL( 01176 obj_sky_struct = kmo_read_objSkyStruct(fn_obj_sky_table, 01177 frameset, 01178 SCIENCE)); 01179 01180 KMO_TRY_EXIT_IF_NULL( 01181 arm_name_struct = kmo_create_armNameStruct2(obj_sky_struct, 01182 frameset, 01183 SCIENCE, 01184 ifus, 01185 name, 01186 unused_ifus_after, 01187 bounds, 01188 mapping_mode, 01189 no_subtract)); 01190 01191 } 01192 kmo_print_armNameStruct(frameset, arm_name_struct); 01193 cpl_free(bounds); bounds = NULL; 01194 01195 // 01196 // check availability of tellurics for the different IFUs used 01197 // 01198 if (has_telluric && (mapping_mode != NULL)) { 01199 // in mapping-mode check if for all IFUs there is either no telluric at all 01200 // or the same number of tellurics than object names 01201 int telluric_ok = TRUE; 01202 for (cnt = 0; cnt < arm_name_struct->nrNames; cnt++) { 01203 if (!((arm_name_struct->telluricCnt[cnt] == arm_name_struct->namesCnt[cnt]) || 01204 (arm_name_struct->telluricCnt[cnt] == 0))) 01205 { 01206 telluric_ok = FALSE; 01207 break; 01208 } 01209 } 01210 if (!telluric_ok) { 01211 KMO_TRY_ASSURE(1==0, 01212 CPL_ERROR_UNSUPPORTED_MODE, 01213 "Mosaics need a TELLURIC frame with at least a telluric correction per detector available! " 01214 "Omit the TELLURIC from your sof-file or choose another TELLURIC!"); 01215 } 01216 } 01217 01218 // 01219 // loop over all object names 01220 // (for mapping template only once,) 01221 // (when ifus or name is set as well only once) 01222 // 01223 for (arm_index = 0; arm_index < arm_name_struct->nrNames; arm_index++) { 01224 01225 nr_frames = arm_name_struct->namesCnt[arm_index]; 01226 01227 KMO_TRY_EXIT_IF_NULL( 01228 sub_headers = kmo_mr_get_headers(arm_name_struct, 01229 arm_index+1, 01230 frameset, 01231 gd_14x14)); 01232 01233 if ((strcmp(comb_method, "center") == 0) || 01234 (ref_spectrum_frame != NULL)) 01235 { 01236 // 01237 // reconstruct preliminary cubes 01238 // 01239 KMO_TRY_EXIT_IF_NULL( 01240 pre_data_cube_list = kmo_mr_create_datacubes(arm_name_struct, 01241 arm_index+1, 01242 frameset, 01243 gd_14x14, 01244 xcal_interpolation)); 01245 // 01246 // calculate lambda-correction coefficients 01247 // 01248 if (ref_spectrum_frame != NULL) { 01249 KMO_TRY_EXIT_IF_NULL( 01250 lcorr_coeffs = cpl_calloc(nr_frames, sizeof(cpl_polynomial*))); 01251 01252 cnt = 0; 01253 for (iy = 0; iy < arm_name_struct->size; iy++) { 01254 for (ix = 0; ix < KMOS_NR_IFUS; ix++) { 01255 ifu_nr = ix + 1; 01256 if (arm_name_struct->name_ids[ix+iy*KMOS_NR_IFUS] == arm_index+1) { 01257 KMO_TRY_EXIT_IF_NULL( 01258 lcorr_coeffs[cnt] = kmo_lcorr_get(pre_data_cube_list[cnt], 01259 sub_headers[cnt], 01260 ref_spectrum_frame, 01261 gd_14x14, 01262 filter_id, 01263 ifu_nr)); 01264 cnt++; 01265 } 01266 } 01267 } 01268 } // end if (lcorr) 01269 } // end if (center, lcorr) 01270 01271 // 01272 // calculate offsets 01273 // 01274 KMO_TRY_EXIT_IF_ERROR( 01275 kmo_mr_get_offsets(arm_name_struct, 01276 arm_index+1, 01277 comb_method, 01278 imethod, 01279 filename, 01280 frameset, 01281 pre_data_cube_list, 01282 sub_headers, 01283 fmethod, 01284 cmethod, 01285 cpos_rej, 01286 cneg_rej, 01287 citer, 01288 cmin, 01289 cmax, 01290 dev_cal, 01291 mapping_mode, 01292 &xshifts, 01293 &yshifts)); 01294 01295 KMO_TRY_EXIT_IF_NULL( 01296 ref_sub_header = cpl_propertylist_duplicate(sub_headers[0])); 01297 01298 for (cnt = 0; cnt < nr_frames; cnt++) { 01299 cpl_propertylist_delete(sub_headers[cnt]); sub_headers[cnt] = NULL; 01300 } 01301 cpl_free(sub_headers); sub_headers = NULL; 01302 01303 if (pre_data_cube_list != NULL) { 01304 for (cnt = 0; cnt < nr_frames; cnt++) { 01305 cpl_imagelist_delete(pre_data_cube_list[cnt]); 01306 } 01307 cpl_free(pre_data_cube_list); pre_data_cube_list = NULL; 01308 } 01309 01310 // 01311 // set spatial part of the grid 01312 // 01313 for (cnt = 0; cnt < nr_frames; cnt++) { 01314 if (xmin > xshifts[cnt]) { 01315 xmin = xshifts[cnt]; 01316 } 01317 if (xmax < xshifts[cnt]) { 01318 xmax = xshifts[cnt]; 01319 } 01320 if (ymin > yshifts[cnt]) { 01321 ymin = yshifts[cnt]; 01322 } 01323 if (ymax < yshifts[cnt]) { 01324 ymax = yshifts[cnt]; 01325 } 01326 } 01327 01328 if (xmax > 0.0001) { 01329 gxshift = -rint(xmax); //(int)xmax; // gxshift = - ceil(xmax); 01330 } else { 01331 gxshift = 0.; 01332 } 01333 if (ymin < -0.0001) { 01334 gyshift = rint(ymin); //(int)ymin; // gyshift = floor(ymin); 01335 } else { 01336 gyshift = 0.; 01337 } 01338 if (xmin < -0.0001) { 01339 gxdim = - floor(xmin); 01340 } else { 01341 gxdim = 0.; 01342 } 01343 if (ymax > 0.0001) { 01344 gydim = ceil(ymax); 01345 } else { 01346 gydim = 0.; 01347 } 01348 01349 xdim = (int)(gxdim - gxshift + .5); 01350 ydim = (int)(gydim - gyshift + .5); 01351 gd.x.start += gxshift * pix_scale*1000; 01352 gd.y.start += gyshift * pix_scale*1000; 01353 gd.x.dim += xdim; 01354 gd.y.dim += ydim; 01355 01356 // cpl_msg_set_level(CPL_MSG_DEBUG); 01357 // cpl_msg_debug(cpl_func,"x: %f < %f, y: %f < %f", 01358 // xmin,xmax,ymin,ymax); 01359 // cpl_msg_debug(cpl_func,"gxshift: %f gxdim: %f xdim: %d, gyshift: %f gydim: %f ydim: %d", 01360 // gxshift, gxdim, xdim, gyshift, gydim, ydim); 01361 // cpl_msg_debug(cpl_func,"gd: start delta dim"); 01362 // cpl_msg_debug(cpl_func," x: %f %f %d", gd.x.start, gd.x.delta, gd.x.dim); 01363 // cpl_msg_debug(cpl_func," y: %f %f %d", gd.y.start, gd.y.delta, gd.y.dim); 01364 // cpl_msg_debug(cpl_func," l: %f %f %d", gd.l.start, gd.l.delta, gd.l.dim); 01365 // cpl_msg_set_level(CPL_MSG_INFO); 01366 01367 // 01368 // reconstruct multiple detector images 01369 // 01370 KMO_TRY_EXIT_IF_ERROR( 01371 kmo_mr_reconstruct(frameset, 01372 arm_name_struct, 01373 arm_index+1, 01374 xshifts, 01375 yshifts, 01376 gd, 01377 gd_14x14, 01378 pix_scale, 01379 xcal_interpolation, 01380 lcorr_coeffs, 01381 &cube_combined_data, 01382 &cube_combined_noise, 01383 no_subtract, 01384 flux, 01385 background)); 01386 01387 if (lcorr_coeffs != NULL) { 01388 for (cnt = 0; cnt < nr_frames; cnt++) { 01389 cpl_polynomial_delete(lcorr_coeffs[cnt]); lcorr_coeffs[cnt] = NULL; 01390 } 01391 cpl_free(lcorr_coeffs); lcorr_coeffs = NULL; 01392 } 01393 01394 // 01395 // identify ifu_nr of current object name in first SCIENCE frame 01396 // containing this object name (e.g. first frame could contain skies only) 01397 // 01398 ifu_nr = -1; 01399 science_frame = NULL; 01400 for (iy = 0; iy < arm_name_struct->size; iy++) { 01401 for (ix = 0; ix < KMOS_NR_IFUS; ix++) { 01402 if (arm_name_struct->name_ids[ix+iy*KMOS_NR_IFUS] == arm_index+1) { 01403 if (ifu_nr == -1) { 01404 KMO_TRY_EXIT_IF_NULL( 01405 science_frame = arm_name_struct->obj_sky_struct->table[iy].objFrame); 01406 01407 ifu_nr = ix + 1; 01408 break; 01409 } 01410 } 01411 } 01412 if (ifu_nr != -1) { break; } 01413 } 01414 01415 // 01416 // divide cube by telluric correction 01417 // 01418 if (has_telluric && 01419 (arm_name_struct->sameTelluric[arm_index] > 0)) 01420 { 01421 telluric_data = kmo_tweak_load_telluric(frameset, ifu_nr, FALSE, no_subtract); 01422 KMO_TRY_CHECK_ERROR_STATE(); 01423 if (telluric_data != NULL) { 01424 int index = kmo_identify_index_desc(desc_telluric, ifu_nr, TRUE); 01425 KMO_TRY_CHECK_ERROR_STATE(); 01426 if (desc_telluric.sub_desc[index-1].valid_data == TRUE) { 01427 // load noise if present 01428 telluric_noise = kmo_tweak_load_telluric(frameset, ifu_nr, TRUE, no_subtract); 01429 KMO_TRY_CHECK_ERROR_STATE(); 01430 } else { 01431 if (print_warning_once_tweak_std_noise && (cube_combined_noise != NULL)) { 01432 cpl_msg_warning("","************************************************************"); 01433 cpl_msg_warning("","* Noise cubes were calculated, but won't be divided by *"); 01434 cpl_msg_warning("","* telluric error since it is missing. *"); 01435 cpl_msg_warning("","* In order to get a telluric with errors, execute *"); 01436 cpl_msg_warning("","* kmo_std_star with one of the nearest neighbour methods *"); 01437 cpl_msg_warning("","* (set --imethod to NN, lwNN or swNN) *"); 01438 cpl_msg_warning("","************************************************************"); 01439 print_warning_once_tweak_std_noise = FALSE; 01440 } 01441 } 01442 01443 KMO_TRY_EXIT_IF_ERROR( 01444 kmo_arithmetic_3D_1D( 01445 cube_combined_data, telluric_data, 01446 cube_combined_noise, telluric_noise, "/")); 01447 } 01448 kmclipm_vector_delete(telluric_data); telluric_data = NULL; 01449 kmclipm_vector_delete(telluric_noise); telluric_noise = NULL; 01450 } 01451 01452 // 01453 // saving 01454 // 01455 fn_cube = CUBE_MULTI; 01456 if (!suppress_extension) { 01457 char tmp_suffix[1024]; 01458 tmp_suffix[0] = '\0'; 01459 01460 if (arm_name_struct->telluricCnt[arm_index] == nr_frames) { 01461 strcat(tmp_suffix, "_telluric"); 01462 } 01463 if (has_illum_corr) { 01464 strcat(tmp_suffix, "_illum"); 01465 } 01466 // if (sky_tweak) { 01467 // strcat(tmp_suffix, "_skytweak"); 01468 // } 01469 01470 if (strlen(tmp_suffix) > 0) { 01471 KMO_TRY_EXIT_IF_NULL( 01472 fn_suffix = cpl_sprintf("_%s_%s", arm_name_struct->names[arm_index], tmp_suffix)); 01473 } else { 01474 KMO_TRY_EXIT_IF_NULL( 01475 fn_suffix = cpl_sprintf("_%s", arm_name_struct->names[arm_index])); 01476 } 01477 } else { 01478 KMO_TRY_EXIT_IF_NULL( 01479 fn_suffix = cpl_sprintf("_%d", suppress_index++)); 01480 } 01481 01482 // 01483 // calculate WCS 01484 // 01485 KMO_TRY_EXIT_IF_NULL( 01486 science_frame_header = kmclipm_propertylist_load(cpl_frame_get_filename(science_frame), 0)); 01487 01488 KMO_TRY_EXIT_IF_ERROR( 01489 kmo_calc_wcs_gd(science_frame_header, ref_sub_header, ifu_nr, gd)); 01490 01491 cpl_propertylist_delete(science_frame_header); science_frame_header = NULL; 01492 01493 // 01494 // save product 01495 // 01496 KMO_TRY_EXIT_IF_ERROR( 01497 kmo_dfs_save_main_header(frameset, fn_cube, fn_suffix, 01498 science_frame, NULL, parlist, cpl_func)); 01499 01500 KMO_TRY_EXIT_IF_NULL( 01501 extname = cpl_sprintf("%s.DATA", arm_name_struct->names[arm_index])); 01502 KMO_TRY_EXIT_IF_ERROR( 01503 kmclipm_update_property_string(ref_sub_header, 01504 EXTNAME, 01505 extname, 01506 "FITS extension name")); 01507 cpl_free(extname); extname = NULL; 01508 01509 KMO_TRY_EXIT_IF_ERROR( 01510 kmo_dfs_save_cube(cube_combined_data, fn_cube, fn_suffix, 01511 ref_sub_header, 0./0.)); 01512 01513 if (cube_combined_noise != NULL) { 01514 KMO_TRY_EXIT_IF_NULL( 01515 extname = cpl_sprintf("%s.NOISE", arm_name_struct->names[arm_index])); 01516 KMO_TRY_EXIT_IF_ERROR( 01517 kmclipm_update_property_string(ref_sub_header, 01518 EXTNAME, 01519 extname, 01520 "FITS extension name")); 01521 cpl_free(extname); extname = NULL; 01522 01523 KMO_TRY_EXIT_IF_ERROR( 01524 kmo_dfs_save_cube(cube_combined_noise, fn_cube, fn_suffix, 01525 ref_sub_header, 0./0.)); 01526 } 01527 01528 cpl_imagelist_delete(cube_combined_data); cube_combined_data = NULL; 01529 cpl_imagelist_delete(cube_combined_noise); cube_combined_noise = NULL; 01530 cpl_propertylist_delete(ref_sub_header); ref_sub_header = NULL; 01531 cpl_free(fn_suffix); fn_suffix = NULL; 01532 cpl_free(xshifts); xshifts = NULL; 01533 cpl_free(yshifts); yshifts = NULL; 01534 } // for (arm_index = nrNames) 01535 01536 kmo_print_unused_ifus(unused_ifus_after, TRUE); 01537 } 01538 KMO_CATCH 01539 { 01540 KMO_CATCH_MSG(); 01541 ret_val = -1; 01542 } 01543 01544 kmo_free_fits_desc(&desc1); 01545 kmo_free_fits_desc(&desc2); 01546 kmo_free_fits_desc(&desc_telluric); 01547 cpl_vector_delete(ifus); ifus = NULL; 01548 cpl_free(mapping_mode); mapping_mode = NULL; 01549 if (unused_ifus_before != NULL) { 01550 kmo_free_unused_ifus(unused_ifus_before); unused_ifus_before = NULL; 01551 } 01552 if (unused_ifus_after != NULL) { 01553 kmo_free_unused_ifus(unused_ifus_after); unused_ifus_after = NULL; 01554 } 01555 if (bounds != NULL) { 01556 cpl_free(bounds); bounds = NULL; 01557 } 01558 01559 kmo_delete_armNameStruct(arm_name_struct); 01560 01561 // frees for the case of errors 01562 kmclipm_vector_delete(telluric_data); telluric_data = NULL; 01563 kmclipm_vector_delete(telluric_noise); telluric_noise = NULL; 01564 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01565 cpl_table_delete(band_table); band_table = NULL; 01566 cpl_free(suffix); suffix = NULL; 01567 cpl_free(fn_suffix); fn_suffix = NULL; 01568 cpl_free(filter_id); filter_id = NULL; 01569 01570 return ret_val; 01571 } 01572
1.7.6.1