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