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