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