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