KMOS Pipeline Reference Manual
1.3.0
|
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 <math.h> 00029 #include <string.h> 00030 00031 #include <cpl.h> 00032 00033 #include "kmclipm_math.h" 00034 00035 #include "kmo_constants.h" 00036 #include "kmo_cpl_extensions.h" 00037 #include "kmo_utils.h" 00038 #include "kmo_functions.h" 00039 #include "kmo_priv_std_star.h" 00040 #include "kmo_priv_fit_profile.h" 00041 #include "kmo_priv_extract_spec.h" 00042 #include "kmo_priv_functions.h" 00043 #include "kmo_dfs.h" 00044 #include "kmo_error.h" 00045 #include "kmo_debug.h" 00046 #include "kmo_priv_reconstruct.h" 00047 00048 /*----------------------------------------------------------------------------- 00049 * Lines (all vacuum) 00050 * 00051 # Line lists for use in telluric transmission correction for KMOS, etc. 00052 # based on OBA standard stars. 00053 # 00054 # 30/01/2013 NMFS 00055 # 00056 # 00057 # - H lines of the Paschen and Brackett series (perhaps also Pfund series 00058 # at the very red edge of K band) will be most prominent for late-O to 00059 # A types. 00060 # 00061 # - HeI lines in absorption are mostly for O types (with some dependence 00062 # on luminosity class). 00063 # - HeII lines will only be relevant in the earliest O types 00064 # - HeI and HeII lines may also appear in emission. 00065 # 00066 # The note "weak - irrelevant?" indicates lines that tend to be much 00067 # weaker, and would only be discernable in R > 5000 spectra with very 00068 # high S/N ratio. They may cause asymmetric wings for neighbouring 00069 # stronger features depending on the star/spectral type. 00070 # They are included here for completeness, but can probably be ignored 00071 # in the context of KMOS telluric calibration. 00072 # 00073 # It is important, however, to include the stronger HeI and HeII features, 00074 # experience with SINFONI shows they are frequently there (esp. in H band). 00075 # 00076 # 00077 # N.B. 00078 # The H line list in this file is complete within the Iz - K coverage 00079 # of KMOS (excluding the highest Pa, Br, abd Pf transitions, which 00080 # become very weak). 00081 # The He line for >= 1.0um is fairly complete (strongest common lines 00082 # are included). 00083 # HOWEVER: the He line list at < 1.0um, relevant for Iz band, is missing. 00084 # 00085 # 00086 # Useful references: 00087 # Wallace et al. 2000, ApJ, 535, 325 00088 # Wallace & Hinkle 1997, 00089 # Meyer et al. 1998, 00090 # Hanson et al. 2005, ApJS, 161, 154 00091 # 00092 # In the future: planned XShooter stellar library (PI S. Trager) will 00093 # provide a cross-check over the full Iz - K band, as well as allow the 00094 # identification of potentially missing He features in the range 0.8-1um. 00095 00096 *-----------------------------------------------------------------------------*/ 00097 const int nr_lines_h = 10; 00098 const double lines_center_h[] = { 00099 1.7001, // HeI // triplet 00100 // 1.52616, // Br-19 // (weak - irrelevant?) 00101 1.53429, // Br-18 00102 1.54400, // Br-17 00103 1.55576, // Br-16 00104 1.57018, // Br-15 00105 1.58817, // Br-14 00106 1.61105, // Br-13 00107 1.64084, // Br-12 00108 1.68077, // Br-11 00109 1.73634 // Br-10 00110 // 1.6918, // HeII // weak 00111 // 1.81754, // Br-epsilon // (in band, but low transmission) 00112 // 1.87524 // Pa-alpha // (out of H-band? useful for HK?) 00113 }; 00114 const double lines_width_h[] = { 00115 0.025, // HeI 00116 // 0.015, // Br-19 00117 0.003, // Br-18 00118 0.015, // Br-17 00119 0.015, // Br-16 00120 0.015, // Br-15 00121 0.025, // Br-14 00122 0.015, // Br-13 00123 0.025, // Br-12 00124 0.025, // Br-11 00125 0.05 // Br-10 00126 // 0.015, // HeII 00127 // 0.015, // Br-epsilon 00128 // 0.015 // Pa-alpha 00129 }; 00130 const int nr_lines_k = 2; 00131 const double lines_center_k[] = { 00132 // 1.94470, // Br-delta // out of K-band 00133 // 2.0581, // HeI // singlet // very faint, non detectable 00134 2.1120, // HeI // triplet 00135 //2.1132, // HeI // singlet 00136 // 2.1494, // HeI // (weak - irrelevant?) 00137 // 2.1607, // HeI // triplet (weak - irrelevant?) 00138 // 2.1617, // HeI // singlet (weak - irrelevant?) 00139 // 2.1641, // HeI // triplet (weak - irrelevant?) 00140 2.16569 // Br-gamma 00141 // 2.1815, // HeI // (weak - irrelevant?) 00142 // 2.1840, // HeI // (weak - irrelevant?) 00143 // wo ?!? 2.1885, // HeII 00144 // 2.43087, // Pf-20 // (weak - irrelevant?) 00145 // 2.44851, // Pf-19 // (weak - irrelevant?) 00146 // 2.46949, // Pf-18 // (weak - irrelevant?) 00147 // 2.49475 // Pf-17 // (weak - irrelevant?) // out of band 00148 }; 00149 const double lines_width_k[] = { 00150 // 0.015, // Br-delta // (out of K-band? useful for HK?) 00151 // 0.008, // HeI // singlet 00152 0.01, // HeI // triplet 00153 //0.0015, // HeI // singlet 00154 // 0.003, // HeI // (weak - irrelevant?) 00155 // 0.003, // HeI // triplet (weak - irrelevant?) 00156 // 0.003, // HeI // singlet (weak - irrelevant?) 00157 // 0.015, // HeI // triplet (weak - irrelevant?) 00158 0.015 // Br-gamma 00159 // 0.003, // HeI // (weak - irrelevant?) 00160 // 0.003, // HeI // (weak - irrelevant?) 00161 // 0.015, // HeII 00162 // 0.015, // Pf-20 // (weak - irrelevant?) 00163 // 0.015, // Pf-19 // (weak - irrelevant?) 00164 // 0.015, // Pf-18 // (weak - irrelevant?) 00165 // 0.015 // Pf-17 // (weak - irrelevant?) 00166 }; 00167 const int nr_lines_hk = 12; 00168 const double lines_center_hk[] = { 00169 // H 00170 1.7001, // HeI // triplet 00171 00172 1.53429, // Br-18 00173 1.54400, // Br-17 00174 1.55576, // Br-16 00175 1.57018, // Br-15 00176 1.58817, // Br-14 00177 1.61105, // Br-13 00178 1.64084, // Br-12 00179 1.68077, // Br-11 00180 1.73634, // Br-10 00181 // K 00182 2.1120, // HeI // triplet 00183 2.16569 // Br-gamma 00184 }; 00185 const double lines_width_hk[] = { 00186 // H 00187 0.025, // HeI 00188 0.003, // Br-18 00189 0.015, // Br-17 00190 0.015, // Br-16 00191 0.015, // Br-15 00192 0.025, // Br-14 00193 0.015, // Br-13 00194 0.025, // Br-12 00195 0.025, // Br-11 00196 0.05, // Br-10 00197 // K 00198 0.015, // HeI // triplet 00199 0.015 // Br-gamma 00200 }; 00201 const int nr_lines_iz = 12; 00202 const double lines_center_iz[] = { 00203 0.84386, // Pa-18 00204 0.84679, // Pa-17 00205 0.85031, // Pa-16 00206 0.85460, // Pa-15 00207 0.85990, // Pa-14 00208 0.86657, // Pa-13 00209 0.87511, // Pa-12 00210 0.88635, // Pa-11 00211 0.90156, // Pa-10 00212 0.92297, // Pa-9 00213 0.95467, // Pa-epsilon 00214 1.00501 // Pa-delta 00215 }; 00216 const double lines_width_iz[] = { 00217 0.0008, // Pa-18 00218 0.003225, // Pa-17 00219 0.0039, // Pa-16 00220 0.0048, // Pa-15 00221 0.006, // Pa-14 00222 0.0076, // Pa-13 00223 0.001, // Pa-12 00224 0.013, // Pa-11 00225 0.01, // Pa-10 00226 0.013, // Pa-9 00227 0.02, // Pa-epsilon 00228 0.025 // Pa-delta 00229 }; 00230 const int nr_lines_yj = 7; 00231 const double lines_center_yj[] = { 00232 // 1.00501, // Pa-delta // (out of band?) 00233 1.08331, // HeI 00234 1.09160, // HeI 00235 1.09389, // Pa-gamma 00236 00237 1.19723, // HeI 00238 00239 1.28191, // Pa-beta 00240 1.27882, // HeI 00241 // 1.28495, // HeI // faint 00242 1.29720 // HeI 00243 }; 00244 const double lines_width_yj[] = { 00245 // 0.015, // Pa-delta // (out of band?) 00246 .01,//0.005, // HeI 00247 .01,//0.002, // HeI 00248 0.02, // Pa-gamma 00249 00250 0.003, // HeI 00251 00252 0.02, // Pa-beta 00253 0.0025, // HeI 00254 // 0.0007, // HeI 00255 0.002 // HeI 00256 }; 00257 00258 /*----------------------------------------------------------------------------- 00259 * Functions prototypes 00260 *----------------------------------------------------------------------------*/ 00261 00262 static int kmo_std_star_create(cpl_plugin *); 00263 static int kmo_std_star_exec(cpl_plugin *); 00264 static int kmo_std_star_destroy(cpl_plugin *); 00265 static int kmo_std_star(cpl_parameterlist *, cpl_frameset *); 00266 00267 /*----------------------------------------------------------------------------- 00268 * Static variables 00269 *----------------------------------------------------------------------------*/ 00270 00271 static char kmo_std_star_description[] = 00272 "This recipe creates a telluric calibration frame and a PSF frame. It must be\n" 00273 "called after the kmo_illumination-recipe.\n" 00274 "Since there won’t be enough standard stars to observe for all IFUs in one ex-\n" 00275 "posure, one has to do several exposures in a way that there is at least one\n" 00276 "standard star and one sky exposure in each IFU. A internal data organiser will\n" 00277 "analyse the provided exposures and select the appropriate frames as follows:\n" 00278 "1. For each IFU the first standard star in the list of provided exposures is\n" 00279 " taken. All subsequent standard star exposures for this IFU will be ignored\n" 00280 "2. A corresponding sky exposure will be chosen which will be as close in time\n" 00281 " to the standard star exposure as possible.\n" 00282 "3. For any IFUs not containing a standard star and a sky exposure an empty\n" 00283 " frame will be returned.\n" 00284 "\n" 00285 "NOISE_SPEC contains in any case the shot noise [sqrt(counts*gain)/gain]. If the\n" 00286 "exposures have been taken with template KMOS_spec_cal_stdstarscipatt, then an\n" 00287 "additional noise component is added in: All existing sky exposures for an IFU\n" 00288 "are subtracted pairwise, spectra are extracted and the std deviation is calculated.\n" 00289 "\n" 00290 "BASIC PARAMETERS:\n" 00291 "-----------------\n" 00292 "--startype\n" 00293 "If this parameter is specified, the stored star types of the observed obejcts \n" 00294 "in the FITS headers are overridden. This value applies to all objects exa-\n" 00295 "mined in the input frames. Examples would be “A3I”, “G3IV” or “K0I”. The first\n" 00296 "letter defines the star type, the second letter the spectral class and the last\n" 00297 "letters the luminosity class.\n" 00298 "\n" 00299 "--magnitude\n" 00300 "If this parameter is specified, the stored magnitudes in the FITS headers are \n" 00301 "overridden. For HK two magnitudes for each H and K have to be specified. All \n" 00302 "other gratings just use a single magnitude. If two values are provided, they \n" 00303 "have to be separated with a comma. \n" 00304 "\n" 00305 "--fmethod\n" 00306 "The type of function that should be fitted spatially to the collapsed image.\n" 00307 "This fit is used to create a mask to extract the spectrum of the object. Valid\n" 00308 "values are “gauss” and “moffat”.\n" 00309 "\n" 00310 "--imethod\n" 00311 "The interpolation method used for reconstruction. As default 'CS' is selected.\n" 00312 "Note that no error spectra will be generated for this interpolation method.\n" 00313 "Select a nearest neighbour method otherwise\n" 00314 "\n" 00315 "--range\n" 00316 "The spectral range [um] to combine when collapsing the reconstructed cubes.\n" 00317 "\n" 00318 "--save_cubes\n" 00319 "Set to TRUE if the intermediate reconstructed cubes (eventually divided by " 00320 "illumination correction) should be saved as well. Default is FALSE.\n" 00321 "\n" 00322 "--no_noise\n" 00323 "Applies only for data taken with template KMOS_spec_cal_stdstarscipatt:\n" 00324 "Skip lengthy calculation of noise-spectra on all sky exposures (no NOISE_SPEC\n" 00325 "will be produced).\n" 00326 "\n" 00327 "ADVANCED PARAMETERS\n" 00328 "-------------------\n" 00329 "--flux\n" 00330 "Specify if flux conservation should be applied.\n" 00331 "\n" 00332 "--neighborhoodRange\n" 00333 "Defines the range to search for neighbors during reconstruction\n" 00334 "\n" 00335 "--b_samples\n" 00336 "The number of samples in spectral direction for the reconstructed cube.\n" 00337 "Ideally this number should be greater than 2048, the detector size.\n" 00338 "\n" 00339 "--b_start\n" 00340 "--b_end\n" 00341 "Used to define manually the start and end wavelength for the reconstructed\n" 00342 "cube. By default the internally defined values are used.\n" 00343 "\n" 00344 "--cmethod\n" 00345 "Following methods of frame combination are available:\n" 00346 " * 'ksigma' (Default)\n" 00347 " An iterative sigma clipping. For each position all pixels in the spectrum\n" 00348 " are examined. If they deviate significantly, they will be rejected according\n" 00349 " to the conditions:\n" 00350 " val > mean + stdev * cpos_rej\n" 00351 " and\n" 00352 " val < mean - stdev * cneg_rej\n" 00353 " where --cpos_rej, --cneg_rej and --citer are the corresponding configuration\n" 00354 " parameters. In the first iteration median and percentile level are used.\n" 00355 "\n" 00356 " * 'median'\n" 00357 " At each pixel position the median is calculated.\n" 00358 "\n" 00359 " * 'average'\n" 00360 " At each pixel position the average is calculated.\n" 00361 "\n" 00362 " * 'sum'\n" 00363 " At each pixel position the sum is calculated.\n" 00364 "\n" 00365 " * 'min_max'\n" 00366 " The specified number of minimum and maximum pixel values will be rejected.\n" 00367 " --cmax and --cmin apply to this method.\n" 00368 "\n" 00369 "--cpos_rej\n" 00370 "--cneg_rej\n" 00371 "--citer\n" 00372 "see --cmethod='ksigma'\n" 00373 "\n" 00374 "--cmax\n" 00375 "--cmin\n" 00376 "see --cmethod='min_max'\n" 00377 "\n" 00378 "--xcal_interpolation\n" 00379 "If true interpolate the pixel position in the slitlet (xcal) using the two\n" 00380 "closest rotator angles in the calibration file. Otherwise take the values\n" 00381 "of the closest rotator angle\n" 00382 "\n" 00383 "--suppress_extension\n" 00384 "If set to TRUE, the arbitrary filename extensions are supressed. If multiple\n" 00385 "products with the same category are produced, they will be numered consecutively\n" 00386 "starting from 0.\n" 00387 "\n" 00388 "-------------------------------------------------------------------------------\n" 00389 " Input files: \n" 00390 " \n" 00391 " DO KMOS \n" 00392 " category Type Explanation Required #Frames\n" 00393 " -------- ----- ----------- -------- -------\n" 00394 " STD RAW Std. star & sky exposures Y >=1 \n" 00395 " XCAL F2D x calibration frame Y 1 \n" 00396 " YCAL F2D y calibration frame Y 1 \n" 00397 " LCAL F2D Wavelength calib. frame Y 1 \n" 00398 " MASTER_FLAT F2D Master flat frame Y 1 \n" 00399 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00400 " ILLUM_CORR F2I Illumination correction N 0,1 \n" 00401 " SOLAR_SPEC F1S Solar spectrum N 0,1 \n" 00402 " (only for G stars) \n" 00403 " ATMOS_MODEL F1S Model atmospheric transmisson N 0,1 \n" 00404 " (only for OBAF stars in K band) \n" 00405 " SPEC_TYPE_LOOKUP F2L LUT eff. stellar temperature N 0,1 \n" 00406 " \n" 00407 " Output files: \n" 00408 " \n" 00409 " DO KMOS \n" 00410 " category Type Explanation \n" 00411 " -------- ----- ----------- \n" 00412 " TELLURIC F1I The normalised telluric spectrum \n" 00413 " (including errors) \n" 00414 " STAR_SPEC F1I The extracted star spectrum \n" 00415 " (including errors) \n" 00416 " STD_IMAGE F2I The standard star PSF images \n" 00417 " STD_MASK F2I The generated mask used to extract the star \n" 00418 " spectrum \n" 00419 " NOISE_SPEC F1I The extracted noise spectrum \n" 00420 "-------------------------------------------------------------------------------\n" 00421 "\n"; 00422 00423 /*----------------------------------------------------------------------------- 00424 * Functions code 00425 *----------------------------------------------------------------------------*/ 00426 00443 int cpl_plugin_get_info(cpl_pluginlist *list) 00444 { 00445 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00446 cpl_plugin *plugin = &recipe->interface; 00447 00448 cpl_plugin_init(plugin, 00449 CPL_PLUGIN_API, 00450 KMOS_BINARY_VERSION, 00451 CPL_PLUGIN_TYPE_RECIPE, 00452 "kmo_std_star", 00453 "Create the telluric correction frame.", 00454 kmo_std_star_description, 00455 "Alex Agudo Berbel", 00456 "usd-help@eso.org", 00457 kmos_get_license(), 00458 kmo_std_star_create, 00459 kmo_std_star_exec, 00460 kmo_std_star_destroy); 00461 00462 cpl_pluginlist_append(list, plugin); 00463 00464 return 0; 00465 } 00466 00474 static int kmo_std_star_create(cpl_plugin *plugin) 00475 { 00476 cpl_recipe *recipe; 00477 cpl_parameter *p; 00478 00479 /* Check that the plugin is part of a valid recipe */ 00480 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00481 recipe = (cpl_recipe *)plugin; 00482 else 00483 return -1; 00484 00485 /* Create the parameters list in the cpl_recipe object */ 00486 recipe->parameters = cpl_parameterlist_new(); 00487 00488 /* --startype */ 00489 p = cpl_parameter_new_value("kmos.kmo_std_star.startype", 00490 CPL_TYPE_STRING, 00491 "The spectral type of the star (O, B, A, F, G)" 00492 " Format: G4V etc.", 00493 "kmos.kmo_std_star", 00494 ""); 00495 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startype"); 00496 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00497 cpl_parameterlist_append(recipe->parameters, p); 00498 00499 /* --imethod */ 00500 p = cpl_parameter_new_value("kmos.kmo_std_star.imethod", 00501 CPL_TYPE_STRING, 00502 "Method to use for interpolation. " 00503 "[\"NN\" (nearest neighbour), " 00504 "\"lwNN\" (linear weighted nearest neighbor), " 00505 "\"swNN\" (square weighted nearest neighbor), " 00506 "\"MS\" (Modified Shepard's method), " 00507 "\"CS\" (Cubic spline)]", 00508 "kmos.kmo_std_star", 00509 "CS"); 00510 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00511 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00512 cpl_parameterlist_append(recipe->parameters, p); 00513 00514 /* --fmethod */ 00515 p = cpl_parameter_new_value("kmos.kmo_std_star.fmethod", 00516 CPL_TYPE_STRING, 00517 "Either fit a 'gauss' or 'moffat' profile.", 00518 "kmos.kmo_std_star", 00519 "gauss"); 00520 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00521 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00522 cpl_parameterlist_append(recipe->parameters, p); 00523 00524 /* --neighborhoodRange */ 00525 p = cpl_parameter_new_value("kmos.kmo_std_star.neighborhoodRange", 00526 CPL_TYPE_DOUBLE, 00527 "Defines the range to search for neighbors " 00528 "in pixels", 00529 "kmos.kmo_std_star", 00530 1.001); 00531 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00532 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00533 cpl_parameterlist_append(recipe->parameters, p); 00534 00535 /* --magnitude */ 00536 p = cpl_parameter_new_value("kmos.kmo_std_star.magnitude", 00537 CPL_TYPE_STRING, 00538 "The magnitude of the std star. For HK two " 00539 "values have to provided (eg. 12.1,13.2)", 00540 "kmos.kmo_std_star", 00541 ""); 00542 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "magnitude"); 00543 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00544 cpl_parameterlist_append(recipe->parameters, p); 00545 00546 /* --flux */ 00547 p = cpl_parameter_new_value("kmos.kmo_std_star.flux", 00548 CPL_TYPE_BOOL, 00549 "TRUE: Apply flux conservation. FALSE: otherwise", 00550 "kmos.kmo_std_star", 00551 TRUE); 00552 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00553 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00554 cpl_parameterlist_append(recipe->parameters, p); 00555 00556 /* --save_cubes */ 00557 p = cpl_parameter_new_value("kmos.kmo_std_star.save_cubes", 00558 CPL_TYPE_BOOL, 00559 "TRUE: Save reconstructed cubes, FALSE: otherwise", 00560 "kmos.kmo_std_star", 00561 FALSE); 00562 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save_cubes"); 00563 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00564 cpl_parameterlist_append(recipe->parameters, p); 00565 00566 /* --no_noise */ 00567 p = cpl_parameter_new_value("kmos.kmo_std_star.no_noise", 00568 CPL_TYPE_BOOL, 00569 "Applies only for data taken with template KMOS_spec_cal_stdstarscipatt: " 00570 "FALSE: Calculate noise-spectra on all sky exposures. " 00571 "TRUE: skip this step", 00572 "kmos.kmo_std_star", 00573 FALSE); 00574 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "no_noise"); 00575 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00576 cpl_parameterlist_append(recipe->parameters, p); 00577 00578 /* --xcal_interpolation */ 00579 p = cpl_parameter_new_value("kmos.kmo_std_star.xcal_interpolation", 00580 CPL_TYPE_BOOL, 00581 "TRUE: Interpolate xcal between rotator angles. FALSE: otherwise", 00582 "kmos.kmo_std_star", 00583 TRUE); 00584 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcal_interpolation"); 00585 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00586 cpl_parameterlist_append(recipe->parameters, p); 00587 00588 /* --suppress_extension */ 00589 p = cpl_parameter_new_value("kmos.kmo_std_star.suppress_extension", 00590 CPL_TYPE_BOOL, 00591 "Suppress arbitrary filename extension." 00592 "(TRUE (apply) or FALSE (don't apply)", 00593 "kmos.kmo_std_star", 00594 FALSE); 00595 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00596 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00597 cpl_parameterlist_append(recipe->parameters, p); 00598 00599 // add parameters for band-definition 00600 kmo_band_pars_create(recipe->parameters, 00601 "kmos.kmo_std_star"); 00602 00603 // add parameters for combining 00604 return kmo_combine_pars_create(recipe->parameters, 00605 "kmos.kmo_std_star", 00606 DEF_REJ_METHOD, 00607 FALSE); 00608 } 00609 00615 static int kmo_std_star_exec(cpl_plugin *plugin) 00616 { 00617 cpl_recipe *recipe; 00618 00619 /* Get the recipe out of the plugin */ 00620 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00621 recipe = (cpl_recipe *)plugin; 00622 else return -1; 00623 00624 return kmo_std_star(recipe->parameters, recipe->frames); 00625 } 00626 00632 static int kmo_std_star_destroy(cpl_plugin *plugin) 00633 { 00634 cpl_recipe *recipe; 00635 00636 /* Get the recipe out of the plugin */ 00637 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00638 recipe = (cpl_recipe *)plugin; 00639 else return -1 ; 00640 00641 cpl_parameterlist_delete(recipe->parameters); 00642 return 0 ; 00643 } 00644 00659 static int kmo_std_star(cpl_parameterlist *parlist, cpl_frameset *frameset) 00660 { 00661 cpl_imagelist **stored_data_cube = NULL, 00662 **stored_noise_cube = NULL; 00663 cpl_image **stored_psf_data = NULL, 00664 *illum_corr = NULL, 00665 **stored_mask = NULL, 00666 *lcal = NULL; 00667 const cpl_image *tmp_img = NULL; 00668 cpl_frame *xcal_frame = NULL, 00669 *ycal_frame = NULL, 00670 *lcal_frame = NULL, 00671 *flat_frame = NULL, 00672 *illum_frame = NULL, 00673 *obj_frame = NULL, 00674 *sky_frame = NULL, 00675 *tmp_frame = NULL; 00676 cpl_vector *solar_spec = NULL, 00677 *atmos_model = NULL, 00678 **stored_telluric_data = NULL, 00679 **stored_telluric_noise = NULL, 00680 **stored_starspec_data = NULL, 00681 **stored_starspec_noise = NULL, 00682 *shot_noise = NULL, 00683 **stored_noisespec = NULL, 00684 *tmp_spec_data = NULL, 00685 *spec_qc = NULL, 00686 *tmp_spec_noise = NULL, 00687 *identified_slices = NULL, 00688 *tmp_vec = NULL, 00689 *lambda_x = NULL; 00690 int ret_val = 0, 00691 nr_devices = 0, 00692 nr_exp = 0, 00693 j = 0, 00694 *bounds = NULL, 00695 ifu_nr = 0, 00696 citer = 0, 00697 cmax = 0, 00698 cmin = 0, 00699 line_warning = FALSE, 00700 nr_std_stars = 0, 00701 print_warning_once = TRUE, 00702 flux = FALSE, 00703 background = FALSE, 00704 save_cubes = FALSE, 00705 no_noise = FALSE, 00706 has_magnitude = TRUE, 00707 xcal_interpolation = FALSE, 00708 suppress_extension = FALSE, 00709 nr_split_mag = 0, 00710 nr_sky_pairs = 0, 00711 i = 0, 00712 ii = 0, 00713 l = 0, 00714 gx = 0, 00715 gy = 0, 00716 k = 0; 00717 const int *punused_ifus = NULL; 00718 objSkyStruct *obj_sky_struct = NULL; 00719 skySkyStruct *sky_sky_struct = NULL; 00720 double *stored_qc_throughput = NULL, 00721 star_temperature = 0.0, 00722 neighborhoodRange = 1.001, 00723 cpos_rej = 0.0, 00724 cneg_rej = 0.0, 00725 zeropoint = -1.0, 00726 throughput_mean = -1.0, 00727 throughput_sdv = -1.0, 00728 std_trace = -1.0, 00729 counts1 = 0.0, 00730 counts2 = 0.0, 00731 magnitude1 = 0.0, 00732 magnitude2 = 0.0, 00733 gain = 0.0, 00734 flux_scale_factor = 0.0, 00735 exptime = 0., 00736 cdelt3 = 0., 00737 mean_data = 0., 00738 mean_data2 = 0., 00739 *ptmp_spec_noise = NULL, 00740 *ppp = NULL, 00741 crpix1 = 0., 00742 crval1 = 0., 00743 cdelt1 = 0., 00744 tmp_data = 0., 00745 tmp_noise = 0.; 00746 const double *ptmp_spec_data = NULL; 00747 cpl_propertylist *main_header_tel = NULL, 00748 *main_header_psf = NULL, 00749 *sub_header_orig = NULL, 00750 *tmp_sub_header = NULL, 00751 *tmp_header = NULL, 00752 **stored_sub_tel_data_headers = NULL, 00753 **stored_sub_tel_noise_headers = NULL, 00754 **stored_sub_cube_data_headers = NULL, 00755 **stored_sub_cube_noise_headers = NULL, 00756 **stored_sub_psf_headers = NULL, 00757 *pl_psf = NULL; 00758 cpl_table *spec_type_LUT = NULL, 00759 *band_table = NULL;; 00760 main_fits_desc desc1, 00761 desc2; 00762 char *extname = NULL, 00763 *keyword = NULL, 00764 filename_telluric[256], 00765 filename_starspec[256], 00766 filename_psf[256], 00767 filename_mask[256], 00768 filename_cubes[256], 00769 filename_noise[256], 00770 *suffix = NULL, 00771 *fn_suffix = NULL, 00772 spec_class[256], 00773 lum_class[256], 00774 star_type[2], 00775 **split_mag = NULL, 00776 *grat_id = NULL, 00777 *tplid = NULL; 00778 const char *filter_id = NULL, 00779 *spec_type = NULL, 00780 *magnitude_txt = NULL, 00781 *imethod = NULL, 00782 *cmethod = NULL, 00783 *fmethod = NULL, 00784 *tmp_str = NULL; 00785 gridDefinition gd; 00786 cpl_array **unused_ifus_before = NULL, 00787 **unused_ifus_after = NULL; 00788 cpl_frameset *frameset_std = NULL; 00789 00790 KMO_TRY 00791 { 00792 kmo_init_fits_desc(&desc1); 00793 kmo_init_fits_desc(&desc2); 00794 00795 /* --- check input --- */ 00796 KMO_TRY_ASSURE((parlist != NULL) && 00797 (frameset != NULL), 00798 CPL_ERROR_NULL_INPUT, 00799 "Not all input data is provided!"); 00800 00801 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, STD) >= 1, 00802 CPL_ERROR_ILLEGAL_INPUT, 00803 "At least one STD frame is required!"); 00804 if (cpl_frameset_count_tags(frameset, STD) == 1) { 00805 cpl_msg_warning("", "At least two STD frames should be provided " 00806 "in order to apply sky subtraction!"); 00807 } 00808 00809 KMO_TRY_ASSURE((cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) || 00810 (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 0), 00811 CPL_ERROR_FILE_NOT_FOUND, 00812 "Exactly one ILLUM_CORR frame is required!"); 00813 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00814 CPL_ERROR_FILE_NOT_FOUND, 00815 "Exactly one XCAL frame is required!"); 00816 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00817 CPL_ERROR_FILE_NOT_FOUND, 00818 "Exactly one YCAL frame is required!"); 00819 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00820 CPL_ERROR_FILE_NOT_FOUND, 00821 "Exactly one LCAL frame is required!"); 00822 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, MASTER_FLAT) == 1, 00823 CPL_ERROR_FILE_NOT_FOUND, 00824 "Exactly one MASTER_FLAT frame is required!"); 00825 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00826 CPL_ERROR_FILE_NOT_FOUND, 00827 "Exactly one WAVE_BAND frame is required!"); 00828 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_std_star") == 1, 00829 CPL_ERROR_ILLEGAL_INPUT, 00830 "Cannot identify RAW and CALIB frames!"); 00831 00832 /* --- get parameters --- */ 00833 cpl_msg_info("", "--- Parameter setup for kmo_std_star ------"); 00834 00835 KMO_TRY_EXIT_IF_NULL( 00836 spec_type = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_std_star.startype")); 00837 KMO_TRY_EXIT_IF_ERROR( 00838 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.startype")); 00839 00840 KMO_TRY_EXIT_IF_NULL( 00841 imethod = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_std_star.imethod")); 00842 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00843 (strcmp(imethod, "lwNN") == 0) || 00844 (strcmp(imethod, "swNN") == 0) || 00845 (strcmp(imethod, "MS") == 0) || 00846 (strcmp(imethod, "CS") == 0), 00847 CPL_ERROR_ILLEGAL_INPUT, 00848 "method must be either \"NN\", \"lwNN\", " 00849 "\"swNN\", \"MS\" or \"CS\"!"); 00850 KMO_TRY_EXIT_IF_ERROR( 00851 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.imethod")); 00852 00853 KMO_TRY_EXIT_IF_NULL( 00854 fmethod = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_std_star.fmethod")); 00855 KMO_TRY_ASSURE((strcmp(fmethod, "gauss") == 0) || 00856 (strcmp(fmethod, "moffat") == 0), 00857 CPL_ERROR_ILLEGAL_INPUT, 00858 "fmethod must be either 'gauss' or " 00859 "'moffat' !"); 00860 KMO_TRY_EXIT_IF_ERROR( 00861 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.method")); 00862 00863 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, "kmos.kmo_std_star.neighborhoodRange"); 00864 KMO_TRY_CHECK_ERROR_STATE(); 00865 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00866 CPL_ERROR_ILLEGAL_INPUT, 00867 "neighborhoodRange must be greater than 0.0"); 00868 KMO_TRY_EXIT_IF_ERROR( 00869 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.neighborhoodRange")); 00870 00871 magnitude_txt = kmo_dfs_get_parameter_string(parlist, "kmos.kmo_std_star.magnitude"); 00872 KMO_TRY_CHECK_ERROR_STATE(); 00873 KMO_TRY_EXIT_IF_ERROR( 00874 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.magnitude")); 00875 00876 flux = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_std_star.flux"); 00877 KMO_TRY_ASSURE((flux == FALSE) || (flux == TRUE), 00878 CPL_ERROR_ILLEGAL_INPUT, 00879 "flux must be either FALSE or TRUE!"); 00880 KMO_TRY_EXIT_IF_ERROR( 00881 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.flux")); 00882 00883 save_cubes = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_std_star.save_cubes"); 00884 KMO_TRY_ASSURE((save_cubes == FALSE) || (save_cubes == TRUE), 00885 CPL_ERROR_ILLEGAL_INPUT, 00886 "save_cubes must be either FALSE or TRUE!"); 00887 KMO_TRY_EXIT_IF_ERROR( 00888 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.save_cubes")); 00889 00890 no_noise = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_std_star.no_noise"); 00891 KMO_TRY_ASSURE((no_noise == FALSE) || (no_noise == TRUE), 00892 CPL_ERROR_ILLEGAL_INPUT, 00893 "no_noise must be either FALSE or TRUE!"); 00894 KMO_TRY_EXIT_IF_ERROR( 00895 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.no_noise")); 00896 00897 xcal_interpolation = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_std_star.xcal_interpolation"); 00898 KMO_TRY_CHECK_ERROR_STATE(); 00899 KMO_TRY_EXIT_IF_ERROR( 00900 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.xcal_interpolation")); 00901 KMO_TRY_ASSURE((xcal_interpolation == TRUE) || 00902 (xcal_interpolation == FALSE), 00903 CPL_ERROR_ILLEGAL_INPUT, 00904 "xcal_interpolation must be TRUE or FALSE!"); 00905 00906 suppress_extension = kmo_dfs_get_parameter_bool(parlist, "kmos.kmo_std_star.suppress_extension"); 00907 KMO_TRY_CHECK_ERROR_STATE(); 00908 KMO_TRY_EXIT_IF_ERROR( 00909 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.suppress_extension")); 00910 00911 KMO_TRY_ASSURE((suppress_extension == TRUE) || (suppress_extension == FALSE), 00912 CPL_ERROR_ILLEGAL_INPUT, 00913 "suppress_extension must be TRUE or FALSE!"); 00914 00915 kmo_band_pars_load(parlist, "kmos.kmo_std_star"); 00916 00917 KMO_TRY_EXIT_IF_ERROR( 00918 kmo_combine_pars_load(parlist, 00919 "kmos.kmo_std_star", 00920 &cmethod, 00921 &cpos_rej, 00922 &cneg_rej, 00923 &citer, 00924 &cmin, 00925 &cmax, 00926 FALSE)); 00927 cpl_msg_info("", "-------------------------------------------"); 00928 00929 // 00930 // Check if magnitude/frameset is valid and if throughput and zeropoint should be calculated 00931 // 00932 00933 // Check if all STD frames have the same GRAT-ID 00934 // if not: don't calculate zeropoint and throughput 00935 KMO_TRY_EXIT_IF_NULL( 00936 frameset_std = cpl_frameset_new()); 00937 00938 KMO_TRY_EXIT_IF_NULL( 00939 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00940 KMO_TRY_EXIT_IF_NULL( 00941 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 00942 KMO_TRY_EXIT_IF_NULL( 00943 grat_id = cpl_sprintf("%s", cpl_propertylist_get_string(tmp_header, "ESO INS GRAT1 ID"))); 00944 KMO_TRY_EXIT_IF_NULL( 00945 tplid = cpl_sprintf("%s", cpl_propertylist_get_string(tmp_header, TPL_ID))); 00946 KMO_TRY_EXIT_IF_ERROR( 00947 cpl_frameset_insert(frameset_std, cpl_frame_duplicate(tmp_frame))); 00948 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00949 KMO_TRY_CHECK_ERROR_STATE(); 00950 00951 KMO_TRY_EXIT_IF_NULL( 00952 tmp_frame = kmo_dfs_get_frame(frameset, NULL)); 00953 while (tmp_frame != NULL ) { 00954 KMO_TRY_EXIT_IF_NULL( 00955 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 00956 if (strcmp(grat_id, cpl_propertylist_get_string(tmp_header, "ESO INS GRAT1 ID")) == 0) { 00957 // same grating 00958 KMO_TRY_EXIT_IF_ERROR( 00959 cpl_frameset_insert(frameset_std, cpl_frame_duplicate(tmp_frame))); 00960 } else { 00961 // there are STD frames with different gratings 00962 if (has_magnitude) { 00963 cpl_msg_warning(cpl_func, "The STD frames have different gratings," 00964 "following QC parameters won't be " 00965 "calculated: QC ZEROPOINT, QC THROUGHPUT," 00966 "QC THROUGHPUT MEAN and QC THROUGHPUT STD"); 00967 } 00968 has_magnitude = FALSE; 00969 } 00970 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00971 00972 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 00973 KMO_TRY_CHECK_ERROR_STATE(); 00974 } 00975 KMO_TRY_CHECK_ERROR_STATE(); 00976 00977 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 00978 // check if ATMOS_MODEL is the band as the STD frames 00979 KMO_TRY_EXIT_IF_NULL( 00980 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL)); 00981 KMO_TRY_EXIT_IF_NULL( 00982 tmp_sub_header = kmclipm_propertylist_load( cpl_frame_get_filename(tmp_frame), 0)); 00983 KMO_TRY_EXIT_IF_NULL( 00984 tmp_str = cpl_propertylist_get_string(tmp_sub_header, FILT_ID)); 00985 KMO_TRY_ASSURE(strcmp(grat_id, tmp_str) == 0, 00986 CPL_ERROR_ILLEGAL_INPUT, 00987 "ATMOS model must have primary " 00988 "keyword '%s' equal '%s'!!!", 00989 FILT_ID, grat_id); 00990 cpl_propertylist_delete(tmp_sub_header); 00991 tmp_sub_header = NULL; 00992 } 00993 00994 if (has_magnitude) { 00995 // all STD frames have the same GRAT-ID 00996 // now check source of magnitude (user or keyword) 00997 KMO_TRY_EXIT_IF_NULL( 00998 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00999 KMO_TRY_EXIT_IF_NULL( 01000 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 01001 01002 if (strcmp(magnitude_txt, "") == 0) { 01003 // no user defined magnitude 01004 01005 // check for magnitude-keyword 01006 if ((cpl_propertylist_has(tmp_header, STDSTAR_MAG)) && 01007 (cpl_propertylist_get_type(tmp_header, STDSTAR_MAG) == CPL_TYPE_STRING)) 01008 { 01009 KMO_TRY_EXIT_IF_NULL( 01010 magnitude_txt = cpl_propertylist_get_string(tmp_header, STDSTAR_MAG)); 01011 KMO_TRY_EXIT_IF_NULL( 01012 split_mag = kmo_strsplit(magnitude_txt, ",", &nr_split_mag)); 01013 01014 // check if band and number of magnitudes matches 01015 if ((nr_split_mag == 2) && 01016 (strcmp(grat_id, "HK") == 0)) 01017 { 01018 magnitude1 = atof(split_mag[0]); 01019 magnitude2 = atof(split_mag[1]); 01020 cpl_msg_info("", "Magnitude in H: %g", magnitude1); 01021 cpl_msg_info("", "Magnitude in K: %g", magnitude2); 01022 } else if ((nr_split_mag >= 1) && 01023 ((strcmp(grat_id, "K") == 0) || 01024 (strcmp(grat_id, "H") == 0) || 01025 (strcmp(grat_id, "IZ") == 0) || 01026 (strcmp(grat_id, "YJ") == 0))) 01027 { 01028 magnitude1 = atof(split_mag[0]); 01029 cpl_msg_info("", "Magnitude in %s: %g", grat_id, magnitude1); 01030 } else { 01031 // keyword STDSTAR_MAG doesn't match filter 01032 has_magnitude = FALSE; 01033 cpl_msg_warning(cpl_func, "The keyword %s doesn't match to grating'," 01034 "following QC parameters won't be " 01035 "calculated: QC ZEROPOINT, QC THROUGHPUT," 01036 "QC THROUGHPUT MEAN and QC THROUGHPUT STD", STDSTAR_MAG); 01037 } 01038 kmo_strfreev(split_mag); 01039 } else { 01040 // keyword STDSTAR_MAG unavailable or wrong type 01041 has_magnitude = FALSE; 01042 cpl_msg_warning(cpl_func, "The keyword %s is not set or of wrong type," 01043 "following QC parameters won't be " 01044 "calculated: QC ZEROPOINT, QC THROUGHPUT," 01045 "QC THROUGHPUT MEAN and QC THROUGHPUT STD", STDSTAR_MAG); 01046 } 01047 } else { 01048 // magnitude is user specified 01049 cpl_msg_info(cpl_func, "Magnitude has been specified by user. Any " 01050 "value in keyword %s will be ignored.", STDSTAR_MAG); 01051 01052 KMO_TRY_EXIT_IF_NULL( 01053 split_mag = kmo_strsplit(magnitude_txt, ",", &nr_split_mag)); 01054 switch (nr_split_mag) { 01055 case 1: 01056 magnitude1 = atof(split_mag[0]); 01057 cpl_msg_info("", "Magnitude in %s: %g", grat_id, magnitude1); 01058 break; 01059 case 2: 01060 magnitude1 = atof(split_mag[0]); 01061 magnitude2 = atof(split_mag[1]); 01062 cpl_msg_info("", "Magnitude in H: %g", magnitude1); 01063 cpl_msg_info("", "Magnitude in K: %g", magnitude2); 01064 break; 01065 default: 01066 KMO_TRY_ASSURE(1 == 0, 01067 CPL_ERROR_ILLEGAL_INPUT, 01068 "Provided magnitude was in wrong format! " 01069 "Either a single float value or two separated by comma"); 01070 } 01071 kmo_strfreev(split_mag); 01072 } 01073 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01074 } // if (has_magnitude) 01075 cpl_msg_info("", "-------------------------------------------"); 01076 KMO_TRY_CHECK_ERROR_STATE(); 01077 01078 // 01079 // check for spectral type (--startype) (user or keyword) 01080 // 01081 if (strcmp(spec_type, "") == 0) { 01082 // no user defined startype 01083 01084 KMO_TRY_EXIT_IF_NULL( 01085 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 01086 KMO_TRY_EXIT_IF_NULL( 01087 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 01088 01089 // check for startype-keyword 01090 if ((cpl_propertylist_has(tmp_header, STDSTAR_TYPE)) && 01091 (cpl_propertylist_get_type(tmp_header, STDSTAR_TYPE) == CPL_TYPE_STRING)) 01092 { 01093 KMO_TRY_EXIT_IF_NULL( 01094 spec_type = cpl_propertylist_get_string(tmp_header, STDSTAR_TYPE)); 01095 } else { 01096 // keyword STDSTAR_TYPE unavailable or wrong type 01097 } 01098 } else { 01099 // startype is user specified 01100 cpl_msg_info(cpl_func, "Type of star has been specified by user. Any " 01101 "value in keyword %s will be ignored.", STDSTAR_TYPE); 01102 } 01103 KMO_TRY_CHECK_ERROR_STATE(); 01104 01105 if (strlen(spec_type) > 0) { 01106 if (kmo_get_spec_type(spec_type, spec_class, lum_class) != CPL_ERROR_NONE) { 01107 cpl_error_reset(); 01108 spec_class[0] = '\0'; 01109 lum_class[0] = '\0'; 01110 star_type[0] = '\0'; 01111 cpl_msg_warning("", "The keyword %s is not set or of wrong type nor was it provided by the user. " 01112 "Can't divide solar spectrum for G stars or fit a profile " 01113 "to atmospheric transmission for OBAF stars and can't " 01114 "divide blackbody for any star.", STDSTAR_TYPE); 01115 cpl_msg_warning("", "%s = '%s' (should be something like e.g.'G2V' odr 'A9III')", STDSTAR_TYPE, spec_type); 01116 } else { 01117 strncpy(star_type, spec_class, 1); 01118 star_type[1] = '\0'; 01119 cpl_msg_info("", "Spectral class: %s", spec_class); 01120 cpl_msg_info("", "Luminosity class: %s", lum_class); 01121 } 01122 } else { 01123 spec_class[0] = '\0'; 01124 lum_class[0] = '\0'; 01125 star_type[0] = '\0'; 01126 cpl_msg_warning("", "The keyword %s is not set nor was it provided by the user. " 01127 "Can't divide solar spectrum for G stars or fit a profile " 01128 "to atmospheric transmission for OBAF stars and can't " 01129 "divide blackbody for any star.", STDSTAR_TYPE); 01130 } 01131 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01132 cpl_msg_info("", "-------------------------------------------"); 01133 KMO_TRY_CHECK_ERROR_STATE(); 01134 01135 // assure that filters, grating and rotation offsets match for 01136 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 01137 // frames) 01138 // check if filter_id and grating_id match for all detectors 01139 KMO_TRY_EXIT_IF_ERROR( 01140 kmo_check_frameset_setup(frameset, XCAL, FALSE, FALSE, TRUE)); 01141 KMO_TRY_EXIT_IF_ERROR( 01142 kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE)); 01143 KMO_TRY_EXIT_IF_ERROR( 01144 kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE)); 01145 KMO_TRY_EXIT_IF_ERROR( 01146 kmo_check_frame_setup(frameset, XCAL, MASTER_FLAT, TRUE, FALSE, TRUE)); 01147 KMO_TRY_EXIT_IF_ERROR( 01148 kmo_check_frame_setup(frameset, XCAL, STD, FALSE, FALSE, TRUE)); 01149 01150 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 01151 KMO_TRY_EXIT_IF_ERROR( 01152 kmo_check_frame_setup(frameset, XCAL, ILLUM_CORR, TRUE, FALSE, FALSE)); 01153 } 01154 01155 // check descriptors of all frames 01156 KMO_TRY_EXIT_IF_NULL( 01157 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 01158 01159 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 01160 KMO_TRY_CHECK_ERROR_STATE(); 01161 01162 KMO_TRY_ASSURE((desc1.nr_ext % 3 == 0) && 01163 (desc1.ex_badpix == FALSE) && 01164 (desc1.fits_type == f2d_fits) && 01165 (desc1.frame_type == detector_frame), 01166 CPL_ERROR_ILLEGAL_INPUT, 01167 "XCAL isn't in the correct format!!!"); 01168 01169 KMO_TRY_EXIT_IF_NULL( 01170 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 01171 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 01172 KMO_TRY_CHECK_ERROR_STATE(); 01173 01174 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 01175 (desc1.ex_badpix == desc2.ex_badpix) && 01176 (desc1.fits_type == desc2.fits_type) && 01177 (desc1.frame_type == desc2.frame_type), 01178 CPL_ERROR_ILLEGAL_INPUT, 01179 "YCAL isn't in the correct format!!!"); 01180 kmo_free_fits_desc(&desc2); 01181 kmo_init_fits_desc(&desc2); 01182 01183 KMO_TRY_EXIT_IF_NULL( 01184 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 01185 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 01186 KMO_TRY_CHECK_ERROR_STATE(); 01187 01188 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 01189 (desc1.ex_badpix == desc2.ex_badpix) && 01190 (desc1.fits_type == desc2.fits_type) && 01191 (desc1.frame_type == desc2.frame_type), 01192 CPL_ERROR_ILLEGAL_INPUT, 01193 "YCAL isn't in the correct format!!!"); 01194 kmo_free_fits_desc(&desc2); 01195 kmo_init_fits_desc(&desc2); 01196 01197 KMO_TRY_EXIT_IF_NULL( 01198 flat_frame = kmo_dfs_get_frame(frameset, MASTER_FLAT)); 01199 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(flat_frame)); 01200 KMO_TRY_CHECK_ERROR_STATE(); 01201 01202 KMO_TRY_ASSURE((desc2.nr_ext % 6 == 0) && 01203 (desc1.ex_badpix == desc2.ex_badpix) && 01204 (desc1.fits_type == desc2.fits_type) && 01205 (desc1.frame_type == desc2.frame_type), 01206 CPL_ERROR_ILLEGAL_INPUT, 01207 "MASTER_FLAT isn't in the correct format!!!"); 01208 kmo_free_fits_desc(&desc2); 01209 kmo_init_fits_desc(&desc2); 01210 01211 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 01212 KMO_TRY_EXIT_IF_NULL( 01213 illum_frame = kmo_dfs_get_frame(frameset, ILLUM_CORR)); 01214 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(illum_frame)); 01215 KMO_TRY_CHECK_ERROR_STATE(); 01216 KMO_TRY_ASSURE(((desc2.nr_ext == 24) || (desc2.nr_ext == 48)) && 01217 (desc2.ex_badpix == FALSE) && 01218 (desc2.fits_type == f2i_fits) && 01219 (desc2.frame_type == ifu_frame), 01220 CPL_ERROR_ILLEGAL_INPUT, 01221 "ILLUM_CORR isn't in the correct format!!!"); 01222 kmo_free_fits_desc(&desc2); 01223 kmo_init_fits_desc(&desc2); 01224 } 01225 01226 if (cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) == 1) { 01227 KMO_TRY_EXIT_IF_NULL( 01228 tmp_frame = kmo_dfs_get_frame(frameset, SPEC_TYPE_LOOKUP)); 01229 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01230 KMO_TRY_CHECK_ERROR_STATE(); 01231 KMO_TRY_ASSURE((desc2.nr_ext == 1) && 01232 (desc2.ex_badpix == FALSE) && 01233 (desc2.fits_type == f2l_fits) && 01234 (desc2.frame_type == list_frame), 01235 CPL_ERROR_ILLEGAL_INPUT, 01236 "SPEC_TYPE_LOOKUP isn't in the correct format!!!"); 01237 kmo_free_fits_desc(&desc2); 01238 kmo_init_fits_desc(&desc2); 01239 } 01240 01241 if (cpl_frameset_count_tags(frameset, SOLAR_SPEC) == 1) { 01242 KMO_TRY_EXIT_IF_NULL( 01243 tmp_frame = kmo_dfs_get_frame(frameset, SOLAR_SPEC)); 01244 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01245 KMO_TRY_CHECK_ERROR_STATE(); 01246 KMO_TRY_ASSURE((desc2.nr_ext == 1) && 01247 (desc2.ex_badpix == FALSE) && 01248 (desc2.fits_type == f1s_fits) && 01249 (desc2.frame_type == spectrum_frame), 01250 CPL_ERROR_ILLEGAL_INPUT, 01251 "SOLAR_SPEC isn't in the correct format!!!"); 01252 kmo_free_fits_desc(&desc2); 01253 kmo_init_fits_desc(&desc2); 01254 } 01255 01256 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 01257 KMO_TRY_EXIT_IF_NULL( 01258 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL)); 01259 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01260 KMO_TRY_CHECK_ERROR_STATE(); 01261 KMO_TRY_ASSURE((desc2.nr_ext == 1) && 01262 (desc2.ex_badpix == FALSE) && 01263 (desc2.fits_type == f1s_fits) && 01264 (desc2.frame_type == spectrum_frame), 01265 CPL_ERROR_ILLEGAL_INPUT, 01266 "ATMOS_MODEL isn't in the correct format!!!"); 01267 kmo_free_fits_desc(&desc2); 01268 kmo_init_fits_desc(&desc2); 01269 } 01270 01271 KMO_TRY_EXIT_IF_NULL( 01272 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 01273 while (tmp_frame != NULL ) { 01274 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01275 KMO_TRY_CHECK_ERROR_STATE(); 01276 KMO_TRY_ASSURE((desc2.nr_ext == 3) && 01277 (desc2.ex_badpix == FALSE) && 01278 (desc2.fits_type == raw_fits) && 01279 (desc2.frame_type == detector_frame), 01280 CPL_ERROR_ILLEGAL_INPUT, 01281 "STD isn't in the correct format!!!"); 01282 nr_devices = desc2.nr_ext; 01283 kmo_free_fits_desc(&desc2); 01284 kmo_init_fits_desc(&desc2); 01285 01286 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01287 KMO_TRY_CHECK_ERROR_STATE(); 01288 } 01289 KMO_TRY_EXIT_IF_NULL( 01290 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 01291 KMO_TRY_EXIT_IF_NULL( 01292 suffix = kmo_dfs_get_suffix(tmp_frame, TRUE, FALSE)); 01293 01294 KMO_TRY_EXIT_IF_ERROR( 01295 kmo_check_frame_setup_md5_xycal(frameset)); 01296 KMO_TRY_EXIT_IF_ERROR( 01297 kmo_check_frame_setup_md5(frameset)); 01298 01299 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 01300 cpl_msg_info("", "(grating 1, 2 & 3)"); 01301 01302 // check which IFUs are active for all frames 01303 KMO_TRY_EXIT_IF_NULL( 01304 unused_ifus_before = kmo_get_unused_ifus(frameset, 0, 0)); 01305 01306 KMO_TRY_EXIT_IF_NULL( 01307 unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before)); 01308 01309 kmo_print_unused_ifus(unused_ifus_before, FALSE); 01310 01311 /* --- load data --- */ 01312 01313 if ((cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) == 1) && 01314 ((strlen(spec_class) > 0) || (strlen(lum_class) > 0))) 01315 { 01316 // get star temperature out of SPEC_TYPE_LOOKUP table 01317 KMO_TRY_EXIT_IF_NULL( 01318 spec_type_LUT = kmo_dfs_load_table(frameset, SPEC_TYPE_LOOKUP, 1, 0)); 01319 star_temperature = kmo_get_temperature(spec_type_LUT, spec_class, lum_class); 01320 KMO_TRY_CHECK_ERROR_STATE(); 01321 } else if (cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) != 1) { 01322 cpl_msg_warning("","No SPEC_TYPE_LOOKUP was provided! Can't divide blackbody."); 01323 } else if ((strlen(spec_class) == 0) || (strlen(lum_class) == 0)) { 01324 // cpl_msg_warning("","No startype was provided! Can't " 01325 // "divide blackbody."); 01326 } 01327 01328 // allocate intermediate memory 01329 KMO_TRY_EXIT_IF_NULL( 01330 stored_telluric_data = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01331 sizeof(cpl_vector*))); 01332 KMO_TRY_EXIT_IF_NULL( 01333 stored_telluric_noise = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01334 sizeof(cpl_vector*))); 01335 KMO_TRY_EXIT_IF_NULL( 01336 stored_starspec_data = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01337 sizeof(cpl_vector*))); 01338 KMO_TRY_EXIT_IF_NULL( 01339 stored_starspec_noise = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01340 sizeof(cpl_vector*))); 01341 KMO_TRY_EXIT_IF_NULL( 01342 stored_psf_data = (cpl_image**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01343 sizeof(cpl_image*))); 01344 KMO_TRY_EXIT_IF_NULL( 01345 stored_mask = (cpl_image**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01346 sizeof(cpl_image*))); 01347 KMO_TRY_EXIT_IF_NULL( 01348 stored_data_cube = (cpl_imagelist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01349 sizeof(cpl_imagelist*))); 01350 KMO_TRY_EXIT_IF_NULL( 01351 stored_noise_cube = (cpl_imagelist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01352 sizeof(cpl_imagelist*))); 01353 KMO_TRY_EXIT_IF_NULL( 01354 stored_qc_throughput = (double*)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01355 sizeof(double))); 01356 KMO_TRY_EXIT_IF_NULL( 01357 stored_sub_psf_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01358 sizeof(cpl_propertylist*))); 01359 KMO_TRY_EXIT_IF_NULL( 01360 stored_sub_tel_data_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01361 sizeof(cpl_propertylist*))); 01362 KMO_TRY_EXIT_IF_NULL( 01363 stored_sub_tel_noise_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01364 sizeof(cpl_propertylist*))); 01365 if (save_cubes) { 01366 KMO_TRY_EXIT_IF_NULL( 01367 stored_sub_cube_data_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01368 sizeof(cpl_propertylist*))); 01369 KMO_TRY_EXIT_IF_NULL( 01370 stored_sub_cube_noise_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01371 sizeof(cpl_propertylist*))); 01372 } 01373 01374 // get bounds 01375 KMO_TRY_EXIT_IF_NULL( 01376 tmp_header = kmo_dfs_load_primary_header(frameset, XCAL)); 01377 KMO_TRY_EXIT_IF_NULL( 01378 bounds = kmclipm_extract_bounds(tmp_header)); 01379 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01380 01381 // setup grid definition, wavelength start and end points will be set 01382 // in the detector loop 01383 KMO_TRY_EXIT_IF_ERROR( 01384 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, KMOS_PIX_RESOLUTION, 0.)); 01385 01386 // get valid STD frames with objects in it and associated sky exposures 01387 KMO_TRY_EXIT_IF_NULL( 01388 obj_sky_struct = kmo_create_objSkyStruct(frameset_std, STD, FALSE)); 01389 kmo_print_objSkyStruct(obj_sky_struct); 01390 01391 KMO_TRY_EXIT_IF_NULL( 01392 stored_noisespec = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01393 sizeof(cpl_vector*))); 01394 01395 // identify sky-sky-pairs for NOISE_SPEC calculation 01396 KMO_TRY_EXIT_IF_NULL( 01397 sky_sky_struct = kmo_create_skySkyStruct(frameset_std)); 01398 01399 // loop the object-sky pairs 01400 if (obj_sky_struct->size == 0) { 01401 cpl_msg_warning(cpl_func,"Not a single frame contains an object"); 01402 } else { 01403 strcpy(filename_telluric, TELLURIC); 01404 strcpy(filename_starspec, STAR_SPEC); 01405 strcpy(filename_psf, STD_IMAGE); 01406 strcpy(filename_mask, STD_MASK); 01407 strcpy(filename_cubes, STD_CUBE); 01408 strcpy(filename_noise, NOISE_SPEC); 01409 01410 obj_frame = obj_sky_struct->table[nr_exp].objFrame; 01411 KMO_TRY_EXIT_IF_NULL( 01412 main_header_tel = kmclipm_propertylist_load(cpl_frame_get_filename(obj_frame), 0)); 01413 01414 exptime = cpl_propertylist_get_double(main_header_tel, EXPTIME); 01415 KMO_TRY_CHECK_ERROR_STATE(); 01416 01417 // load, process & store frames 01418 01419 for (i = 1; i <= nr_devices; i++) { 01420 // extract LCAL image close to ROTANGLE 0. assuming that the wavelength range 01421 // doesn't differ too much with different ROTANGLEs. 01422 print_cal_angle_msg_once = FALSE; 01423 print_xcal_angle_msg_once = FALSE; 01424 double rotangle_found; 01425 KMO_TRY_EXIT_IF_NULL( 01426 lcal = kmo_dfs_load_cal_image(frameset, LCAL, i, FALSE, 0., FALSE, NULL, 01427 &rotangle_found, -1, 0, 0)); 01428 if (i==1) { 01429 print_cal_angle_msg_once = TRUE; 01430 print_xcal_angle_msg_once = TRUE; 01431 } 01432 01433 // get filter for this detector 01434 // ESO INS FILTi ID 01435 KMO_TRY_EXIT_IF_NULL( 01436 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, i, IFU_FILTID_POSTFIX)); 01437 filter_id = cpl_propertylist_get_string(main_header_tel, keyword); 01438 cpl_free(keyword); keyword = NULL; 01439 01440 KMO_TRY_EXIT_IF_NULL( 01441 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0)); 01442 KMO_TRY_EXIT_IF_ERROR( 01443 kmclipm_setup_grid_band_lcal(&gd, filter_id, 01444 band_table)); 01445 cpl_image_delete(lcal); lcal = NULL; 01446 cpl_table_delete(band_table); band_table = NULL; 01447 01448 // load sub_header of original F2D image 01449 KMO_TRY_EXIT_IF_NULL( 01450 sub_header_orig = kmclipm_propertylist_load( cpl_frame_get_filename(obj_frame), i)); 01451 01452 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 01453 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 01454 // check if IFU is valid according to main header keywords & 01455 // calibration files 01456 // AND check if there is a sky frame available for this IFU 01457 kmo_collapse_objSkyStruct(obj_sky_struct, ifu_nr, 01458 &obj_frame, &sky_frame); 01459 01460 KMO_TRY_EXIT_IF_NULL( 01461 punused_ifus = cpl_array_get_data_int_const(unused_ifus_after[i-1])); 01462 01463 // Search for keyword ESO OCS ARMi NOTUSED 01464 // If not present (CPL_ERROR_DATA_NOT_FOUND) we will eventually 01465 // process standard star 01466 KMO_TRY_EXIT_IF_NULL( 01467 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, IFU_VALID_POSTFIX)); 01468 tmp_str = cpl_propertylist_get_string(main_header_tel, keyword); 01469 cpl_free(keyword); keyword = NULL; 01470 01471 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 01472 (bounds[2*(ifu_nr-1)] != -1) && 01473 (bounds[2*(ifu_nr-1)+1] != -1) && 01474 (sky_frame != NULL) && 01475 (punused_ifus[j] == 0)) 01476 { 01477 cpl_error_reset(); 01478 // IFU is valid 01479 01480 if (sky_frame != NO_CORRESPONDING_SKYFRAME) { 01481 cpl_msg_info("", "Processing standard star in IFU %d", ifu_nr); 01482 cpl_msg_info("", " (obj: %s, sky: %s)", 01483 cpl_frame_get_filename(obj_frame), cpl_frame_get_filename(sky_frame)); 01484 } else { 01485 sky_frame = NULL; 01486 cpl_msg_warning("", "Processing standard star in IFU %d", ifu_nr); 01487 cpl_msg_warning("", " (obj: %s, no corresponding sky frame)", 01488 cpl_frame_get_filename(obj_frame)); 01489 } 01490 01491 nr_std_stars++; 01492 01493 char *ggg = cpl_sprintf("%s%d", PRO_STD, ifu_nr); 01494 KMO_TRY_EXIT_IF_ERROR( 01495 cpl_propertylist_update_int(main_header_tel, ggg, 1)); 01496 cpl_free(ggg); ggg = NULL; 01497 01498 // calculate WCS and make copies of sub_header 01499 KMO_TRY_EXIT_IF_NULL( 01500 tmp_sub_header = cpl_propertylist_duplicate(sub_header_orig)); 01501 KMO_TRY_EXIT_IF_ERROR( 01502 kmo_calc_wcs_gd(main_header_tel, tmp_sub_header, ifu_nr, gd)); 01503 KMO_TRY_EXIT_IF_NULL( 01504 stored_sub_tel_data_headers[ifu_nr-1] = 01505 cpl_propertylist_duplicate(tmp_sub_header)); 01506 KMO_TRY_EXIT_IF_NULL( 01507 stored_sub_psf_headers[ifu_nr-1] = 01508 cpl_propertylist_duplicate(tmp_sub_header)); 01509 if (save_cubes) { 01510 KMO_TRY_EXIT_IF_NULL( 01511 stored_sub_cube_data_headers[ifu_nr-1] = 01512 cpl_propertylist_duplicate(tmp_sub_header)); 01513 } 01514 cpl_propertylist_delete(tmp_sub_header); 01515 tmp_sub_header = NULL; 01516 01517 // 01518 // adjust telluric-headers: copy CRPIX3 to CRPIX1, 01519 // 01520 cpl_propertylist_update_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL1, 01521 cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL3)); 01522 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRVAL2); 01523 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRVAL3); 01524 KMO_TRY_CHECK_ERROR_STATE(); 01525 01526 // CRPIX 01527 cpl_propertylist_update_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX1, 01528 cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX3)); 01529 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRPIX2); 01530 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRPIX3); 01531 KMO_TRY_CHECK_ERROR_STATE(); 01532 01533 // CDELT 01534 cdelt3 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT3); 01535 cpl_propertylist_update_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT1, 01536 cdelt3); 01537 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CDELT2); 01538 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CDELT3); 01539 KMO_TRY_CHECK_ERROR_STATE(); 01540 01541 // CTYPE 01542 cpl_propertylist_update_string(stored_sub_tel_data_headers[ifu_nr-1], CTYPE1, 01543 cpl_propertylist_get_string(stored_sub_tel_data_headers[ifu_nr-1], CTYPE3)); 01544 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CTYPE2); 01545 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CTYPE3); 01546 KMO_TRY_CHECK_ERROR_STATE(); 01547 01548 // CUNIT 01549 cpl_propertylist_update_string(stored_sub_tel_data_headers[ifu_nr-1], CUNIT1, 01550 cpl_propertylist_get_string(stored_sub_tel_data_headers[ifu_nr-1], CUNIT3)); 01551 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CUNIT2); 01552 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CUNIT3); 01553 01554 // CDx_x 01555 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_1); 01556 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_2); 01557 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_3); 01558 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_1); 01559 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_2); 01560 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_3); 01561 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_1); 01562 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_2); 01563 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_3); 01564 KMO_TRY_CHECK_ERROR_STATE(); 01565 01566 // 01567 // adjust psf-headers: delete CRPIX3 etc. 01568 // 01569 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRPIX3); 01570 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRPIX3); 01571 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CDELT3); 01572 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRVAL3); 01573 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CTYPE3); 01574 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CUNIT3); 01575 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD1_3); 01576 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD2_3); 01577 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD3_1); 01578 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD3_2); 01579 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD3_3); 01580 KMO_TRY_CHECK_ERROR_STATE(); 01581 01582 KMO_TRY_EXIT_IF_ERROR( 01583 kmo_reconstruct_sci(ifu_nr, 01584 bounds[2*(ifu_nr-1)], 01585 bounds[2*(ifu_nr-1)+1], 01586 obj_frame, 01587 STD, 01588 sky_frame, 01589 STD, 01590 flat_frame, 01591 xcal_frame, 01592 ycal_frame, 01593 lcal_frame, 01594 NULL, 01595 NULL, 01596 &gd, 01597 &stored_data_cube[ifu_nr-1], 01598 &stored_noise_cube[ifu_nr-1], 01599 flux, 01600 background, 01601 xcal_interpolation)); 01602 01603 // divide illumination correction from the data_cube 01604 // (illumination noise will be very small versus 01605 // noise_cube, so it is skipped here) 01606 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 01607 KMO_TRY_EXIT_IF_NULL( 01608 illum_corr = kmo_dfs_load_image_frame(illum_frame, ifu_nr, 01609 FALSE, FALSE, NULL)); 01610 KMO_TRY_EXIT_IF_ERROR( 01611 cpl_imagelist_divide_image(stored_data_cube[ifu_nr-1], illum_corr)); 01612 cpl_image_delete(illum_corr); illum_corr = NULL; 01613 } 01614 01615 // calculate QC_STD_TRACE 01616 // (the distance of the PSF to the centre) 01617 KMO_TRY_EXIT_IF_ERROR( 01618 kmo_calculate_std_trace(stored_data_cube[ifu_nr-1], fmethod, &std_trace)); 01619 01620 KMO_TRY_EXIT_IF_ERROR( 01621 kmclipm_update_property_double(stored_sub_psf_headers[ifu_nr-1], 01622 QC_STD_TRACE, std_trace, 01623 "[pix] distance of PSF and centre of IFU")); 01624 01625 KMO_TRY_EXIT_IF_NULL( 01626 identified_slices = cpl_vector_new(cpl_imagelist_get_size(stored_data_cube[ifu_nr-1]))); 01627 KMO_TRY_EXIT_IF_ERROR( 01628 cpl_vector_fill(identified_slices, 1.0)); 01629 01630 // collapse cube and get PSF image 01631 KMO_TRY_EXIT_IF_ERROR( 01632 kmclipm_make_image(stored_data_cube[ifu_nr-1], NULL, 01633 &stored_psf_data[ifu_nr-1], NULL, 01634 identified_slices, 01635 cmethod, 01636 cpos_rej, cneg_rej, citer, 01637 cmax, cmin)); 01638 cpl_vector_delete(identified_slices); 01639 identified_slices= NULL; 01640 01641 // fit a 2D profile to get a mask and fwhm in x and y, 01642 KMO_TRY_EXIT_IF_NULL( 01643 tmp_vec = kmo_fit_profile_2D(stored_psf_data[ifu_nr-1], 01644 NULL, 01645 fmethod, 01646 &stored_mask[ifu_nr-1], 01647 &pl_psf)); 01648 01649 // normalise mask to 1 and clip values below 0.5 01650 cpl_image_divide_scalar(stored_mask[ifu_nr-1], cpl_image_get_max(stored_mask[ifu_nr-1])); 01651 KMO_TRY_CHECK_ERROR_STATE(); 01652 01653 int dummy=0; 01654 for (gx = 1; gx <= cpl_image_get_size_x(stored_mask[ifu_nr-1]); gx++) { 01655 for (gy = 1; gy <= cpl_image_get_size_y(stored_mask[ifu_nr-1]); gy++) { 01656 if (cpl_image_get(stored_mask[ifu_nr-1], gx, gy, &dummy) < 0.5) { 01657 cpl_image_set(stored_mask[ifu_nr-1], gx, gy, 0.); 01658 } else { 01659 cpl_image_set(stored_mask[ifu_nr-1], gx, gy, 1.); 01660 } 01661 } 01662 } 01663 KMO_TRY_CHECK_ERROR_STATE(); 01664 01665 // update subheader with fit parameters 01666 KMO_TRY_EXIT_IF_ERROR( 01667 cpl_propertylist_append(stored_sub_tel_data_headers[ifu_nr-1], pl_psf)); 01668 cpl_propertylist_delete(pl_psf); pl_psf = NULL; 01669 01670 // store QC_SPAT_RES (RMS of fwhm_x and fwhm_y) 01671 double factor_fwhm = 2*sqrt(2*log(2)); 01672 double spat_res = pow(cpl_vector_get(tmp_vec, 4) * factor_fwhm, 2); 01673 spat_res += pow(cpl_vector_get(tmp_vec, 5) * factor_fwhm, 2); 01674 spat_res /= 2; 01675 KMO_TRY_EXIT_IF_ERROR( 01676 kmclipm_update_property_double(stored_sub_psf_headers[ifu_nr-1], 01677 QC_SPAT_RES, 01678 sqrt(spat_res)*KMOS_PIX_RESOLUTION, 01679 "[arcsec] mean fwhm resolution of PSF")); 01680 cpl_vector_delete(tmp_vec); tmp_vec = NULL; 01681 01682 // extract spectrum in masked area and convert returned mean to sum 01683 // (times mask aperture) 01684 KMO_TRY_EXIT_IF_ERROR( 01685 kmo_priv_extract_spec(stored_data_cube[ifu_nr-1], 01686 stored_noise_cube[ifu_nr-1], 01687 stored_mask[ifu_nr-1], 01688 &tmp_spec_data, 01689 &tmp_spec_noise)); 01690 KMO_TRY_CHECK_ERROR_STATE(); 01691 01692 KMO_TRY_EXIT_IF_ERROR( 01693 cpl_vector_multiply_scalar(tmp_spec_data, cpl_image_get_flux(stored_mask[ifu_nr-1]))); 01694 if (tmp_spec_noise != NULL) { 01695 KMO_TRY_EXIT_IF_ERROR( 01696 cpl_vector_multiply_scalar(tmp_spec_noise, cpl_image_get_flux(stored_mask[ifu_nr-1]))); 01697 } 01698 KMO_TRY_CHECK_ERROR_STATE(); 01699 01700 // extract spectrum of whole area for QC THRUHPUT and QC ZEROPOINT and 01701 // convert returned mean to sum (times 196, IFU area) 01702 KMO_TRY_EXIT_IF_ERROR( 01703 kmo_priv_extract_spec(stored_data_cube[ifu_nr-1], 01704 stored_noise_cube[ifu_nr-1], 01705 NULL, 01706 &spec_qc, 01707 &tmp_vec)); 01708 01709 KMO_TRY_EXIT_IF_NULL( 01710 tmp_img = cpl_imagelist_get(stored_data_cube[ifu_nr-1], 0)); 01711 int tmpx = cpl_image_get_size_x(tmp_img), 01712 tmpy = cpl_image_get_size_x(tmp_img); 01713 KMO_TRY_EXIT_IF_ERROR( 01714 cpl_vector_multiply_scalar(spec_qc, tmpx*tmpy)); 01715 if (tmp_vec != NULL) { 01716 KMO_TRY_EXIT_IF_ERROR( 01717 cpl_vector_multiply_scalar(tmp_vec, tmpx*tmpy)); 01718 } 01719 01720 // calculate shot noise 01721 crpix1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX1); 01722 crval1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL1); 01723 cdelt1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT1); 01724 gain = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], GAIN); 01725 KMO_TRY_CHECK_ERROR_STATE(); 01726 01727 // shot_noise = sqrt(tmp_spec_data*gain)/gain 01728 // (set negative values and NaN's to zero before sqrt) 01729 KMO_TRY_EXIT_IF_NULL( 01730 shot_noise = cpl_vector_duplicate(tmp_spec_data)); 01731 KMO_TRY_EXIT_IF_ERROR( 01732 cpl_vector_multiply_scalar(shot_noise, gain)); 01733 01734 ppp = cpl_vector_get_data(shot_noise); 01735 for (ii = 0; ii < cpl_vector_get_size(shot_noise); ii++) { 01736 if ((ppp[ii] < 0.0) || kmclipm_is_nan_or_inf(ppp[ii])) { 01737 ppp[ii] = 0.0; 01738 } 01739 } 01740 KMO_TRY_EXIT_IF_ERROR( 01741 cpl_vector_sqrt(shot_noise)); 01742 KMO_TRY_EXIT_IF_ERROR( 01743 cpl_vector_divide_scalar(shot_noise, gain)); 01744 01745 // scale extracted spectrum to match the one calculated over the whole area 01746 // (this is done in a band-specific range!) 01747 KMO_TRY_EXIT_IF_ERROR( 01748 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 01749 filter_id, 01750 tmp_spec_data, 01751 tmp_spec_noise, 01752 &mean_data, 01753 NULL)); 01754 01755 KMO_TRY_EXIT_IF_ERROR( 01756 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 01757 filter_id, 01758 spec_qc, 01759 tmp_vec, 01760 &mean_data2, 01761 NULL)); 01762 01763 cpl_vector_delete(tmp_vec); tmp_vec = NULL; 01764 01765 flux_scale_factor = mean_data2/mean_data; 01766 KMO_TRY_EXIT_IF_ERROR( 01767 cpl_vector_multiply_scalar(shot_noise, flux_scale_factor)); 01768 KMO_TRY_EXIT_IF_ERROR( 01769 cpl_vector_multiply_scalar(tmp_spec_data, flux_scale_factor)); 01770 if ((tmp_spec_noise != NULL) && (fabs(mean_data) > 1e-8)) { 01771 KMO_TRY_EXIT_IF_ERROR( 01772 cpl_vector_multiply_scalar(tmp_spec_noise, flux_scale_factor)); 01773 } 01774 01775 // store to save to disk later on 01776 stored_starspec_data[ifu_nr-1] = cpl_vector_duplicate(tmp_spec_data); 01777 if (tmp_spec_noise != NULL) { 01778 stored_starspec_noise[ifu_nr-1] = cpl_vector_duplicate(tmp_spec_noise); 01779 } 01780 KMO_TRY_CHECK_ERROR_STATE(); 01781 01782 // 01783 // calculate noise spectra 01784 // 01785 if (!no_noise && (strcmp(tplid, "KMOS_spec_cal_stdstarscipatt") == 0)) { 01786 nr_sky_pairs = sky_sky_struct[ifu_nr-1].nrSkyPairs; 01787 if (nr_sky_pairs > 2) { 01788 cpl_msg_info("", " Calculating noise-spectra on sky exposures for IFU %d", ifu_nr); 01789 int ll = 0; 01790 double **pvec_array = NULL, 01791 *ptmp_vec = NULL, 01792 *pstored_noisespec = NULL; 01793 cpl_vector **vec_array = NULL; 01794 cpl_imagelist *tmp_cube = NULL; 01795 01796 KMO_TRY_EXIT_IF_NULL( 01797 vec_array = cpl_calloc(nr_sky_pairs, sizeof(cpl_vector*))); 01798 KMO_TRY_EXIT_IF_NULL( 01799 pvec_array = cpl_calloc(nr_sky_pairs, sizeof(double*))); 01800 // reconstruct all sky-Pairs, extract spectra using a mask and store temporarily 01801 for (ii = 0; ii < nr_sky_pairs; ii++) { 01802 // reconstruct (sky1-sky2)/flatfield 01803 KMO_TRY_EXIT_IF_ERROR( 01804 kmo_reconstruct_sci(ifu_nr, 01805 bounds[2*(ifu_nr-1)], 01806 bounds[2*(ifu_nr-1)+1], 01807 sky_sky_struct[ifu_nr-1].skyPairs[ii].skyFrame1, 01808 STD, 01809 sky_sky_struct[ifu_nr-1].skyPairs[ii].skyFrame2, 01810 STD, 01811 flat_frame, 01812 xcal_frame, 01813 ycal_frame, 01814 lcal_frame, 01815 NULL, 01816 NULL, 01817 &gd, 01818 &tmp_cube, 01819 NULL, 01820 FALSE, 01821 FALSE, 01822 xcal_interpolation)); 01823 01824 // extract spectrum in masked area and convert mean to sum 01825 // (times mask aperture) 01826 KMO_TRY_EXIT_IF_ERROR( 01827 kmo_priv_extract_spec(tmp_cube, 01828 NULL, 01829 stored_mask[ifu_nr-1], 01830 &(vec_array[ii]), 01831 NULL)); 01832 KMO_TRY_EXIT_IF_ERROR( 01833 cpl_vector_multiply_scalar(vec_array[ii], cpl_image_get_flux(stored_mask[ifu_nr-1]))); 01834 01835 // again: scale calculated noise spectrum to match the one calculated over the whole area 01836 // (this is done in a band-specific range!) 01837 KMO_TRY_EXIT_IF_ERROR( 01838 cpl_vector_multiply_scalar(vec_array[ii], flux_scale_factor)); 01839 01840 KMO_TRY_EXIT_IF_NULL( 01841 pvec_array[ii] = cpl_vector_get_data(vec_array[ii])); 01842 01843 cpl_imagelist_delete(tmp_cube); tmp_cube = NULL; 01844 } 01845 KMO_TRY_CHECK_ERROR_STATE(); 01846 01847 // now calculate stddev on every wavelength of all temporary 01848 // extracted spectra 01849 KMO_TRY_EXIT_IF_NULL( 01850 stored_noisespec[ifu_nr-1] = cpl_vector_new(gd.l.dim)); 01851 KMO_TRY_EXIT_IF_NULL( 01852 pstored_noisespec = cpl_vector_get_data(stored_noisespec[ifu_nr-1])); 01853 KMO_TRY_EXIT_IF_NULL( 01854 tmp_vec = cpl_vector_new(nr_sky_pairs)); 01855 KMO_TRY_EXIT_IF_NULL( 01856 ptmp_vec = cpl_vector_get_data(tmp_vec)); 01857 for (ll = 0; ll < gd.l.dim; ll++) { 01858 for (ii = 0; ii < nr_sky_pairs; ii++) { 01859 ptmp_vec[ii] = pvec_array[ii][ll]; 01860 } 01861 01862 pstored_noisespec[ll] = cpl_vector_get_stdev(tmp_vec); 01863 } 01864 KMO_TRY_CHECK_ERROR_STATE(); 01865 01866 // free temporary data 01867 for (ii = 0; ii < nr_sky_pairs; ii++) { 01868 cpl_vector_delete(vec_array[ii]); vec_array[ii] = NULL; 01869 } 01870 cpl_free(vec_array); vec_array = NULL; 01871 cpl_free(pvec_array); pvec_array = NULL; 01872 cpl_vector_delete(tmp_vec); tmp_vec = NULL; 01873 01874 // apply shot_noise (total noise = sqrt (shot_noise^2 + sky_noise^2) ) 01875 // and set negative values and NaN's to zero 01876 KMO_TRY_EXIT_IF_ERROR( 01877 cpl_vector_power(stored_noisespec[ifu_nr-1], 2.)); 01878 KMO_TRY_EXIT_IF_ERROR( 01879 cpl_vector_power(shot_noise, 2.)); 01880 KMO_TRY_EXIT_IF_ERROR( 01881 cpl_vector_add(stored_noisespec[ifu_nr-1], shot_noise)); 01882 ppp = cpl_vector_get_data(stored_noisespec[ifu_nr-1]); 01883 for (ii = 0; ii < cpl_vector_get_size(stored_noisespec[ifu_nr-1]); ii++) { 01884 if ((ppp[ii] < 0.0) || kmclipm_is_nan_or_inf(ppp[ii])) { 01885 ppp[ii] = 0.0; 01886 } 01887 } 01888 KMO_TRY_EXIT_IF_ERROR( 01889 cpl_vector_sqrt(stored_noisespec[ifu_nr-1])); 01890 cpl_vector_delete(shot_noise); shot_noise = NULL; 01891 } else { 01892 cpl_msg_warning("", " Not calculating noise-spectra because there are less than " 01893 "2 sky-sky pairs present (skies must be subsequent in time)!" 01894 " Just storing shot-noise."); 01895 stored_noisespec[ifu_nr-1] = shot_noise; 01896 } // end if (nr_sky_pairs > 0) 01897 } else { 01898 stored_noisespec[ifu_nr-1] = shot_noise; 01899 } // end if (!no_noise & ...) 01900 KMO_TRY_CHECK_ERROR_STATE(); 01901 01902 // 01903 // spectrum correction 01904 // 01905 01906 // calculate abscissa of output spectrum 01907 KMO_TRY_EXIT_IF_NULL( 01908 lambda_x = kmo_create_lambda_vec(gd.l.dim, 1, 01909 gd.l.start, 01910 gd.l.delta)); 01911 01912 if ((strcmp(star_type, "O") == 0) || 01913 (strcmp(star_type, "B") == 0) || 01914 (strcmp(star_type, "A") == 0) || 01915 (strcmp(star_type, "F") == 0)) 01916 { 01917 // we have a OBAF star 01918 01919 // if ATMOS_MODEL is present, lines will be removed 01920 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 01921 // interpolate ATMOS_MODEL to same scale as data 01922 KMO_TRY_EXIT_IF_NULL( 01923 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL)); 01924 01925 KMO_TRY_EXIT_IF_NULL( 01926 atmos_model = kmo_interpolate_vector_wcs(tmp_frame, lambda_x)); 01927 cpl_vector *tmp_spec_data_orig = NULL; 01928 int plot_it = 0; 01929 if (plot_it) { 01930 // store original spectrum 01931 KMO_TRY_EXIT_IF_NULL( 01932 tmp_spec_data_orig = cpl_vector_duplicate(tmp_spec_data)); 01933 } 01934 // remove band-specific lines 01935 if (strcmp(filter_id, "H") == 0) { 01936 for (l = 0; l < nr_lines_h; l++) { 01937 KMO_TRY_EXIT_IF_ERROR( 01938 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_h[l], lines_width_h[l])); 01939 } 01940 } else if (strcmp(filter_id, "HK") == 0) { 01941 for (l = 0; l < nr_lines_hk; l++) { 01942 KMO_TRY_EXIT_IF_ERROR( 01943 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_hk[l], lines_width_hk[l])); 01944 } 01945 } else if (strcmp(filter_id, "K") == 0) { 01946 for (l = 0; l < nr_lines_k; l++) { 01947 KMO_TRY_EXIT_IF_ERROR( 01948 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_k[l], lines_width_k[l])); 01949 } 01950 } else if (strcmp(filter_id, "IZ") == 0) { 01951 for (l = 0; l < nr_lines_iz; l++) { 01952 KMO_TRY_EXIT_IF_ERROR( 01953 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_iz[l], lines_width_iz[l])); 01954 } 01955 } else if (strcmp(filter_id, "YJ") == 0) { 01956 for (l = 0; l < nr_lines_yj; l++) { 01957 KMO_TRY_EXIT_IF_ERROR( 01958 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_yj[l], lines_width_yj[l])); 01959 } 01960 } 01961 if (plot_it) { 01962 cpl_vector *tmp_spec_data_atmo = NULL; 01963 cpl_vector *tmp_spec_data_new = NULL; 01964 KMO_TRY_EXIT_IF_NULL( 01965 tmp_spec_data_atmo = cpl_vector_duplicate(tmp_spec_data_orig)); 01966 KMO_TRY_EXIT_IF_NULL( 01967 tmp_spec_data_new = cpl_vector_duplicate(tmp_spec_data)); 01968 KMO_TRY_EXIT_IF_ERROR( 01969 cpl_vector_divide(tmp_spec_data_atmo, atmos_model)); 01970 01971 char *sss = cpl_sprintf("atmo_div_%s.fits", filter_id); 01972 if (i == 1) { 01973 cpl_vector_save(tmp_spec_data_atmo, sss, CPL_BPP_IEEE_DOUBLE, stored_sub_tel_data_headers[ifu_nr-1], CPL_IO_CREATE); 01974 } else { 01975 cpl_vector_save(tmp_spec_data_atmo, sss, CPL_BPP_IEEE_DOUBLE, stored_sub_tel_data_headers[ifu_nr-1], CPL_IO_EXTEND); 01976 } 01977 01978 cpl_vector *med_vec = cpl_vector_duplicate(tmp_spec_data_orig); 01979 double median = cpl_vector_get_median(med_vec); 01980 cpl_vector_delete(med_vec); 01981 int ii = 0; 01982 for (ii = 0; ii < cpl_vector_get_size(tmp_spec_data_orig); ii++) { 01983 if (cpl_vector_get(tmp_spec_data_orig, ii) < median/8) 01984 cpl_vector_set(tmp_spec_data_orig, ii, 0); 01985 if (cpl_vector_get(tmp_spec_data_atmo, ii) < median/8) 01986 cpl_vector_set(tmp_spec_data_atmo, ii, 0); 01987 if (cpl_vector_get(tmp_spec_data_new, ii) < median/8) 01988 cpl_vector_set(tmp_spec_data_new, ii, 0); 01989 01990 if (cpl_vector_get(tmp_spec_data_orig, ii) > 3*median) 01991 cpl_vector_set(tmp_spec_data_orig, ii, 3*median); 01992 if (cpl_vector_get(tmp_spec_data_atmo, ii) > 3*median) 01993 cpl_vector_set(tmp_spec_data_atmo, ii, 3*median); 01994 if (cpl_vector_get(tmp_spec_data_new, ii) > 3*median) 01995 cpl_vector_set(tmp_spec_data_new, ii, 3*median); 01996 } 01997 01998 double *pspec_dup = cpl_vector_get_data(tmp_spec_data_atmo); 01999 for (ii = 0; ii < cpl_vector_get_size(tmp_spec_data_atmo); ii++) { 02000 if (kmclipm_is_nan_or_inf(pspec_dup[ii])) { 02001 pspec_dup[ii] = 0.; 02002 } 02003 } 02004 02005 cpl_bivector *plots[3]; 02006 plots[0] = cpl_bivector_wrap_vectors((cpl_vector*)lambda_x, tmp_spec_data_orig); 02007 plots[1] = cpl_bivector_wrap_vectors((cpl_vector*)lambda_x, tmp_spec_data_atmo); 02008 plots[2] = cpl_bivector_wrap_vectors((cpl_vector*)lambda_x, tmp_spec_data_new); 02009 char *options[3] = {"w l t 'original'", 02010 "w l t 'atmo divided'", 02011 "w l t 'lines removed'"}; 02012 sss = cpl_sprintf("set title '%s-band line removal (DET #%d)';", filter_id, i); 02013 cpl_plot_bivectors(sss, 02014 (const char**)options, "", (const cpl_bivector**)plots, 3); 02015 // cpl_plot_bivectors("set title 'Spectrum with lines removed'; set xrange [2.14:2.19];", 02016 // (const char**)options, "", (const cpl_bivector**)plots, 2); 02017 cpl_bivector_unwrap_vectors(plots[0]); 02018 cpl_bivector_unwrap_vectors(plots[1]); 02019 cpl_bivector_unwrap_vectors(plots[2]); 02020 cpl_free(sss); sss = NULL; 02021 cpl_vector_delete(tmp_spec_data_orig); tmp_spec_data_orig = NULL; 02022 cpl_vector_delete(tmp_spec_data_atmo); tmp_spec_data_atmo = NULL; 02023 cpl_vector_delete(tmp_spec_data_new); tmp_spec_data_new = NULL; 02024 } 02025 cpl_vector_delete(atmos_model); atmos_model = NULL; 02026 } else { 02027 if (line_warning == FALSE) { 02028 cpl_msg_warning("", "No atmospheric model (ATMOS_MODEL) provided! " 02029 "Won't remove any lines."); 02030 line_warning = TRUE; 02031 } 02032 } 02033 } else if (strcmp(star_type, "G") == 0) { 02034 // we have a G star 02035 if (cpl_frameset_count_tags(frameset, SOLAR_SPEC) == 1) { 02036 // interpolate SOLAR_SPEC to same scale as data 02037 // and divide it 02038 KMO_TRY_EXIT_IF_NULL( 02039 tmp_frame = kmo_dfs_get_frame(frameset, SOLAR_SPEC)); 02040 02041 // check if SOLAR_SPEC is the filter_id-one 02042 KMO_TRY_EXIT_IF_NULL( 02043 tmp_sub_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 02044 KMO_TRY_EXIT_IF_NULL( 02045 tmp_str = cpl_propertylist_get_string(tmp_sub_header, FILT_ID)); 02046 KMO_TRY_ASSURE(strcmp(filter_id, tmp_str) == 0, 02047 CPL_ERROR_ILLEGAL_INPUT, 02048 "SOLAR_SPEC model must have primary " 02049 "keyword '%s' equal '%s'!!!", 02050 FILT_ID, filter_id); 02051 cpl_propertylist_delete(tmp_sub_header); tmp_sub_header = NULL; 02052 02053 KMO_TRY_EXIT_IF_NULL( 02054 solar_spec = kmo_interpolate_vector_wcs(tmp_frame, lambda_x)); 02055 02056 // values are set to zero if solar_spec isn't 02057 // overlapping wavelength range of star apectrum 02058 // completely 02059 KMO_TRY_EXIT_IF_ERROR( 02060 cpl_vector_divide(tmp_spec_data, solar_spec)); 02061 cpl_vector_delete(solar_spec); solar_spec = NULL; 02062 } else { 02063 if (print_warning_once == TRUE) { 02064 cpl_msg_warning("","No solar spectrum (SOLAR_SPEC) provided! " 02065 "Can't divide it from extracted " 02066 "standard star spectrum!"); 02067 print_warning_once = FALSE; 02068 } 02069 } 02070 } else { 02071 // cpl_msg_warning("","No startype was provided! Can't" 02072 // " divide solar spectrum for G stars " 02073 // "or fit a profile to atmospheric " 02074 // "transmission for OBAF stars."); 02075 } 02076 02077 if (star_temperature > 0.0) { 02078 // divide blackbody from tmp_spec_data 02079 KMO_TRY_EXIT_IF_ERROR( 02080 kmo_divide_blackbody(tmp_spec_data, lambda_x, star_temperature)); 02081 } 02082 02083 cpl_vector_delete(lambda_x); lambda_x = NULL; 02084 02085 // normalise telluric and its noise 02086 // mean is taken in lambda defined range 02087 KMO_TRY_EXIT_IF_ERROR( 02088 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 02089 filter_id, 02090 tmp_spec_data, 02091 tmp_spec_noise, 02092 &mean_data, 02093 NULL)); 02094 02095 KMO_TRY_EXIT_IF_ERROR( 02096 cpl_vector_divide_scalar(tmp_spec_data, mean_data)); 02097 02098 if (tmp_spec_noise != NULL) { 02099 // scale noise with the same factor as data 02100 KMO_TRY_EXIT_IF_ERROR( 02101 cpl_vector_divide_scalar(tmp_spec_noise, mean_data)); 02102 02103 // set noise spectrum also to zero when solar_spec is too short 02104 KMO_TRY_EXIT_IF_NULL( 02105 ptmp_spec_data = cpl_vector_get_data_const(tmp_spec_data)); 02106 KMO_TRY_EXIT_IF_NULL( 02107 ptmp_spec_noise = cpl_vector_get_data(tmp_spec_noise)); 02108 for (k = 0; k < cpl_vector_get_size(tmp_spec_data); k++) { 02109 if (ptmp_spec_data[k] == 0.0) { 02110 ptmp_spec_noise[k] = 0.0; 02111 } 02112 } 02113 } 02114 KMO_TRY_CHECK_ERROR_STATE(); 02115 02116 // store telluric & error spectrum 02117 stored_telluric_data[ifu_nr-1] = tmp_spec_data; 02118 stored_telluric_noise[ifu_nr-1] = tmp_spec_noise; 02119 02120 // if magnitude is provided 02121 // calculate zeropoint and throughput 02122 if (has_magnitude) { 02123 // calculate QC THROUGHPUT 02124 KMO_TRY_EXIT_IF_ERROR( 02125 kmo_calc_counts(spec_qc, filter_id, 02126 crpix1, crval1, cdelt1, 02127 &counts1, &counts2)); 02128 KMO_TRY_CHECK_ERROR_STATE(); 02129 02130 counts1 /= exptime; 02131 counts2 /= exptime; 02132 02133 stored_qc_throughput[ifu_nr-1] = kmo_calc_throughput(magnitude1, magnitude2, 02134 counts1, counts2, gain, filter_id); 02135 KMO_TRY_CHECK_ERROR_STATE(); 02136 02137 if (kmclipm_is_nan_or_inf(stored_qc_throughput[ifu_nr-1])) { 02138 stored_qc_throughput[ifu_nr-1] = -1; 02139 } 02140 KMO_TRY_EXIT_IF_ERROR( 02141 kmclipm_update_property_double(stored_sub_tel_data_headers[ifu_nr-1], 02142 QC_THROUGHPUT, 02143 stored_qc_throughput[ifu_nr-1], 02144 "[] IFU throughput")); 02145 02146 // calculate QC ZEROPOINT 02147 zeropoint = kmo_calc_zeropoint(magnitude1, magnitude2, counts1, counts2, cdelt3, filter_id); 02148 if (kmclipm_is_nan_or_inf(zeropoint)) { 02149 zeropoint = -1; 02150 } 02151 KMO_TRY_CHECK_ERROR_STATE(); 02152 02153 KMO_TRY_EXIT_IF_ERROR( 02154 kmclipm_update_property_double(stored_sub_tel_data_headers[ifu_nr-1], 02155 QC_ZEROPOINT, 02156 zeropoint, 02157 "[mag] IFU zeropoint")); 02158 } 02159 cpl_vector_delete(spec_qc); spec_qc = NULL; 02160 } else { 02161 cpl_error_reset(); 02162 // IFU is invalid 02163 KMO_TRY_EXIT_IF_NULL( 02164 stored_sub_tel_data_headers[ifu_nr-1] = 02165 cpl_propertylist_duplicate(sub_header_orig)); 02166 KMO_TRY_EXIT_IF_NULL( 02167 stored_sub_tel_noise_headers[ifu_nr-1] = 02168 cpl_propertylist_duplicate(sub_header_orig)); 02169 KMO_TRY_EXIT_IF_NULL( 02170 stored_sub_psf_headers[ifu_nr-1] = 02171 cpl_propertylist_duplicate(sub_header_orig)); 02172 if (save_cubes) { 02173 KMO_TRY_EXIT_IF_NULL( 02174 stored_sub_cube_data_headers[ifu_nr-1] = 02175 cpl_propertylist_duplicate(sub_header_orig)); 02176 KMO_TRY_EXIT_IF_NULL( 02177 stored_sub_cube_noise_headers[ifu_nr-1] = 02178 cpl_propertylist_duplicate(sub_header_orig)); 02179 } 02180 } 02181 02182 // create EXTNAME keyword as DATA 02183 KMO_TRY_EXIT_IF_NULL( 02184 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_DATA)); 02185 KMO_TRY_EXIT_IF_ERROR( 02186 kmclipm_update_property_string(stored_sub_tel_data_headers[ifu_nr-1], 02187 EXTNAME, extname, "FITS extension name")); 02188 KMO_TRY_EXIT_IF_ERROR( 02189 kmclipm_update_property_string(stored_sub_psf_headers[ifu_nr-1], 02190 EXTNAME, extname, "FITS extension name")); 02191 if (save_cubes) { 02192 KMO_TRY_EXIT_IF_ERROR( 02193 kmclipm_update_property_string(stored_sub_cube_data_headers[ifu_nr-1], 02194 EXTNAME, extname, "FITS extension name")); 02195 } 02196 cpl_free(extname); extname = NULL; 02197 02198 // create EXTNAME keyword as NOISE 02199 if (stored_sub_tel_noise_headers[ifu_nr-1] == NULL) { 02200 KMO_TRY_EXIT_IF_NULL( 02201 stored_sub_tel_noise_headers[ifu_nr-1] = 02202 cpl_propertylist_duplicate( 02203 stored_sub_tel_data_headers[ifu_nr-1])); 02204 } 02205 KMO_TRY_EXIT_IF_NULL( 02206 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE)); 02207 KMO_TRY_EXIT_IF_ERROR( 02208 kmclipm_update_property_string(stored_sub_tel_noise_headers[ifu_nr-1], 02209 EXTNAME, extname, "FITS extension name")); 02210 if (save_cubes) { 02211 if (stored_sub_cube_noise_headers[ifu_nr-1] == NULL) { 02212 KMO_TRY_EXIT_IF_NULL( 02213 stored_sub_cube_noise_headers[ifu_nr-1] = 02214 cpl_propertylist_duplicate( 02215 stored_sub_cube_data_headers[ifu_nr-1])); 02216 } 02217 02218 KMO_TRY_EXIT_IF_ERROR( 02219 kmclipm_update_property_string(stored_sub_cube_noise_headers[ifu_nr-1], 02220 EXTNAME, extname, "FITS extension name")); 02221 } 02222 cpl_free(extname); extname = NULL; 02223 } // for j ifus (load, process & store) 02224 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 02225 } // for i detectors (load, process & store) 02226 KMO_TRY_CHECK_ERROR_STATE(); 02227 02228 // write QC parameter: nr of std stars 02229 KMO_TRY_EXIT_IF_ERROR( 02230 kmclipm_update_property_int(main_header_tel, QC_NR_STD_STARS, 02231 nr_std_stars, "[] Nr. of std stars")); 02232 02233 // update which IFUs are not used 02234 kmo_print_unused_ifus(unused_ifus_after, TRUE); 02235 02236 KMO_TRY_EXIT_IF_ERROR( 02237 kmo_set_unused_ifus(unused_ifus_after, main_header_tel, "kmo_std_star")); 02238 02239 KMO_TRY_EXIT_IF_NULL( 02240 main_header_psf = cpl_propertylist_duplicate(main_header_tel)); 02241 02242 if (has_magnitude) { 02243 // calculate QC THROUGHPUT MEAN and QC THROUGHPUT SDV 02244 // and update main header 02245 KMO_TRY_EXIT_IF_ERROR( 02246 kmo_calc_mean_throughput(stored_qc_throughput, 02247 nr_devices * KMOS_IFUS_PER_DETECTOR, 02248 &throughput_mean, 02249 &throughput_sdv)); 02250 KMO_TRY_EXIT_IF_ERROR( 02251 kmclipm_update_property_double(main_header_tel, QC_THROUGHPUT_MEAN, 02252 throughput_mean, "[] mean throughput for all detectors")); 02253 KMO_TRY_EXIT_IF_ERROR( 02254 kmclipm_update_property_double(main_header_tel, QC_THROUGHPUT_SDV, 02255 throughput_sdv, "[] stdev throughput for all detectors")); 02256 } 02257 KMO_TRY_CHECK_ERROR_STATE(); 02258 02259 // 02260 // save output data 02261 // 02262 if (!suppress_extension) { 02263 KMO_TRY_EXIT_IF_NULL( 02264 fn_suffix = cpl_sprintf("%s", suffix)); 02265 } else { 02266 KMO_TRY_EXIT_IF_NULL( 02267 fn_suffix = cpl_sprintf("%s", "")); 02268 } 02269 02270 // save primary extension 02271 KMO_TRY_EXIT_IF_ERROR( 02272 kmo_dfs_save_main_header(frameset, filename_telluric, fn_suffix, 02273 obj_frame, main_header_tel, parlist, 02274 cpl_func)); 02275 KMO_TRY_EXIT_IF_ERROR( 02276 kmo_dfs_save_main_header(frameset, filename_starspec, fn_suffix, 02277 obj_frame, main_header_tel, parlist, 02278 cpl_func)); 02279 KMO_TRY_EXIT_IF_ERROR( 02280 kmo_dfs_save_main_header(frameset, filename_mask, fn_suffix, 02281 obj_frame, main_header_psf, parlist, 02282 cpl_func)); 02283 KMO_TRY_EXIT_IF_ERROR( 02284 kmo_dfs_save_main_header(frameset, filename_psf, fn_suffix, 02285 obj_frame, main_header_psf, parlist, 02286 cpl_func)); 02287 if (!no_noise && (strcmp(tplid, "KMOS_spec_cal_stdstarscipatt") == 0)) { 02288 KMO_TRY_EXIT_IF_ERROR( 02289 kmo_dfs_save_main_header(frameset, filename_noise, fn_suffix, 02290 obj_frame, main_header_tel, parlist, 02291 cpl_func)); 02292 } 02293 if (save_cubes) { 02294 KMO_TRY_EXIT_IF_ERROR( 02295 kmo_dfs_save_main_header(frameset, filename_cubes, fn_suffix, 02296 obj_frame, main_header_psf, parlist, 02297 cpl_func)); 02298 } 02299 02300 // save stored frames 02301 for (i = 1; i <= nr_devices; i++) { 02302 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 02303 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 02304 02305 // save telluric-vector 02306 kmclipm_vector *ddd = NULL; 02307 if (stored_telluric_data[ifu_nr-1] != NULL) 02308 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_telluric_data[ifu_nr-1])); 02309 KMO_TRY_EXIT_IF_ERROR( 02310 kmo_dfs_save_vector(ddd, filename_telluric, fn_suffix, 02311 stored_sub_tel_data_headers[ifu_nr-1], 02312 0./0.)); 02313 kmclipm_vector_delete(ddd); ddd = NULL; 02314 02315 if (stored_telluric_noise[ifu_nr-1] != NULL) 02316 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_telluric_noise[ifu_nr-1])); 02317 KMO_TRY_EXIT_IF_ERROR( 02318 kmo_dfs_save_vector(ddd, filename_telluric, fn_suffix, 02319 stored_sub_tel_noise_headers[ifu_nr-1], 02320 0./0.)); 02321 kmclipm_vector_delete(ddd); ddd = NULL; 02322 02323 // save star_spec-vector 02324 if (stored_starspec_data[ifu_nr-1] != NULL) 02325 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_starspec_data[ifu_nr-1])); 02326 KMO_TRY_EXIT_IF_ERROR( 02327 kmo_dfs_save_vector(ddd, filename_starspec, fn_suffix, 02328 stored_sub_tel_data_headers[ifu_nr-1], 02329 0./0.)); 02330 kmclipm_vector_delete(ddd); ddd = NULL; 02331 02332 if (stored_starspec_noise[ifu_nr-1] != NULL) 02333 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_starspec_noise[ifu_nr-1])); 02334 KMO_TRY_EXIT_IF_ERROR( 02335 kmo_dfs_save_vector(ddd, filename_starspec, fn_suffix, 02336 stored_sub_tel_noise_headers[ifu_nr-1], 02337 0./0.)); 02338 kmclipm_vector_delete(ddd); ddd = NULL; 02339 02340 // save psf-image 02341 KMO_TRY_EXIT_IF_ERROR( 02342 kmo_dfs_save_image(stored_psf_data[ifu_nr-1], 02343 filename_psf, fn_suffix, 02344 stored_sub_psf_headers[ifu_nr-1], 02345 0./0.)); 02346 02347 // save mask-image 02348 KMO_TRY_EXIT_IF_ERROR( 02349 kmo_dfs_save_image(stored_mask[ifu_nr-1], 02350 filename_mask, fn_suffix, 02351 stored_sub_psf_headers[ifu_nr-1], 02352 0./0.)); 02353 02354 // save noise_spec-vector 02355 if (!no_noise && 02356 (strcmp(tplid, "KMOS_spec_cal_stdstarscipatt") == 0) && 02357 (stored_noisespec != NULL) && 02358 (stored_noisespec[ifu_nr-1] != NULL) && 02359 (stored_starspec_data[ifu_nr-1] != NULL)) 02360 { 02361 // calculate QC SNR 02362 KMO_TRY_EXIT_IF_ERROR( 02363 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 02364 filter_id, 02365 stored_starspec_data[ifu_nr-1], NULL, 02366 &tmp_data, NULL)); 02367 KMO_TRY_EXIT_IF_ERROR( 02368 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 02369 filter_id, 02370 stored_noisespec[ifu_nr-1], NULL, 02371 &tmp_noise, NULL)); 02372 KMO_TRY_EXIT_IF_ERROR( 02373 kmclipm_update_property_double(stored_sub_tel_data_headers[ifu_nr-1], QC_SNR, 02374 tmp_data/tmp_noise, "[] SNR")); 02375 } 02376 02377 if (!no_noise && (strcmp(tplid, "KMOS_spec_cal_stdstarscipatt") == 0)) { 02378 if ((stored_noisespec != NULL) && (stored_noisespec[ifu_nr-1] != NULL)) 02379 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_noisespec[ifu_nr-1])); 02380 KMO_TRY_EXIT_IF_ERROR( 02381 kmo_dfs_save_vector(ddd, filename_noise, fn_suffix, 02382 stored_sub_tel_data_headers[ifu_nr-1], 02383 0./0.)); 02384 kmclipm_vector_delete(ddd); ddd = NULL; 02385 } 02386 02387 // save reonstructed cubes 02388 if (save_cubes) { 02389 KMO_TRY_EXIT_IF_ERROR( 02390 kmo_dfs_save_cube(stored_data_cube[ifu_nr-1], 02391 filename_cubes, fn_suffix, 02392 stored_sub_cube_data_headers[ifu_nr-1], 02393 0./0.)); 02394 KMO_TRY_EXIT_IF_ERROR( 02395 kmo_dfs_save_cube(stored_noise_cube[ifu_nr-1], 02396 filename_cubes, fn_suffix, 02397 stored_sub_cube_noise_headers[ifu_nr-1], 02398 0./0.)); 02399 } 02400 } // for j ifus (save stored) 02401 } // for i detectors (save stored) 02402 KMO_TRY_CHECK_ERROR_STATE(); 02403 } // if (frameCnt == 0) 02404 } 02405 KMO_CATCH 02406 { 02407 KMO_CATCH_MSG(); 02408 ret_val = -1; 02409 } 02410 02411 kmo_delete_objSkyStruct(obj_sky_struct); 02412 kmo_free_fits_desc(&desc1); 02413 kmo_free_fits_desc(&desc2); 02414 kmo_free_unused_ifus(unused_ifus_before); unused_ifus_before = NULL; 02415 kmo_free_unused_ifus(unused_ifus_after); unused_ifus_after = NULL; 02416 cpl_free(bounds); bounds = NULL; 02417 cpl_propertylist_delete(main_header_tel); main_header_tel = NULL; 02418 cpl_propertylist_delete(main_header_psf); main_header_psf = NULL; 02419 cpl_vector_delete(atmos_model); atmos_model = NULL; 02420 cpl_vector_delete(solar_spec); solar_spec = NULL; 02421 cpl_table_delete(spec_type_LUT); spec_type_LUT = NULL; 02422 cpl_vector_delete(identified_slices); identified_slices = NULL; 02423 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 02424 for (i = 0; i < nr_devices * KMOS_IFUS_PER_DETECTOR; i++) { 02425 cpl_vector_delete(stored_telluric_data[i]); stored_telluric_data[i] = NULL; 02426 cpl_vector_delete(stored_telluric_noise[i]); stored_telluric_noise[i] = NULL; 02427 cpl_vector_delete(stored_starspec_data[i]); stored_starspec_data[i] = NULL; 02428 cpl_vector_delete(stored_starspec_noise[i]); stored_starspec_noise[i] = NULL; 02429 cpl_image_delete(stored_psf_data[i]); stored_psf_data[i] = NULL; 02430 if ((stored_noisespec != NULL) && (stored_noisespec[i] != NULL)) { 02431 cpl_vector_delete(stored_noisespec[i]); stored_noisespec[i] = NULL; 02432 } 02433 cpl_propertylist_delete(stored_sub_tel_data_headers[i]); stored_sub_tel_data_headers[i] = NULL; 02434 cpl_propertylist_delete(stored_sub_tel_noise_headers[i]); stored_sub_tel_noise_headers[i] = NULL; 02435 if (save_cubes) { 02436 cpl_propertylist_delete(stored_sub_cube_data_headers[i]); stored_sub_cube_data_headers[i] = NULL; 02437 cpl_propertylist_delete(stored_sub_cube_noise_headers[i]); stored_sub_cube_noise_headers[i] = NULL; 02438 } 02439 cpl_propertylist_delete(stored_sub_psf_headers[i]); stored_sub_psf_headers[i] = NULL; 02440 cpl_image_delete(stored_mask[i]); stored_mask[i] = NULL; 02441 cpl_imagelist_delete(stored_data_cube[i]); stored_data_cube[i] = NULL; 02442 cpl_imagelist_delete(stored_noise_cube[i]); stored_noise_cube[i] = NULL; 02443 } 02444 cpl_free(stored_telluric_data); stored_telluric_data = NULL; 02445 cpl_free(stored_telluric_noise); stored_telluric_noise = NULL; 02446 cpl_free(stored_starspec_data); stored_starspec_data = NULL; 02447 if (stored_noisespec != NULL) { 02448 cpl_free(stored_noisespec); stored_noisespec = NULL; 02449 } 02450 kmo_delete_skySkyStruct(sky_sky_struct); sky_sky_struct = NULL; 02451 cpl_free(stored_starspec_noise); stored_starspec_noise = NULL; 02452 cpl_free(stored_psf_data); stored_psf_data = NULL; 02453 cpl_free(stored_sub_tel_data_headers); stored_sub_tel_data_headers = NULL; 02454 cpl_free(stored_sub_tel_noise_headers); stored_sub_tel_noise_headers = NULL; 02455 if (save_cubes) { 02456 cpl_free(stored_sub_cube_data_headers); stored_sub_cube_data_headers = NULL; 02457 cpl_free(stored_sub_cube_noise_headers); stored_sub_cube_noise_headers = NULL; 02458 } 02459 cpl_free(stored_sub_psf_headers); stored_sub_psf_headers = NULL; 02460 cpl_free(stored_qc_throughput); stored_qc_throughput = NULL; 02461 cpl_free(suffix); suffix = NULL; 02462 cpl_free(fn_suffix); fn_suffix = NULL; 02463 cpl_free(stored_mask); stored_mask = NULL; 02464 cpl_free(stored_data_cube); stored_data_cube = NULL; 02465 cpl_free(stored_noise_cube); stored_noise_cube = NULL; 02466 cpl_free(grat_id); grat_id = NULL; 02467 cpl_frameset_delete(frameset_std); frameset_std = NULL; 02468 cpl_free(extname); extname = NULL; 02469 cpl_free(tplid); tplid = NULL; 02470 02471 return ret_val; 02472 } 02473