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