|
KMOS Pipeline Reference Manual
1.2.3
|
00001 /* $Id: kmo_std_star.c,v 1.75 2013/08/02 18:03:53 aagudo 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: aagudo $ 00023 * $Date: 2013/08/02 18:03:53 $ 00024 * $Revision: 1.75 $ 00025 * $Name: HEAD $ 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 "BASIC PARAMETERS:\n" 00293 "-----------------\n" 00294 "--startype\n" 00295 "If this parameter is specified, the stored star types of the observed obejcts \n" 00296 "in the FITS headers are overridden. This value applies to all objects exa-\n" 00297 "mined in the input frames. Examples would be “A3I”, “G3IV” or “K0I”. The first\n" 00298 "letter defines the star type, the second letter the spectral class and the last\n" 00299 "letters the luminosity class.\n" 00300 "\n" 00301 "--magnitude\n" 00302 "If this parameter is specified, the stored magnitudes in the FITS headers are \n" 00303 "overridden. For HK two magnitudes for each H and K have to be specified. All \n" 00304 "other gratings just use a single magnitude. If two values are provided, they \n" 00305 "have to be separated with a comma. \n" 00306 "\n" 00307 "--fmethod\n" 00308 "The type of function that should be fitted spatially to the collapsed image.\n" 00309 "This fit is used to create a mask to extract the spectrum of the object. Valid\n" 00310 "values are “gauss” and “moffat”.\n" 00311 "\n" 00312 "--imethod\n" 00313 "The interpolation method used for reconstruction. As default 'CS' is selected.\n" 00314 "Note that no error spectra will be generated for this interpolation method.\n" 00315 "Select a nearest neighbour method otherwise\n" 00316 "\n" 00317 "--range\n" 00318 "The spectral range [um] to combine when collapsing the reconstructed cubes.\n" 00319 "\n" 00320 "--save_cubes\n" 00321 "Set to TRUE if the intermediate reconstructed cubes (eventually divided by " 00322 "illumination correction) should be saved as well. Default is FALSE.\n" 00323 "\n" 00324 "ADVANCED PARAMETERS\n" 00325 "-------------------\n" 00326 "--flux\n" 00327 "Specify if flux conservation should be applied.\n" 00328 "\n" 00329 "--neighborhoodRange\n" 00330 "Defines the range to search for neighbors during reconstruction\n" 00331 "\n" 00332 "--b_samples\n" 00333 "The number of samples in spectral direction for the reconstructed cube.\n" 00334 "Ideally this number should be greater than 2048, the detector size.\n" 00335 "\n" 00336 "--b_start\n" 00337 "--b_end\n" 00338 "Used to define manually the start and end wavelength for the reconstructed\n" 00339 "cube. By default the internally defined values are used.\n" 00340 "\n" 00341 "--cmethod\n" 00342 "Following methods of frame combination are available:\n" 00343 " * 'ksigma' (Default)\n" 00344 " An iterative sigma clipping. For each position all pixels in the spectrum\n" 00345 " are examined. If they deviate significantly, they will be rejected according\n" 00346 " to the conditions:\n" 00347 " val > mean + stdev * cpos_rej\n" 00348 " and\n" 00349 " val < mean - stdev * cneg_rej\n" 00350 " where --cpos_rej, --cneg_rej and --citer are the corresponding configuration\n" 00351 " parameters. In the first iteration median and percentile level are used.\n" 00352 "\n" 00353 " * 'median'\n" 00354 " At each pixel position the median is calculated.\n" 00355 "\n" 00356 " * 'average'\n" 00357 " At each pixel position the average is calculated.\n" 00358 "\n" 00359 " * 'sum'\n" 00360 " At each pixel position the sum is calculated.\n" 00361 "\n" 00362 " * 'min_max'\n" 00363 " The specified number of minimum and maximum pixel values will be rejected.\n" 00364 " --cmax and --cmin apply to this method.\n" 00365 "\n" 00366 "--cpos_rej\n" 00367 "--cneg_rej\n" 00368 "--citer\n" 00369 "see --cmethod='ksigma'\n" 00370 "\n" 00371 "--cmax\n" 00372 "--cmin\n" 00373 "see --cmethod='min_max'\n" 00374 "\n" 00375 "--xcal_interpolation\n" 00376 "If true interpolate the pixel position in the slitlet (xcal) using the two\n" 00377 "closest rotator angles in the calibration file. Otherwise take the values\n" 00378 "of the closest rotator angle\n" 00379 "\n" 00380 "--suppress_extension\n" 00381 "If set to TRUE, the arbitrary filename extensions are supressed. If multiple\n" 00382 "products with the same category are produced, they will be numered consecutively\n" 00383 "starting from 0.\n" 00384 "\n" 00385 "-------------------------------------------------------------------------------\n" 00386 " Input files:\n" 00387 "\n" 00388 " DO KMOS \n" 00389 " category Type Explanation Required #Frames\n" 00390 " -------- ----- ----------- -------- -------\n" 00391 " STD RAW Std. star & sky exposures Y >=1 \n" 00392 " XCAL F2D x calibration frame Y 1 \n" 00393 " YCAL F2D y calibration frame Y 1 \n" 00394 " LCAL F2D Wavelength calib. frame Y 1 \n" 00395 " MASTER_FLAT F2D Master flat frame Y 1 \n" 00396 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00397 " ILLUM_CORR F2I Illumination correction N 0,1 \n" 00398 " SOLAR_SPEC F1S Solar spectrum N 0,1 \n" 00399 " (only for G stars) \n" 00400 " ATMOS_MODEL F1S Model atmospheric transmisson N 0,1 \n" 00401 " (only for OBAF stars in K band) \n" 00402 " SPEC_TYPE_LOOKUP F2L LUT eff. stellar temperature N 0,1 \n" 00403 "\n" 00404 " Output files:\n" 00405 "\n" 00406 " DO KMOS\n" 00407 " category Type Explanation\n" 00408 " -------- ----- -----------\n" 00409 " TELLURIC F1I The normalised telluric spectrum \n" 00410 " (including errors) \n" 00411 " STAR_SPEC F1I The extracted star spectrum \n" 00412 " (including errors) \n" 00413 " STD_IMAGE F2I The standard star PSF images \n" 00414 " STD_MASK F2I The generated mask used to extract the star \n" 00415 " spectrum \n" 00416 "-------------------------------------------------------------------------------\n" 00417 "\n"; 00418 00419 /*----------------------------------------------------------------------------- 00420 * Functions code 00421 *----------------------------------------------------------------------------*/ 00422 00439 int cpl_plugin_get_info(cpl_pluginlist *list) 00440 { 00441 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00442 cpl_plugin *plugin = &recipe->interface; 00443 00444 cpl_plugin_init(plugin, 00445 CPL_PLUGIN_API, 00446 KMOS_BINARY_VERSION, 00447 CPL_PLUGIN_TYPE_RECIPE, 00448 "kmo_std_star", 00449 "Create the telluric correction frame.", 00450 kmo_std_star_description, 00451 "Alex Agudo Berbel", 00452 "kmos-spark@mpe.mpg.de", 00453 kmos_get_license(), 00454 kmo_std_star_create, 00455 kmo_std_star_exec, 00456 kmo_std_star_destroy); 00457 00458 cpl_pluginlist_append(list, plugin); 00459 00460 return 0; 00461 } 00462 00470 static int kmo_std_star_create(cpl_plugin *plugin) 00471 { 00472 cpl_recipe *recipe; 00473 cpl_parameter *p; 00474 00475 /* Check that the plugin is part of a valid recipe */ 00476 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00477 recipe = (cpl_recipe *)plugin; 00478 else 00479 return -1; 00480 00481 /* Create the parameters list in the cpl_recipe object */ 00482 recipe->parameters = cpl_parameterlist_new(); 00483 00484 /* --startype */ 00485 p = cpl_parameter_new_value("kmos.kmo_std_star.startype", 00486 CPL_TYPE_STRING, 00487 "The spectral type of the star (O, B, A, F, G)" 00488 " Format: G4V etc.", 00489 "kmos.kmo_std_star", 00490 ""); 00491 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startype"); 00492 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00493 cpl_parameterlist_append(recipe->parameters, p); 00494 00495 /* --imethod */ 00496 p = cpl_parameter_new_value("kmos.kmo_std_star.imethod", 00497 CPL_TYPE_STRING, 00498 "Method to use for interpolation. " 00499 "[\"NN\" (nearest neighbour), " 00500 "\"lwNN\" (linear weighted nearest neighbor), " 00501 "\"swNN\" (square weighted nearest neighbor), " 00502 "\"MS\" (Modified Shepard's method), " 00503 "\"CS\" (Cubic spline)]", 00504 "kmos.kmo_std_star", 00505 "CS"); 00506 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00507 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00508 cpl_parameterlist_append(recipe->parameters, p); 00509 00510 /* --fmethod */ 00511 p = cpl_parameter_new_value("kmos.kmo_std_star.fmethod", 00512 CPL_TYPE_STRING, 00513 "Either fit a 'gauss' or 'moffat' profile.", 00514 "kmos.kmo_std_star", 00515 "gauss"); 00516 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00517 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00518 cpl_parameterlist_append(recipe->parameters, p); 00519 00520 /* --neighborhoodRange */ 00521 p = cpl_parameter_new_value("kmos.kmo_std_star.neighborhoodRange", 00522 CPL_TYPE_DOUBLE, 00523 "Defines the range to search for neighbors " 00524 "in pixels", 00525 "kmos.kmo_std_star", 00526 1.001); 00527 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00528 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00529 cpl_parameterlist_append(recipe->parameters, p); 00530 00531 /* --magnitude */ 00532 p = cpl_parameter_new_value("kmos.kmo_std_star.magnitude", 00533 CPL_TYPE_STRING, 00534 "The magnitude of the std star. For HK two " 00535 "values have to provided (eg. 12.1,13.2)", 00536 "kmos.kmo_std_star", 00537 ""); 00538 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "magnitude"); 00539 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00540 cpl_parameterlist_append(recipe->parameters, p); 00541 00542 /* --flux */ 00543 p = cpl_parameter_new_value("kmos.kmo_std_star.flux", 00544 CPL_TYPE_BOOL, 00545 "TRUE: Apply flux conservation. FALSE: otherwise", 00546 "kmos.kmo_std_star", 00547 TRUE); 00548 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00549 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00550 cpl_parameterlist_append(recipe->parameters, p); 00551 00552 /* --save_cubes */ 00553 p = cpl_parameter_new_value("kmos.kmo_std_star.save_cubes", 00554 CPL_TYPE_BOOL, 00555 "TRUE: Save reconstructed cubes, FALSE: otherwise", 00556 "kmos.kmo_std_star", 00557 FALSE); 00558 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save_cubes"); 00559 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00560 cpl_parameterlist_append(recipe->parameters, p); 00561 00562 /* --xcal_interpolation */ 00563 p = cpl_parameter_new_value("kmos.kmo_std_star.xcal_interpolation", 00564 CPL_TYPE_BOOL, 00565 "TRUE: Interpolate xcal between rotator angles. FALSE: otherwise", 00566 "kmos.kmo_std_star", 00567 TRUE); 00568 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcal_interpolation"); 00569 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00570 cpl_parameterlist_append(recipe->parameters, p); 00571 00572 /* --suppress_extension */ 00573 p = cpl_parameter_new_value("kmos.kmo_std_star.suppress_extension", 00574 CPL_TYPE_BOOL, 00575 "Suppress arbitrary filename extension." 00576 "(TRUE (apply) or FALSE (don't apply)", 00577 "kmos.kmo_std_star", 00578 FALSE); 00579 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00580 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00581 cpl_parameterlist_append(recipe->parameters, p); 00582 00583 // add parameters for band-definition 00584 kmo_band_pars_create(recipe->parameters, 00585 "kmos.kmo_std_star"); 00586 00587 // add parameters for combining 00588 return kmo_combine_pars_create(recipe->parameters, 00589 "kmos.kmo_std_star", 00590 DEF_REJ_METHOD, 00591 FALSE); 00592 } 00593 00599 static int kmo_std_star_exec(cpl_plugin *plugin) 00600 { 00601 cpl_recipe *recipe; 00602 00603 /* Get the recipe out of the plugin */ 00604 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00605 recipe = (cpl_recipe *)plugin; 00606 else return -1; 00607 00608 return kmo_std_star(recipe->parameters, recipe->frames); 00609 } 00610 00616 static int kmo_std_star_destroy(cpl_plugin *plugin) 00617 { 00618 cpl_recipe *recipe; 00619 00620 /* Get the recipe out of the plugin */ 00621 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00622 recipe = (cpl_recipe *)plugin; 00623 else return -1 ; 00624 00625 cpl_parameterlist_delete(recipe->parameters); 00626 return 0 ; 00627 } 00628 00643 static int kmo_std_star(cpl_parameterlist *parlist, cpl_frameset *frameset) 00644 { 00645 cpl_imagelist **stored_data_cube = NULL, 00646 **stored_noise_cube = NULL; 00647 cpl_image **stored_psf_data = NULL, 00648 *illum_corr = NULL, 00649 **stored_mask = NULL, 00650 *lcal = NULL; 00651 cpl_frame *xcal_frame = NULL, 00652 *ycal_frame = NULL, 00653 *lcal_frame = NULL, 00654 *flat_frame = NULL, 00655 *illum_frame = NULL, 00656 *obj_frame = NULL, 00657 *sky_frame = NULL, 00658 *tmp_frame = NULL; 00659 cpl_vector *solar_spec = NULL, 00660 *atmos_model = NULL, 00661 **stored_telluric_data = NULL, 00662 **stored_telluric_noise = NULL, 00663 **stored_starspec_data = NULL, 00664 **stored_starspec_noise = NULL, 00665 *tmp_spec_data = NULL, 00666 *spec_qc = NULL, 00667 *tmp_spec_noise = NULL, 00668 *identified_slices = NULL, 00669 *tmp_vec = NULL, 00670 *lambda_x = NULL; 00671 int ret_val = 0, 00672 nr_devices = 0, 00673 nr_exp = 0, 00674 j = 0, 00675 *bounds = NULL, 00676 ifu_nr = 0, 00677 citer = 0, 00678 cmax = 0, 00679 cmin = 0, 00680 line_warning = FALSE, 00681 nr_std_stars = 0, 00682 print_warning_once = TRUE, 00683 flux = FALSE, 00684 background = FALSE, 00685 band_method = 0, 00686 save_cubes = FALSE, 00687 has_magnitude = TRUE, 00688 xcal_interpolation = FALSE, 00689 suppress_extension = FALSE, 00690 nr_split_mag = 0, 00691 i = 0, 00692 l = 0, 00693 gx = 0, 00694 gy = 0, 00695 k = 0; 00696 const int *punused_ifus = NULL; 00697 objSkyStruct *obj_sky_struct = NULL; 00698 double *stored_qc_throughput = NULL, 00699 star_temperature = 0.0, 00700 neighborhoodRange = 1.001, 00701 cpos_rej = 0.0, 00702 cneg_rej = 0.0, 00703 zeropoint = -1.0, 00704 throughput_mean = -1.0, 00705 throughput_sdv = -1.0, 00706 std_trace = -1.0, 00707 counts1 = 0.0, 00708 counts2 = 0.0, 00709 magnitude1 = 0.0, 00710 magnitude2 = 0.0, 00711 exptime = 0., 00712 cdelt3 = 0., 00713 mean_data = 0., 00714 mean_noise = 0., 00715 *ptmp_spec_noise = NULL, 00716 crpix1 = 0., 00717 crval1 = 0., 00718 cdelt1 = 0.; 00719 const double *ptmp_spec_data = NULL; 00720 cpl_propertylist *main_header_tel = NULL, 00721 *main_header_psf = NULL, 00722 *sub_header_orig = NULL, 00723 *tmp_sub_header = NULL, 00724 *tmp_header = NULL, 00725 **stored_sub_tel_data_headers = NULL, 00726 **stored_sub_tel_noise_headers = NULL, 00727 **stored_sub_cube_data_headers = NULL, 00728 **stored_sub_cube_noise_headers = NULL, 00729 **stored_sub_psf_headers = NULL, 00730 *pl_psf = NULL; 00731 cpl_table *spec_type_LUT = NULL, 00732 *band_table = NULL;; 00733 main_fits_desc desc1, 00734 desc2; 00735 char *extname = NULL, 00736 *keyword = NULL, 00737 filename_telluric[256], 00738 filename_starspec[256], 00739 filename_psf[256], 00740 filename_mask[256], 00741 filename_cubes[256], 00742 *suffix = NULL, 00743 *fn_suffix = NULL, 00744 spec_class[256], 00745 lum_class[256], 00746 star_type[2], 00747 *tmp_band_method = getenv("KMO_BAND_METHOD"), 00748 **split_mag = NULL, 00749 *grat_id = NULL; 00750 const char *filter_id = NULL, 00751 *spec_type = NULL, 00752 *magnitude_txt = NULL, 00753 *imethod = NULL, 00754 *cmethod = NULL, 00755 *fmethod = NULL, 00756 *tmp_str = NULL; 00757 gridDefinition gd; 00758 cpl_array **unused_ifus_before = NULL, 00759 **unused_ifus_after = NULL; 00760 cpl_frameset *frameset_std = NULL; 00761 00762 KMO_TRY 00763 { 00764 kmo_init_fits_desc(&desc1); 00765 kmo_init_fits_desc(&desc2); 00766 00767 /* --- check input --- */ 00768 KMO_TRY_ASSURE((parlist != NULL) && 00769 (frameset != NULL), 00770 CPL_ERROR_NULL_INPUT, 00771 "Not all input data is provided!"); 00772 00773 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, STD) >= 1, 00774 CPL_ERROR_ILLEGAL_INPUT, 00775 "At least one STD frame is required!"); 00776 if (cpl_frameset_count_tags(frameset, STD) == 1) { 00777 cpl_msg_warning("", "At least two STD frames should be provided " 00778 "in order to apply sky subtraction!"); 00779 } 00780 00781 KMO_TRY_ASSURE((cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) || 00782 (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 0), 00783 CPL_ERROR_FILE_NOT_FOUND, 00784 "Exactly one ILLUM_CORR frame is required!"); 00785 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00786 CPL_ERROR_FILE_NOT_FOUND, 00787 "Exactly one XCAL frame is required!"); 00788 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00789 CPL_ERROR_FILE_NOT_FOUND, 00790 "Exactly one YCAL frame is required!"); 00791 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00792 CPL_ERROR_FILE_NOT_FOUND, 00793 "Exactly one LCAL frame is required!"); 00794 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, MASTER_FLAT) == 1, 00795 CPL_ERROR_FILE_NOT_FOUND, 00796 "Exactly one MASTER_FLAT frame is required!"); 00797 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00798 CPL_ERROR_FILE_NOT_FOUND, 00799 "Exactly one WAVE_BAND frame is required!"); 00800 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_std_star") == 1, 00801 CPL_ERROR_ILLEGAL_INPUT, 00802 "Cannot identify RAW and CALIB frames!"); 00803 00804 /* --- get parameters --- */ 00805 cpl_msg_info("", "--- Parameter setup for kmo_std_star ------"); 00806 00807 KMO_TRY_EXIT_IF_NULL( 00808 spec_type = kmo_dfs_get_parameter_string(parlist, 00809 "kmos.kmo_std_star.startype")); 00810 KMO_TRY_EXIT_IF_ERROR( 00811 kmo_dfs_print_parameter_help(parlist, 00812 "kmos.kmo_std_star.startype")); 00813 00814 KMO_TRY_EXIT_IF_NULL( 00815 imethod = kmo_dfs_get_parameter_string(parlist, 00816 "kmos.kmo_std_star.imethod")); 00817 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00818 (strcmp(imethod, "lwNN") == 0) || 00819 (strcmp(imethod, "swNN") == 0) || 00820 (strcmp(imethod, "MS") == 0) || 00821 (strcmp(imethod, "CS") == 0), 00822 CPL_ERROR_ILLEGAL_INPUT, 00823 "method must be either \"NN\", \"lwNN\", " 00824 "\"swNN\", \"MS\" or \"CS\"!"); 00825 KMO_TRY_EXIT_IF_ERROR( 00826 kmo_dfs_print_parameter_help(parlist, 00827 "kmos.kmo_std_star.imethod")); 00828 00829 KMO_TRY_EXIT_IF_NULL( 00830 fmethod = kmo_dfs_get_parameter_string(parlist, 00831 "kmos.kmo_std_star.fmethod")); 00832 KMO_TRY_ASSURE((strcmp(fmethod, "gauss") == 0) || 00833 (strcmp(fmethod, "moffat") == 0), 00834 CPL_ERROR_ILLEGAL_INPUT, 00835 "fmethod must be either 'gauss' or " 00836 "'moffat' !"); 00837 KMO_TRY_EXIT_IF_ERROR( 00838 kmo_dfs_print_parameter_help(parlist, 00839 "kmos.kmo_std_star.method")); 00840 00841 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00842 "kmos.kmo_std_star.neighborhoodRange"); 00843 KMO_TRY_CHECK_ERROR_STATE(); 00844 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00845 CPL_ERROR_ILLEGAL_INPUT, 00846 "neighborhoodRange must be greater than 0.0"); 00847 KMO_TRY_EXIT_IF_ERROR( 00848 kmo_dfs_print_parameter_help(parlist, 00849 "kmos.kmo_std_star.neighborhoodRange")); 00850 00851 magnitude_txt = kmo_dfs_get_parameter_string(parlist, 00852 "kmos.kmo_std_star.magnitude"); 00853 KMO_TRY_CHECK_ERROR_STATE(); 00854 KMO_TRY_EXIT_IF_ERROR( 00855 kmo_dfs_print_parameter_help(parlist, 00856 "kmos.kmo_std_star.magnitude")); 00857 00858 flux = kmo_dfs_get_parameter_bool(parlist, 00859 "kmos.kmo_std_star.flux"); 00860 KMO_TRY_ASSURE((flux == FALSE) || (flux == TRUE), 00861 CPL_ERROR_ILLEGAL_INPUT, 00862 "flux must be either FALSE or TRUE!"); 00863 KMO_TRY_EXIT_IF_ERROR( 00864 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.flux")); 00865 00866 save_cubes = kmo_dfs_get_parameter_bool(parlist, 00867 "kmos.kmo_std_star.save_cubes"); 00868 KMO_TRY_ASSURE((save_cubes == FALSE) || (save_cubes == TRUE), 00869 CPL_ERROR_ILLEGAL_INPUT, 00870 "save_cubes must be either FALSE or TRUE!"); 00871 KMO_TRY_EXIT_IF_ERROR( 00872 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.save_cubes")); 00873 00874 xcal_interpolation = kmo_dfs_get_parameter_bool(parlist, 00875 "kmos.kmo_std_star.xcal_interpolation"); 00876 KMO_TRY_CHECK_ERROR_STATE(); 00877 KMO_TRY_EXIT_IF_ERROR( 00878 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.xcal_interpolation")); 00879 KMO_TRY_ASSURE((xcal_interpolation == TRUE) || 00880 (xcal_interpolation == FALSE), 00881 CPL_ERROR_ILLEGAL_INPUT, 00882 "xcal_interpolation must be TRUE or FALSE!"); 00883 00884 suppress_extension = kmo_dfs_get_parameter_bool(parlist, 00885 "kmos.kmo_std_star.suppress_extension"); 00886 KMO_TRY_CHECK_ERROR_STATE(); 00887 KMO_TRY_EXIT_IF_ERROR( 00888 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.suppress_extension")); 00889 00890 KMO_TRY_ASSURE((suppress_extension == TRUE) || (suppress_extension == FALSE), 00891 CPL_ERROR_ILLEGAL_INPUT, 00892 "suppress_extension must be TRUE or FALSE!"); 00893 00894 kmo_band_pars_load(parlist, "kmos.kmo_std_star"); 00895 00896 KMO_TRY_EXIT_IF_ERROR( 00897 kmo_combine_pars_load(parlist, 00898 "kmos.kmo_std_star", 00899 &cmethod, 00900 &cpos_rej, 00901 &cneg_rej, 00902 &citer, 00903 &cmin, 00904 &cmax, 00905 FALSE)); 00906 cpl_msg_info("", "-------------------------------------------"); 00907 00908 // 00909 // Check if magnitude/frameset is valid and if throughput and zeropoint should be calculated 00910 // 00911 00912 // Check if all STD frames have the same GRAT-ID 00913 // if not: don't calculate zeropoint and throughput 00914 KMO_TRY_EXIT_IF_NULL( 00915 frameset_std = cpl_frameset_new()); 00916 00917 KMO_TRY_EXIT_IF_NULL( 00918 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00919 KMO_TRY_EXIT_IF_NULL( 00920 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 00921 KMO_TRY_EXIT_IF_NULL( 00922 grat_id = cpl_sprintf("%s", cpl_propertylist_get_string(tmp_header, "ESO INS GRAT1 ID"))); 00923 KMO_TRY_EXIT_IF_ERROR( 00924 cpl_frameset_insert(frameset_std, cpl_frame_duplicate(tmp_frame))); 00925 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00926 KMO_TRY_CHECK_ERROR_STATE(); 00927 KMO_TRY_EXIT_IF_NULL( 00928 tmp_frame = kmo_dfs_get_frame(frameset, NULL)); 00929 while (tmp_frame != NULL ) { 00930 KMO_TRY_EXIT_IF_NULL( 00931 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 00932 if (strcmp(grat_id, cpl_propertylist_get_string(tmp_header, "ESO INS GRAT1 ID")) == 0) { 00933 // same grating 00934 KMO_TRY_EXIT_IF_ERROR( 00935 cpl_frameset_insert(frameset_std, cpl_frame_duplicate(tmp_frame))); 00936 } else { 00937 // there are STD frames with different gratings 00938 if (has_magnitude) { 00939 cpl_msg_warning(cpl_func, "The STD frames have different gratings," 00940 "following QC parameters won't be " 00941 "calculated: QC ZEROPOINT, QC THROUGHPUT," 00942 "QC THROUGHPUT MEAN and QC THROUGHPUT STD"); 00943 } 00944 has_magnitude = FALSE; 00945 } 00946 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00947 00948 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 00949 KMO_TRY_CHECK_ERROR_STATE(); 00950 } 00951 KMO_TRY_CHECK_ERROR_STATE(); 00952 00953 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 00954 // check if ATMOS_MODEL is the band as the STD frames 00955 KMO_TRY_EXIT_IF_NULL( 00956 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL)); 00957 KMO_TRY_EXIT_IF_NULL( 00958 tmp_sub_header = kmclipm_propertylist_load( cpl_frame_get_filename(tmp_frame), 0)); 00959 KMO_TRY_EXIT_IF_NULL( 00960 tmp_str = cpl_propertylist_get_string(tmp_sub_header, FILT_ID)); 00961 KMO_TRY_ASSURE(strcmp(grat_id, tmp_str) == 0, 00962 CPL_ERROR_ILLEGAL_INPUT, 00963 "ATMOS model must have primary " 00964 "keyword '%s' equal '%s'!!!", 00965 FILT_ID, grat_id); 00966 cpl_propertylist_delete(tmp_sub_header); 00967 tmp_sub_header = NULL; 00968 } 00969 00970 if (has_magnitude) { 00971 // all STD frames have the same GRAT-ID 00972 // now check source of magnitude (user or keyword) 00973 KMO_TRY_EXIT_IF_NULL( 00974 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00975 KMO_TRY_EXIT_IF_NULL( 00976 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 00977 00978 if (strcmp(magnitude_txt, "") == 0) { 00979 // no user defined magnitude 00980 00981 // check for magnitude-keyword 00982 if ((cpl_propertylist_has(tmp_header, STDSTAR_MAG)) && 00983 (cpl_propertylist_get_type(tmp_header, STDSTAR_MAG) == CPL_TYPE_STRING)) 00984 { 00985 KMO_TRY_EXIT_IF_NULL( 00986 magnitude_txt = cpl_propertylist_get_string(tmp_header, STDSTAR_MAG)); 00987 KMO_TRY_EXIT_IF_NULL( 00988 split_mag = kmo_strsplit(magnitude_txt, ",", &nr_split_mag)); 00989 00990 // check if band and number of magnitudes matches 00991 if ((nr_split_mag == 2) && 00992 (strcmp(grat_id, "HK") == 0)) 00993 { 00994 magnitude1 = atof(split_mag[0]); 00995 magnitude2 = atof(split_mag[1]); 00996 cpl_msg_info("", "Magnitude in H: %g", magnitude1); 00997 cpl_msg_info("", "Magnitude in K: %g", magnitude2); 00998 } else if ((nr_split_mag >= 1) && 00999 ((strcmp(grat_id, "K") == 0) || 01000 (strcmp(grat_id, "H") == 0) || 01001 (strcmp(grat_id, "IZ") == 0) || 01002 (strcmp(grat_id, "YJ") == 0))) 01003 { 01004 magnitude1 = atof(split_mag[0]); 01005 cpl_msg_info("", "Magnitude in %s: %g", grat_id, magnitude1); 01006 } else { 01007 // keyword STDSTAR_MAG doesn't match filter 01008 has_magnitude = FALSE; 01009 cpl_msg_warning(cpl_func, "The keyword %s doesn't match to grating'," 01010 "following QC parameters won't be " 01011 "calculated: QC ZEROPOINT, QC THROUGHPUT," 01012 "QC THROUGHPUT MEAN and QC THROUGHPUT STD", STDSTAR_MAG); 01013 } 01014 kmo_strfreev(split_mag); 01015 } else { 01016 // keyword STDSTAR_MAG unavailable or wrong type 01017 has_magnitude = FALSE; 01018 cpl_msg_warning(cpl_func, "The keyword %s is not set or of wrong type," 01019 "following QC parameters won't be " 01020 "calculated: QC ZEROPOINT, QC THROUGHPUT," 01021 "QC THROUGHPUT MEAN and QC THROUGHPUT STD", STDSTAR_MAG); 01022 } 01023 } else { 01024 // magnitude is user specified 01025 cpl_msg_info(cpl_func, "Magnitude has been specified by user. Any " 01026 "value in keyword %s will be ignored.", STDSTAR_MAG); 01027 01028 KMO_TRY_EXIT_IF_NULL( 01029 split_mag = kmo_strsplit(magnitude_txt, ",", &nr_split_mag)); 01030 switch (nr_split_mag) { 01031 case 1: 01032 magnitude1 = atof(split_mag[0]); 01033 cpl_msg_info("", "Magnitude in %s: %g", grat_id, magnitude1); 01034 break; 01035 case 2: 01036 magnitude1 = atof(split_mag[0]); 01037 magnitude2 = atof(split_mag[1]); 01038 cpl_msg_info("", "Magnitude in H: %g", magnitude1); 01039 cpl_msg_info("", "Magnitude in K: %g", magnitude2); 01040 break; 01041 default: 01042 KMO_TRY_ASSURE(1 == 0, 01043 CPL_ERROR_ILLEGAL_INPUT, 01044 "Provided magnitude was in wrong format! " 01045 "Either a single float value or two separated by comma"); 01046 } 01047 kmo_strfreev(split_mag); 01048 } 01049 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01050 } // if (has_magnitude) 01051 cpl_msg_info("", "-------------------------------------------"); 01052 KMO_TRY_CHECK_ERROR_STATE(); 01053 01054 // 01055 // check for spectral type (--startype) (user or keyword) 01056 // 01057 if (strcmp(spec_type, "") == 0) { 01058 // no user defined startype 01059 01060 KMO_TRY_EXIT_IF_NULL( 01061 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 01062 KMO_TRY_EXIT_IF_NULL( 01063 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 01064 01065 // check for startype-keyword 01066 if ((cpl_propertylist_has(tmp_header, STDSTAR_TYPE)) && 01067 (cpl_propertylist_get_type(tmp_header, STDSTAR_TYPE) == CPL_TYPE_STRING)) 01068 { 01069 KMO_TRY_EXIT_IF_NULL( 01070 spec_type = cpl_propertylist_get_string(tmp_header, STDSTAR_TYPE)); 01071 } else { 01072 // keyword STDSTAR_TYPE unavailable or wrong type 01073 } 01074 } else { 01075 // startype is user specified 01076 cpl_msg_info(cpl_func, "Type of star has been specified by user. Any " 01077 "value in keyword %s will be ignored.", STDSTAR_TYPE); 01078 } 01079 KMO_TRY_CHECK_ERROR_STATE(); 01080 01081 if (strlen(spec_type) > 0) { 01082 if (kmo_get_spec_type(spec_type, spec_class, lum_class) != CPL_ERROR_NONE) { 01083 cpl_error_reset(); 01084 spec_class[0] = '\0'; 01085 lum_class[0] = '\0'; 01086 star_type[0] = '\0'; 01087 cpl_msg_warning("", "The keyword %s is not set or of wrong type nor was it provided by the user. " 01088 "Can't divide solar spectrum for G stars or fit a profile " 01089 "to atmospheric transmission for OBAF stars and can't " 01090 "divide blackbody for any star.", STDSTAR_TYPE); 01091 cpl_msg_warning("", "%s = '%s' (should be something like e.g.'G2V' odr 'A9III')", STDSTAR_TYPE, spec_type); 01092 } else { 01093 strncpy(star_type, spec_class, 1); 01094 star_type[1] = '\0'; 01095 cpl_msg_info("", "Spectral class: %s", spec_class); 01096 cpl_msg_info("", "Luminosity class: %s", lum_class); 01097 } 01098 } else { 01099 spec_class[0] = '\0'; 01100 lum_class[0] = '\0'; 01101 star_type[0] = '\0'; 01102 cpl_msg_warning("", "The keyword %s is not set nor was it provided by the user. " 01103 "Can't divide solar spectrum for G stars or fit a profile " 01104 "to atmospheric transmission for OBAF stars and can't " 01105 "divide blackbody for any star.", STDSTAR_TYPE); 01106 } 01107 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01108 cpl_msg_info("", "-------------------------------------------"); 01109 KMO_TRY_CHECK_ERROR_STATE(); 01110 01111 // assure that filters, grating and rotation offsets match for 01112 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 01113 // frames) 01114 // check if filter_id and grating_id match for all detectors 01115 KMO_TRY_EXIT_IF_ERROR( 01116 kmo_check_frameset_setup(frameset, XCAL, FALSE, FALSE, TRUE)); 01117 KMO_TRY_EXIT_IF_ERROR( 01118 kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE)); 01119 KMO_TRY_EXIT_IF_ERROR( 01120 kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE)); 01121 KMO_TRY_EXIT_IF_ERROR( 01122 kmo_check_frame_setup(frameset, XCAL, MASTER_FLAT, TRUE, FALSE, TRUE)); 01123 KMO_TRY_EXIT_IF_ERROR( 01124 kmo_check_frame_setup(frameset, XCAL, STD, FALSE, FALSE, TRUE)); 01125 // KMO_TRY_EXIT_IF_ERROR( 01126 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 01127 // KMO_TRY_EXIT_IF_ERROR( 01128 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 01129 01130 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 01131 KMO_TRY_EXIT_IF_ERROR( 01132 kmo_check_frame_setup(frameset, XCAL, ILLUM_CORR, TRUE, FALSE, FALSE)); 01133 } 01134 01135 // check descriptors of all frames 01136 KMO_TRY_EXIT_IF_NULL( 01137 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 01138 01139 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 01140 KMO_TRY_CHECK_ERROR_STATE(); 01141 01142 KMO_TRY_ASSURE((desc1.nr_ext % 3 == 0) && 01143 (desc1.ex_badpix == FALSE) && 01144 (desc1.fits_type == f2d_fits) && 01145 (desc1.frame_type == detector_frame), 01146 CPL_ERROR_ILLEGAL_INPUT, 01147 "XCAL isn't in the correct format!!!"); 01148 01149 KMO_TRY_EXIT_IF_NULL( 01150 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 01151 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 01152 KMO_TRY_CHECK_ERROR_STATE(); 01153 01154 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 01155 (desc1.ex_badpix == desc2.ex_badpix) && 01156 (desc1.fits_type == desc2.fits_type) && 01157 (desc1.frame_type == desc2.frame_type), 01158 CPL_ERROR_ILLEGAL_INPUT, 01159 "YCAL isn't in the correct format!!!"); 01160 kmo_free_fits_desc(&desc2); 01161 kmo_init_fits_desc(&desc2); 01162 01163 KMO_TRY_EXIT_IF_NULL( 01164 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 01165 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 01166 KMO_TRY_CHECK_ERROR_STATE(); 01167 01168 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 01169 (desc1.ex_badpix == desc2.ex_badpix) && 01170 (desc1.fits_type == desc2.fits_type) && 01171 (desc1.frame_type == desc2.frame_type), 01172 CPL_ERROR_ILLEGAL_INPUT, 01173 "YCAL isn't in the correct format!!!"); 01174 kmo_free_fits_desc(&desc2); 01175 kmo_init_fits_desc(&desc2); 01176 01177 KMO_TRY_EXIT_IF_NULL( 01178 flat_frame = kmo_dfs_get_frame(frameset, MASTER_FLAT)); 01179 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(flat_frame)); 01180 KMO_TRY_CHECK_ERROR_STATE(); 01181 01182 KMO_TRY_ASSURE((desc2.nr_ext % 6 == 0) && 01183 (desc1.ex_badpix == desc2.ex_badpix) && 01184 (desc1.fits_type == desc2.fits_type) && 01185 (desc1.frame_type == desc2.frame_type), 01186 CPL_ERROR_ILLEGAL_INPUT, 01187 "MASTER_FLAT isn't in the correct format!!!"); 01188 kmo_free_fits_desc(&desc2); 01189 kmo_init_fits_desc(&desc2); 01190 01191 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 01192 KMO_TRY_EXIT_IF_NULL( 01193 illum_frame = kmo_dfs_get_frame(frameset, ILLUM_CORR)); 01194 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(illum_frame)); 01195 KMO_TRY_CHECK_ERROR_STATE(); 01196 KMO_TRY_ASSURE(((desc2.nr_ext == 24) || (desc2.nr_ext == 48)) && 01197 (desc2.ex_badpix == FALSE) && 01198 (desc2.fits_type == f2i_fits) && 01199 (desc2.frame_type == ifu_frame), 01200 CPL_ERROR_ILLEGAL_INPUT, 01201 "ILLUM_CORR isn't in the correct format!!!"); 01202 kmo_free_fits_desc(&desc2); 01203 kmo_init_fits_desc(&desc2); 01204 } 01205 01206 if (cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) == 1) { 01207 KMO_TRY_EXIT_IF_NULL( 01208 tmp_frame = kmo_dfs_get_frame(frameset, SPEC_TYPE_LOOKUP)); 01209 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01210 KMO_TRY_CHECK_ERROR_STATE(); 01211 KMO_TRY_ASSURE((desc2.nr_ext == 1) && 01212 (desc2.ex_badpix == FALSE) && 01213 (desc2.fits_type == f2l_fits) && 01214 (desc2.frame_type == list_frame), 01215 CPL_ERROR_ILLEGAL_INPUT, 01216 "SPEC_TYPE_LOOKUP isn't in the correct format!!!"); 01217 kmo_free_fits_desc(&desc2); 01218 kmo_init_fits_desc(&desc2); 01219 } 01220 01221 if (cpl_frameset_count_tags(frameset, SOLAR_SPEC) == 1) { 01222 KMO_TRY_EXIT_IF_NULL( 01223 tmp_frame = kmo_dfs_get_frame(frameset, SOLAR_SPEC)); 01224 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01225 KMO_TRY_CHECK_ERROR_STATE(); 01226 KMO_TRY_ASSURE((desc2.nr_ext == 1) && 01227 (desc2.ex_badpix == FALSE) && 01228 (desc2.fits_type == f1s_fits) && 01229 (desc2.frame_type == spectrum_frame), 01230 CPL_ERROR_ILLEGAL_INPUT, 01231 "SOLAR_SPEC isn't in the correct format!!!"); 01232 kmo_free_fits_desc(&desc2); 01233 kmo_init_fits_desc(&desc2); 01234 } 01235 01236 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 01237 KMO_TRY_EXIT_IF_NULL( 01238 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL)); 01239 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01240 KMO_TRY_CHECK_ERROR_STATE(); 01241 KMO_TRY_ASSURE((desc2.nr_ext == 1) && 01242 (desc2.ex_badpix == FALSE) && 01243 (desc2.fits_type == f1s_fits) && 01244 (desc2.frame_type == spectrum_frame), 01245 CPL_ERROR_ILLEGAL_INPUT, 01246 "ATMOS_MODEL isn't in the correct format!!!"); 01247 kmo_free_fits_desc(&desc2); 01248 kmo_init_fits_desc(&desc2); 01249 } 01250 01251 KMO_TRY_EXIT_IF_NULL( 01252 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 01253 while (tmp_frame != NULL ) { 01254 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 01255 KMO_TRY_CHECK_ERROR_STATE(); 01256 KMO_TRY_ASSURE((desc2.nr_ext == 3) && 01257 (desc2.ex_badpix == FALSE) && 01258 (desc2.fits_type == raw_fits) && 01259 (desc2.frame_type == detector_frame), 01260 CPL_ERROR_ILLEGAL_INPUT, 01261 "STD isn't in the correct format!!!"); 01262 nr_devices = desc2.nr_ext; 01263 kmo_free_fits_desc(&desc2); 01264 kmo_init_fits_desc(&desc2); 01265 01266 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 01267 KMO_TRY_CHECK_ERROR_STATE(); 01268 } 01269 KMO_TRY_EXIT_IF_NULL( 01270 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 01271 KMO_TRY_EXIT_IF_NULL( 01272 suffix = kmo_dfs_get_suffix(tmp_frame, TRUE, FALSE)); 01273 01274 KMO_TRY_EXIT_IF_ERROR( 01275 kmo_check_frame_setup_md5_xycal(frameset)); 01276 KMO_TRY_EXIT_IF_ERROR( 01277 kmo_check_frame_setup_md5(frameset)); 01278 01279 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 01280 cpl_msg_info("", "(grating 1, 2 & 3)"); 01281 01282 // check which IFUs are active for all frames 01283 KMO_TRY_EXIT_IF_NULL( 01284 unused_ifus_before = kmo_get_unused_ifus(frameset, 0, 0)); 01285 01286 KMO_TRY_EXIT_IF_NULL( 01287 unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before)); 01288 01289 kmo_print_unused_ifus(unused_ifus_before, FALSE); 01290 01291 /* --- load data --- */ 01292 01293 if ((cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) == 1) && 01294 ((strlen(spec_class) > 0) || (strlen(lum_class) > 0))) 01295 { 01296 // get star temperature out of SPEC_TYPE_LOOKUP table 01297 KMO_TRY_EXIT_IF_NULL( 01298 spec_type_LUT = kmo_dfs_load_table(frameset, SPEC_TYPE_LOOKUP, 1, 0)); 01299 star_temperature = kmo_get_temperature(spec_type_LUT, spec_class, lum_class); 01300 KMO_TRY_CHECK_ERROR_STATE(); 01301 } else if (cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) != 1) { 01302 cpl_msg_warning("","No SPEC_TYPE_LOOKUP was provided! Can't divide blackbody."); 01303 } else if ((strlen(spec_class) == 0) || (strlen(lum_class) == 0)) { 01304 // cpl_msg_warning("","No startype was provided! Can't " 01305 // "divide blackbody."); 01306 } 01307 01308 // allocate intermediate memory 01309 KMO_TRY_EXIT_IF_NULL( 01310 stored_telluric_data = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01311 sizeof(cpl_vector*))); 01312 KMO_TRY_EXIT_IF_NULL( 01313 stored_telluric_noise = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01314 sizeof(cpl_vector*))); 01315 KMO_TRY_EXIT_IF_NULL( 01316 stored_starspec_data = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01317 sizeof(cpl_vector*))); 01318 KMO_TRY_EXIT_IF_NULL( 01319 stored_starspec_noise = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01320 sizeof(cpl_vector*))); 01321 KMO_TRY_EXIT_IF_NULL( 01322 stored_psf_data = (cpl_image**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01323 sizeof(cpl_image*))); 01324 KMO_TRY_EXIT_IF_NULL( 01325 stored_mask = (cpl_image**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01326 sizeof(cpl_image*))); 01327 KMO_TRY_EXIT_IF_NULL( 01328 stored_data_cube = (cpl_imagelist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01329 sizeof(cpl_imagelist*))); 01330 KMO_TRY_EXIT_IF_NULL( 01331 stored_noise_cube = (cpl_imagelist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01332 sizeof(cpl_imagelist*))); 01333 KMO_TRY_EXIT_IF_NULL( 01334 stored_qc_throughput = (double*)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01335 sizeof(double))); 01336 KMO_TRY_EXIT_IF_NULL( 01337 stored_sub_psf_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01338 sizeof(cpl_propertylist*))); 01339 KMO_TRY_EXIT_IF_NULL( 01340 stored_sub_tel_data_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01341 sizeof(cpl_propertylist*))); 01342 KMO_TRY_EXIT_IF_NULL( 01343 stored_sub_tel_noise_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01344 sizeof(cpl_propertylist*))); 01345 01346 if (save_cubes) { 01347 KMO_TRY_EXIT_IF_NULL( 01348 stored_sub_cube_data_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01349 sizeof(cpl_propertylist*))); 01350 KMO_TRY_EXIT_IF_NULL( 01351 stored_sub_cube_noise_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01352 sizeof(cpl_propertylist*))); 01353 } 01354 01355 // get bounds 01356 KMO_TRY_EXIT_IF_NULL( 01357 tmp_header = kmo_dfs_load_primary_header(frameset, XCAL)); 01358 KMO_TRY_EXIT_IF_NULL( 01359 bounds = kmclipm_extract_bounds(tmp_header)); 01360 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01361 01362 // setup grid definition, wavelength start and end points will be set 01363 // in the detector loop 01364 KMO_TRY_EXIT_IF_ERROR( 01365 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, KMOS_PIX_RESOLUTION)); 01366 01367 // get valid STD frames with objects in it and associated sky exposures 01368 KMO_TRY_EXIT_IF_NULL( 01369 obj_sky_struct = kmo_create_objSkyStruct(frameset_std, STD, FALSE)); 01370 kmo_debug_objSkyStruct(frameset, obj_sky_struct); 01371 01372 // loop the object-sky pairs 01373 if (obj_sky_struct->size == 0) { 01374 cpl_msg_warning(cpl_func,"Not a single frame contains an object"); 01375 } else { 01376 strcpy(filename_telluric, TELLURIC); 01377 strcpy(filename_starspec, STAR_SPEC); 01378 strcpy(filename_psf, STD_IMAGE); 01379 strcpy(filename_mask, STD_MASK); 01380 strcpy(filename_cubes, STD_CUBE); 01381 01382 obj_frame = obj_sky_struct->table[nr_exp].objFrame; 01383 KMO_TRY_EXIT_IF_NULL( 01384 main_header_tel = kmclipm_propertylist_load(cpl_frame_get_filename(obj_frame), 0)); 01385 01386 exptime = cpl_propertylist_get_double(main_header_tel, EXPTIME); 01387 KMO_TRY_CHECK_ERROR_STATE(); 01388 01389 // load, process & store frames 01390 01391 for (i = 1; i <= nr_devices; i++) { 01392 // extract LCAL image close to ROTANGLE 0. assuming that the wavelength range 01393 // doesn't differ too much with different ROTANGLEs. 01394 print_cal_angle_msg_once = FALSE; 01395 double rotangle_found; 01396 KMO_TRY_EXIT_IF_NULL( 01397 lcal = kmo_dfs_load_cal_image(frameset, LCAL, i, FALSE, 0., FALSE, NULL, 01398 &rotangle_found, -1, 0, 0)); 01399 if (i==1) { 01400 print_cal_angle_msg_once = TRUE; 01401 } 01402 if (tmp_band_method != NULL) { 01403 band_method = atoi(tmp_band_method); 01404 } 01405 01406 // get filter for this detector 01407 // ESO INS FILTi ID 01408 KMO_TRY_EXIT_IF_NULL( 01409 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, i, IFU_FILTID_POSTFIX)); 01410 filter_id = cpl_propertylist_get_string(main_header_tel, keyword); 01411 cpl_free(keyword); keyword = NULL; 01412 01413 KMO_TRY_EXIT_IF_NULL( 01414 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0)); 01415 KMO_TRY_EXIT_IF_ERROR( 01416 kmclipm_setup_grid_band_lcal(&gd, lcal, filter_id, 01417 band_method, band_table)); 01418 cpl_image_delete(lcal); lcal = NULL; 01419 cpl_table_delete(band_table); band_table = NULL; 01420 01421 // load sub_header of original F2D image 01422 KMO_TRY_EXIT_IF_NULL( 01423 sub_header_orig = kmclipm_propertylist_load( cpl_frame_get_filename(obj_frame), i)); 01424 01425 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 01426 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 01427 // check if IFU is valid according to main header keywords & 01428 // calibration files 01429 // AND check if there is a sky frame available for this IFU 01430 kmo_collapse_objSkyStruct(obj_sky_struct, ifu_nr, 01431 &obj_frame, &sky_frame); 01432 01433 KMO_TRY_EXIT_IF_NULL( 01434 punused_ifus = cpl_array_get_data_int_const(unused_ifus_after[i-1])); 01435 01436 // Search for keyword ESO OCS ARMi NOTUSED 01437 // If not present (CPL_ERROR_DATA_NOT_FOUND) we will eventually 01438 // process standard star 01439 KMO_TRY_EXIT_IF_NULL( 01440 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, IFU_VALID_POSTFIX)); 01441 tmp_str = cpl_propertylist_get_string(main_header_tel, keyword); 01442 cpl_free(keyword); keyword = NULL; 01443 01444 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 01445 (bounds[2*(ifu_nr-1)] != -1) && 01446 (bounds[2*(ifu_nr-1)+1] != -1) && 01447 (sky_frame != NULL) && 01448 (punused_ifus[j] == 0)) 01449 { 01450 cpl_error_reset(); 01451 // IFU is valid 01452 01453 if (sky_frame != NO_CORRESPONDING_SKYFRAME) { 01454 cpl_msg_info("","Processing standard star in IFU %d " 01455 "(obj: %s, sky: %s)", ifu_nr, 01456 cpl_frame_get_filename(obj_frame), 01457 cpl_frame_get_filename(sky_frame)); 01458 } else { 01459 sky_frame = NULL; 01460 cpl_msg_warning("","Processing standard star in IFU %d " 01461 "(obj: %s, no corresponding sky frame", 01462 ifu_nr, cpl_frame_get_filename(obj_frame)); 01463 } 01464 01465 nr_std_stars++; 01466 01467 char *ggg = cpl_sprintf("%s%d", PRO_STD, ifu_nr); 01468 KMO_TRY_EXIT_IF_ERROR( 01469 cpl_propertylist_update_int(main_header_tel, ggg, 1)); 01470 cpl_free(ggg); ggg = NULL; 01471 01472 // calculate WCS and make copies of sub_header 01473 KMO_TRY_EXIT_IF_NULL( 01474 tmp_sub_header = cpl_propertylist_duplicate(sub_header_orig)); 01475 KMO_TRY_EXIT_IF_ERROR( 01476 kmo_calc_wcs_gd(main_header_tel, tmp_sub_header, ifu_nr, gd)); 01477 KMO_TRY_EXIT_IF_NULL( 01478 stored_sub_tel_data_headers[ifu_nr-1] = 01479 cpl_propertylist_duplicate(tmp_sub_header)); 01480 KMO_TRY_EXIT_IF_NULL( 01481 stored_sub_psf_headers[ifu_nr-1] = 01482 cpl_propertylist_duplicate(tmp_sub_header)); 01483 if (save_cubes) { 01484 KMO_TRY_EXIT_IF_NULL( 01485 stored_sub_cube_data_headers[ifu_nr-1] = 01486 cpl_propertylist_duplicate(tmp_sub_header)); 01487 } 01488 cpl_propertylist_delete(tmp_sub_header); 01489 tmp_sub_header = NULL; 01490 01491 // 01492 // adjust telluric-headers: copy CRPIX3 to CRPIX1, 01493 // 01494 cpl_propertylist_update_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL1, 01495 cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL3)); 01496 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRVAL2); 01497 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRVAL3); 01498 KMO_TRY_CHECK_ERROR_STATE(); 01499 01500 // CRPIX 01501 cpl_propertylist_update_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX1, 01502 cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX3)); 01503 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRPIX2); 01504 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRPIX3); 01505 KMO_TRY_CHECK_ERROR_STATE(); 01506 01507 // CDELT 01508 cdelt3 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT3); 01509 cpl_propertylist_update_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT1, 01510 cdelt3); 01511 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CDELT2); 01512 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CDELT3); 01513 KMO_TRY_CHECK_ERROR_STATE(); 01514 01515 // CTYPE 01516 cpl_propertylist_update_string(stored_sub_tel_data_headers[ifu_nr-1], CTYPE1, 01517 cpl_propertylist_get_string(stored_sub_tel_data_headers[ifu_nr-1], CTYPE3)); 01518 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CTYPE2); 01519 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CTYPE3); 01520 KMO_TRY_CHECK_ERROR_STATE(); 01521 01522 // CUNIT 01523 cpl_propertylist_update_string(stored_sub_tel_data_headers[ifu_nr-1], CUNIT1, 01524 cpl_propertylist_get_string(stored_sub_tel_data_headers[ifu_nr-1], CUNIT3)); 01525 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CUNIT2); 01526 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CUNIT3); 01527 01528 // CDx_x 01529 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_1); 01530 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_2); 01531 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_3); 01532 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_1); 01533 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_2); 01534 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_3); 01535 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_1); 01536 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_2); 01537 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_3); 01538 KMO_TRY_CHECK_ERROR_STATE(); 01539 01540 // 01541 // adjust psf-headers: delete CRPIX3 etc. 01542 // 01543 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRPIX3); 01544 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRPIX3); 01545 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CDELT3); 01546 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRVAL3); 01547 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CTYPE3); 01548 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CUNIT3); 01549 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD1_3); 01550 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD2_3); 01551 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD3_1); 01552 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD3_2); 01553 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD3_3); 01554 KMO_TRY_CHECK_ERROR_STATE(); 01555 01556 KMO_TRY_EXIT_IF_ERROR( 01557 kmo_reconstruct_sci(ifu_nr, 01558 bounds[2*(ifu_nr-1)], 01559 bounds[2*(ifu_nr-1)+1], 01560 obj_frame, 01561 STD, 01562 sky_frame, 01563 STD, 01564 flat_frame, 01565 xcal_frame, 01566 ycal_frame, 01567 lcal_frame, 01568 NULL, 01569 &gd, 01570 &stored_data_cube[ifu_nr-1], 01571 &stored_noise_cube[ifu_nr-1], 01572 flux, 01573 background, 01574 xcal_interpolation)); 01575 01576 // divide illumination correction from the data_cube 01577 // (illumination noise will be very small versus 01578 // noise_cube, so it is skipped here) 01579 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 01580 KMO_TRY_EXIT_IF_NULL( 01581 illum_corr = kmo_dfs_load_image_frame(illum_frame, ifu_nr, 01582 FALSE, FALSE, NULL)); 01583 KMO_TRY_EXIT_IF_ERROR( 01584 cpl_imagelist_divide_image(stored_data_cube[ifu_nr-1], illum_corr)); 01585 cpl_image_delete(illum_corr); illum_corr = NULL; 01586 } 01587 01588 // calculate QC_STD_TRACE 01589 // (the distance of the PSF to the centre) 01590 KMO_TRY_EXIT_IF_ERROR( 01591 kmo_calculate_std_trace(stored_data_cube[ifu_nr-1], fmethod, &std_trace)); 01592 01593 KMO_TRY_EXIT_IF_ERROR( 01594 kmclipm_update_property_double(stored_sub_psf_headers[ifu_nr-1], 01595 QC_STD_TRACE, std_trace, 01596 "[pix] distance of PSF and centre of IFU")); 01597 01598 KMO_TRY_EXIT_IF_NULL( 01599 identified_slices = cpl_vector_new(cpl_imagelist_get_size(stored_data_cube[ifu_nr-1]))); 01600 KMO_TRY_EXIT_IF_ERROR( 01601 cpl_vector_fill(identified_slices, 1.0)); 01602 01603 // collapse cube and get PSF image 01604 KMO_TRY_EXIT_IF_ERROR( 01605 kmclipm_make_image(stored_data_cube[ifu_nr-1], NULL, 01606 &stored_psf_data[ifu_nr-1], NULL, 01607 identified_slices, 01608 cmethod, 01609 cpos_rej, cneg_rej, citer, 01610 cmax, cmin)); 01611 cpl_vector_delete(identified_slices); 01612 identified_slices= NULL; 01613 01614 // fit a 2D profile to get a mask and fwhm in x and y, 01615 KMO_TRY_EXIT_IF_NULL( 01616 tmp_vec = kmo_fit_profile_2D(stored_psf_data[ifu_nr-1], 01617 NULL, 01618 fmethod, 01619 &stored_mask[ifu_nr-1], 01620 &pl_psf)); 01621 01622 // normalise mask to 1 and clip values below 0.5 01623 cpl_image_divide_scalar(stored_mask[ifu_nr-1], cpl_image_get_max(stored_mask[ifu_nr-1])); 01624 KMO_TRY_CHECK_ERROR_STATE(); 01625 01626 int dummy=0; 01627 for (gx = 1; gx <= cpl_image_get_size_x(stored_mask[ifu_nr-1]); gx++) { 01628 for (gy = 1; gy <= cpl_image_get_size_y(stored_mask[ifu_nr-1]); gy++) { 01629 if (cpl_image_get(stored_mask[ifu_nr-1], gx, gy, &dummy) < 0.5) { 01630 cpl_image_set(stored_mask[ifu_nr-1], gx, gy, 0.); 01631 } else { 01632 cpl_image_set(stored_mask[ifu_nr-1], gx, gy, 1.); 01633 } 01634 } 01635 } 01636 KMO_TRY_CHECK_ERROR_STATE(); 01637 01638 // update subheader with fit parameters 01639 KMO_TRY_EXIT_IF_ERROR( 01640 cpl_propertylist_append(stored_sub_tel_data_headers[ifu_nr-1], pl_psf)); 01641 cpl_propertylist_delete(pl_psf); pl_psf = NULL; 01642 01643 // store QC_SPAT_RES (RMS of fwhm_x and fwhm_y) 01644 double factor_fwhm = 2*sqrt(2*log(2)); 01645 double spat_res = pow(cpl_vector_get(tmp_vec, 4) * factor_fwhm, 2); 01646 spat_res += pow(cpl_vector_get(tmp_vec, 5) * factor_fwhm, 2); 01647 spat_res /= 2; 01648 KMO_TRY_EXIT_IF_ERROR( 01649 kmclipm_update_property_double(stored_sub_psf_headers[ifu_nr-1], 01650 QC_SPAT_RES, 01651 sqrt(spat_res)*KMOS_PIX_RESOLUTION, 01652 "[arcsec] mean fwhm resolution of PSF")); 01653 cpl_vector_delete(tmp_vec); tmp_vec = NULL; 01654 01655 // extract spectrum in masked area 01656 KMO_TRY_EXIT_IF_ERROR( 01657 kmo_priv_extract_spec(stored_data_cube[ifu_nr-1], 01658 stored_noise_cube[ifu_nr-1], 01659 stored_mask[ifu_nr-1], 01660 &tmp_spec_data, 01661 &tmp_spec_noise)); 01662 01663 // store to save to disk later on 01664 stored_starspec_data[ifu_nr-1] = cpl_vector_duplicate(tmp_spec_data); 01665 if (tmp_spec_noise != NULL) { 01666 stored_starspec_noise[ifu_nr-1] = cpl_vector_duplicate(tmp_spec_noise); 01667 } 01668 KMO_TRY_CHECK_ERROR_STATE(); 01669 01670 // if magnitude is provided 01671 // calculate zeropoint and throughput 01672 if (has_magnitude) { 01673 // extract spectrum of whole are for QC THRUHput and ZEROPOINT 01674 KMO_TRY_EXIT_IF_ERROR( 01675 kmo_priv_extract_spec(stored_data_cube[ifu_nr-1], 01676 NULL, 01677 NULL, 01678 &spec_qc, 01679 NULL)); 01680 01681 // multiply spectrum with area of IFU (196) to get the sum 01682 const cpl_image *tmp_img = cpl_imagelist_get(stored_data_cube[ifu_nr-1], 0); 01683 int tmpx = cpl_image_get_size_x(tmp_img), 01684 tmpy = cpl_image_get_size_x(tmp_img); 01685 cpl_vector_multiply_scalar(spec_qc, tmpx*tmpy); 01686 } 01687 01688 // calculate abscissa of output spectrum 01689 KMO_TRY_EXIT_IF_NULL( 01690 lambda_x = kmo_create_lambda_vec(gd.l.dim, 1, 01691 gd.l.start, 01692 gd.l.delta)); 01693 // 01694 // spectrum correction 01695 // 01696 if ((strcmp(star_type, "O") == 0) || 01697 (strcmp(star_type, "B") == 0) || 01698 (strcmp(star_type, "A") == 0) || 01699 (strcmp(star_type, "F") == 0)) 01700 { 01701 // we have a OBAF star 01702 01703 // if ATMOS_MODEL is present, lines will be removed 01704 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 01705 // interpolate ATMOS_MODEL to same scale as data 01706 KMO_TRY_EXIT_IF_NULL( 01707 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL)); 01708 01709 KMO_TRY_EXIT_IF_NULL( 01710 atmos_model = kmo_interpolate_vector_wcs(tmp_frame, lambda_x)); 01711 cpl_vector *tmp_spec_data_orig = NULL; 01712 int plot_it = 0; 01713 if (plot_it) { 01714 // store original spectrum 01715 KMO_TRY_EXIT_IF_NULL( 01716 tmp_spec_data_orig = cpl_vector_duplicate(tmp_spec_data)); 01717 } 01718 // remove band-specific lines 01719 if (strcmp(filter_id, "H") == 0) { 01720 for (l = 0; l < nr_lines_h; l++) { 01721 KMO_TRY_EXIT_IF_ERROR( 01722 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_h[l], lines_width_h[l])); 01723 } 01724 } else if (strcmp(filter_id, "HK") == 0) { 01725 for (l = 0; l < nr_lines_hk; l++) { 01726 KMO_TRY_EXIT_IF_ERROR( 01727 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_hk[l], lines_width_hk[l])); 01728 } 01729 } else if (strcmp(filter_id, "K") == 0) { 01730 for (l = 0; l < nr_lines_k; l++) { 01731 KMO_TRY_EXIT_IF_ERROR( 01732 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_k[l], lines_width_k[l])); 01733 } 01734 } else if (strcmp(filter_id, "IZ") == 0) { 01735 for (l = 0; l < nr_lines_iz; l++) { 01736 KMO_TRY_EXIT_IF_ERROR( 01737 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_iz[l], lines_width_iz[l])); 01738 } 01739 } else if (strcmp(filter_id, "YJ") == 0) { 01740 for (l = 0; l < nr_lines_yj; l++) { 01741 KMO_TRY_EXIT_IF_ERROR( 01742 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, lines_center_yj[l], lines_width_yj[l])); 01743 } 01744 } 01745 if (plot_it) { 01746 cpl_vector *tmp_spec_data_atmo = NULL; 01747 cpl_vector *tmp_spec_data_new = NULL; 01748 KMO_TRY_EXIT_IF_NULL( 01749 tmp_spec_data_atmo = cpl_vector_duplicate(tmp_spec_data_orig)); 01750 KMO_TRY_EXIT_IF_NULL( 01751 tmp_spec_data_new = cpl_vector_duplicate(tmp_spec_data)); 01752 KMO_TRY_EXIT_IF_ERROR( 01753 cpl_vector_divide(tmp_spec_data_atmo, atmos_model)); 01754 01755 char *sss = cpl_sprintf("atmo_div_%s.fits", filter_id); 01756 if (i == 1) { 01757 cpl_vector_save(tmp_spec_data_atmo, sss, CPL_BPP_IEEE_DOUBLE, stored_sub_tel_data_headers[ifu_nr-1], CPL_IO_CREATE); 01758 } else { 01759 cpl_vector_save(tmp_spec_data_atmo, sss, CPL_BPP_IEEE_DOUBLE, stored_sub_tel_data_headers[ifu_nr-1], CPL_IO_EXTEND); 01760 } 01761 01762 cpl_vector *med_vec = cpl_vector_duplicate(tmp_spec_data_orig); 01763 double median = cpl_vector_get_median(med_vec); 01764 cpl_vector_delete(med_vec); 01765 int ii = 0; 01766 for (ii = 0; ii < cpl_vector_get_size(tmp_spec_data_orig); ii++) { 01767 if (cpl_vector_get(tmp_spec_data_orig, ii) < median/8) 01768 cpl_vector_set(tmp_spec_data_orig, ii, 0); 01769 if (cpl_vector_get(tmp_spec_data_atmo, ii) < median/8) 01770 cpl_vector_set(tmp_spec_data_atmo, ii, 0); 01771 if (cpl_vector_get(tmp_spec_data_new, ii) < median/8) 01772 cpl_vector_set(tmp_spec_data_new, ii, 0); 01773 01774 if (cpl_vector_get(tmp_spec_data_orig, ii) > 3*median) 01775 cpl_vector_set(tmp_spec_data_orig, ii, 3*median); 01776 if (cpl_vector_get(tmp_spec_data_atmo, ii) > 3*median) 01777 cpl_vector_set(tmp_spec_data_atmo, ii, 3*median); 01778 if (cpl_vector_get(tmp_spec_data_new, ii) > 3*median) 01779 cpl_vector_set(tmp_spec_data_new, ii, 3*median); 01780 } 01781 01782 double *pspec_dup = cpl_vector_get_data(tmp_spec_data_atmo); 01783 for (ii = 0; ii < cpl_vector_get_size(tmp_spec_data_atmo); ii++) { 01784 if (kmclipm_is_nan_or_inf(pspec_dup[ii])) { 01785 pspec_dup[ii] = 0.; 01786 } 01787 } 01788 01789 cpl_bivector *plots[3]; 01790 plots[0] = cpl_bivector_wrap_vectors((cpl_vector*)lambda_x, tmp_spec_data_orig); 01791 plots[1] = cpl_bivector_wrap_vectors((cpl_vector*)lambda_x, tmp_spec_data_atmo); 01792 plots[2] = cpl_bivector_wrap_vectors((cpl_vector*)lambda_x, tmp_spec_data_new); 01793 char *options[3] = {"w l t 'original'", 01794 "w l t 'atmo divided'", 01795 "w l t 'lines removed'"}; 01796 sss = cpl_sprintf("set title '%s-band line removal (DET #%d)';", filter_id, i); 01797 cpl_plot_bivectors(sss, 01798 (const char**)options, "", (const cpl_bivector**)plots, 3); 01799 // cpl_plot_bivectors("set title 'Spectrum with lines removed'; set xrange [2.14:2.19];", 01800 // (const char**)options, "", (const cpl_bivector**)plots, 2); 01801 cpl_bivector_unwrap_vectors(plots[0]); 01802 cpl_bivector_unwrap_vectors(plots[1]); 01803 cpl_bivector_unwrap_vectors(plots[2]); 01804 cpl_free(sss); sss = NULL; 01805 cpl_vector_delete(tmp_spec_data_orig); tmp_spec_data_orig = NULL; 01806 cpl_vector_delete(tmp_spec_data_atmo); tmp_spec_data_atmo = NULL; 01807 cpl_vector_delete(tmp_spec_data_new); tmp_spec_data_new = NULL; 01808 } 01809 cpl_vector_delete(atmos_model); atmos_model = NULL; 01810 } else { 01811 if (line_warning == FALSE) { 01812 cpl_msg_warning("", "No atmospheric model (ATMOS_MODEL) provided! " 01813 "Won't remove any lines."); 01814 line_warning = TRUE; 01815 } 01816 } 01817 } else if (strcmp(star_type, "G") == 0) { 01818 // we have a G star 01819 if (cpl_frameset_count_tags(frameset, SOLAR_SPEC) == 1) { 01820 // interpolate SOLAR_SPEC to same scale as data 01821 // and divide it 01822 KMO_TRY_EXIT_IF_NULL( 01823 tmp_frame = kmo_dfs_get_frame(frameset, SOLAR_SPEC)); 01824 01825 // check if SOLAR_SPEC is the filter_id-one 01826 KMO_TRY_EXIT_IF_NULL( 01827 tmp_sub_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 01828 KMO_TRY_EXIT_IF_NULL( 01829 tmp_str = cpl_propertylist_get_string(tmp_sub_header, FILT_ID)); 01830 KMO_TRY_ASSURE(strcmp(filter_id, tmp_str) == 0, 01831 CPL_ERROR_ILLEGAL_INPUT, 01832 "SOLAR_SPEC model must have primary " 01833 "keyword '%s' equal '%s'!!!", 01834 FILT_ID, filter_id); 01835 cpl_propertylist_delete(tmp_sub_header); tmp_sub_header = NULL; 01836 01837 KMO_TRY_EXIT_IF_NULL( 01838 solar_spec = kmo_interpolate_vector_wcs(tmp_frame, lambda_x)); 01839 01840 // values are set to zero if solar_spec isn't 01841 // overlapping wavelength range of star apectrum 01842 // completely 01843 KMO_TRY_EXIT_IF_ERROR( 01844 cpl_vector_divide(tmp_spec_data, solar_spec)); 01845 cpl_vector_delete(solar_spec); solar_spec = NULL; 01846 } else { 01847 if (print_warning_once == TRUE) { 01848 cpl_msg_warning("","No solar spectrum (SOLAR_SPEC) provided! " 01849 "Can't divide it from extracted " 01850 "standard star spectrum!"); 01851 print_warning_once = FALSE; 01852 } 01853 } 01854 } else { 01855 // cpl_msg_warning("","No startype was provided! Can't" 01856 // " divide solar spectrum for G stars " 01857 // "or fit a profile to atmospheric " 01858 // "transmission for OBAF stars."); 01859 } 01860 01861 if (star_temperature > 0.0) { 01862 // divide blackbody from tmp_spec_data 01863 KMO_TRY_EXIT_IF_ERROR( 01864 kmo_divide_blackbody(tmp_spec_data, lambda_x, star_temperature)); 01865 } 01866 01867 cpl_vector_delete(lambda_x); lambda_x = NULL; 01868 01869 // normalise telluric and its noise 01870 // mean is taken in lambda defined range 01871 KMO_TRY_EXIT_IF_ERROR( 01872 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 01873 filter_id, 01874 tmp_spec_data, 01875 tmp_spec_noise, 01876 &mean_data, 01877 &mean_noise)); 01878 01879 KMO_TRY_EXIT_IF_ERROR( 01880 cpl_vector_divide_scalar(tmp_spec_data, mean_data)); 01881 01882 if (tmp_spec_noise != NULL) { 01883 KMO_TRY_EXIT_IF_ERROR( 01884 cpl_vector_divide_scalar(tmp_spec_noise, mean_noise)); 01885 01886 // set noise spectrum also to zero when solar_spec is too short 01887 KMO_TRY_EXIT_IF_NULL( 01888 ptmp_spec_data = cpl_vector_get_data_const(tmp_spec_data)); 01889 KMO_TRY_EXIT_IF_NULL( 01890 ptmp_spec_noise = cpl_vector_get_data(tmp_spec_noise)); 01891 for (k = 0; k < cpl_vector_get_size(tmp_spec_data); k++) { 01892 if (ptmp_spec_data[k] == 0.0) { 01893 ptmp_spec_noise[k] = 0.0; 01894 } 01895 } 01896 } 01897 KMO_TRY_CHECK_ERROR_STATE(); 01898 01899 // store telluric & error spectrum 01900 stored_telluric_data[ifu_nr-1] = tmp_spec_data; 01901 stored_telluric_noise[ifu_nr-1] = tmp_spec_noise; 01902 01903 // if magnitude is provided 01904 // calculate zeropoint and throughput 01905 if (has_magnitude) { 01906 // calculate QC THROUGHPUT 01907 crpix1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX1); 01908 crval1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL1); 01909 cdelt1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT1); 01910 KMO_TRY_CHECK_ERROR_STATE(); 01911 01912 KMO_TRY_EXIT_IF_ERROR( 01913 kmo_calc_counts(spec_qc, filter_id, 01914 crpix1, crval1, cdelt1, 01915 &counts1, &counts2)); 01916 KMO_TRY_CHECK_ERROR_STATE(); 01917 01918 counts1 /= exptime; 01919 counts2 /= exptime; 01920 01921 stored_qc_throughput[ifu_nr-1] = 01922 kmo_calc_throughput(magnitude1, magnitude2, counts1, counts2, 01923 cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], GAIN), 01924 filter_id); 01925 KMO_TRY_CHECK_ERROR_STATE(); 01926 01927 if (kmclipm_is_nan_or_inf(stored_qc_throughput[ifu_nr-1])) { 01928 stored_qc_throughput[ifu_nr-1] = -1; 01929 } 01930 KMO_TRY_EXIT_IF_ERROR( 01931 kmclipm_update_property_double(stored_sub_tel_data_headers[ifu_nr-1], 01932 QC_THROUGHPUT, 01933 stored_qc_throughput[ifu_nr-1], 01934 "[] IFU throughput")); 01935 01936 // calculate QC ZEROPOINT 01937 zeropoint = kmo_calc_zeropoint(magnitude1, magnitude2, counts1, counts2, cdelt3, filter_id); 01938 if (kmclipm_is_nan_or_inf(zeropoint)) { 01939 zeropoint = -1; 01940 } 01941 KMO_TRY_CHECK_ERROR_STATE(); 01942 01943 KMO_TRY_EXIT_IF_ERROR( 01944 kmclipm_update_property_double(stored_sub_tel_data_headers[ifu_nr-1], 01945 QC_ZEROPOINT, 01946 zeropoint, 01947 "[mag] IFU zeropoint")); 01948 } 01949 cpl_vector_delete(spec_qc);spec_qc = NULL; 01950 } else { 01951 cpl_error_reset(); 01952 // IFU is invalid 01953 KMO_TRY_EXIT_IF_NULL( 01954 stored_sub_tel_data_headers[ifu_nr-1] = 01955 cpl_propertylist_duplicate(sub_header_orig)); 01956 KMO_TRY_EXIT_IF_NULL( 01957 stored_sub_tel_noise_headers[ifu_nr-1] = 01958 cpl_propertylist_duplicate(sub_header_orig)); 01959 KMO_TRY_EXIT_IF_NULL( 01960 stored_sub_psf_headers[ifu_nr-1] = 01961 cpl_propertylist_duplicate(sub_header_orig)); 01962 if (save_cubes) { 01963 KMO_TRY_EXIT_IF_NULL( 01964 stored_sub_cube_data_headers[ifu_nr-1] = 01965 cpl_propertylist_duplicate(sub_header_orig)); 01966 KMO_TRY_EXIT_IF_NULL( 01967 stored_sub_cube_noise_headers[ifu_nr-1] = 01968 cpl_propertylist_duplicate(sub_header_orig)); 01969 } 01970 } 01971 01972 // create EXTNAME keyword as DATA 01973 KMO_TRY_EXIT_IF_NULL( 01974 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_DATA)); 01975 KMO_TRY_EXIT_IF_ERROR( 01976 kmclipm_update_property_string(stored_sub_tel_data_headers[ifu_nr-1], 01977 EXTNAME, extname, "FITS extension name")); 01978 KMO_TRY_EXIT_IF_ERROR( 01979 kmclipm_update_property_string(stored_sub_psf_headers[ifu_nr-1], 01980 EXTNAME, extname, "FITS extension name")); 01981 if (save_cubes) { 01982 KMO_TRY_EXIT_IF_ERROR( 01983 kmclipm_update_property_string(stored_sub_cube_data_headers[ifu_nr-1], 01984 EXTNAME, extname, "FITS extension name")); 01985 } 01986 cpl_free(extname); extname = NULL; 01987 01988 // create EXTNAME keyword as NOISE 01989 if (stored_sub_tel_noise_headers[ifu_nr-1] == NULL) { 01990 KMO_TRY_EXIT_IF_NULL( 01991 stored_sub_tel_noise_headers[ifu_nr-1] = 01992 cpl_propertylist_duplicate( 01993 stored_sub_tel_data_headers[ifu_nr-1])); 01994 } 01995 KMO_TRY_EXIT_IF_NULL( 01996 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE)); 01997 KMO_TRY_EXIT_IF_ERROR( 01998 kmclipm_update_property_string(stored_sub_tel_noise_headers[ifu_nr-1], 01999 EXTNAME, extname, "FITS extension name")); 02000 if (save_cubes) { 02001 KMO_TRY_EXIT_IF_NULL( 02002 stored_sub_cube_noise_headers[ifu_nr-1] = 02003 cpl_propertylist_duplicate( 02004 stored_sub_cube_data_headers[ifu_nr-1])); 02005 KMO_TRY_EXIT_IF_ERROR( 02006 kmclipm_update_property_string(stored_sub_cube_noise_headers[ifu_nr-1], 02007 EXTNAME, extname, "FITS extension name")); 02008 } 02009 cpl_free(extname); extname = NULL; 02010 } // for j ifus (load, process & store) 02011 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 02012 } // for i detectors (load, process & store) 02013 KMO_TRY_CHECK_ERROR_STATE(); 02014 02015 // write QC parameter: nr of std stars 02016 KMO_TRY_EXIT_IF_ERROR( 02017 kmclipm_update_property_int(main_header_tel, QC_NR_STD_STARS, 02018 nr_std_stars, "[] Nr. of std stars")); 02019 02020 // update which IFUs are not used 02021 kmo_print_unused_ifus(unused_ifus_after, TRUE); 02022 02023 KMO_TRY_EXIT_IF_ERROR( 02024 kmo_set_unused_ifus(unused_ifus_after, main_header_tel, "kmo_std_star")); 02025 02026 KMO_TRY_EXIT_IF_NULL( 02027 main_header_psf = cpl_propertylist_duplicate(main_header_tel)); 02028 02029 if (has_magnitude) { 02030 // calculate QC THROUGHPUT MEAN and QC THROUGHPUT SDV 02031 // and update main header 02032 KMO_TRY_EXIT_IF_ERROR( 02033 kmo_calc_mean_throughput(stored_qc_throughput, 02034 nr_devices * KMOS_IFUS_PER_DETECTOR, 02035 &throughput_mean, 02036 &throughput_sdv)); 02037 KMO_TRY_EXIT_IF_ERROR( 02038 kmclipm_update_property_double(main_header_tel, QC_THROUGHPUT_MEAN, 02039 throughput_mean, "[] mean throughput for all detectors")); 02040 KMO_TRY_EXIT_IF_ERROR( 02041 kmclipm_update_property_double(main_header_tel, QC_THROUGHPUT_SDV, 02042 throughput_sdv, "[] stdev throughput for all detectors")); 02043 } 02044 KMO_TRY_CHECK_ERROR_STATE(); 02045 02046 // 02047 // save output data 02048 // 02049 if (!suppress_extension) { 02050 KMO_TRY_EXIT_IF_NULL( 02051 fn_suffix = cpl_sprintf("%s", suffix)); 02052 } else { 02053 KMO_TRY_EXIT_IF_NULL( 02054 fn_suffix = cpl_sprintf("%s", "")); 02055 } 02056 02057 // save primary extension 02058 cpl_msg_info("","Saving STD exposure No. %d", nr_exp+1); 02059 KMO_TRY_EXIT_IF_ERROR( 02060 kmo_dfs_save_main_header(frameset, filename_telluric, fn_suffix, 02061 obj_frame, main_header_tel, parlist, 02062 cpl_func)); 02063 KMO_TRY_EXIT_IF_ERROR( 02064 kmo_dfs_save_main_header(frameset, filename_starspec, fn_suffix, 02065 obj_frame, main_header_tel, parlist, 02066 cpl_func)); 02067 KMO_TRY_EXIT_IF_ERROR( 02068 kmo_dfs_save_main_header(frameset, filename_mask, fn_suffix, 02069 obj_frame, main_header_psf, parlist, 02070 cpl_func)); 02071 KMO_TRY_EXIT_IF_ERROR( 02072 kmo_dfs_save_main_header(frameset, filename_psf, fn_suffix, 02073 obj_frame, main_header_psf, parlist, 02074 cpl_func)); 02075 if (save_cubes) { 02076 KMO_TRY_EXIT_IF_ERROR( 02077 kmo_dfs_save_main_header(frameset, filename_cubes, fn_suffix, 02078 obj_frame, main_header_psf, parlist, 02079 cpl_func)); 02080 } 02081 02082 // save stored frames 02083 for (i = 1; i <= nr_devices; i++) { 02084 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 02085 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 02086 02087 // save telluric-vector 02088 kmclipm_vector *ddd = NULL; 02089 if (stored_telluric_data[ifu_nr-1] != NULL) 02090 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_telluric_data[ifu_nr-1])); 02091 KMO_TRY_EXIT_IF_ERROR( 02092 kmo_dfs_save_vector(ddd, filename_telluric, fn_suffix, 02093 stored_sub_tel_data_headers[ifu_nr-1], 02094 0./0.)); 02095 kmclipm_vector_delete(ddd); ddd =NULL; 02096 02097 if (stored_telluric_noise[ifu_nr-1] != NULL) 02098 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_telluric_noise[ifu_nr-1])); 02099 KMO_TRY_EXIT_IF_ERROR( 02100 kmo_dfs_save_vector(ddd, filename_telluric, fn_suffix, 02101 stored_sub_tel_noise_headers[ifu_nr-1], 02102 0./0.)); 02103 kmclipm_vector_delete(ddd); ddd =NULL; 02104 02105 // save star_spec-vector 02106 if (stored_starspec_data[ifu_nr-1] != NULL) 02107 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_starspec_data[ifu_nr-1])); 02108 KMO_TRY_EXIT_IF_ERROR( 02109 kmo_dfs_save_vector(ddd, filename_starspec, fn_suffix, 02110 stored_sub_tel_data_headers[ifu_nr-1], 02111 0./0.)); 02112 kmclipm_vector_delete(ddd); ddd =NULL; 02113 02114 if (stored_starspec_noise[ifu_nr-1] != NULL) 02115 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_starspec_noise[ifu_nr-1])); 02116 KMO_TRY_EXIT_IF_ERROR( 02117 kmo_dfs_save_vector(ddd, filename_starspec, fn_suffix, 02118 stored_sub_tel_noise_headers[ifu_nr-1], 02119 0./0.)); 02120 kmclipm_vector_delete(ddd); ddd =NULL; 02121 02122 // save psf-image 02123 KMO_TRY_EXIT_IF_ERROR( 02124 kmo_dfs_save_image(stored_psf_data[ifu_nr-1], 02125 filename_psf, fn_suffix, 02126 stored_sub_psf_headers[ifu_nr-1], 02127 0./0.)); 02128 02129 // save mask-image 02130 KMO_TRY_EXIT_IF_ERROR( 02131 kmo_dfs_save_image(stored_mask[ifu_nr-1], 02132 filename_mask, fn_suffix, 02133 stored_sub_psf_headers[ifu_nr-1], 02134 0./0.)); 02135 // save reonstructed cubes 02136 if (save_cubes) { 02137 KMO_TRY_EXIT_IF_ERROR( 02138 kmo_dfs_save_cube(stored_data_cube[ifu_nr-1], 02139 filename_cubes, fn_suffix, 02140 stored_sub_cube_data_headers[ifu_nr-1], 02141 0./0.)); 02142 KMO_TRY_EXIT_IF_ERROR( 02143 kmo_dfs_save_cube(stored_noise_cube[ifu_nr-1], 02144 filename_cubes, fn_suffix, 02145 stored_sub_cube_noise_headers[ifu_nr-1], 02146 0./0.)); 02147 } 02148 } // for j ifus (save stored) 02149 } // for i detectors (save stored) 02150 KMO_TRY_CHECK_ERROR_STATE(); 02151 } // if (frameCnt == 0) 02152 } 02153 KMO_CATCH 02154 { 02155 KMO_CATCH_MSG(); 02156 ret_val = -1; 02157 } 02158 02159 kmo_delete_objSkyStruct(obj_sky_struct); 02160 kmo_free_fits_desc(&desc1); 02161 kmo_free_fits_desc(&desc2); 02162 kmo_free_unused_ifus(unused_ifus_before); unused_ifus_before = NULL; 02163 kmo_free_unused_ifus(unused_ifus_after); unused_ifus_after = NULL; 02164 cpl_free(bounds); bounds = NULL; 02165 cpl_propertylist_delete(main_header_tel); main_header_tel = NULL; 02166 cpl_propertylist_delete(main_header_psf); main_header_psf = NULL; 02167 cpl_vector_delete(atmos_model); atmos_model = NULL; 02168 cpl_vector_delete(solar_spec); solar_spec = NULL; 02169 cpl_table_delete(spec_type_LUT); spec_type_LUT = NULL; 02170 cpl_vector_delete(identified_slices); identified_slices = NULL; 02171 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 02172 for (i = 0; i < nr_devices * KMOS_IFUS_PER_DETECTOR; i++) { 02173 cpl_vector_delete(stored_telluric_data[i]); stored_telluric_data[i] = NULL; 02174 cpl_vector_delete(stored_telluric_noise[i]); stored_telluric_noise[i] = NULL; 02175 cpl_vector_delete(stored_starspec_data[i]); stored_starspec_data[i] = NULL; 02176 cpl_vector_delete(stored_starspec_noise[i]); stored_starspec_noise[i] = NULL; 02177 cpl_image_delete(stored_psf_data[i]); stored_psf_data[i] = NULL; 02178 cpl_propertylist_delete(stored_sub_tel_data_headers[i]); stored_sub_tel_data_headers[i] = NULL; 02179 cpl_propertylist_delete(stored_sub_tel_noise_headers[i]); stored_sub_tel_noise_headers[i] = NULL; 02180 if (save_cubes) { 02181 cpl_propertylist_delete(stored_sub_cube_data_headers[i]); stored_sub_cube_data_headers[i] = NULL; 02182 cpl_propertylist_delete(stored_sub_cube_noise_headers[i]); stored_sub_cube_noise_headers[i] = NULL; 02183 } 02184 cpl_propertylist_delete(stored_sub_psf_headers[i]); stored_sub_psf_headers[i] = NULL; 02185 cpl_image_delete(stored_mask[i]); stored_mask[i] = NULL; 02186 cpl_imagelist_delete(stored_data_cube[i]); stored_data_cube[i] = NULL; 02187 cpl_imagelist_delete(stored_noise_cube[i]); stored_noise_cube[i] = NULL; 02188 } 02189 cpl_free(stored_telluric_data); stored_telluric_data = NULL; 02190 cpl_free(stored_telluric_noise); stored_telluric_noise = NULL; 02191 cpl_free(stored_starspec_data); stored_starspec_data = NULL; 02192 cpl_free(stored_starspec_noise); stored_starspec_noise = NULL; 02193 cpl_free(stored_psf_data); stored_psf_data = NULL; 02194 cpl_free(stored_sub_tel_data_headers); stored_sub_tel_data_headers = NULL; 02195 cpl_free(stored_sub_tel_noise_headers); stored_sub_tel_noise_headers = NULL; 02196 if (save_cubes) { 02197 cpl_free(stored_sub_cube_data_headers); stored_sub_cube_data_headers = NULL; 02198 cpl_free(stored_sub_cube_noise_headers); stored_sub_cube_noise_headers = NULL; 02199 } 02200 cpl_free(stored_sub_psf_headers); stored_sub_psf_headers = NULL; 02201 cpl_free(stored_qc_throughput); stored_qc_throughput = NULL; 02202 cpl_free(suffix); suffix = NULL; 02203 cpl_free(fn_suffix); fn_suffix = NULL; 02204 cpl_free(stored_mask); stored_mask = NULL; 02205 cpl_free(stored_data_cube); stored_data_cube = NULL; 02206 cpl_free(stored_noise_cube); stored_noise_cube = NULL; 02207 cpl_free(grat_id); grat_id = NULL; 02208 cpl_frameset_delete(frameset_std); frameset_std = NULL; 02209 02210 return ret_val; 02211 } 02212
1.7.6.1