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