|
KMOS Pipeline Reference Manual
1.3.15
|
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 00028 #include <string.h> 00029 #include <math.h> 00030 00031 #include <cpl.h> 00032 00033 #include "kmclipm_constants.h" 00034 #include "kmclipm_functions.h" 00035 00036 #include "kmo_debug.h" 00037 #include "kmo_constants.h" 00038 #include "kmo_cpl_extensions.h" 00039 #include "kmo_priv_lcorr.h" 00040 #include "kmo_utils.h" 00041 #include "kmo_error.h" 00042 #include "kmo_dfs.h" 00043 #include "kmo_functions.h" 00044 #include "kmo_priv_make_image.h" 00045 00046 #include "kmo_priv_arithmetic.h" 00047 #include "kmo_priv_combine.h" 00048 #include "kmo_priv_functions.h" 00049 #include "kmo_priv_reconstruct.h" 00050 #include "kmos_priv_sky_tweak.h" 00051 #include "kmos_oscan.h" 00052 00053 /*----------------------------------------------------------------------------- 00054 * Functions prototypes 00055 *----------------------------------------------------------------------------*/ 00056 static kmclipm_vector * kmo_tweak_load_telluric( 00057 cpl_frameset * frameset, 00058 int ifu_nr, 00059 int is_noise, 00060 int no_subtract, 00061 int * ifu_nr_telluric) ; 00062 00063 static double kmos_sci_red_get_f0(const char *, int, double, double) ; 00064 static double kmos_sci_red_get_zpoint(cpl_frame *, int) ; 00065 static int kmos_sci_red_check_inputs(cpl_frameset *, double, int *); 00066 00067 static int kmos_sci_red_create(cpl_plugin *); 00068 static int kmos_sci_red_exec(cpl_plugin *); 00069 static int kmos_sci_red_destroy(cpl_plugin *); 00070 static int kmos_sci_red(cpl_parameterlist *, cpl_frameset *); 00071 00072 /*----------------------------------------------------------------------------- 00073 * Static variables 00074 *----------------------------------------------------------------------------*/ 00075 00076 static char kmos_sci_red_description[] = 00077 "Two data frames are expected in order to have a sky IFU for the IFU Objects.\n" 00078 "If an OH spectrum is given in the SOF file the lambda axis will be corrected\n" 00079 "using the OH lines as reference.\n" 00080 "Every IFU containing an object will be reconstructed and divided by telluric\n" 00081 "and illumination correction. By default these intermediate cubes are saved\n" 00082 "to disk. The reconstructed objects with the same object name are combined.\n" 00083 "In order to combine a specific object, the parameters --name or --ifus can\n" 00084 "be used.\n" 00085 "For exposures taken with the templates KMOS_spec_obs_mapping8 and\n" 00086 "KMOS_spec_obs_mapping24, all active IFUs are combined.\n" 00087 "\n" 00088 "--------------------------------------------------------------------------\n" 00089 " Input files:\n" 00090 "\n" 00091 " DO KMOS \n" 00092 " category Type Explanation Required #Frames\n" 00093 " -------- ----- ----------- -------- -------\n" 00094 " SCIENCE RAW The science frames Y >=1 \n" 00095 " XCAL F2D x calibration frame Y 1 \n" 00096 " YCAL F2D y calibration frame Y 1 \n" 00097 " LCAL F2D Wavelength calib. frame Y 1 \n" 00098 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00099 " MASTER_FLAT F2D Master flat Y 0,1 \n" 00100 " ILLUM_CORR F2I Illumination correction N 0,1 \n" 00101 " TELLURIC F1I normalised telluric spectrum N 0,1 \n" 00102 " OH_SPEC F1S Vector holding OH lines N 0,1 \n" 00103 "\n" 00104 " Output files:\n" 00105 "\n" 00106 " DO KMOS\n" 00107 " category Type Explanation\n" 00108 " -------- ----- -----------\n" 00109 " SCI_COMBINED F3I Combined cubes with noise\n" 00110 " SCI_RECONSTRUCTED F3I Reconstructed cube with noise\n" 00111 " EXP_MASK F3I Exposure time mask (not for mapping-templates!)\n" 00112 " SCI_INTERIM_OBJECT F3I (optional) Intermediate reconstructed object \n" 00113 " cubes used for sky tweaking, no noise \n" 00114 " (set --sky_tweak and --save_interims)\n" 00115 " SCI_INTERIM_SKY F3I (optional) Intermediate reconstructed sky \n" 00116 " cubes used for sky tweaking, no noise\n" 00117 " (set --sky_tweak and --save_interims)\n" 00118 " SCI_COMBINED_COLL (optional) Collapsed combined cube\n" 00119 " (set --collapse_combined)\n" 00120 " SCI_RECONSTRUCTED_COLL (optional) Collapsed reconstructed cube\n" 00121 " (set --collapse_reconstructed)\n" 00122 "--------------------------------------------------------------------------\n" 00123 "\n"; 00124 00125 /*----------------------------------------------------------------------------- 00126 * Functions code 00127 *----------------------------------------------------------------------------*/ 00128 00129 /*----------------------------------------------------------------------------*/ 00134 /*----------------------------------------------------------------------------*/ 00135 00138 /*----------------------------------------------------------------------------*/ 00147 /*----------------------------------------------------------------------------*/ 00148 int cpl_plugin_get_info(cpl_pluginlist *list) 00149 { 00150 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00151 cpl_plugin *plugin = &recipe->interface; 00152 00153 cpl_plugin_init(plugin, 00154 CPL_PLUGIN_API, 00155 KMOS_BINARY_VERSION, 00156 CPL_PLUGIN_TYPE_RECIPE, 00157 "kmos_sci_red", 00158 "Reconstruct obj/sky-pairs individually and combine " 00159 "them afterwards", 00160 kmos_sci_red_description, 00161 "Alex Agudo Berbel, Yves Jung", 00162 "usd-help@eso.org", 00163 kmos_get_license(), 00164 kmos_sci_red_create, 00165 kmos_sci_red_exec, 00166 kmos_sci_red_destroy); 00167 00168 cpl_pluginlist_append(list, plugin); 00169 00170 return 0; 00171 } 00172 00173 /*----------------------------------------------------------------------------*/ 00181 /*----------------------------------------------------------------------------*/ 00182 static int kmos_sci_red_create(cpl_plugin *plugin) 00183 { 00184 cpl_recipe *recipe; 00185 cpl_parameter *p; 00186 00187 /* Check that the plugin is part of a valid recipe */ 00188 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00189 recipe = (cpl_recipe *)plugin; 00190 else 00191 return -1; 00192 00193 /* Create the parameters list in the cpl_recipe object */ 00194 recipe->parameters = cpl_parameterlist_new(); 00195 00196 /* --imethod (interpolation method) */ 00197 p = cpl_parameter_new_value("kmos.kmos_sci_red.imethod", CPL_TYPE_STRING, 00198 "Method to use for interpolation during reconstruction. " 00199 "[\"NN\" (nearest neighbour), " 00200 "\"lwNN\" (linear weighted nearest neighbor), " 00201 "\"swNN\" (square weighted nearest neighbor), " 00202 "\"MS\" (Modified Shepard's method)" 00203 "\"CS\" (Cubic spline)]", 00204 "kmos.kmos_sci_red", "CS"); 00205 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00206 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00207 cpl_parameterlist_append(recipe->parameters, p); 00208 00209 /* --smethod (shift interpolation method) */ 00210 p = cpl_parameter_new_value("kmos.kmos_sci_red.smethod", CPL_TYPE_STRING, 00211 "Method to use for interpolation during shifting. " 00212 "[\"NN\" (nearest neighbour), " 00213 "\"CS\" (Cubic spline)]", 00214 "kmos.kmos_sci_red", "CS"); 00215 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "smethod"); 00216 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00217 cpl_parameterlist_append(recipe->parameters, p); 00218 00219 /* --method (shift method) */ 00220 p = cpl_parameter_new_value("kmos.kmos_sci_red.method", CPL_TYPE_STRING, 00221 "The shifting method: " 00222 "'none': no shifting, combined directly, " 00223 "'header': shift according to WCS (default), " 00224 "'center': centering algorithm, " 00225 "'user': read shifts from file", 00226 "kmos.kmos_sci_red", "header"); 00227 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "method"); 00228 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00229 cpl_parameterlist_append(recipe->parameters, p); 00230 00231 /* --fmethod */ 00232 p = cpl_parameter_new_value("kmos.kmos_sci_red.fmethod", CPL_TYPE_STRING, 00233 "The fitting method (applies only when method='center'): " 00234 "'gauss': fit a gauss function to collapsed image (default), " 00235 "'moffat': fit a moffat function to collapsed image", 00236 "kmos.kmos_sci_red", "gauss"); 00237 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00238 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00239 cpl_parameterlist_append(recipe->parameters, p); 00240 00241 /* --name */ 00242 p = cpl_parameter_new_value("kmos.kmos_sci_red.name", CPL_TYPE_STRING, 00243 "Name of the object to combine.", "kmos.kmos_sci_red", ""); 00244 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "name"); 00245 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00246 cpl_parameterlist_append(recipe->parameters, p); 00247 00248 /* --ifus */ 00249 p = cpl_parameter_new_value("kmos.kmos_sci_red.ifus", CPL_TYPE_STRING, 00250 "The indices of the IFUs to combine. \"ifu1;ifu2;...\"", 00251 "kmos.kmos_sci_red", ""); 00252 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifus"); 00253 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00254 cpl_parameterlist_append(recipe->parameters, p); 00255 00256 /* --oscan */ 00257 p = cpl_parameter_new_value("kmos.kmos_sci_red.oscan", 00258 CPL_TYPE_BOOL, "Apply Overscan Correction", 00259 "kmos.kmos_sci_red", TRUE); 00260 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "oscan"); 00261 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00262 cpl_parameterlist_append(recipe->parameters, p); 00263 00264 /* --pix_scale */ 00265 p = cpl_parameter_new_value("kmos.kmos_sci_red.pix_scale", CPL_TYPE_DOUBLE, 00266 "Change the pixel scale [arcsec]. " 00267 "Default of 0.2\" results into cubes of 14x14pix, " 00268 "a scale of 0.1\" results into cubes of 28x28pix, etc.", 00269 "kmos.kmos_sci_red", KMOS_PIX_RESOLUTION); 00270 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pix_scale"); 00271 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00272 cpl_parameterlist_append(recipe->parameters, p); 00273 00274 /* --suppress_extension */ 00275 p = cpl_parameter_new_value("kmos.kmos_sci_red.suppress_extension", 00276 CPL_TYPE_BOOL, 00277 "Suppress arbitrary filename extension." 00278 "(TRUE (apply) or FALSE (don't apply)", 00279 "kmos.kmos_sci_red", FALSE); 00280 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00281 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00282 cpl_parameterlist_append(recipe->parameters, p); 00283 00284 /* --neighborhoodRange */ 00285 p = cpl_parameter_new_value("kmos.kmos_sci_red.neighborhoodRange", 00286 CPL_TYPE_DOUBLE, 00287 "Defines the range to search for neighbors in pixels", 00288 "kmos.kmos_sci_red", 1.001); 00289 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00290 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00291 cpl_parameterlist_append(recipe->parameters, p); 00292 00293 /* --filename */ 00294 p = cpl_parameter_new_value("kmos.kmos_sci_red.filename", CPL_TYPE_STRING, 00295 "The path to the file with the shift vectors." 00296 "(Applies only to method='user')", 00297 "kmos.kmos_sci_red", ""); 00298 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "filename"); 00299 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00300 cpl_parameterlist_append(recipe->parameters, p); 00301 00302 /* --flux */ 00303 p = cpl_parameter_new_value("kmos.kmos_sci_red.flux", CPL_TYPE_BOOL, 00304 "TRUE: Apply flux conservation. FALSE: otherwise", 00305 "kmos.kmos_sci_red", FALSE); 00306 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00307 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00308 cpl_parameterlist_append(recipe->parameters, p); 00309 00310 /* --background */ 00311 p = cpl_parameter_new_value("kmos.kmos_sci_red.background", CPL_TYPE_BOOL, 00312 "TRUE: Apply background removal. FALSE: otherwise", 00313 "kmos.kmos_sci_red", FALSE); 00314 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "background"); 00315 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00316 cpl_parameterlist_append(recipe->parameters, p); 00317 00318 /* --fast_mode */ 00319 p = cpl_parameter_new_value("kmos.kmos_sci_red.fast_mode", CPL_TYPE_BOOL, 00320 "FALSE: cubes are shifted and combined," 00321 "TRUE: cubes are collapsed and then shifted and combined", 00322 "kmos.kmos_sci_red", FALSE); 00323 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fast_mode"); 00324 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00325 cpl_parameterlist_append(recipe->parameters, p); 00326 00327 /* --extrapolate */ 00328 p = cpl_parameter_new_value("kmos.kmos_sci_red.extrapolate", CPL_TYPE_BOOL, 00329 "Applies only to 'smethod=CS' when doing sub-pixel shifts: " 00330 "FALSE: shifted IFU will be filled with NaN's at the borders," 00331 "TRUE: shifted IFU will be extrapolated at the borders", 00332 "kmos.kmos_sci_red", FALSE); 00333 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "extrapolate"); 00334 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00335 cpl_parameterlist_append(recipe->parameters, p); 00336 00337 /* --xcal_interpolation */ 00338 p = cpl_parameter_new_value("kmos.kmos_sci_red.xcal_interpolation", 00339 CPL_TYPE_BOOL, 00340 "TRUE: Interpolate xcal between rotator angles. FALSE: otherwise", 00341 "kmos.kmos_sci_red", TRUE); 00342 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcal_interpolation"); 00343 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00344 cpl_parameterlist_append(recipe->parameters, p); 00345 00346 /* --edge_nan */ 00347 p = cpl_parameter_new_value("kmos.kmos_sci_red.edge_nan", CPL_TYPE_BOOL, 00348 "Set borders of cubes to NaN before combining them." 00349 "(TRUE (apply) or FALSE (don't apply)", 00350 "kmos.kmos_sci_red", FALSE); 00351 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "edge_nan"); 00352 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00353 cpl_parameterlist_append(recipe->parameters, p); 00354 00355 /* --no_combine */ 00356 p = cpl_parameter_new_value("kmos.kmos_sci_red.no_combine", CPL_TYPE_BOOL, 00357 "Don't combine cubes after reconstruction." 00358 "(TRUE (apply) or FALSE (don't apply)", 00359 "kmos.kmos_sci_red", FALSE); 00360 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "no_combine"); 00361 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00362 cpl_parameterlist_append(recipe->parameters, p); 00363 00364 /* --no_subtract */ 00365 p = cpl_parameter_new_value("kmos.kmos_sci_red.no_subtract", CPL_TYPE_BOOL, 00366 "Don't sky subtract object and references." 00367 "(TRUE (apply) or FALSE (don't apply)", 00368 "kmos.kmos_sci_red", FALSE); 00369 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "no_subtract"); 00370 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00371 cpl_parameterlist_append(recipe->parameters, p); 00372 00373 /* --sky_tweak */ 00374 p = cpl_parameter_new_value("kmos.kmos_sci_red.sky_tweak", CPL_TYPE_BOOL, 00375 "Use modified sky cube for sky subtraction." 00376 "(TRUE (apply) or FALSE (don't apply)", 00377 "kmos.kmos_sci_red", FALSE); 00378 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sky_tweak"); 00379 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00380 cpl_parameterlist_append(recipe->parameters, p); 00381 00382 /* --tbsub */ 00383 p = cpl_parameter_new_value("kmos.kmos_sci_red.tbsub", CPL_TYPE_BOOL, 00384 "Subtract thermal background from input cube." 00385 "(TRUE (apply) or FALSE (don't apply)", 00386 "kmos.kmos_sci_red", TRUE); 00387 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "tbsub"); 00388 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00389 cpl_parameterlist_append(recipe->parameters, p); 00390 00391 // add parameters for band-definition 00392 kmos_band_pars_create(recipe->parameters, "kmos.kmos_sci_red"); 00393 00394 /* --obj_sky_table */ 00395 p = cpl_parameter_new_value("kmos.kmos_sci_red.obj_sky_table", 00396 CPL_TYPE_STRING, 00397 "The path to the file with the modified obj/sky associations.", 00398 "kmos.kmos_sci_red", ""); 00399 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "obj_sky_table"); 00400 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00401 cpl_parameterlist_append(recipe->parameters, p); 00402 00403 /* --velocity_offset */ 00404 p = cpl_parameter_new_value("kmos.kmos_sci_red.velocity_offset", 00405 CPL_TYPE_DOUBLE, 00406 "Specify velocity offset correction in km/s for lambda scale", 00407 "kmos.kmos_sci_red", 0.0); 00408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "velocity_offset"); 00409 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00410 cpl_parameterlist_append(recipe->parameters, p); 00411 00412 /* --save_interims */ 00413 p=cpl_parameter_new_value("kmos.kmos_sci_red.save_interims", CPL_TYPE_BOOL, 00414 "Save interim object and sky cubes. " 00415 "Can only be used together with --sky_tweak", 00416 "kmos.kmos_sci_red", FALSE); 00417 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save_interims"); 00418 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00419 cpl_parameterlist_append(recipe->parameters, p); 00420 00421 /* --collapse_reconstructed */ 00422 p = cpl_parameter_new_value("kmos.kmos_sci_red.collapse_reconstructed", 00423 CPL_TYPE_BOOL, "Flag to collapse the reconstructed images", 00424 "kmos.kmos_sci_red", FALSE); 00425 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"collapse_reconstructed"); 00426 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00427 cpl_parameterlist_append(recipe->parameters, p); 00428 00429 /* --collapse_combined */ 00430 p = cpl_parameter_new_value("kmos.kmos_sci_red.collapse_combined", 00431 CPL_TYPE_BOOL, "Flag to collapse the combined images", 00432 "kmos.kmos_sci_red", FALSE); 00433 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "collapse_combined"); 00434 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00435 cpl_parameterlist_append(recipe->parameters, p); 00436 00437 return kmos_combine_pars_create(recipe->parameters, "kmos.kmos_sci_red", 00438 DEF_REJ_METHOD, FALSE); 00439 } 00440 00441 /*----------------------------------------------------------------------------*/ 00447 /*----------------------------------------------------------------------------*/ 00448 static int kmos_sci_red_exec(cpl_plugin *plugin) 00449 { 00450 cpl_recipe *recipe; 00451 00452 /* Get the recipe out of the plugin */ 00453 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00454 recipe = (cpl_recipe *)plugin; 00455 else return -1 ; 00456 00457 return kmos_sci_red(recipe->parameters, recipe->frames); 00458 } 00459 00460 /*----------------------------------------------------------------------------*/ 00466 /*----------------------------------------------------------------------------*/ 00467 static int kmos_sci_red_destroy(cpl_plugin *plugin) 00468 { 00469 cpl_recipe *recipe; 00470 00471 /* Get the recipe out of the plugin */ 00472 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00473 recipe = (cpl_recipe *)plugin; 00474 else return -1 ; 00475 00476 cpl_parameterlist_delete(recipe->parameters); 00477 return 0 ; 00478 } 00479 00480 /*----------------------------------------------------------------------------*/ 00493 /*----------------------------------------------------------------------------*/ 00494 static int kmos_sci_red(cpl_parameterlist * parlist, cpl_frameset * frameset) 00495 { 00496 const cpl_parameter * par ; 00497 /*********************/ 00498 /* Parsed Parameters */ 00499 int flux, background, extrapolate, fast_mode, edge_nan, no_combine, 00500 no_subtract, sky_tweak, tbsub, xcal_interpolation, suppress_extension, 00501 save_interims, citer, cmin, cmax, collapse_combined, 00502 collapse_reconstructed, oscan ; 00503 double neighborhoodRange, pix_scale, cpos_rej, cneg_rej, 00504 velo_offset, velo_corr ; 00505 double * velo_corr_ptr ; 00506 const char * imethod, * smethod, * cmethod, * comb_method, * fmethod, 00507 * filename, * ifus_txt, * name, * fn_obj_sky_table, * fn_reconstr ; 00508 /*********************/ 00509 00510 double scaling, conversion, f_0, zpoint ; 00511 int print_once, cube_counter_data, cube_counter_noise, do_sky_subtraction, 00512 suppress_index, mapping_id, nb_science, nb_telluric, nb_illum_corr, 00513 telluric_ok, actual_msg_level, nr_data ; 00514 int i, j, jj, sf, ifu_nr, sky_ifu_nr, det_nr, ifu_nr_telluric ; 00515 char * suffix ; 00516 char * mapping_mode ; 00517 char * extname ; 00518 char * keyword ; 00519 char ** split ; 00520 char * fn_suffix ; 00521 const char * tmp_str ; 00522 const char * fn_obj ; 00523 const char * filter_id ; 00524 const char * fn_out ; 00525 00526 /*****************************/ 00527 /* TO BE CHECKED AND REMOVED */ 00528 enum kmo_frame_type ft ; 00529 char content[256]; 00530 main_fits_desc desc_telluric, desc1 ; 00531 int tmp_int, idx ; 00532 /*****************************/ 00533 00534 enum extrapolationType extrapol_enum ; 00535 cpl_propertylist * header_tmp ; 00536 cpl_propertylist * main_header ; 00537 int * qc_output_unit ; 00538 int * bounds ; 00539 gridDefinition gd ; 00540 armNameStruct * arm_name_struct ; 00541 00542 cpl_polynomial * oh_lcorr_coeffs ; 00543 cpl_vector * ifus ; 00544 cpl_array ** unused_ifus_before ; 00545 cpl_array ** unused_ifus_after ; 00546 cpl_frame * sky_frame ; 00547 cpl_frame * sky_as_object_frame ; 00548 cpl_frame * ref_spectrum_frame ; 00549 cpl_frame * xcal_frame ; 00550 cpl_frame * ycal_frame ; 00551 cpl_frame * lcal_frame ; 00552 cpl_frame * flat_frame ; 00553 cpl_frame * telluric_frame ; 00554 cpl_frame * tmp_frame ; 00555 00556 cpl_table * band_table ; 00557 00558 cpl_imagelist * combined_data ; 00559 cpl_imagelist * combined_noise ; 00560 cpl_imagelist * tmp_cube1 ; 00561 cpl_imagelist * tmp_cube2 ; 00562 00563 cpl_image * tmpImg ; 00564 cpl_image * exp_mask ; 00565 cpl_image * illum_data ; 00566 cpl_image * illum_noise ; 00567 00568 cpl_imagelist ** cube_data ; 00569 cpl_imagelist ** cube_noise ; 00570 cpl_imagelist ** cube_interim_object ; 00571 cpl_imagelist ** cube_interim_sky ; 00572 00573 cpl_propertylist ** header_data ; 00574 cpl_propertylist ** header_noise ; 00575 cpl_propertylist ** header_sky ; 00576 00577 kmclipm_vector * telluric_data ; 00578 kmclipm_vector * telluric_noise ; 00579 00580 /* Initialise */ 00581 print_once = FALSE ; 00582 cube_counter_data = cube_counter_noise = 0 ; 00583 do_sky_subtraction = FALSE ; 00584 suppress_index = 0 ; 00585 mapping_id = -1 ; 00586 combined_data = combined_noise = NULL ; 00587 sky_as_object_frame = NULL ; 00588 00589 /* Check entries */ 00590 if (parlist == NULL || frameset == NULL) { 00591 cpl_msg_error(__func__, "Null Inputs") ; 00592 cpl_error_set(__func__, CPL_ERROR_NULL_INPUT) ; 00593 return -1 ; 00594 } 00595 00596 /* Get parameters */ 00597 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.flux"); 00598 flux = cpl_parameter_get_bool(par); 00599 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.background"); 00600 background = cpl_parameter_get_bool(par); 00601 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.imethod"); 00602 imethod = cpl_parameter_get_string(par) ; 00603 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.smethod"); 00604 smethod = cpl_parameter_get_string(par) ; 00605 par = cpl_parameterlist_find_const(parlist, 00606 "kmos.kmos_sci_red.neighborhoodRange"); 00607 neighborhoodRange = cpl_parameter_get_double(par) ; 00608 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.method"); 00609 comb_method = cpl_parameter_get_string(par) ; 00610 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.fmethod"); 00611 fmethod = cpl_parameter_get_string(par) ; 00612 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.filename"); 00613 filename = cpl_parameter_get_string(par) ; 00614 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.ifus"); 00615 ifus_txt = cpl_parameter_get_string(par) ; 00616 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.name"); 00617 name = cpl_parameter_get_string(par) ; 00618 kmos_band_pars_load(parlist, "kmos.kmos_sci_red"); 00619 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_sci_red.extrapolate"); 00620 extrapolate = cpl_parameter_get_bool(par); 00621 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_sci_red.fast_mode"); 00622 fast_mode = cpl_parameter_get_bool(par); 00623 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_sci_red.edge_nan"); 00624 edge_nan = cpl_parameter_get_bool(par); 00625 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_sci_red.no_combine"); 00626 no_combine = cpl_parameter_get_bool(par); 00627 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_sci_red.no_subtract"); 00628 no_subtract = cpl_parameter_get_bool(par); 00629 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_sci_red.sky_tweak"); 00630 sky_tweak = cpl_parameter_get_bool(par); 00631 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_sci_red.tbsub"); 00632 tbsub = cpl_parameter_get_bool(par); 00633 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.oscan"); 00634 oscan = cpl_parameter_get_bool(par); 00635 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sci_red.pix_scale"); 00636 pix_scale = cpl_parameter_get_double(par) ; 00637 par = cpl_parameterlist_find_const(parlist, 00638 "kmos.kmos_sci_red.xcal_interpolation"); 00639 xcal_interpolation = cpl_parameter_get_bool(par); 00640 par = cpl_parameterlist_find_const(parlist, 00641 "kmos.kmos_sci_red.suppress_extension"); 00642 suppress_extension = cpl_parameter_get_bool(par); 00643 par = cpl_parameterlist_find_const(parlist, 00644 "kmos.kmos_sci_red.obj_sky_table"); 00645 fn_obj_sky_table = cpl_parameter_get_string(par) ; 00646 kmos_combine_pars_load(parlist, "kmos.kmos_sci_red", &cmethod, &cpos_rej, 00647 &cneg_rej, &citer, &cmin, &cmax, FALSE); 00648 par = cpl_parameterlist_find_const(parlist, 00649 "kmos.kmos_sci_red.velocity_offset"); 00650 velo_offset = cpl_parameter_get_double(par) ; 00651 velo_corr = 1. + velo_offset * 1000. / CPL_PHYS_C; 00652 velo_corr_ptr = &velo_corr; 00653 par = cpl_parameterlist_find_const(parlist, 00654 "kmos.kmos_sci_red.save_interims"); 00655 save_interims = cpl_parameter_get_bool(par); 00656 par = cpl_parameterlist_find_const(parlist, 00657 "kmos.kmos_sci_red.collapse_combined"); 00658 collapse_combined = cpl_parameter_get_bool(par); 00659 par = cpl_parameterlist_find_const(parlist, 00660 "kmos.kmos_sci_red.collapse_reconstructed"); 00661 collapse_reconstructed = cpl_parameter_get_bool(par); 00662 00663 /* Check Parameters */ 00664 if (strcmp(imethod, "NN") && strcmp(imethod, "lwNN") && 00665 strcmp(imethod, "swNN") && strcmp(imethod, "MS") && 00666 strcmp(imethod, "CS")) { 00667 cpl_msg_error(__func__, 00668 "imethod must be 'NN','lwNN','swNN','MS' or 'CS'") ; 00669 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00670 return -1 ; 00671 } 00672 if (strcmp(smethod, "NN") && strcmp(smethod, "CS")) { 00673 cpl_msg_error(__func__, 00674 "smethod must be 'NN' or 'CS'") ; 00675 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00676 return -1 ; 00677 } 00678 if (neighborhoodRange <= 0.0) { 00679 cpl_msg_error(__func__, 00680 "neighborhoodRange must be greater than 0.0") ; 00681 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00682 return -1 ; 00683 } 00684 if (strcmp(comb_method, "none") && strcmp(comb_method, "header") && 00685 strcmp(comb_method, "center") && strcmp(comb_method, "user")) { 00686 cpl_msg_error(__func__, 00687 "shift methods must be 'none', 'header', 'center' or 'user'") ; 00688 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00689 return -1 ; 00690 } 00691 if (strcmp(ifus_txt, "") && strcmp(name, "")) { 00692 cpl_msg_error(__func__, 00693 "name and IFU indices cannot be both provided") ; 00694 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00695 return -1 ; 00696 } 00697 if (strcmp(smethod, "NN") && strcmp(smethod, "CS")) { 00698 cpl_msg_error(__func__, "smethod must be 'NN' or 'CS'") ; 00699 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00700 return -1 ; 00701 } 00702 if (!strcmp(smethod, "NN") && extrapolate == TRUE) { 00703 cpl_msg_error(__func__, 00704 "extrapolation in not compatible with smethod 'NN'"); 00705 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00706 return -1 ; 00707 } 00708 if (!strcmp(smethod, "CS")) smethod = "BCS"; 00709 if (!strcmp(smethod, "BCS") && extrapolate == TRUE) 00710 extrapol_enum = BCS_NATURAL; 00711 else 00712 extrapol_enum = NONE_NANS; 00713 00714 if (no_subtract && sky_tweak) { 00715 cpl_msg_error(__func__,"no_subtract and sky_tweak cannot be both TRUE"); 00716 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00717 return -1 ; 00718 } 00719 if (pix_scale < 0.01 || pix_scale > 0.4) { 00720 cpl_msg_error(__func__, "pix_scale must be between 0.01 and 0.4"); 00721 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00722 return -1 ; 00723 } 00724 00725 if (cpl_frameset_count_tags(frameset, SCIENCE) == 1 || no_subtract) { 00726 no_combine = TRUE; 00727 cpl_msg_info(__func__, 00728 "--no_combine set to TRUE (1 SCIENCE frame or --no_subtract"); 00729 } 00730 00731 /* Identify the RAW and CALIB frames in the input frameset */ 00732 if (kmo_dfs_set_groups(frameset, "kmos_sci_red") != 1) { 00733 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00734 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00735 return -1 ; 00736 } 00737 00738 /* Check the inputs consistency */ 00739 if (kmos_sci_red_check_inputs(frameset, pix_scale, &mapping_id) != 1) { 00740 cpl_msg_error(__func__, "Input frameset is not consistent") ; 00741 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00742 return -1 ; 00743 } 00744 if (mapping_id == 0) mapping_mode = NULL ; 00745 if (mapping_id == 1) mapping_mode = "mapping8" ; 00746 if (mapping_id == 2) mapping_mode = "mapping24" ; 00747 00748 /* Instrument setup */ 00749 suffix = kmo_dfs_get_suffix(kmo_dfs_get_frame(frameset,SCIENCE),TRUE,FALSE); 00750 cpl_msg_info(__func__, "Detected instrument setup: %s", suffix+1); 00751 cpl_free(suffix); 00752 00753 /* Load IFUS if specified */ 00754 if (strcmp(ifus_txt, "")) { 00755 nb_science = cpl_frameset_count_tags(frameset, SCIENCE); 00756 ifus = kmo_identify_values(ifus_txt); 00757 if (ifus == NULL || cpl_vector_get_size(ifus) != nb_science) { 00758 if (ifus != NULL) cpl_vector_delete(ifus); 00759 cpl_msg_error(__func__, "ifus size must match the science frames") ; 00760 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00761 return -1 ; 00762 } 00763 } else { 00764 ifus = NULL ; 00765 } 00766 00767 /* Mapping mode */ 00768 if (mapping_id > 0) { 00769 if ((ifus != NULL) || (strcmp(name, ""))) { 00770 cpl_msg_warning(__func__,"Mapping Mode ٍ+ Specific IFUs requested") ; 00771 } else { 00772 if (!strcmp(smethod, "BCS")) { 00773 extrapol_enum = BCS_NATURAL; 00774 cpl_msg_info(__func__, "Mapping Mode : extrapolation set") ; 00775 } 00776 } 00777 } 00778 00779 /* Check which IFUs are active for all frames */ 00780 unused_ifus_before = kmo_get_unused_ifus(frameset, 1, 1); 00781 unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before); 00782 kmo_print_unused_ifus(unused_ifus_before, FALSE); 00783 kmo_free_unused_ifus(unused_ifus_before); 00784 00785 /* Setup grid definition, wavelength start and end are set later */ 00786 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, pix_scale, 0.); 00787 00788 /* Get frames */ 00789 xcal_frame = kmo_dfs_get_frame(frameset, XCAL) ; 00790 ycal_frame = kmo_dfs_get_frame(frameset, YCAL) ; 00791 lcal_frame = kmo_dfs_get_frame(frameset, LCAL) ; 00792 flat_frame = kmo_dfs_get_frame(frameset, MASTER_FLAT) ; 00793 ref_spectrum_frame = kmo_dfs_get_frame(frameset, OH_SPEC) ; 00794 nb_illum_corr = cpl_frameset_count_tags(frameset, ILLUM_CORR); 00795 00796 /* Get left and right bounds of IFUs from XCAL */ 00797 header_tmp = kmo_dfs_load_primary_header(frameset, XCAL); 00798 bounds = kmclipm_extract_bounds(header_tmp); 00799 cpl_propertylist_delete(header_tmp); 00800 if (bounds == NULL) { 00801 if (ifus != NULL) cpl_vector_delete(ifus); 00802 kmo_free_unused_ifus(unused_ifus_after); 00803 cpl_msg_error(__func__, "Cannot compute bounds") ; 00804 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00805 return -1 ; 00806 } 00807 00808 /* armNameStruct: objects that need to be reconstructed and their 00809 associated sky. Valid STD frames with objects and associated sky. 00810 Get valid object names, either one object name in several frames, 00811 or all object names */ 00812 if (!strcmp(fn_obj_sky_table, "")) { 00813 arm_name_struct = kmo_create_armNameStruct(frameset, SCIENCE, ifus, 00814 name, unused_ifus_after, bounds, mapping_mode, no_subtract); 00815 /* TODO : need to save ?? */ 00816 kmo_save_objSkyStruct(arm_name_struct->obj_sky_struct); 00817 } else { 00818 // read in obj/sky-table 00819 objSkyStruct *obj_sky_struct = NULL; 00820 obj_sky_struct = kmo_read_objSkyStruct(fn_obj_sky_table, frameset, 00821 SCIENCE); 00822 00823 /* Check if any sky-IFUs have been specified not beeing the */ 00824 /* same IFU# for objects. */ 00825 // In this case sky_tweak must be activated 00826 for (i = 0; i < obj_sky_struct->size; i++) { 00827 if (obj_sky_struct->table[i].objFrame != NULL) { 00828 for (j = 0; j < KMOS_NR_IFUS; j++) { 00829 if ((obj_sky_struct->table[i].skyIfus[j] > 0) && 00830 (sky_tweak == FALSE)) { 00831 kmo_print_objSkyStruct(obj_sky_struct); 00832 kmo_delete_objSkyStruct(obj_sky_struct); 00833 cpl_msg_error(__func__, 00834 "--sky_tweak needs to be set when sky are used from other IFUs"); 00835 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00836 return -1 ; 00837 } 00838 } 00839 } 00840 } 00841 arm_name_struct = kmo_create_armNameStruct2(obj_sky_struct, frameset, 00842 SCIENCE, ifus, name, unused_ifus_after, bounds, mapping_mode, 00843 no_subtract); 00844 } 00845 if (ifus != NULL) cpl_vector_delete(ifus); 00846 if (arm_name_struct == NULL) { 00847 kmo_free_unused_ifus(unused_ifus_after); 00848 cpl_free(bounds); 00849 cpl_msg_error(__func__, "Cannot compute ARM/name structure") ; 00850 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00851 return -1 ; 00852 } 00853 kmo_print_armNameStruct(frameset, arm_name_struct); 00854 00855 /* Check Telluric availability for each Object */ 00856 /* in mapping-mode check if for all IFUs there is either no */ 00857 /* telluric at all or the same number of tellurics than object names */ 00858 nb_telluric = cpl_frameset_count_tags(frameset, TELLURIC); 00859 if (nb_telluric > 0 && mapping_id > 0) { 00860 for (i = 0; i < arm_name_struct->nrNames; i++) { 00861 if (arm_name_struct->telluricCnt[i] != arm_name_struct->namesCnt[i] 00862 && (arm_name_struct->telluricCnt[i] != 0)) { 00863 cpl_msg_error(__func__, "Mosaics need a TELLURIC per detector"); 00864 cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE) ; 00865 return -1 ; 00866 } 00867 } 00868 } 00869 00870 /* Allocate data */ 00871 cube_data=(cpl_imagelist**)cpl_calloc(KMOS_NR_IFUS, sizeof(cpl_imagelist*)); 00872 cube_noise=(cpl_imagelist**)cpl_calloc(KMOS_NR_IFUS,sizeof(cpl_imagelist*)); 00873 header_data = (cpl_propertylist**)cpl_calloc(KMOS_NR_IFUS, 00874 sizeof(cpl_propertylist*)); 00875 header_noise = (cpl_propertylist**)cpl_calloc(KMOS_NR_IFUS, 00876 sizeof(cpl_propertylist*)); 00877 if (save_interims) { 00878 cube_interim_object=(cpl_imagelist**)cpl_calloc(KMOS_NR_IFUS, 00879 sizeof(cpl_imagelist*)); 00880 cube_interim_sky =(cpl_imagelist**)cpl_calloc(KMOS_NR_IFUS, 00881 sizeof(cpl_imagelist*)); 00882 header_sky = (cpl_propertylist**)cpl_calloc(KMOS_NR_IFUS, 00883 sizeof(cpl_propertylist*)); 00884 } 00885 00886 /* Loop all science frames containing at least one object */ 00887 cpl_msg_info(__func__, "Reconstructing & saving cubes with objects"); 00888 for (sf = 0; sf < arm_name_struct->size; sf++) { 00889 fn_obj = cpl_frame_get_filename( 00890 arm_name_struct->obj_sky_struct->table[sf].objFrame); 00891 if ((main_header = kmclipm_propertylist_load(fn_obj, 0)) == NULL) { 00892 kmo_free_unused_ifus(unused_ifus_after); 00893 cpl_free(bounds); 00894 kmo_delete_armNameStruct(arm_name_struct); 00895 cpl_free(qc_output_unit) ; 00896 cpl_free(cube_data) ; 00897 cpl_free(cube_noise) ; 00898 cpl_free(header_data) ; 00899 cpl_free(header_noise) ; 00900 if (save_interims) { 00901 cpl_free(cube_interim_object) ; 00902 cpl_free(cube_interim_sky) ; 00903 cpl_free(header_sky) ; 00904 } 00905 cpl_msg_error(__func__, "Cannot Load main header"); 00906 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00907 return -1 ; 00908 } 00909 actual_msg_level = cpl_msg_get_level(); 00910 00911 /* Hold the QC parameter */ 00912 qc_output_unit = cpl_calloc(KMOS_NR_IFUS, sizeof(int)) ; 00913 00914 /* Reconstruct science frame */ 00915 cpl_msg_info(__func__, " > processing frame: %s", fn_obj); 00916 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 00917 00918 /* Initialise */ 00919 cube_data[ifu_nr-1] = cube_noise[ifu_nr-1] = NULL ; 00920 00921 sky_ifu_nr = ifu_nr; 00922 det_nr = (ifu_nr - 1)/KMOS_IFUS_PER_DETECTOR + 1; 00923 00924 /* Get subheader data */ 00925 header_data[ifu_nr-1] = kmclipm_propertylist_load(fn_obj, det_nr); 00926 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_DATA); 00927 kmclipm_update_property_string(header_data[ifu_nr-1], 00928 EXTNAME, extname, "FITS extension name"); 00929 cpl_free(extname); 00930 00931 if (arm_name_struct->name_ids[ifu_nr-1+sf*KMOS_NR_IFUS] >= 1) { 00932 // IFU is valid 00933 00934 /* Fill sky_as_object_frame, do_sky_subtraction and sky_frame */ 00935 sky_as_object_frame = NULL ; 00936 if ((arm_name_struct->obj_sky_struct->table[sf].skyFrames[ifu_nr-1] != NO_CORRESPONDING_SKYFRAME) && !no_subtract) { 00937 do_sky_subtraction = TRUE; 00938 if (no_subtract) sky_frame = NULL; 00939 else sky_frame = 00940 arm_name_struct->obj_sky_struct->table[sf].skyFrames[ifu_nr-1]; 00941 00942 if (sky_tweak){ 00943 sky_as_object_frame = sky_frame; 00944 sky_frame = NULL; 00945 sky_ifu_nr = arm_name_struct->obj_sky_struct->table[sf].skyIfus[ifu_nr-1]; 00946 } 00947 } else { 00948 do_sky_subtraction = FALSE; 00949 sky_frame = NULL; 00950 } 00951 00952 /* Get filter and setup grid definition using WAVE_BAND */ 00953 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, det_nr, 00954 IFU_FILTID_POSTFIX); 00955 filter_id = cpl_propertylist_get_string(main_header, keyword); 00956 cpl_free(keyword); 00957 00958 if (print_once) cpl_msg_set_level(CPL_MSG_WARNING); 00959 print_once = TRUE; 00960 00961 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0); 00962 kmclipm_setup_grid_band_lcal(&gd, filter_id, band_table); 00963 cpl_table_delete(band_table); 00964 00965 cpl_msg_set_level(actual_msg_level); 00966 00967 /* calc WCS & update subheader */ 00968 kmo_calc_wcs_gd(main_header, header_data[ifu_nr-1], ifu_nr, gd); 00969 00970 /* Update some keywords */ 00971 kmclipm_update_property_int(header_data[ifu_nr-1], NAXIS, 3, 00972 "number of data axes"); 00973 kmclipm_update_property_int(header_data[ifu_nr-1], NAXIS1, 00974 gd.x.dim, "length of data axis 1"); 00975 kmclipm_update_property_int(header_data[ifu_nr-1], NAXIS2, 00976 gd.y.dim, "length of data axis 2"); 00977 kmclipm_update_property_int(header_data[ifu_nr-1], NAXIS3, 00978 gd.l.dim, "length of data axis 3"); 00979 00980 /* Option save_interim only applies if sky_tweak is used */ 00981 if (save_interims && sky_as_object_frame != NULL) { 00982 header_tmp = kmclipm_propertylist_load( 00983 cpl_frame_get_filename(sky_as_object_frame), 0); 00984 00985 header_sky[ifu_nr-1]=kmclipm_propertylist_load( 00986 cpl_frame_get_filename(sky_as_object_frame),det_nr); 00987 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_DATA); 00988 kmclipm_update_property_string(header_sky[ifu_nr-1], 00989 EXTNAME, extname, "FITS extension name"); 00990 cpl_free(extname); 00991 00992 kmo_calc_wcs_gd(header_tmp, header_sky[ifu_nr-1], 00993 ifu_nr, gd); 00994 kmclipm_update_property_int(header_sky[ifu_nr-1], NAXIS, 3, 00995 "number of data axes"); 00996 kmclipm_update_property_int(header_sky[ifu_nr-1], NAXIS1, 00997 gd.x.dim, "length of data axis 1"); 00998 kmclipm_update_property_int(header_sky[ifu_nr-1], NAXIS2, 00999 gd.y.dim, "length of data axis 2"); 01000 kmclipm_update_property_int(header_sky[ifu_nr-1], NAXIS3, 01001 gd.l.dim, "length of data axis 3"); 01002 cpl_propertylist_delete(header_tmp); 01003 } 01004 01005 /* OH lines based lambda correction */ 01006 oh_lcorr_coeffs = NULL ; 01007 if (ref_spectrum_frame != NULL) { 01008 if (kmo_reconstruct_sci(ifu_nr, bounds[2*(ifu_nr-1)], 01009 bounds[2*(ifu_nr-1)+1], 01010 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01011 SCIENCE, NULL, NULL, flat_frame, xcal_frame, 01012 ycal_frame, lcal_frame, NULL, NULL, &gd, &tmp_cube1, 01013 &tmp_cube2, FALSE, FALSE, xcal_interpolation, 01014 oscan) == CPL_ERROR_NONE) { 01015 oh_lcorr_coeffs = kmo_lcorr_get(tmp_cube1, 01016 header_data[ifu_nr-1], ref_spectrum_frame, gd, 01017 filter_id, ifu_nr); 01018 cpl_imagelist_delete(tmp_cube1); 01019 cpl_imagelist_delete(tmp_cube2); 01020 } 01021 } 01022 01023 /* Reconstruct object */ 01024 kmo_reconstruct_sci(ifu_nr, bounds[2*(ifu_nr-1)], 01025 bounds[2*(ifu_nr-1)+1], 01026 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01027 SCIENCE, sky_frame, SCIENCE, flat_frame, xcal_frame, 01028 ycal_frame, lcal_frame, oh_lcorr_coeffs, velo_corr_ptr, 01029 &gd, &cube_data[ifu_nr-1], &cube_noise[ifu_nr-1], flux, 01030 background, xcal_interpolation, oscan); 01031 01032 if (oh_lcorr_coeffs != NULL) 01033 cpl_polynomial_delete(oh_lcorr_coeffs); 01034 01035 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01036 kmo_free_unused_ifus(unused_ifus_after); 01037 cpl_free(bounds); 01038 kmo_delete_armNameStruct(arm_name_struct); 01039 for (j=0 ; j<ifu_nr-1 ; j++) { 01040 if (cube_data[j] != NULL) 01041 cpl_imagelist_delete(cube_data[j]); 01042 if (cube_noise[j] != NULL) 01043 cpl_imagelist_delete(cube_noise[j]); 01044 cpl_propertylist_delete(header_data[j]); 01045 cpl_propertylist_delete(header_noise[j]); 01046 if (save_interims) { 01047 cpl_imagelist_delete(cube_interim_object[j]); 01048 cpl_imagelist_delete(cube_interim_sky[j]); 01049 cpl_propertylist_delete(header_sky[j]); 01050 } 01051 } 01052 cpl_propertylist_delete(header_data[ifu_nr-1]); 01053 cpl_free(cube_data) ; 01054 cpl_free(cube_noise) ; 01055 cpl_free(header_data) ; 01056 cpl_free(header_noise) ; 01057 if (save_interims) { 01058 cpl_free(cube_interim_object) ; 01059 cpl_free(cube_interim_sky) ; 01060 cpl_free(header_sky) ; 01061 } 01062 cpl_msg_error(__func__, "Cannot reconstruct"); 01063 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01064 return -1 ; 01065 } 01066 01067 /* If sky_tweak is set, reconstruct sky frame as object */ 01068 /* use kmos_priv_sky_tweak to subtract a modified sky cube */ 01069 if (do_sky_subtraction && sky_tweak) { 01070 01071 /* OH lines based lambda correction */ 01072 oh_lcorr_coeffs = NULL ; 01073 if (ref_spectrum_frame != NULL) { 01074 if (kmo_reconstruct_sci(sky_ifu_nr, 01075 bounds[2*(sky_ifu_nr-1)], 01076 bounds[2*(sky_ifu_nr-1)+1], 01077 sky_as_object_frame, SCIENCE, NULL, NULL, 01078 flat_frame, xcal_frame, ycal_frame, 01079 lcal_frame, NULL, NULL, &gd, &tmp_cube1, 01080 &tmp_cube2, FALSE, FALSE, 01081 xcal_interpolation, 01082 oscan) == CPL_ERROR_NONE) { 01083 oh_lcorr_coeffs = kmo_lcorr_get(tmp_cube1, 01084 header_data[ifu_nr-1], ref_spectrum_frame, 01085 gd, filter_id, ifu_nr); 01086 cpl_imagelist_delete(tmp_cube1); 01087 cpl_imagelist_delete(tmp_cube2); 01088 } 01089 } 01090 01091 /* Reconstruct object */ 01092 kmo_reconstruct_sci(sky_ifu_nr, 01093 bounds[2*(sky_ifu_nr-1)], 01094 bounds[2*(sky_ifu_nr-1)+1], sky_as_object_frame, 01095 SCIENCE, sky_frame, SCIENCE, flat_frame, 01096 xcal_frame, ycal_frame, lcal_frame, oh_lcorr_coeffs, 01097 velo_corr_ptr, &gd, &tmp_cube1, &tmp_cube2, 01098 flux, background, xcal_interpolation, oscan); 01099 01100 cpl_imagelist_delete(tmp_cube2); 01101 if (oh_lcorr_coeffs != NULL) 01102 cpl_polynomial_delete(oh_lcorr_coeffs); 01103 01104 if (save_interims && (sky_as_object_frame != NULL)) { 01105 cube_interim_object[ifu_nr-1]= 01106 cpl_imagelist_duplicate(cube_data[ifu_nr-1]); 01107 cube_interim_sky[ifu_nr-1]= 01108 cpl_imagelist_duplicate(tmp_cube1); 01109 } 01110 01111 /* Apply the SKY tweaking */ 01112 tmp_cube2 = kmos_priv_sky_tweak(cube_data[ifu_nr-1], 01113 tmp_cube1,header_data[ifu_nr-1], .3, tbsub, ifu_nr); 01114 cpl_imagelist_delete(cube_data[ifu_nr-1]); 01115 cpl_imagelist_delete(tmp_cube1); 01116 cube_data[ifu_nr-1] = tmp_cube2 ; 01117 } 01118 01119 /* Maintain flux constant in case the pixscale is diff */ 01120 /* For example, pixscale=0.1 => images 28x28 => scaling=4 */ 01121 tmpImg = cpl_imagelist_get(cube_data[ifu_nr-1], 0); 01122 scaling = (cpl_image_get_size_x(tmpImg) * 01123 cpl_image_get_size_y(tmpImg)) / 01124 (KMOS_SLITLET_X*KMOS_SLITLET_Y); 01125 cpl_imagelist_divide_scalar(cube_data[ifu_nr-1], scaling); 01126 if (cube_noise[ifu_nr-1] != NULL) { 01127 cpl_imagelist_divide_scalar(cube_noise[ifu_nr-1], scaling); 01128 } 01129 01130 /* Divide cube by telluric correction */ 01131 qc_output_unit[ifu_nr-1] = 0 ; 01132 if (nb_telluric > 0) { 01133 /* Create the mapping string */ 01134 if (mapping_id == 0) { 01135 /* Get object name */ 01136 keyword = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, 01137 ifu_nr, IFU_NAME_POSTFIX); 01138 tmp_str = cpl_propertylist_get_string( 01139 header_data[ifu_nr-1], keyword); 01140 cpl_free(keyword); 01141 } else if (mapping_id == 1) { 01142 tmp_str = "mapping8"; 01143 } else if (mapping_id == 2) { 01144 tmp_str = "mapping24"; 01145 } 01146 01147 /* Check if the nb of occurences of the object name */ 01148 /* is the same as the number of found tellurics for */ 01149 /* this object (which can be on different arms) */ 01150 telluric_ok = FALSE; 01151 for (jj = 0; jj < arm_name_struct->nrNames; jj++) { 01152 if ((!strcmp(arm_name_struct->names[jj], tmp_str) || 01153 !strcmp(arm_name_struct->names[jj], IFUS_USER_DEFINED)) && 01154 arm_name_struct->telluricCnt[jj] == arm_name_struct->namesCnt[jj]) { 01155 telluric_ok = TRUE; 01156 break; 01157 } 01158 } 01159 01160 if (telluric_ok) { 01161 telluric_data = kmo_tweak_load_telluric(frameset, 01162 ifu_nr, FALSE, no_subtract, &ifu_nr_telluric); 01163 if (telluric_data != NULL) { 01164 telluric_frame=kmo_dfs_get_frame(frameset,TELLURIC); 01165 kmo_init_fits_desc(&desc_telluric); 01166 desc_telluric=kmo_identify_fits_header( 01167 cpl_frame_get_filename(telluric_frame)); 01168 01169 /* Get the index of the telluric noise */ 01170 idx = kmo_identify_index_desc(desc_telluric, 01171 ifu_nr, TRUE); 01172 if (desc_telluric.sub_desc[idx-1].valid_data) { 01173 /* Load noise if present */ 01174 telluric_noise = kmo_tweak_load_telluric( 01175 frameset,ifu_nr, TRUE, no_subtract, 01176 &ifu_nr_telluric); 01177 } else { 01178 telluric_noise = NULL ; 01179 } 01180 kmo_free_fits_desc(&desc_telluric); 01181 01182 kmo_arithmetic_3D_1D(cube_data[ifu_nr-1], 01183 telluric_data, cube_noise[ifu_nr-1], 01184 telluric_noise, "/"); 01185 if (telluric_noise != NULL) 01186 kmclipm_vector_delete(telluric_noise); 01187 kmclipm_vector_delete(telluric_data); 01188 01189 /* Convert to ERG if zpoint available */ 01190 zpoint = kmos_sci_red_get_zpoint(telluric_frame, 01191 ifu_nr_telluric) ; 01192 if (zpoint > 0.0) { 01193 f_0 = kmos_sci_red_get_f0(filter_id, gd.l.dim, 01194 gd.l.start, gd.l.delta) ; 01195 if (f_0 > 0.0) { 01196 conversion = f_0*pow(10,-0.4*zpoint)/10.0 ; 01197 cpl_msg_info(__func__, 01198 "Apply Unit conversion factor %g for IFU nb %d", 01199 conversion, ifu_nr) ; 01200 kmo_arithmetic_3D_scalar( 01201 cube_data[ifu_nr-1], conversion, 01202 cube_noise[ifu_nr-1], "*") ; 01203 qc_output_unit[ifu_nr-1] = 1 ; 01204 } 01205 } 01206 } 01207 } 01208 } 01209 01210 /* Divide cube by illumination correction */ 01211 if (nb_illum_corr > 0) { 01212 illum_data = kmo_dfs_load_image(frameset, ILLUM_CORR, 01213 ifu_nr, FALSE, FALSE, NULL); 01214 illum_noise = kmo_dfs_load_image(frameset, ILLUM_CORR, 01215 ifu_nr, TRUE, FALSE, NULL); 01216 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01217 cpl_msg_warning(__func__, 01218 "No illumination correction for IFU %d available! " 01219 "Proceeding anyway.", ifu_nr); 01220 if (illum_data != NULL) cpl_image_delete(illum_data); 01221 if (illum_noise != NULL) cpl_image_delete(illum_noise); 01222 cpl_error_reset(); 01223 } else { 01224 kmo_arithmetic_3D_2D(cube_data[ifu_nr-1], illum_data, 01225 cube_noise[ifu_nr-1], illum_noise, "/"); 01226 cpl_image_delete(illum_data); 01227 cpl_image_delete(illum_noise); 01228 } 01229 } 01230 } 01231 01232 /* Duplicate subheader data */ 01233 header_noise[ifu_nr-1] = cpl_propertylist_duplicate( 01234 header_data[ifu_nr-1]); 01235 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE); 01236 kmclipm_update_property_string(header_noise[ifu_nr-1], EXTNAME, 01237 extname, "FITS extension name"); 01238 cpl_free(extname); 01239 } 01240 cpl_propertylist_delete(main_header) ; 01241 01242 /* Count number of reconstructed data- and noise-cubes */ 01243 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01244 if (cube_data[ifu_nr-1] != NULL) cube_counter_data++; 01245 if (cube_noise[ifu_nr-1] != NULL) cube_counter_noise++; 01246 } 01247 01248 /* Save reconstructed cubes of science frame */ 01249 if (cube_counter_data > 0) { 01250 cpl_msg_info(__func__, " > saving..."); 01251 01252 if (!suppress_extension) { 01253 fn_out = fn_obj; 01254 01255 int nr_found = 0; 01256 // remove any path-elements from filename and use it as suffix 01257 split = kmo_strsplit(fn_out, "/", &nr_found); 01258 fn_suffix = cpl_sprintf("_%s", split[nr_found-1]); 01259 kmo_strfreev(split); 01260 01261 // remove '.fits' at the end if there is any 01262 char *fff = fn_suffix; 01263 fff += strlen(fn_suffix)-5; 01264 if (strcmp(fff, ".fits") == 0) { 01265 fn_suffix[strlen(fn_suffix)-5] = '\0'; 01266 } 01267 } else { 01268 fn_suffix = cpl_sprintf("_%d", suppress_index++); 01269 } 01270 01271 fn_out = RECONSTRUCTED_CUBE; 01272 01273 /* Create Primary Header */ 01274 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, 01275 arm_name_struct->obj_sky_struct->table[sf].objFrame, NULL, 01276 parlist, cpl_func); 01277 /* save intermediate products (only in sky tweak case) */ 01278 if (save_interims && (sky_as_object_frame != NULL)) { 01279 kmo_dfs_save_main_header(frameset, INTERIM_OBJECT_CUBE, 01280 fn_suffix, 01281 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01282 NULL, parlist, cpl_func); 01283 kmo_dfs_save_main_header(frameset, INTERIM_OBJECT_SKY, 01284 fn_suffix, 01285 arm_name_struct->obj_sky_struct->table[sf].objFrame, 01286 NULL, parlist, cpl_func); 01287 } 01288 01289 /* Loop on IFUs */ 01290 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01291 01292 /* Hold the QC */ 01293 if (qc_output_unit[ifu_nr-1] == 0) 01294 kmclipm_update_property_string(header_data[ifu_nr-1], 01295 "ESO QC CUBE_UNIT", "ADU/sec", "Cube Unit"); 01296 else 01297 kmclipm_update_property_string(header_data[ifu_nr-1], 01298 "ESO QC CUBE_UNIT", "ERG/sec/cm2/A", "Cube Unit"); 01299 01300 /* Save data Extension */ 01301 kmo_dfs_save_cube(cube_data[ifu_nr-1], fn_out, fn_suffix, 01302 header_data[ifu_nr-1], 0./0.); 01303 cpl_imagelist_delete(cube_data[ifu_nr-1]); 01304 01305 /* Save noise Extension */ 01306 if (cube_counter_noise > 0) { 01307 kmo_dfs_save_cube(cube_noise[ifu_nr-1], fn_out, fn_suffix, 01308 header_noise[ifu_nr-1], 0./0.); 01309 } 01310 cpl_propertylist_delete(header_noise[ifu_nr-1]); 01311 cpl_imagelist_delete(cube_noise[ifu_nr-1]); 01312 01313 /* save intermediate products (only in sky tweak case */ 01314 if (save_interims && (sky_as_object_frame != NULL)) { 01315 kmo_dfs_save_cube(cube_interim_object[ifu_nr-1], 01316 INTERIM_OBJECT_CUBE, fn_suffix, 01317 header_data[ifu_nr-1], 0./0.); 01318 kmo_dfs_save_cube(cube_interim_sky[ifu_nr-1], 01319 INTERIM_OBJECT_SKY, fn_suffix, header_sky[ifu_nr-1], 01320 0./0.); 01321 } 01322 cpl_propertylist_delete(header_data[ifu_nr-1]); 01323 if (save_interims) { 01324 cpl_imagelist_delete(cube_interim_object[ifu_nr-1]); 01325 cpl_imagelist_delete(cube_interim_sky[ifu_nr-1]); 01326 cpl_propertylist_delete(header_sky[ifu_nr-1]); 01327 } 01328 } 01329 cpl_free(fn_suffix); 01330 } else { 01331 cpl_msg_info(__func__, " > all IFUs invalid, don't save"); 01332 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01333 cpl_propertylist_delete(header_data[ifu_nr-1]); 01334 cpl_propertylist_delete(header_noise[ifu_nr-1]); 01335 } 01336 } 01337 cpl_free(qc_output_unit) ; 01338 } 01339 cpl_free(bounds) ; 01340 cpl_free(cube_data); 01341 cpl_free(cube_noise); 01342 cpl_free(header_data); 01343 cpl_free(header_noise); 01344 if (save_interims) { 01345 cpl_free(cube_interim_object); 01346 cpl_free(cube_interim_sky); 01347 cpl_free(header_sky); 01348 } 01349 01350 kmo_print_unused_ifus(unused_ifus_after, TRUE); 01351 kmo_free_unused_ifus(unused_ifus_after); 01352 01353 /* Combine */ 01354 suppress_index = 0; 01355 if (!no_combine) { 01356 cpl_msg_info(__func__, "Combining reconstructed objects"); 01357 if (mapping_id==0 || (mapping_id>0 && (strcmp(ifus_txt, "") || 01358 strcmp(name,"")))){ 01359 /* Loop all available objects */ 01360 for (i = 0; i < arm_name_struct->nrNames; i++) { 01361 cpl_msg_info(__func__, 01362 " > object: %s", arm_name_struct->names[i]); 01363 nr_data = arm_name_struct->namesCnt[i]; 01364 cube_data=(cpl_imagelist**)cpl_calloc(nr_data, 01365 sizeof(cpl_imagelist*)); 01366 cube_noise=(cpl_imagelist**)cpl_calloc(nr_data, 01367 sizeof(cpl_imagelist*)); 01368 header_data=(cpl_propertylist**)cpl_calloc(nr_data, 01369 sizeof(cpl_propertylist*)); 01370 header_noise=(cpl_propertylist**)cpl_calloc(nr_data, 01371 sizeof(cpl_propertylist*)); 01372 01373 /* Initialise */ 01374 for (jj = 0; jj < nr_data; jj++) { 01375 cube_data[jj] = NULL ; 01376 cube_noise[jj] = NULL ; 01377 header_data[jj] = NULL ; 01378 header_noise[jj] = NULL ; 01379 } 01380 01381 // setup cube-list and header-list for kmo_priv_combine() 01382 cube_counter_data = 0; 01383 cube_counter_noise = 0; 01384 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE); 01385 while (tmp_frame != NULL ) { 01386 fn_reconstr = cpl_frame_get_filename(tmp_frame); 01387 main_header = kmclipm_propertylist_load(fn_reconstr, 0); 01388 01389 kmo_init_fits_desc(&desc1); 01390 desc1 = kmo_identify_fits_header(fn_reconstr); 01391 01392 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01393 // check if object-name equals the one in our list 01394 keyword = cpl_sprintf("%s%d%s", IFU_NAME_PREFIX, ifu_nr, 01395 IFU_NAME_POSTFIX); 01396 tmp_str=cpl_propertylist_get_string(main_header, 01397 keyword); 01398 cpl_free(keyword); 01399 01400 if (!strcmp(arm_name_struct->names[i],tmp_str) || 01401 !strcmp(arm_name_struct->names[i], IFUS_USER_DEFINED)) { 01402 /* Found object-IFU with matching name */ 01403 /* Load data & subheader */ 01404 idx=kmo_identify_index(fn_reconstr,ifu_nr,FALSE); 01405 01406 if (desc1.sub_desc[idx-1].valid_data) { 01407 cube_data[cube_counter_data] = 01408 kmclipm_imagelist_load(fn_reconstr, 01409 CPL_TYPE_FLOAT, idx); 01410 /* Set cubes borders (1 pixel) to Nan to avoid jumps in combined cube */ 01411 if (edge_nan) { 01412 kmo_edge_nan(cube_data[cube_counter_data], 01413 ifu_nr); 01414 } 01415 01416 header_data[cube_counter_data] = 01417 kmclipm_propertylist_load(fn_reconstr, 01418 idx); 01419 cpl_propertylist_update_string( 01420 header_data[cube_counter_data], 01421 "ESO PRO FRNAME", fn_reconstr); 01422 cpl_propertylist_update_int( 01423 header_data[cube_counter_data], 01424 "ESO PRO IFUNR", ifu_nr); 01425 cube_counter_data++; 01426 } 01427 01428 /* Load noise & subheader (if existing) */ 01429 if (desc1.ex_noise) { 01430 idx = kmo_identify_index(fn_reconstr, ifu_nr, 01431 TRUE); 01432 if (desc1.sub_desc[idx-1].valid_data) { 01433 cube_noise[cube_counter_noise] = 01434 kmclipm_imagelist_load(fn_reconstr, 01435 CPL_TYPE_FLOAT, idx); 01436 if (edge_nan) { 01437 kmo_edge_nan( 01438 cube_noise[cube_counter_noise], 01439 ifu_nr); 01440 } 01441 header_noise[cube_counter_noise] = 01442 kmclipm_propertylist_load(fn_reconstr, 01443 idx); 01444 cube_counter_noise++; 01445 } 01446 } 01447 cpl_error_reset(); 01448 } 01449 } 01450 kmo_free_fits_desc(&desc1); 01451 cpl_propertylist_delete(main_header); 01452 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01453 } 01454 01455 if (cube_counter_noise == 0) { 01456 cpl_free(cube_noise); 01457 cube_noise = NULL ; 01458 } 01459 01460 if (cube_counter_data > 1) { 01461 if (cube_counter_data == cube_counter_noise || 01462 cube_counter_noise == 0) { 01463 kmo_priv_combine(cube_data, cube_noise, header_data, 01464 header_noise, cube_counter_data, 01465 cube_counter_noise, arm_name_struct->names[i], 01466 "", comb_method, smethod, fmethod, filename, 01467 cmethod, cpos_rej, cneg_rej, citer, cmin, cmax, 01468 extrapol_enum, flux, &combined_data, 01469 &combined_noise, &exp_mask); 01470 } else { 01471 cpl_msg_error(__func__, "Data/Noise cubes nb mismatch"); 01472 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01473 return -1 ; 01474 } 01475 } else if (cube_counter_data == 1) { 01476 cpl_msg_warning(__func__, 01477 "Only one reconstructed cube with this object"); 01478 combined_data = cpl_imagelist_duplicate(cube_data[0]); 01479 tmpImg = cpl_imagelist_get(combined_data, 0); 01480 exp_mask = cpl_image_new(cpl_image_get_size_x(tmpImg), 01481 cpl_image_get_size_y(tmpImg), CPL_TYPE_FLOAT); 01482 kmo_image_fill(exp_mask, 1.); 01483 01484 combined_noise = NULL ; 01485 if (cube_counter_noise > 0 && cube_noise[0] != NULL) { 01486 combined_noise = cpl_imagelist_duplicate(cube_noise[0]); 01487 } 01488 } else { 01489 cpl_msg_error(__func__, "No cube found with this obj name"); 01490 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01491 return -1 ; 01492 } 01493 for (jj = 0; jj < nr_data; jj++) { 01494 cpl_imagelist_delete(cube_data[jj]); 01495 if (cube_counter_noise > 0) 01496 cpl_imagelist_delete(cube_noise[jj]); 01497 } 01498 cpl_free(cube_data); 01499 cpl_free(cube_noise); 01500 01501 fn_out = COMBINED_CUBE; 01502 if (!suppress_extension) { 01503 char tmp_suffix[1024]; 01504 tmp_suffix[0] = '\0'; 01505 01506 if (arm_name_struct->telluricCnt[i] == 01507 arm_name_struct->namesCnt[i]) { 01508 strcat(tmp_suffix, "_telluric"); 01509 } 01510 if (nb_illum_corr > 0) strcat(tmp_suffix, "_illum"); 01511 if (sky_tweak) strcat(tmp_suffix, "_skytweak"); 01512 01513 if (strlen(tmp_suffix) > 0) { 01514 fn_suffix = cpl_sprintf("_%s_%s", 01515 arm_name_struct->names[i], tmp_suffix); 01516 } else { 01517 fn_suffix = cpl_sprintf("_%s", 01518 arm_name_struct->names[i]); 01519 } 01520 } else { 01521 fn_suffix = cpl_sprintf("_%d", suppress_index++); 01522 } 01523 01524 // save combined cube 01525 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE); 01526 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, 01527 tmp_frame, NULL, parlist, cpl_func); 01528 kmo_dfs_save_main_header(frameset, EXP_MASK, fn_suffix, 01529 tmp_frame, NULL, parlist, cpl_func); 01530 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, 01531 header_data[0], 0./0.); 01532 kmo_dfs_save_image(exp_mask, EXP_MASK, fn_suffix, 01533 header_data[0], 0./0.); 01534 cpl_image_delete(exp_mask); 01535 01536 if (header_noise[0] == NULL) { 01537 header_noise[0]=cpl_propertylist_duplicate(header_data[0]); 01538 tmp_str=cpl_propertylist_get_string(header_data[0],EXTNAME); 01539 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content); 01540 extname = kmo_extname_creator(ifu_frame, tmp_int,EXT_NOISE); 01541 kmclipm_update_property_string(header_noise[0], EXTNAME, 01542 extname, "FITS extension name"); 01543 cpl_free(extname); 01544 } 01545 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix, 01546 header_noise[0], 0./0.); 01547 01548 cpl_free(fn_suffix); 01549 for (jj = 0; jj < nr_data; jj++) { 01550 cpl_propertylist_delete(header_data[jj]); 01551 cpl_propertylist_delete(header_noise[jj]); 01552 } 01553 cpl_free(header_data); 01554 cpl_free(header_noise); 01555 cpl_imagelist_delete(combined_data); 01556 if (combined_noise != NULL) 01557 cpl_imagelist_delete(combined_noise); 01558 } 01559 } else { 01560 /* Mapping_mode */ 01561 nr_data = KMOS_NR_IFUS * 01562 cpl_frameset_count_tags(frameset,RECONSTRUCTED_CUBE); 01563 cube_data = (cpl_imagelist**)cpl_calloc(nr_data, 01564 sizeof(cpl_imagelist*)); 01565 cube_noise = (cpl_imagelist**)cpl_calloc(nr_data, 01566 sizeof(cpl_imagelist*)); 01567 header_data=(cpl_propertylist**)cpl_calloc(nr_data, 01568 sizeof(cpl_propertylist*)); 01569 header_noise=(cpl_propertylist**)cpl_calloc(nr_data, 01570 sizeof(cpl_propertylist*)); 01571 01572 /* Initialise */ 01573 for (jj = 0; jj < nr_data; jj++) { 01574 cube_data[jj] = NULL ; 01575 cube_noise[jj] = NULL ; 01576 header_data[jj] = NULL ; 01577 header_noise[jj] = NULL ; 01578 } 01579 01580 cube_counter_data = 0; 01581 cube_counter_noise = 0; 01582 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE); 01583 while (tmp_frame != NULL ) { 01584 fn_reconstr = cpl_frame_get_filename(tmp_frame); 01585 01586 kmo_init_fits_desc(&desc1); 01587 desc1 = kmo_identify_fits_header(fn_reconstr); 01588 for (ifu_nr = 1; ifu_nr <= KMOS_NR_IFUS; ifu_nr++) { 01589 idx = kmo_identify_index(fn_reconstr, ifu_nr, FALSE); 01590 01591 if (desc1.sub_desc[idx-1].valid_data) { 01592 cpl_msg_debug(__func__, 01593 "Load in cube_data - Frame: %s IFU: %d", 01594 fn_reconstr, ifu_nr) ; 01595 cube_data[cube_counter_data] = kmclipm_imagelist_load( 01596 fn_reconstr, CPL_TYPE_FLOAT, idx); 01597 if (edge_nan) 01598 kmo_edge_nan(cube_data[cube_counter_data], ifu_nr); 01599 01600 if (fast_mode) { 01601 tmpImg = cpl_imagelist_collapse_median_create( 01602 cube_data[cube_counter_data]); 01603 tmp_cube1 = cpl_imagelist_new(); 01604 cpl_imagelist_set(tmp_cube1, tmpImg, 0); 01605 cpl_imagelist_delete(cube_data[cube_counter_data]); 01606 cube_data[cube_counter_data] = tmp_cube1; 01607 } 01608 01609 cpl_msg_debug(__func__, 01610 "Load in header_data - Frame: %s IFU: %d", 01611 fn_reconstr, ifu_nr) ; 01612 header_data[cube_counter_data] = 01613 kmclipm_propertylist_load(fn_reconstr, idx); 01614 cpl_propertylist_update_string( 01615 header_data[cube_counter_data], 01616 "ESO PRO FRNAME", fn_reconstr); 01617 cpl_propertylist_update_int( 01618 header_data[cube_counter_data], 01619 "ESO PRO IFUNR", ifu_nr); 01620 cube_counter_data++; 01621 cpl_msg_debug(__func__, "cube_counter_data: %d\n", 01622 cube_counter_data) ; 01623 } 01624 01625 /* Load noise & subheader (if existing) */ 01626 if (desc1.ex_noise) { 01627 idx = kmo_identify_index(fn_reconstr,ifu_nr,TRUE); 01628 if (desc1.sub_desc[idx-1].valid_data) { 01629 cpl_msg_debug(__func__, 01630 "Load in cube_noise - Frame: %s IFU: %d", 01631 fn_reconstr, ifu_nr) ; 01632 cube_noise[cube_counter_noise] = 01633 kmclipm_imagelist_load(fn_reconstr, 01634 CPL_TYPE_FLOAT, idx); 01635 01636 if (edge_nan) 01637 kmo_edge_nan(cube_noise[cube_counter_noise], 01638 ifu_nr); 01639 if (fast_mode) { 01640 tmpImg=cpl_imagelist_collapse_median_create( 01641 cube_noise[cube_counter_noise]); 01642 tmp_cube1 = cpl_imagelist_new(); 01643 cpl_imagelist_set(tmp_cube1, tmpImg, 0); 01644 cpl_imagelist_delete( 01645 cube_noise[cube_counter_noise]); 01646 cube_noise[cube_counter_noise] = tmp_cube1; 01647 } 01648 cpl_msg_debug(__func__, 01649 "Load in header_noise - Frame: %s IFU: %d", 01650 fn_reconstr, ifu_nr) ; 01651 header_noise[cube_counter_noise] = 01652 kmclipm_propertylist_load(fn_reconstr, idx); 01653 cube_counter_noise++; 01654 cpl_msg_debug(__func__, "cube_counter_noise: %d\n", 01655 cube_counter_noise) ; 01656 } 01657 } 01658 cpl_error_reset(); 01659 } 01660 kmo_free_fits_desc(&desc1); 01661 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01662 } 01663 01664 if (cube_counter_noise == 0) { 01665 cpl_free(cube_noise); 01666 cube_noise = NULL ; 01667 } 01668 01669 if (cube_counter_data > 1) { 01670 if (cube_counter_data == cube_counter_noise || 01671 cube_counter_noise == 0) { 01672 kmo_priv_combine(cube_data, cube_noise, header_data, 01673 header_noise, cube_counter_data, cube_counter_noise, 01674 mapping_mode, "", comb_method, smethod, fmethod, 01675 filename, cmethod, cpos_rej, cneg_rej, citer, cmin, 01676 cmax, extrapol_enum, flux, &combined_data, 01677 &combined_noise, NULL); 01678 } else { 01679 cpl_msg_error(__func__, "Data/Noise cubes nb mismatch"); 01680 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01681 return -1 ; 01682 } 01683 } else { 01684 cpl_msg_warning(__func__, 01685 "There is only one reconstructed cube - Save it"); 01686 combined_data = cpl_imagelist_duplicate(cube_data[0]); 01687 01688 if (cube_noise[0] != NULL) { 01689 combined_noise = cpl_imagelist_duplicate(cube_noise[0]); 01690 } 01691 } 01692 fn_out = COMBINED_CUBE; 01693 fn_suffix = cpl_sprintf("_%s", mapping_mode); 01694 01695 // save combined cube 01696 tmp_frame = kmo_dfs_get_frame(frameset, RECONSTRUCTED_CUBE); 01697 kmo_dfs_save_main_header(frameset, fn_out, fn_suffix, tmp_frame, 01698 NULL, parlist, cpl_func); 01699 kmo_dfs_save_cube(combined_data, fn_out, fn_suffix, header_data[0], 01700 0./0.); 01701 01702 if (cube_counter_noise == 0) { 01703 header_noise[0] = cpl_propertylist_duplicate(header_data[0]); 01704 tmp_str = cpl_propertylist_get_string(header_data[0], EXTNAME); 01705 kmo_extname_extractor(tmp_str, &ft, &tmp_int, content); 01706 extname = kmo_extname_creator(ifu_frame, tmp_int, EXT_NOISE); 01707 kmclipm_update_property_string(header_noise[0], EXTNAME, 01708 extname, "FITS extension name"); 01709 cpl_free(extname); 01710 } 01711 kmo_dfs_save_cube(combined_noise, fn_out, fn_suffix, 01712 header_noise[0], 0./0.); 01713 01714 if (cube_counter_noise == 0) 01715 cpl_propertylist_delete(header_noise[0]); 01716 cpl_free(fn_suffix); 01717 for (i = 0; i < cube_counter_data ; i++) { 01718 cpl_propertylist_delete(header_data[i]); 01719 cpl_imagelist_delete(cube_data[i]); 01720 } 01721 for (i = 0; i < cube_counter_noise ; i++) { 01722 cpl_propertylist_delete(header_noise[i]); 01723 cpl_imagelist_delete(cube_noise[i]); 01724 } 01725 cpl_free(cube_data); 01726 cpl_free(cube_noise); 01727 cpl_free(header_data); 01728 cpl_free(header_noise); 01729 cpl_imagelist_delete(combined_data); 01730 cpl_imagelist_delete(combined_noise); 01731 } 01732 } 01733 kmo_delete_armNameStruct(arm_name_struct); 01734 01735 /* Collapse the reconstructed cubes if requested */ 01736 if (collapse_reconstructed) { 01737 kmos_collapse_cubes(RECONSTRUCTED_CUBE, frameset, parlist, 0.1, 01738 "", DEF_REJ_METHOD, DEF_POS_REJ_THRES, DEF_NEG_REJ_THRES, 01739 DEF_ITERATIONS, DEF_NR_MIN_REJ, DEF_NR_MAX_REJ) ; 01740 } 01741 01742 /* Collapse the combined cubes if requested */ 01743 if (collapse_combined) { 01744 kmos_collapse_cubes(COMBINED_CUBE, frameset, parlist, 0.1, "", 01745 DEF_REJ_METHOD, DEF_POS_REJ_THRES, DEF_NEG_REJ_THRES, 01746 DEF_ITERATIONS, DEF_NR_MIN_REJ, DEF_NR_MAX_REJ) ; 01747 } 01748 return 0; 01749 } 01750 01753 /*----------------------------------------------------------------------------*/ 01761 /*----------------------------------------------------------------------------*/ 01762 static int kmos_sci_red_check_inputs( 01763 cpl_frameset * frameset, 01764 double pix_scale, 01765 int * mapping_id) 01766 { 01767 int nb_science, nb_xcal, nb_ycal, nb_lcal, nb_wave_band, 01768 nb_master_flat, nb_illum_corr, nb_telluric, nb_oh_spec ; 01769 cpl_error_code err ; 01770 const cpl_frame * frame1 ; 01771 const cpl_frame * frame2 ; 01772 int next1, next2, mapping_id_loc, 01773 mapping_id_curr, nx, ny ; 01774 cpl_propertylist * mh ; 01775 cpl_propertylist * eh ; 01776 const char * tmp_str ; 01777 01778 /* Check Entries */ 01779 if (frameset == NULL || mapping_id == NULL) return -1; 01780 01781 /* Count frames */ 01782 nb_science = cpl_frameset_count_tags(frameset, SCIENCE) ; 01783 nb_xcal = cpl_frameset_count_tags(frameset, XCAL) ; 01784 nb_ycal = cpl_frameset_count_tags(frameset, YCAL) ; 01785 nb_lcal = cpl_frameset_count_tags(frameset, LCAL) ; 01786 nb_wave_band = cpl_frameset_count_tags(frameset, WAVE_BAND) ; 01787 nb_master_flat = cpl_frameset_count_tags(frameset, MASTER_FLAT); 01788 nb_illum_corr = cpl_frameset_count_tags(frameset, ILLUM_CORR); 01789 nb_telluric = cpl_frameset_count_tags(frameset, TELLURIC); 01790 nb_oh_spec = cpl_frameset_count_tags(frameset, OH_SPEC) ; 01791 01792 /* Checks */ 01793 if (nb_science < 1) { 01794 cpl_msg_error(__func__, "At least one SCIENCE frame is required") ; 01795 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01796 return 0 ; 01797 } 01798 if (nb_science == 1) { 01799 cpl_msg_warning(__func__, 01800 "Only 1 SCIENCE: no sky subtraction - reconstruct all IFUs"); 01801 } 01802 if (nb_xcal != 1 || nb_ycal != 1 || nb_lcal != 1) { 01803 cpl_msg_error(__func__, "Exactly 1 XCAL/YCAL/LCAL expected") ; 01804 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01805 return 0 ; 01806 } 01807 if (nb_wave_band != 1) { 01808 cpl_msg_error(__func__, "At most one WAVE_BAND frame expected") ; 01809 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01810 return 0 ; 01811 } 01812 01813 if (nb_master_flat > 1 || nb_illum_corr > 1 || nb_telluric > 1 || 01814 nb_oh_spec > 1) { 01815 cpl_msg_error(__func__, 01816 "MASTER_FLAT/ILLUM_CORR/OH_SPEC/TELLURIC: 0 or 1 frame expected") ; 01817 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01818 return 0 ; 01819 } 01820 01821 /* filter_id, grating_id and rotator offset match all detectors */ 01822 err = CPL_ERROR_NONE ; 01823 err += kmo_check_frameset_setup(frameset, SCIENCE, TRUE, FALSE, TRUE); 01824 err += kmo_check_frame_setup(frameset, SCIENCE, YCAL, TRUE, FALSE, TRUE); 01825 err += kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE); 01826 err += kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE); 01827 if (nb_master_flat > 0) err += kmo_check_frame_setup(frameset, XCAL, 01828 MASTER_FLAT, TRUE, FALSE, TRUE); 01829 if (nb_telluric > 0) err += kmo_check_frame_setup(frameset, XCAL, 01830 TELLURIC, TRUE, FALSE, TRUE); 01831 if (nb_oh_spec > 0) err += kmo_check_oh_spec_setup(frameset, XCAL); 01832 01833 /* Check XCAL */ 01834 frame1 = kmo_dfs_get_frame(frameset, XCAL); 01835 next1 = cpl_frame_get_nextensions(frame1); 01836 if (next1 % KMOS_NR_DETECTORS) { 01837 cpl_msg_error(__func__, "XCAL wrong format") ; 01838 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01839 return 0 ; 01840 } 01841 /* Check YCAL */ 01842 frame2 = kmo_dfs_get_frame(frameset, YCAL); 01843 next2 = cpl_frame_get_nextensions(frame2); 01844 if (next1 != next2) { 01845 cpl_msg_error(__func__, "YCAL wrong format") ; 01846 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01847 return 0 ; 01848 } 01849 /* Check LCAL */ 01850 frame2 = kmo_dfs_get_frame(frameset, LCAL); 01851 next2 = cpl_frame_get_nextensions(frame2); 01852 if (next1 != next2) { 01853 cpl_msg_error(__func__, "LCAL wrong format") ; 01854 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01855 return 0 ; 01856 } 01857 /* Check MASTER_FLAT */ 01858 if (nb_master_flat >= 1) { 01859 frame2 = kmo_dfs_get_frame(frameset, MASTER_FLAT); 01860 next2 = cpl_frame_get_nextensions(frame2); 01861 if (next2 % (2*KMOS_NR_DETECTORS)) { 01862 cpl_msg_error(__func__, "MASTER_FLAT wrong format") ; 01863 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01864 return 0 ; 01865 } 01866 } 01867 /* Check ILLUM_CORR */ 01868 if (nb_illum_corr >= 1) { 01869 frame2 = kmo_dfs_get_frame(frameset, ILLUM_CORR); 01870 /* Check number of extensions */ 01871 next2 = cpl_frame_get_nextensions(frame2); 01872 if (next2 != 24 && next2 != 48) { 01873 cpl_msg_error(__func__, "ILLUM wrong format") ; 01874 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01875 return 0 ; 01876 } 01877 /* Check Size regarding the pixscale */ 01878 eh = cpl_propertylist_load(cpl_frame_get_filename(frame2), 1); 01879 nx = kmos_pfits_get_naxis1(eh) ; 01880 ny = kmos_pfits_get_naxis2(eh) ; 01881 cpl_propertylist_delete(eh) ; 01882 if (fabs(nx*pix_scale-2.8) > 1e-3 || fabs(ny*pix_scale-2.8) > 1e-3) { 01883 cpl_msg_error(__func__, 01884 "ILLUM wrong Size (nx/y*pix_scale= %g/%g <> 2.8)", 01885 nx*pix_scale, ny*pix_scale) ; 01886 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01887 return 0 ; 01888 } 01889 } 01890 /* Check TELLURIC */ 01891 if (nb_telluric >= 1) { 01892 frame2 = kmo_dfs_get_frame(frameset, TELLURIC); 01893 next2 = cpl_frame_get_nextensions(frame2); 01894 if (next2 != 24 && next2 != 48) { 01895 cpl_msg_error(__func__, "TELLURIC wrong format") ; 01896 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01897 return 0 ; 01898 } 01899 } 01900 01901 /* Loop on the SCIENCE frames */ 01902 frame2 = kmo_dfs_get_frame(frameset, SCIENCE); 01903 mapping_id_loc = -1 ; 01904 while (frame2 != NULL ) { 01905 next2 = cpl_frame_get_nextensions(frame2); 01906 if (next2 != 3) { 01907 cpl_msg_error(__func__, "SCIENCE wrong format") ; 01908 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01909 return 0 ; 01910 } 01911 01912 mh = cpl_propertylist_load(cpl_frame_get_filename(frame2), 0); 01913 tmp_str = cpl_propertylist_get_string(mh, TPL_ID); 01914 if (!strcmp(tmp_str, MAPPING8)) mapping_id_curr = 1 ; 01915 else if (strcmp(tmp_str, MAPPING24) == 0) mapping_id_curr = 2 ; 01916 else mapping_id_curr = 0 ; 01917 cpl_propertylist_delete(mh); 01918 01919 if (mapping_id_loc < 0) mapping_id_loc = mapping_id_curr ; 01920 if (mapping_id_curr != mapping_id_loc) { 01921 cpl_msg_error(__func__, "Inconsistent MAPPING information") ; 01922 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01923 return 0 ; 01924 } 01925 frame2 = kmo_dfs_get_frame(frameset, NULL); 01926 } 01927 01928 /* Verify that XCAL / YCAL were generated together */ 01929 err += kmo_check_frame_setup_md5_xycal(frameset); 01930 /* Verify that XCAL and YCAL / LCAL were generated together */ 01931 err += kmo_check_frame_setup_md5(frameset); 01932 /* b_start/b_end/b_samples used for LCAL and TELLURIC were the same */ 01933 err += kmo_check_frame_setup_sampling(frameset); 01934 01935 if (err != CPL_ERROR_NONE) { 01936 cpl_msg_warning(__func__, "Frames are inconsistent") ; 01937 return 0 ; 01938 } 01939 01940 /* Return */ 01941 *mapping_id = mapping_id_loc ; 01942 return 1 ; 01943 } 01944 01945 /*----------------------------------------------------------------------------*/ 01952 /*----------------------------------------------------------------------------*/ 01953 static double kmos_sci_red_get_zpoint( 01954 cpl_frame * frame, 01955 int ifu_nr) 01956 { 01957 cpl_propertylist * plist ; 01958 double zpoint ; 01959 int nb_ext, ext_nb ; 01960 01961 /* Check entries */ 01962 if (frame == NULL) return -1.0 ; 01963 if (cpl_error_get_code() != CPL_ERROR_NONE) return -1.0 ; 01964 01965 /* Get the number of extentions */ 01966 nb_ext = cpl_frame_get_nextensions(frame); 01967 01968 /* Compute ext_nb */ 01969 if (nb_ext == KMOS_NR_IFUS) ext_nb = ifu_nr ; 01970 else if (nb_ext == 2 * KMOS_NR_IFUS) ext_nb = 2 * ifu_nr - 1 ; 01971 else return -1.0 ; 01972 01973 /* Get QC ZPOINT */ 01974 plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext_nb); 01975 zpoint = cpl_propertylist_get_double(plist, "ESO QC ZPOINT") ; 01976 cpl_propertylist_delete(plist) ; 01977 01978 if (cpl_error_get_code() != CPL_ERROR_NONE) { 01979 cpl_error_reset() ; 01980 zpoint = -1.0 ; 01981 } 01982 01983 return zpoint ; 01984 } 01985 01986 /*----------------------------------------------------------------------------*/ 01992 /*----------------------------------------------------------------------------*/ 01993 static double kmos_sci_red_get_f0( 01994 const char * filter_id, 01995 int lam_dim, 01996 double lam_start, 01997 double lam_delta) 01998 { 01999 double f_0 = -1.0 ; 02000 double cent_wl = lam_start + (lam_delta * (lam_dim/2.0)) ; 02001 if (!strcmp(filter_id, "H")) f_0 = 1.133e-9 ; 02002 if (!strcmp(filter_id, "HK") && cent_wl < 1.9) f_0 = 1.133e-9 ; 02003 if (!strcmp(filter_id, "HK") && cent_wl >= 1.9) f_0 = 4.283e-10 ; 02004 if (!strcmp(filter_id, "K")) f_0 = 4.283e-10 ; 02005 if (!strcmp(filter_id, "YJ")) f_0 = 3.129e-9 ; 02006 if (!strcmp(filter_id, "IZ")) f_0 = 7.63e-9 ; 02007 return f_0 ; 02008 } 02009 02010 02011 02012 int print_warning_once_tweak_std = TRUE; 02013 /*----------------------------------------------------------------------------*/ 02038 /*----------------------------------------------------------------------------*/ 02039 static kmclipm_vector * kmo_tweak_load_telluric( 02040 cpl_frameset * frameset, 02041 int ifu_nr, 02042 int is_noise, 02043 int no_subtract, 02044 int * ifu_nr_telluric) 02045 { 02046 kmclipm_vector *vec = NULL; 02047 cpl_propertylist *header = NULL; 02048 const char *tplid = NULL; 02049 int actual_msg_level = 0 ; 02050 02051 02052 /* Check entries */ 02053 if (frameset == NULL || ifu_nr_telluric == NULL) return NULL ; 02054 if (ifu_nr < 1 || ifu_nr > KMOS_NR_IFUS) return NULL ; 02055 02056 header = kmo_dfs_load_primary_header(frameset, TELLURIC); 02057 tplid = cpl_propertylist_get_string(header, TPL_ID); 02058 if (!strcmp(tplid, "KMOS_spec_cal_stdstar")) { 02059 if (print_warning_once_tweak_std) { 02060 cpl_msg_warning(__func__, 02061 "KMOS_spec_cal_stdstar template used => 1 telluric/detector"); 02062 print_warning_once_tweak_std = FALSE; 02063 } 02064 } 02065 02066 *ifu_nr_telluric = kmo_tweak_find_ifu(frameset, ifu_nr); 02067 if (ifu_nr!=*ifu_nr_telluric && *ifu_nr_telluric!=-1 && no_subtract!=-1) { 02068 if (!no_subtract) { 02069 cpl_msg_info(__func__, "Telluric IFU %d selected", 02070 *ifu_nr_telluric); 02071 } else { 02072 cpl_msg_info(__func__, "For IFU %d, telluric in IFU %d selected", 02073 ifu_nr, *ifu_nr_telluric); 02074 } 02075 } 02076 02077 actual_msg_level = cpl_msg_get_level(); 02078 cpl_msg_set_level(CPL_MSG_OFF); 02079 vec = kmo_dfs_load_vector(frameset, TELLURIC, *ifu_nr_telluric,is_noise); 02080 cpl_msg_set_level(actual_msg_level); 02081 02082 if (cpl_error_get_code() != CPL_ERROR_NONE) cpl_error_reset(); 02083 02084 cpl_propertylist_delete(header); 02085 if ((vec == NULL) && !is_noise && (no_subtract != -1)) { 02086 if (!no_subtract) { 02087 cpl_msg_warning(__func__, "No telluric on this detector"); 02088 } else { 02089 cpl_msg_warning(__func__, "No telluric on this detector for IFU %d", 02090 ifu_nr); 02091 } 02092 } 02093 02094 return vec; 02095 } 02096
1.7.6.1