|
KMOS Pipeline Reference Manual
1.0.7
|
00001 /* $Id: kmo_std_star.c,v 1.42 2013/02/04 22:20:50 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/02/04 22:20:50 $ 00024 * $Revision: 1.42 $ 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 *tmp_spec_data_copy = NULL, 00421 *tmp_spec_noise = NULL, 00422 *identified_slices = NULL, 00423 *tmp_vec = NULL, 00424 *solar_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 k_band_warning = FALSE, 00438 nr_std_stars = 0, 00439 print_warning_once = TRUE, 00440 flux = FALSE, 00441 band_method = 0, 00442 save_cubes = FALSE, 00443 has_magnitude = TRUE, 00444 nr_split_mag = 0; 00445 00446 const int *punused_ifus = NULL; 00447 00448 objSkyFrameTableStruct *obj_sky_struct = NULL; 00449 00450 double *stored_qc_throughput = NULL, 00451 star_temperature = 0.0, 00452 neighborhoodRange = 1.001, 00453 cpos_rej = 0.0, 00454 cneg_rej = 0.0, 00455 zeropoint = -1.0, 00456 throughput_mean = -1.0, 00457 throughput_sdv = -1.0, 00458 std_trace = -1.0, 00459 counts1 = 0.0, 00460 counts2 = 0.0, 00461 magnitude1 = 0.0, 00462 magnitude2 = 0.0, 00463 exptime = 0., 00464 cdelt3 = 0., 00465 mean_data = 0., 00466 mean_noise = 0., 00467 *ptmp_spec_noise = NULL, 00468 crpix1 = 0., 00469 crval1 = 0., 00470 cdelt1 = 0.; 00471 00472 const double *ptmp_spec_data = NULL; 00473 00474 cpl_propertylist *main_header_tel = NULL, 00475 *main_header_psf = NULL, 00476 *sub_header_orig = NULL, 00477 *tmp_sub_header = NULL, 00478 *tmp_header = NULL, 00479 **stored_sub_tel_data_headers = NULL, 00480 **stored_sub_tel_noise_headers = NULL, 00481 **stored_sub_psf_headers = NULL, 00482 *pl_psf = NULL; 00483 00484 cpl_property *p = NULL; 00485 00486 cpl_table *spec_type_LUT = NULL, 00487 *band_table = NULL;; 00488 00489 main_fits_desc desc1, 00490 desc2; 00491 00492 char *extname = NULL, 00493 *keyword = NULL, 00494 filename_telluric[256], 00495 filename_starspec[256], 00496 filename_psf[256], 00497 filename_mask[256], 00498 filename_cubes[256], 00499 *suffix = NULL, 00500 spec_class[256], 00501 lum_class[256], 00502 star_type[2], 00503 *tmp_band_method = getenv("KMO_BAND_METHOD"), 00504 **split_mag = NULL, 00505 *grat_id = NULL; 00506 00507 const char *filter_id = NULL, 00508 *spec_type = NULL, 00509 *magnitude_txt = NULL, 00510 *imethod = NULL, 00511 *cmethod = NULL, 00512 *fmethod = NULL, 00513 *tmp_str = NULL; 00514 00515 gridDefinition gd; 00516 00517 cpl_array **unused_ifus_before = NULL, 00518 **unused_ifus_after = NULL; 00519 cpl_frameset *frameset_std = NULL; 00520 00521 KMO_TRY 00522 { 00523 kmo_init_fits_desc(&desc1); 00524 kmo_init_fits_desc(&desc2); 00525 00526 /* --- check input --- */ 00527 KMO_TRY_ASSURE((parlist != NULL) && 00528 (frameset != NULL), 00529 CPL_ERROR_NULL_INPUT, 00530 "Not all input data is provided!"); 00531 00532 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, STD) >= 1, 00533 CPL_ERROR_ILLEGAL_INPUT, 00534 "At least one STD frame is required!"); 00535 if (cpl_frameset_count_tags(frameset, STD) == 1) { 00536 cpl_msg_warning("", "At least two STD frames should be provided " 00537 "in order to apply sky subtraction!"); 00538 } 00539 00540 KMO_TRY_ASSURE((cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) || 00541 (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 0), 00542 CPL_ERROR_FILE_NOT_FOUND, 00543 "Exactly one ILLUM_CORR frame is required!"); 00544 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, XCAL) == 1, 00545 CPL_ERROR_FILE_NOT_FOUND, 00546 "Exactly one XCAL frame is required!"); 00547 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, YCAL) == 1, 00548 CPL_ERROR_FILE_NOT_FOUND, 00549 "Exactly one YCAL frame is required!"); 00550 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, LCAL) == 1, 00551 CPL_ERROR_FILE_NOT_FOUND, 00552 "Exactly one LCAL frame is required!"); 00553 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, MASTER_FLAT) == 1, 00554 CPL_ERROR_FILE_NOT_FOUND, 00555 "Exactly one MASTER_FLAT frame is required!"); 00556 KMO_TRY_ASSURE(cpl_frameset_count_tags(frameset, WAVE_BAND) == 1, 00557 CPL_ERROR_FILE_NOT_FOUND, 00558 "Exactly one WAVE_BAND frame is required!"); 00559 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_std_star") == 1, 00560 CPL_ERROR_ILLEGAL_INPUT, 00561 "Cannot identify RAW and CALIB frames!"); 00562 00563 /* --- get parameters --- */ 00564 cpl_msg_info("", "--- Parameter setup for kmo_std_star ------"); 00565 00566 KMO_TRY_EXIT_IF_NULL( 00567 spec_type = kmo_dfs_get_parameter_string(parlist, 00568 "kmos.kmo_std_star.startype")); 00569 KMO_TRY_EXIT_IF_ERROR( 00570 kmo_dfs_print_parameter_help(parlist, 00571 "kmos.kmo_std_star.startype")); 00572 00573 KMO_TRY_EXIT_IF_NULL( 00574 imethod = kmo_dfs_get_parameter_string(parlist, 00575 "kmos.kmo_std_star.imethod")); 00576 KMO_TRY_ASSURE((strcmp(imethod, "NN") == 0) || 00577 (strcmp(imethod, "lwNN") == 0) || 00578 (strcmp(imethod, "swNN") == 0) || 00579 (strcmp(imethod, "MS") == 0) || 00580 (strcmp(imethod, "CS") == 0), 00581 CPL_ERROR_ILLEGAL_INPUT, 00582 "method must be either \"NN\", \"lwNN\", " 00583 "\"swNN\", \"MS\" or \"CS\"!"); 00584 KMO_TRY_EXIT_IF_ERROR( 00585 kmo_dfs_print_parameter_help(parlist, 00586 "kmos.kmo_std_star.imethod")); 00587 00588 KMO_TRY_EXIT_IF_NULL( 00589 fmethod = kmo_dfs_get_parameter_string(parlist, 00590 "kmos.kmo_std_star.fmethod")); 00591 KMO_TRY_ASSURE((strcmp(fmethod, "gauss") == 0) || 00592 (strcmp(fmethod, "moffat") == 0), 00593 CPL_ERROR_ILLEGAL_INPUT, 00594 "fmethod must be either 'gauss' or " 00595 "'moffat' !"); 00596 KMO_TRY_EXIT_IF_ERROR( 00597 kmo_dfs_print_parameter_help(parlist, 00598 "kmos.kmo_std_star.method")); 00599 00600 neighborhoodRange = kmo_dfs_get_parameter_double(parlist, 00601 "kmos.kmo_std_star.neighborhoodRange"); 00602 KMO_TRY_CHECK_ERROR_STATE(); 00603 KMO_TRY_ASSURE(neighborhoodRange > 0.0, 00604 CPL_ERROR_ILLEGAL_INPUT, 00605 "neighborhoodRange must be greater than 0.0"); 00606 KMO_TRY_EXIT_IF_ERROR( 00607 kmo_dfs_print_parameter_help(parlist, 00608 "kmos.kmo_std_star.neighborhoodRange")); 00609 00610 magnitude_txt = kmo_dfs_get_parameter_string(parlist, 00611 "kmos.kmo_std_star.magnitude"); 00612 KMO_TRY_CHECK_ERROR_STATE(); 00613 KMO_TRY_EXIT_IF_ERROR( 00614 kmo_dfs_print_parameter_help(parlist, 00615 "kmos.kmo_std_star.magnitude")); 00616 00617 flux = kmo_dfs_get_parameter_bool(parlist, 00618 "kmos.kmo_std_star.flux"); 00619 KMO_TRY_ASSURE((flux == FALSE) || (flux == TRUE), 00620 CPL_ERROR_ILLEGAL_INPUT, 00621 "flux must be either FALSE or TRUE!"); 00622 KMO_TRY_EXIT_IF_ERROR( 00623 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.flux")); 00624 00625 save_cubes = kmo_dfs_get_parameter_bool(parlist, 00626 "kmos.kmo_std_star.save-cubes"); 00627 KMO_TRY_ASSURE((save_cubes == FALSE) || (save_cubes == TRUE), 00628 CPL_ERROR_ILLEGAL_INPUT, 00629 "save_cubes must be either FALSE or TRUE!"); 00630 KMO_TRY_EXIT_IF_ERROR( 00631 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_std_star.save-cubes")); 00632 00633 kmo_band_pars_load(parlist, "kmos.kmo_std_star"); 00634 00635 KMO_TRY_EXIT_IF_ERROR( 00636 kmo_combine_pars_load(parlist, 00637 "kmos.kmo_std_star", 00638 &cmethod, 00639 &cpos_rej, 00640 &cneg_rej, 00641 &citer, 00642 &cmin, 00643 &cmax, 00644 FALSE)); 00645 cpl_msg_info("", "-------------------------------------------"); 00646 00647 // 00648 // Check if magnitude/frameset is valid and if throughput and zeropoint should be calculated 00649 // 00650 00651 // Check if all STD frames have the same GRAT-ID 00652 // if not: don't calculate zeropoint and throughput 00653 KMO_TRY_EXIT_IF_NULL( 00654 frameset_std = cpl_frameset_new()); 00655 00656 KMO_TRY_EXIT_IF_NULL( 00657 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00658 KMO_TRY_EXIT_IF_NULL( 00659 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 00660 KMO_TRY_EXIT_IF_NULL( 00661 grat_id = cpl_sprintf("%s", cpl_propertylist_get_string(tmp_header, "ESO INS GRAT1 ID"))); 00662 KMO_TRY_EXIT_IF_ERROR( 00663 cpl_frameset_insert(frameset_std, cpl_frame_duplicate(tmp_frame))); 00664 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00665 00666 KMO_TRY_EXIT_IF_NULL( 00667 tmp_frame = kmo_dfs_get_frame(frameset, NULL)); 00668 while (tmp_frame != NULL ) { 00669 KMO_TRY_EXIT_IF_NULL( 00670 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 00671 if (strcmp(grat_id, cpl_propertylist_get_string(tmp_header, "ESO INS GRAT1 ID")) == 0) { 00672 // same grating 00673 KMO_TRY_EXIT_IF_ERROR( 00674 cpl_frameset_insert(frameset_std, cpl_frame_duplicate(tmp_frame))); 00675 } else { 00676 // there are STD frames with different gratings 00677 if (has_magnitude) { 00678 cpl_msg_warning(cpl_func, "The STD frames have different gratings," 00679 "following QC parameters won't be " 00680 "calculated: QC ZEROPOINT, QC THROUGHPUT," 00681 "QC THROUGHPUT MEAN and QC THROUGHPUT STD"); 00682 } 00683 has_magnitude = FALSE; 00684 } 00685 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00686 00687 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 00688 KMO_TRY_CHECK_ERROR_STATE(); 00689 } 00690 KMO_TRY_CHECK_ERROR_STATE(); 00691 00692 if (has_magnitude) { 00693 // all STD frames have the same GRAT-ID 00694 // now check source of magnitude (user or keyword) 00695 KMO_TRY_EXIT_IF_NULL( 00696 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00697 KMO_TRY_EXIT_IF_NULL( 00698 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 00699 00700 if (strcmp(magnitude_txt, "") == 0) { 00701 // no user defined magnitude 00702 00703 // check for magnitude-keyword 00704 if ((cpl_propertylist_has(tmp_header, STDSTAR_MAG)) && 00705 (cpl_propertylist_get_type(tmp_header, STDSTAR_MAG) == CPL_TYPE_STRING)) 00706 { 00707 KMO_TRY_EXIT_IF_NULL( 00708 magnitude_txt = cpl_propertylist_get_string(tmp_header, STDSTAR_MAG)); 00709 KMO_TRY_EXIT_IF_NULL( 00710 split_mag = kmo_strsplit(magnitude_txt, ",", &nr_split_mag)); 00711 00712 // check if band and number of magnitudes matches 00713 if ((nr_split_mag == 2) && 00714 (strcmp(grat_id, "HK") == 0)) 00715 { 00716 magnitude1 = atof(split_mag[0]); 00717 magnitude2 = atof(split_mag[1]); 00718 cpl_msg_info("", "Magnitude in H: %g", magnitude1); 00719 cpl_msg_info("", "Magnitude in K: %g", magnitude2); 00720 } else if ((nr_split_mag >= 1) && 00721 ((strcmp(grat_id, "K") == 0) || 00722 (strcmp(grat_id, "H") == 0) || 00723 (strcmp(grat_id, "IZ") == 0) || 00724 (strcmp(grat_id, "YJ") == 0))) 00725 { 00726 magnitude1 = atof(split_mag[0]); 00727 cpl_msg_info("", "Magnitude in %s: %g", grat_id, magnitude1); 00728 } else { 00729 // keyword STDSTAR_MAG doesn't match filter 00730 has_magnitude = FALSE; 00731 cpl_msg_warning(cpl_func, "The keyword %s doesn't match to grating'," 00732 "following QC parameters won't be " 00733 "calculated: QC ZEROPOINT, QC THROUGHPUT," 00734 "QC THROUGHPUT MEAN and QC THROUGHPUT STD", STDSTAR_MAG); 00735 } 00736 kmo_strfreev(split_mag); 00737 } else { 00738 // keyword STDSTAR_MAG unavailable or wrong type 00739 has_magnitude = FALSE; 00740 cpl_msg_warning(cpl_func, "The keyword %s is not set or of wrong type," 00741 "following QC parameters won't be " 00742 "calculated: QC ZEROPOINT, QC THROUGHPUT," 00743 "QC THROUGHPUT MEAN and QC THROUGHPUT STD", STDSTAR_MAG); 00744 } 00745 } else { 00746 // magnitude is user specified 00747 cpl_msg_info(cpl_func, "Magnitude has been specified by user. Any " 00748 "value in keyword %s will be ignored.", STDSTAR_MAG); 00749 00750 KMO_TRY_EXIT_IF_NULL( 00751 split_mag = kmo_strsplit(magnitude_txt, ",", &nr_split_mag)); 00752 switch (nr_split_mag) { 00753 case 1: 00754 magnitude1 = atof(split_mag[0]); 00755 cpl_msg_info("", "Magnitude in %s: %g", grat_id, magnitude1); 00756 break; 00757 case 2: 00758 magnitude1 = atof(split_mag[0]); 00759 magnitude2 = atof(split_mag[1]); 00760 cpl_msg_info("", "Magnitude in H: %g", magnitude1); 00761 cpl_msg_info("", "Magnitude in K: %g", magnitude2); 00762 break; 00763 default: 00764 KMO_TRY_ASSURE(1 == 0, 00765 CPL_ERROR_ILLEGAL_INPUT, 00766 "Provided magnitude was in wrong format! " 00767 "Either a single float value or two separated by comma"); 00768 } 00769 kmo_strfreev(split_mag); 00770 } 00771 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00772 } // if (has_magnitude) 00773 cpl_msg_info("", "-------------------------------------------"); 00774 00775 // 00776 // check for spectral type (--startype) (user or keyword) 00777 // 00778 if (strcmp(spec_type, "") == 0) { 00779 // no user defined startype 00780 00781 KMO_TRY_EXIT_IF_NULL( 00782 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00783 KMO_TRY_EXIT_IF_NULL( 00784 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 00785 00786 // check for startype-keyword 00787 if ((cpl_propertylist_has(tmp_header, STDSTAR_TYPE)) && 00788 (cpl_propertylist_get_type(tmp_header, STDSTAR_TYPE) == CPL_TYPE_STRING)) 00789 { 00790 KMO_TRY_EXIT_IF_NULL( 00791 spec_type = cpl_propertylist_get_string(tmp_header, STDSTAR_TYPE)); 00792 } else { 00793 // keyword STDSTAR_TYPE unavailable or wrong type 00794 } 00795 } else { 00796 // startype is user specified 00797 cpl_msg_info(cpl_func, "Type of star has been specified by user. Any " 00798 "value in keyword %s will be ignored.", STDSTAR_TYPE); 00799 } 00800 00801 if (strlen(spec_type) > 0) { 00802 kmo_get_spec_type(spec_type, spec_class, lum_class); 00803 strncpy(star_type, spec_class, 1); 00804 star_type[1] = '\0'; 00805 cpl_msg_info("", "Spectral class: %s", spec_class); 00806 cpl_msg_info("", "Luminosity class: %s", lum_class); 00807 } else { 00808 spec_class[0] = '\0'; 00809 lum_class[0] = '\0'; 00810 star_type[0] = '\0'; 00811 cpl_msg_warning(cpl_func, "The keyword %s is not set or of wrong type nor was it provided by the user. " 00812 "Can't divide solar spectrum for G stars or fit a profile " 00813 "to atmospheric transmission for OBAF stars and can't " 00814 "divide blackbody for any star.", STDSTAR_TYPE); 00815 } 00816 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 00817 cpl_msg_info("", "-------------------------------------------"); 00818 00819 // assure that filters, grating and rotation offsets match for 00820 // XCAL, YCAL, LCAL and for data frame to reconstruct (except DARK 00821 // frames) 00822 // check if filter_id and grating_id match for all detectors 00823 KMO_TRY_EXIT_IF_ERROR( 00824 kmo_check_frameset_setup(frameset, XCAL, FALSE, FALSE, TRUE)); 00825 KMO_TRY_EXIT_IF_ERROR( 00826 kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE)); 00827 KMO_TRY_EXIT_IF_ERROR( 00828 kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE)); 00829 KMO_TRY_EXIT_IF_ERROR( 00830 kmo_check_frame_setup(frameset, XCAL, MASTER_FLAT, TRUE, FALSE, TRUE)); 00831 KMO_TRY_EXIT_IF_ERROR( 00832 kmo_check_frame_setup(frameset, XCAL, STD, FALSE, FALSE, TRUE)); 00833 // KMO_TRY_EXIT_IF_ERROR( 00834 // kmo_check_cal_frames_rotangle(frameset, XCAL, YCAL)); 00835 // KMO_TRY_EXIT_IF_ERROR( 00836 // kmo_check_cal_frames_rotangle(frameset, XCAL, LCAL)); 00837 00838 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 00839 KMO_TRY_EXIT_IF_ERROR( 00840 kmo_check_frame_setup(frameset, XCAL, ILLUM_CORR, TRUE, FALSE, FALSE)); 00841 } 00842 00843 // check descriptors of all frames 00844 KMO_TRY_EXIT_IF_NULL( 00845 xcal_frame = kmo_dfs_get_frame(frameset, XCAL)); 00846 00847 desc1 = kmo_identify_fits_header(cpl_frame_get_filename(xcal_frame)); 00848 KMO_TRY_CHECK_ERROR_STATE(); 00849 00850 KMO_TRY_ASSURE((desc1.nr_ext % 3 == 0) && 00851 (desc1.ex_badpix == FALSE) && 00852 (desc1.fits_type == f2d_fits) && 00853 (desc1.frame_type == detector_frame), 00854 CPL_ERROR_ILLEGAL_INPUT, 00855 "XCAL isn't in the correct format!!!"); 00856 00857 KMO_TRY_EXIT_IF_NULL( 00858 ycal_frame = kmo_dfs_get_frame(frameset, YCAL)); 00859 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(ycal_frame)); 00860 KMO_TRY_CHECK_ERROR_STATE(); 00861 00862 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 00863 (desc1.ex_badpix == desc2.ex_badpix) && 00864 (desc1.fits_type == desc2.fits_type) && 00865 (desc1.frame_type == desc2.frame_type), 00866 CPL_ERROR_ILLEGAL_INPUT, 00867 "YCAL isn't in the correct format!!!"); 00868 kmo_free_fits_desc(&desc2); 00869 kmo_init_fits_desc(&desc2); 00870 00871 KMO_TRY_EXIT_IF_NULL( 00872 lcal_frame = kmo_dfs_get_frame(frameset, LCAL)); 00873 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(lcal_frame)); 00874 KMO_TRY_CHECK_ERROR_STATE(); 00875 00876 KMO_TRY_ASSURE((desc1.nr_ext == desc2.nr_ext) && 00877 (desc1.ex_badpix == desc2.ex_badpix) && 00878 (desc1.fits_type == desc2.fits_type) && 00879 (desc1.frame_type == desc2.frame_type), 00880 CPL_ERROR_ILLEGAL_INPUT, 00881 "YCAL isn't in the correct format!!!"); 00882 kmo_free_fits_desc(&desc2); 00883 kmo_init_fits_desc(&desc2); 00884 00885 KMO_TRY_EXIT_IF_NULL( 00886 flat_frame = kmo_dfs_get_frame(frameset, MASTER_FLAT)); 00887 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(flat_frame)); 00888 KMO_TRY_CHECK_ERROR_STATE(); 00889 00890 KMO_TRY_ASSURE((desc2.nr_ext % 6 == 0) && 00891 (desc1.ex_badpix == desc2.ex_badpix) && 00892 (desc1.fits_type == desc2.fits_type) && 00893 (desc1.frame_type == desc2.frame_type), 00894 CPL_ERROR_ILLEGAL_INPUT, 00895 "MASTER_FLAT isn't in the correct format!!!"); 00896 kmo_free_fits_desc(&desc2); 00897 kmo_init_fits_desc(&desc2); 00898 00899 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 00900 KMO_TRY_EXIT_IF_NULL( 00901 illum_frame = kmo_dfs_get_frame(frameset, ILLUM_CORR)); 00902 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(illum_frame)); 00903 KMO_TRY_CHECK_ERROR_STATE(); 00904 KMO_TRY_ASSURE(((desc2.nr_ext == 24) || (desc2.nr_ext == 48)) && 00905 (desc2.ex_badpix == FALSE) && 00906 (desc2.fits_type == f2i_fits) && 00907 (desc2.frame_type == ifu_frame), 00908 CPL_ERROR_ILLEGAL_INPUT, 00909 "ILLUM_CORR isn't in the correct format!!!"); 00910 kmo_free_fits_desc(&desc2); 00911 kmo_init_fits_desc(&desc2); 00912 } 00913 00914 if (cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) == 1) { 00915 KMO_TRY_EXIT_IF_NULL( 00916 tmp_frame = kmo_dfs_get_frame(frameset, SPEC_TYPE_LOOKUP)); 00917 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 00918 KMO_TRY_CHECK_ERROR_STATE(); 00919 KMO_TRY_ASSURE((desc2.nr_ext == 1) && 00920 (desc2.ex_badpix == FALSE) && 00921 (desc2.fits_type == f2l_fits) && 00922 (desc2.frame_type == list_frame), 00923 CPL_ERROR_ILLEGAL_INPUT, 00924 "SPEC_TYPE_LOOKUP isn't in the correct format!!!"); 00925 kmo_free_fits_desc(&desc2); 00926 kmo_init_fits_desc(&desc2); 00927 } 00928 00929 if (cpl_frameset_count_tags(frameset, SOLAR_SPEC) == 1) { 00930 KMO_TRY_EXIT_IF_NULL( 00931 tmp_frame = kmo_dfs_get_frame(frameset, SOLAR_SPEC)); 00932 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 00933 KMO_TRY_CHECK_ERROR_STATE(); 00934 KMO_TRY_ASSURE((desc2.nr_ext == 1) && 00935 (desc2.ex_badpix == FALSE) && 00936 (desc2.fits_type == f1s_fits) && 00937 (desc2.frame_type == spectrum_frame), 00938 CPL_ERROR_ILLEGAL_INPUT, 00939 "SOLAR_SPEC isn't in the correct format!!!"); 00940 kmo_free_fits_desc(&desc2); 00941 kmo_init_fits_desc(&desc2); 00942 } 00943 00944 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 00945 KMO_TRY_EXIT_IF_NULL( 00946 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL)); 00947 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 00948 KMO_TRY_CHECK_ERROR_STATE(); 00949 KMO_TRY_ASSURE((desc2.nr_ext == 1) && 00950 (desc2.ex_badpix == FALSE) && 00951 (desc2.fits_type == f1s_fits) && 00952 (desc2.frame_type == spectrum_frame), 00953 CPL_ERROR_ILLEGAL_INPUT, 00954 "ATMOS_MODEL isn't in the correct format!!!"); 00955 kmo_free_fits_desc(&desc2); 00956 kmo_init_fits_desc(&desc2); 00957 } 00958 00959 KMO_TRY_EXIT_IF_NULL( 00960 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00961 while (tmp_frame != NULL ) { 00962 desc2 = kmo_identify_fits_header(cpl_frame_get_filename(tmp_frame)); 00963 KMO_TRY_CHECK_ERROR_STATE(); 00964 KMO_TRY_ASSURE((desc2.nr_ext == 3) && 00965 (desc2.ex_badpix == FALSE) && 00966 (desc2.fits_type == raw_fits) && 00967 (desc2.frame_type == detector_frame), 00968 CPL_ERROR_ILLEGAL_INPUT, 00969 "STD isn't in the correct format!!!"); 00970 nr_devices = desc2.nr_ext; 00971 kmo_free_fits_desc(&desc2); 00972 kmo_init_fits_desc(&desc2); 00973 00974 tmp_frame = kmo_dfs_get_frame(frameset, NULL); 00975 KMO_TRY_CHECK_ERROR_STATE(); 00976 } 00977 KMO_TRY_EXIT_IF_NULL( 00978 tmp_frame = kmo_dfs_get_frame(frameset, STD)); 00979 KMO_TRY_EXIT_IF_NULL( 00980 suffix = kmo_dfs_get_suffix(tmp_frame, TRUE, FALSE)); 00981 00982 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00983 cpl_msg_info("", "(grating 1, 2 & 3, rotation angle)"); 00984 00985 // check which IFUs are active for all frames 00986 KMO_TRY_EXIT_IF_NULL( 00987 unused_ifus_before = kmo_get_unused_ifus(frameset, 0, 0)); 00988 00989 KMO_TRY_EXIT_IF_NULL( 00990 unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before)); 00991 00992 kmo_print_unused_ifus(unused_ifus_before, FALSE); 00993 00994 /* --- load data --- */ 00995 00996 if ((cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) == 1) && 00997 ((strlen(spec_class) > 0) || (strlen(lum_class) > 0))) 00998 { 00999 // get star temperature out of SPEC_TYPE_LOOKUP table 01000 KMO_TRY_EXIT_IF_NULL( 01001 spec_type_LUT = kmo_dfs_load_table(frameset, SPEC_TYPE_LOOKUP, 1, 0)); 01002 star_temperature = kmo_get_temperature(spec_type_LUT, spec_class, lum_class); 01003 KMO_TRY_CHECK_ERROR_STATE(); 01004 } else if (cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) != 1) { 01005 cpl_msg_warning("","No SPEC_TYPE_LOOKUP was provided! Can't divide blackbody."); 01006 } else if ((strlen(spec_class) == 0) || (strlen(lum_class) == 0)) { 01007 // cpl_msg_warning("","No startype was provided! Can't " 01008 // "divide blackbody."); 01009 } 01010 01011 // allocate intermediate memory 01012 KMO_TRY_EXIT_IF_NULL( 01013 stored_telluric_data = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01014 sizeof(cpl_vector*))); 01015 KMO_TRY_EXIT_IF_NULL( 01016 stored_telluric_noise = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01017 sizeof(cpl_vector*))); 01018 KMO_TRY_EXIT_IF_NULL( 01019 stored_starspec_data = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01020 sizeof(cpl_vector*))); 01021 KMO_TRY_EXIT_IF_NULL( 01022 stored_starspec_noise = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01023 sizeof(cpl_vector*))); 01024 KMO_TRY_EXIT_IF_NULL( 01025 stored_psf_data = (cpl_image**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01026 sizeof(cpl_image*))); 01027 KMO_TRY_EXIT_IF_NULL( 01028 stored_mask = (cpl_image**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01029 sizeof(cpl_image*))); 01030 KMO_TRY_EXIT_IF_NULL( 01031 stored_data_cube = (cpl_imagelist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01032 sizeof(cpl_imagelist*))); 01033 KMO_TRY_EXIT_IF_NULL( 01034 stored_noise_cube = (cpl_imagelist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01035 sizeof(cpl_imagelist*))); 01036 KMO_TRY_EXIT_IF_NULL( 01037 stored_qc_throughput = (double*)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01038 sizeof(double))); 01039 KMO_TRY_EXIT_IF_NULL( 01040 stored_sub_psf_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01041 sizeof(cpl_propertylist*))); 01042 KMO_TRY_EXIT_IF_NULL( 01043 stored_sub_tel_data_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01044 sizeof(cpl_propertylist*))); 01045 KMO_TRY_EXIT_IF_NULL( 01046 stored_sub_tel_noise_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01047 sizeof(cpl_propertylist*))); 01048 01049 // get bounds 01050 KMO_TRY_EXIT_IF_NULL( 01051 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(xcal_frame), 0)); 01052 KMO_TRY_EXIT_IF_NULL( 01053 bounds = kmclipm_extract_bounds(tmp_header)); 01054 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01055 01056 // setup grid definition, wavelength start and end points will be set 01057 // in the detector loop 01058 KMO_TRY_EXIT_IF_ERROR( 01059 kmclipm_setup_grid(&gd, imethod, neighborhoodRange)); 01060 01061 // get valid STD frames with objects in it and associated sky exposures 01062 KMO_TRY_EXIT_IF_NULL( 01063 obj_sky_struct = kmo_get_obj_sky_frame_table(frameset_std, &frameCnt, STD)); 01064 01065 // loop the object-sky pairs 01066 if (frameCnt == 0) { 01067 cpl_msg_warning(cpl_func,"Not a single frame contains an object"); 01068 } else { 01069 strcpy(filename_telluric, TELLURIC); 01070 strcpy(filename_starspec, STAR_SPEC); 01071 strcpy(filename_psf, STD_IMAGE); 01072 strcpy(filename_mask, STD_MASK); 01073 strcpy(filename_cubes, STD_CUBE); 01074 01075 obj_frame = obj_sky_struct[nr_exp].objectFrame; 01076 KMO_TRY_EXIT_IF_NULL( 01077 main_header_tel = kmclipm_propertylist_load(cpl_frame_get_filename(obj_frame), 0)); 01078 01079 exptime = cpl_propertylist_get_double(main_header_tel, EXPTIME); 01080 KMO_TRY_CHECK_ERROR_STATE(); 01081 01082 // load, process & store frames 01083 01084 for (i = 1; i <= nr_devices; i++) { 01085 // extract LCAL image close to ROTANGLE 0. assuming that the wavelength range 01086 // doesn't differ too much with different ROTANGLEs. 01087 double rotangle_found; 01088 KMO_TRY_EXIT_IF_NULL( 01089 lcal = kmo_dfs_load_cal_image(frameset, LCAL, i, FALSE, 0., FALSE, NULL, 01090 &rotangle_found)); 01091 01092 if (tmp_band_method != NULL) { 01093 band_method = atoi(tmp_band_method); 01094 } 01095 01096 // get filter for this detector 01097 // ESO INS FILTi ID 01098 KMO_TRY_EXIT_IF_NULL( 01099 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, i, IFU_FILTID_POSTFIX)); 01100 filter_id = cpl_propertylist_get_string(main_header_tel, keyword); 01101 cpl_free(keyword); keyword = NULL; 01102 01103 KMO_TRY_EXIT_IF_NULL( 01104 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0)); 01105 KMO_TRY_EXIT_IF_ERROR( 01106 kmclipm_setup_grid_band_lcal(&gd, lcal, filter_id, 01107 band_method, band_table)); 01108 cpl_image_delete(lcal); lcal = NULL; 01109 cpl_table_delete(band_table); band_table = NULL; 01110 01111 // load sub_header of original F2D image 01112 KMO_TRY_EXIT_IF_NULL( 01113 sub_header_orig = kmclipm_propertylist_load( cpl_frame_get_filename(obj_frame), i)); 01114 01115 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 01116 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 01117 // check if IFU is valid according to main header keywords & 01118 // calibration files 01119 // AND check if there is a sky frame available for this IFU 01120 01121 kmo_collapse_object_sky_frame_table(frameCnt, obj_sky_struct, ifu_nr, 01122 &obj_frame, &sky_frame); 01123 01124 KMO_TRY_EXIT_IF_NULL( 01125 punused_ifus = cpl_array_get_data_int_const(unused_ifus_after[i-1])); 01126 01127 // Search for keyword ESO OCS ARMi NOTUSED 01128 // If not present (CPL_ERROR_DATA_NOT_FOUND) we will eventually 01129 // process standard star 01130 KMO_TRY_EXIT_IF_NULL( 01131 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, IFU_VALID_POSTFIX)); 01132 tmp_str = cpl_propertylist_get_string(main_header_tel, keyword); 01133 cpl_free(keyword); keyword = NULL; 01134 01135 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 01136 (bounds[2*(ifu_nr-1)] != -1) && 01137 (bounds[2*(ifu_nr-1)+1] != -1) && 01138 (sky_frame != NULL) && 01139 (punused_ifus[j] == 0)) 01140 { 01141 cpl_error_reset(); 01142 // IFU is valid 01143 01144 if (sky_frame != NO_CORRESPONDING_SKYFRAME) { 01145 cpl_msg_info("","Processing standard star in IFU %d\n" 01146 "(std. star in file: %s,\n" 01147 " sky in file: %s)", ifu_nr, 01148 cpl_frame_get_filename(obj_frame), 01149 cpl_frame_get_filename(sky_frame)); 01150 } else { 01151 sky_frame = NULL; 01152 cpl_msg_warning("","Processing standard star in IFU %d\n" 01153 "(std. star in file: %s, no corresponding sky frame", 01154 ifu_nr, cpl_frame_get_filename(obj_frame)); 01155 } 01156 01157 nr_std_stars++; 01158 01159 // calculate WCS and make copies of sub_header 01160 KMO_TRY_EXIT_IF_NULL( 01161 tmp_sub_header = cpl_propertylist_duplicate(sub_header_orig)); 01162 KMO_TRY_EXIT_IF_ERROR( 01163 kmo_calc_wcs(main_header_tel, tmp_sub_header, 01164 ifu_nr, gd.l.start, gd.l.delta)); 01165 KMO_TRY_EXIT_IF_NULL( 01166 stored_sub_tel_data_headers[ifu_nr-1] = 01167 cpl_propertylist_duplicate(tmp_sub_header)); 01168 KMO_TRY_EXIT_IF_NULL( 01169 stored_sub_psf_headers[ifu_nr-1] = 01170 cpl_propertylist_duplicate(tmp_sub_header)); 01171 cpl_propertylist_delete(tmp_sub_header); 01172 tmp_sub_header = NULL; 01173 01174 // for telluric-headers copy CRPIX3 to CRPIX1, 01175 // delete CRPIX3 etc. 01176 // CRVAL 01177 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRVAL1); 01178 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRVAL2); 01179 KMO_TRY_CHECK_ERROR_STATE(); 01180 KMO_TRY_EXIT_IF_NULL( 01181 p = cpl_propertylist_get_property(stored_sub_tel_data_headers[ifu_nr-1], CRVAL3)); 01182 KMO_TRY_EXIT_IF_ERROR( 01183 cpl_property_set_name (p, CRVAL1)); 01184 01185 // CRPIX 01186 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRPIX1); 01187 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRPIX2); 01188 KMO_TRY_CHECK_ERROR_STATE(); 01189 KMO_TRY_EXIT_IF_NULL( 01190 p = cpl_propertylist_get_property(stored_sub_tel_data_headers[ifu_nr-1], CRPIX3)); 01191 KMO_TRY_EXIT_IF_ERROR( 01192 cpl_property_set_name (p, CRPIX1)); 01193 01194 // CDELT 01195 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CDELT1); 01196 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CDELT2); 01197 KMO_TRY_CHECK_ERROR_STATE(); 01198 KMO_TRY_EXIT_IF_NULL( 01199 p = cpl_propertylist_get_property(stored_sub_tel_data_headers[ifu_nr-1], CDELT3)); 01200 01201 cdelt3 = cpl_property_get_double(p); 01202 KMO_TRY_CHECK_ERROR_STATE(); 01203 01204 KMO_TRY_EXIT_IF_ERROR( 01205 cpl_property_set_name (p, CDELT1)); 01206 01207 // CTYPE 01208 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CTYPE1); 01209 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CTYPE2); 01210 KMO_TRY_CHECK_ERROR_STATE(); 01211 KMO_TRY_EXIT_IF_NULL( 01212 p = cpl_propertylist_get_property(stored_sub_tel_data_headers[ifu_nr-1], CTYPE3)); 01213 KMO_TRY_EXIT_IF_ERROR( 01214 cpl_property_set_name (p, CTYPE1)); 01215 01216 // CDx_x 01217 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_1); 01218 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_2); 01219 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_3); 01220 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_1); 01221 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_2); 01222 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_3); 01223 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_1); 01224 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_2); 01225 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_3); 01226 KMO_TRY_CHECK_ERROR_STATE(); 01227 01228 // for psf-headers: delete CRPIX3 etc. 01229 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRPIX3); 01230 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRPIX3); 01231 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CDELT3); 01232 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRVAL3); 01233 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CTYPE3); 01234 KMO_TRY_CHECK_ERROR_STATE(); 01235 01236 KMO_TRY_EXIT_IF_ERROR( 01237 kmo_reconstruct_sci(ifu_nr, 01238 bounds[2*(ifu_nr-1)], 01239 bounds[2*(ifu_nr-1)+1], 01240 obj_frame, 01241 STD, 01242 sky_frame, 01243 STD, 01244 flat_frame, 01245 xcal_frame, 01246 ycal_frame, 01247 lcal_frame, 01248 &gd, 01249 &stored_data_cube[ifu_nr-1], 01250 &stored_noise_cube[ifu_nr-1], 01251 flux)); 01252 01253 // divide illumination correction from the data_cube 01254 // (illumination noise will be very small versus 01255 // noise_cube, so it is skipped here) 01256 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 01257 KMO_TRY_EXIT_IF_NULL( 01258 illum_corr = kmo_dfs_load_image_frame(illum_frame, ifu_nr, 01259 FALSE, FALSE, NULL)); 01260 KMO_TRY_EXIT_IF_ERROR( 01261 cpl_imagelist_divide_image(stored_data_cube[ifu_nr-1], illum_corr)); 01262 cpl_image_delete(illum_corr); illum_corr = NULL; 01263 } 01264 01265 // calculate QC_STD_TRACE 01266 // (the distance of the PSF to the centre) 01267 KMO_TRY_EXIT_IF_ERROR( 01268 kmo_calculate_std_trace(stored_data_cube[ifu_nr-1], fmethod, &std_trace)); 01269 01270 KMO_TRY_EXIT_IF_ERROR( 01271 kmclipm_update_property_double(stored_sub_psf_headers[ifu_nr-1], 01272 QC_STD_TRACE, std_trace, 01273 "[pix] distance of PSF and centre of IFU")); 01274 01275 KMO_TRY_EXIT_IF_NULL( 01276 identified_slices = cpl_vector_new(cpl_imagelist_get_size(stored_data_cube[ifu_nr-1]))); 01277 KMO_TRY_EXIT_IF_ERROR( 01278 cpl_vector_fill(identified_slices, 1.0)); 01279 01280 // collapse cube and get PSF image 01281 KMO_TRY_EXIT_IF_ERROR( 01282 kmclipm_make_image(stored_data_cube[ifu_nr-1], NULL, 01283 &stored_psf_data[ifu_nr-1], NULL, 01284 identified_slices, 01285 cmethod, 01286 cpos_rej, cneg_rej, citer, 01287 cmax, cmin)); 01288 cpl_vector_delete(identified_slices); 01289 identified_slices= NULL; 01290 01291 // fit a 2D profile to get a mask and fwhm in x and y, 01292 KMO_TRY_EXIT_IF_NULL( 01293 tmp_vec = kmo_fit_profile_2D(stored_psf_data[ifu_nr-1], 01294 NULL, 01295 fmethod, 01296 &stored_mask[ifu_nr-1], 01297 &pl_psf)); 01298 01299 // normalise mask to 1 and clip values below 0.5 01300 cpl_image_divide_scalar(stored_mask[ifu_nr-1], cpl_image_get_max(stored_mask[ifu_nr-1])); 01301 KMO_TRY_CHECK_ERROR_STATE(); 01302 01303 int dummy=0; 01304 for (int gx = 1; gx <= cpl_image_get_size_x(stored_mask[ifu_nr-1]); gx++) { 01305 for (int gy = 1; gy <= cpl_image_get_size_y(stored_mask[ifu_nr-1]); gy++) { 01306 if (cpl_image_get(stored_mask[ifu_nr-1], gx, gy, &dummy) < 0.5) { 01307 cpl_image_set(stored_mask[ifu_nr-1], gx, gy, 0.); 01308 } else { 01309 cpl_image_set(stored_mask[ifu_nr-1], gx, gy, 1.); 01310 } 01311 } 01312 } 01313 KMO_TRY_CHECK_ERROR_STATE(); 01314 01315 // update subheader with fit parameters 01316 KMO_TRY_EXIT_IF_ERROR( 01317 cpl_propertylist_append(stored_sub_tel_data_headers[ifu_nr-1], pl_psf)); 01318 cpl_propertylist_delete(pl_psf); pl_psf = NULL; 01319 01320 // store QC_SPAT_RES (RMS of fwhm_x and fwhm_y) 01321 double factor_fwhm = 2*sqrt(2*log(2)); 01322 double spat_res = pow(cpl_vector_get(tmp_vec, 4) * factor_fwhm, 2); 01323 spat_res += pow(cpl_vector_get(tmp_vec, 5) * factor_fwhm, 2); 01324 spat_res /= 2; 01325 KMO_TRY_EXIT_IF_ERROR( 01326 kmclipm_update_property_double(stored_sub_psf_headers[ifu_nr-1], 01327 QC_SPAT_RES, 01328 sqrt(spat_res)*KMOS_PIX_RESOLUTION, 01329 "[arcsec] mean fwhm resolution of PSF")); 01330 cpl_vector_delete(tmp_vec); tmp_vec = NULL; 01331 01332 // extract spectrum in masked area 01333 KMO_TRY_EXIT_IF_ERROR( 01334 kmo_priv_extract_spec(stored_data_cube[ifu_nr-1], 01335 stored_noise_cube[ifu_nr-1], 01336 stored_mask[ifu_nr-1], 01337 &tmp_spec_data, 01338 &tmp_spec_noise)); 01339 01340 // store to save to disk later on 01341 stored_starspec_data[ifu_nr-1] = cpl_vector_duplicate(tmp_spec_data); 01342 if (tmp_spec_noise != NULL) { 01343 stored_starspec_noise[ifu_nr-1] = cpl_vector_duplicate(tmp_spec_noise); 01344 } 01345 KMO_TRY_CHECK_ERROR_STATE(); 01346 01347 // create duplicate of tmp_spec_data for 01348 // QC calculation below 01349 KMO_TRY_EXIT_IF_NULL( 01350 tmp_spec_data_copy = cpl_vector_duplicate(tmp_spec_data)); 01351 01352 // calculate abscissa of output spectrum 01353 KMO_TRY_EXIT_IF_NULL( 01354 solar_x = kmo_create_lambda_vec(gd.l.dim, 1, 01355 gd.l.start, 01356 gd.l.delta)); 01357 01358 // 01359 // spectrum correction 01360 // 01361 if ((strcmp(star_type, "O") == 0) || 01362 (strcmp(star_type, "B") == 0) || 01363 (strcmp(star_type, "A") == 0) || 01364 (strcmp(star_type, "F") == 0)) 01365 { 01366 // we have a OBAF star 01367 if (strcmp(filter_id, "K") == 0) { 01368 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 01369 // interpolate ATMOS_MODEL to same scale 01370 // as data 01371 KMO_TRY_EXIT_IF_NULL( 01372 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL)); 01373 01374 // check if ATMOS_MODEL is the K one 01375 KMO_TRY_EXIT_IF_NULL( 01376 tmp_sub_header = 01377 kmclipm_propertylist_load( cpl_frame_get_filename(tmp_frame), 0)); 01378 KMO_TRY_EXIT_IF_NULL( 01379 tmp_str = cpl_propertylist_get_string(tmp_sub_header, FILT_ID)); 01380 KMO_TRY_ASSURE(strcmp("K", tmp_str) == 0, 01381 CPL_ERROR_ILLEGAL_INPUT, 01382 "ATMOS model must have primary " 01383 "keyword '%s' equal 'K'!!!", 01384 FILT_ID); 01385 cpl_propertylist_delete(tmp_sub_header); 01386 tmp_sub_header = NULL; 01387 01388 KMO_TRY_EXIT_IF_NULL( 01389 atmos_model = kmo_interpolate_vector_wcs(tmp_frame, solar_x)); 01390 01391 KMO_TRY_EXIT_IF_ERROR( 01392 kmo_remove_brg_line(tmp_spec_data, solar_x, atmos_model)); 01393 01394 cpl_vector_delete(atmos_model);atmos_model = NULL; 01395 } else { 01396 cpl_msg_warning("", "No atmospheric model (ATMOS_MODEL) provided! " 01397 "Can't remove Br-gamma-line."); 01398 } 01399 } else { 01400 if (k_band_warning == FALSE) { 01401 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 01402 cpl_msg_warning("", "The atmospheric model is ignored for all " 01403 "bands except K band (i.e. the Br-gamma " 01404 "line won't be removed')"); 01405 k_band_warning = TRUE; 01406 } 01407 } 01408 } 01409 } else if (strcmp(star_type, "G") == 0) { 01410 // we have a G star 01411 if (cpl_frameset_count_tags(frameset, SOLAR_SPEC) == 1) { 01412 // interpolate SOLAR_SPEC to same scale as data 01413 // and divide it 01414 KMO_TRY_EXIT_IF_NULL( 01415 tmp_frame = kmo_dfs_get_frame(frameset, SOLAR_SPEC)); 01416 01417 // check if SOLAR_SPEC is the filter_id-one 01418 KMO_TRY_EXIT_IF_NULL( 01419 tmp_sub_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 01420 KMO_TRY_EXIT_IF_NULL( 01421 tmp_str = cpl_propertylist_get_string(tmp_sub_header, FILT_ID)); 01422 KMO_TRY_ASSURE(strcmp(filter_id, tmp_str) == 0, 01423 CPL_ERROR_ILLEGAL_INPUT, 01424 "SOLAR_SPEC model must have primary " 01425 "keyword '%s' equal '%s'!!!", 01426 FILT_ID, filter_id); 01427 cpl_propertylist_delete(tmp_sub_header); tmp_sub_header = NULL; 01428 01429 KMO_TRY_EXIT_IF_NULL( 01430 solar_spec = kmo_interpolate_vector_wcs(tmp_frame, solar_x)); 01431 01432 // values are set to zero if solar_spec isn't 01433 // overlapping wavelength range of star apectrum 01434 // completely 01435 KMO_TRY_EXIT_IF_ERROR( 01436 cpl_vector_divide(tmp_spec_data, solar_spec)); 01437 cpl_vector_delete(solar_spec); solar_spec = NULL; 01438 } else { 01439 if (print_warning_once == TRUE) { 01440 cpl_msg_warning("","No solar spectrum (SOLAR_SPEC) provided! " 01441 "Can't divide it from extracted " 01442 "standard star spectrum!"); 01443 print_warning_once = FALSE; 01444 } 01445 } 01446 } else { 01447 // cpl_msg_warning("","No startype was provided! Can't" 01448 // " divide solar spectrum for G stars " 01449 // "or fit a profile to atmospheric " 01450 // "transmission for OBAF stars."); 01451 } 01452 01453 if (star_temperature > 0.0) { 01454 // divide blackbody from tmp_spec_data 01455 KMO_TRY_EXIT_IF_ERROR( 01456 kmo_divide_blackbody(tmp_spec_data, solar_x, star_temperature)); 01457 } 01458 01459 cpl_vector_delete(solar_x); solar_x = NULL; 01460 01461 // normalise telluric and its noise 01462 // mean is taken in lambda defined range 01463 KMO_TRY_EXIT_IF_ERROR( 01464 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 01465 filter_id, 01466 tmp_spec_data, 01467 tmp_spec_noise, 01468 &mean_data, 01469 &mean_noise)); 01470 01471 KMO_TRY_EXIT_IF_ERROR( 01472 cpl_vector_divide_scalar(tmp_spec_data, mean_data)); 01473 01474 if (tmp_spec_noise != NULL) { 01475 KMO_TRY_EXIT_IF_ERROR( 01476 cpl_vector_divide_scalar(tmp_spec_noise, mean_noise)); 01477 01478 // set noise spectrum also to zero when solar_spec is too short 01479 KMO_TRY_EXIT_IF_NULL( 01480 ptmp_spec_data = cpl_vector_get_data_const(tmp_spec_data)); 01481 KMO_TRY_EXIT_IF_NULL( 01482 ptmp_spec_noise = cpl_vector_get_data(tmp_spec_noise)); 01483 for (int i = 0; i < cpl_vector_get_size(tmp_spec_data); i++) { 01484 if (ptmp_spec_data[i] == 0.0) { 01485 ptmp_spec_noise[i] = 0.0; 01486 } 01487 } 01488 } 01489 KMO_TRY_CHECK_ERROR_STATE(); 01490 01491 // store telluric & error spectrum 01492 stored_telluric_data[ifu_nr-1] = tmp_spec_data; 01493 stored_telluric_noise[ifu_nr-1] = tmp_spec_noise; 01494 01495 // if magnitude is provided 01496 // calculate zeropoint and throughput 01497 if (has_magnitude) { 01498 // correct for capped mask (by 0.5) 01499 KMO_TRY_EXIT_IF_ERROR( 01500 cpl_vector_multiply_scalar(tmp_spec_data_copy, 2)); 01501 01502 // calculate QC THROUGHPUT 01503 crpix1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX1); 01504 crval1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL1); 01505 cdelt1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT1); 01506 KMO_TRY_CHECK_ERROR_STATE(); 01507 01508 KMO_TRY_EXIT_IF_ERROR( 01509 kmo_calc_counts(tmp_spec_data_copy, filter_id, 01510 crpix1, crval1, cdelt1, 01511 &counts1, &counts2)); 01512 KMO_TRY_CHECK_ERROR_STATE(); 01513 01514 counts1 /= exptime; 01515 counts2 /= exptime; 01516 01517 stored_qc_throughput[ifu_nr-1] = 01518 kmo_calc_throughput(magnitude1, magnitude2, counts1, counts2, 01519 cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], GAIN), 01520 filter_id); 01521 KMO_TRY_CHECK_ERROR_STATE(); 01522 01523 if (kmclipm_is_nan_or_inf(stored_qc_throughput[ifu_nr-1])) { 01524 stored_qc_throughput[ifu_nr-1] = -1; 01525 } 01526 KMO_TRY_EXIT_IF_ERROR( 01527 kmclipm_update_property_double(stored_sub_tel_data_headers[ifu_nr-1], 01528 QC_THROUGHPUT, 01529 stored_qc_throughput[ifu_nr-1], 01530 "[] IFU throughput")); 01531 01532 // calculate QC ZEROPOINT 01533 zeropoint = kmo_calc_zeropoint(magnitude1, magnitude2, counts1, counts2, cdelt3, filter_id); 01534 if (kmclipm_is_nan_or_inf(zeropoint)) { 01535 zeropoint = -1; 01536 } 01537 KMO_TRY_CHECK_ERROR_STATE(); 01538 01539 KMO_TRY_EXIT_IF_ERROR( 01540 kmclipm_update_property_double(stored_sub_tel_data_headers[ifu_nr-1], 01541 QC_ZEROPOINT, 01542 zeropoint, 01543 "[mag] IFU zeropoint")); 01544 } 01545 cpl_vector_delete(tmp_spec_data_copy);tmp_spec_data_copy = NULL; 01546 } else { 01547 cpl_error_reset(); 01548 // IFU is invalid 01549 KMO_TRY_EXIT_IF_NULL( 01550 stored_sub_tel_data_headers[ifu_nr-1] = 01551 cpl_propertylist_duplicate(sub_header_orig)); 01552 KMO_TRY_EXIT_IF_NULL( 01553 stored_sub_psf_headers[ifu_nr-1] = 01554 cpl_propertylist_duplicate(sub_header_orig)); 01555 } 01556 01557 // create EXTNAME keyword as DATA 01558 KMO_TRY_EXIT_IF_NULL( 01559 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_DATA)); 01560 KMO_TRY_EXIT_IF_ERROR( 01561 kmclipm_update_property_string(stored_sub_tel_data_headers[ifu_nr-1], 01562 EXTNAME, 01563 extname, 01564 "FITS extension name")); 01565 KMO_TRY_EXIT_IF_ERROR( 01566 kmclipm_update_property_string(stored_sub_psf_headers[ifu_nr-1], 01567 EXTNAME, 01568 extname, 01569 "FITS extension name")); 01570 cpl_free(extname); extname = NULL; 01571 01572 // create EXTNAME keyword as NOISE 01573 KMO_TRY_EXIT_IF_NULL( 01574 stored_sub_tel_noise_headers[ifu_nr-1] = 01575 cpl_propertylist_duplicate( 01576 stored_sub_tel_data_headers[ifu_nr-1])); 01577 01578 KMO_TRY_EXIT_IF_NULL( 01579 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE)); 01580 KMO_TRY_EXIT_IF_ERROR( 01581 kmclipm_update_property_string(stored_sub_tel_noise_headers[ifu_nr-1], 01582 EXTNAME, 01583 extname, 01584 "FITS extension name")); 01585 cpl_free(extname); extname = NULL; 01586 } // for j ifus (load, process & store) 01587 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01588 } // for i detectors (load, process & store) 01589 KMO_TRY_CHECK_ERROR_STATE(); 01590 01591 // write QC parameter: nr of std stars 01592 KMO_TRY_EXIT_IF_ERROR( 01593 kmclipm_update_property_int(main_header_tel, QC_NR_STD_STARS, 01594 nr_std_stars, "[] Nr. of std stars")); 01595 01596 // update which IFUs are not used 01597 kmo_print_unused_ifus(unused_ifus_after, TRUE); 01598 01599 KMO_TRY_EXIT_IF_ERROR( 01600 kmo_set_unused_ifus(unused_ifus_after, main_header_tel, "kmo_std_star")); 01601 01602 KMO_TRY_EXIT_IF_NULL( 01603 main_header_psf = cpl_propertylist_duplicate(main_header_tel)); 01604 01605 if (has_magnitude) { 01606 // calculate QC THROUGHPUT MEAN and QC THROUGHPUT SDV 01607 // and update main header 01608 KMO_TRY_EXIT_IF_ERROR( 01609 kmo_calc_mean_throughput(stored_qc_throughput, 01610 nr_devices * KMOS_IFUS_PER_DETECTOR, 01611 &throughput_mean, 01612 &throughput_sdv)); 01613 KMO_TRY_EXIT_IF_ERROR( 01614 kmclipm_update_property_double(main_header_tel, 01615 QC_THROUGHPUT_MEAN, 01616 throughput_mean, 01617 "[] mean throughput for all detectors")); 01618 KMO_TRY_EXIT_IF_ERROR( 01619 kmclipm_update_property_double(main_header_tel, 01620 QC_THROUGHPUT_SDV, 01621 throughput_sdv, 01622 "[] stdev throughput for all detectors")); 01623 } 01624 KMO_TRY_CHECK_ERROR_STATE(); 01625 01626 // 01627 // save output data 01628 // 01629 01630 // save primary extension 01631 cpl_msg_info("","Saving STD exposure No. %d", nr_exp+1); 01632 KMO_TRY_EXIT_IF_ERROR( 01633 kmo_dfs_save_main_header(frameset, filename_telluric, suffix, 01634 obj_frame, main_header_tel, parlist, 01635 cpl_func)); 01636 KMO_TRY_EXIT_IF_ERROR( 01637 kmo_dfs_save_main_header(frameset, filename_starspec, suffix, 01638 obj_frame, main_header_tel, parlist, 01639 cpl_func)); 01640 KMO_TRY_EXIT_IF_ERROR( 01641 kmo_dfs_save_main_header(frameset, filename_mask, suffix, 01642 obj_frame, main_header_psf, parlist, 01643 cpl_func)); 01644 KMO_TRY_EXIT_IF_ERROR( 01645 kmo_dfs_save_main_header(frameset, filename_psf, suffix, 01646 obj_frame, main_header_psf, parlist, 01647 cpl_func)); 01648 if (save_cubes) { 01649 KMO_TRY_EXIT_IF_ERROR( 01650 kmo_dfs_save_main_header(frameset, filename_cubes, suffix, 01651 obj_frame, main_header_psf, parlist, 01652 cpl_func)); 01653 } 01654 01655 // save stored frames 01656 for (i = 1; i <= nr_devices; i++) { 01657 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 01658 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 01659 01660 // save telluric-vector 01661 kmclipm_vector *ddd = NULL; 01662 if (stored_telluric_data[ifu_nr-1] != NULL) 01663 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_telluric_data[ifu_nr-1])); 01664 KMO_TRY_EXIT_IF_ERROR( 01665 kmo_dfs_save_vector(ddd, filename_telluric, suffix, 01666 stored_sub_tel_data_headers[ifu_nr-1], 01667 0./0.)); 01668 kmclipm_vector_delete(ddd); ddd =NULL; 01669 01670 if (stored_telluric_noise[ifu_nr-1] != NULL) 01671 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_telluric_noise[ifu_nr-1])); 01672 KMO_TRY_EXIT_IF_ERROR( 01673 kmo_dfs_save_vector(ddd, filename_telluric, suffix, 01674 stored_sub_tel_noise_headers[ifu_nr-1], 01675 0./0.)); 01676 kmclipm_vector_delete(ddd); ddd =NULL; 01677 01678 // save star_spec-vector 01679 if (stored_starspec_data[ifu_nr-1] != NULL) 01680 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_starspec_data[ifu_nr-1])); 01681 KMO_TRY_EXIT_IF_ERROR( 01682 kmo_dfs_save_vector(ddd, filename_starspec, suffix, 01683 stored_sub_tel_data_headers[ifu_nr-1], 01684 0./0.)); 01685 kmclipm_vector_delete(ddd); ddd =NULL; 01686 01687 if (stored_starspec_noise[ifu_nr-1] != NULL) 01688 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_starspec_noise[ifu_nr-1])); 01689 KMO_TRY_EXIT_IF_ERROR( 01690 kmo_dfs_save_vector(ddd, filename_starspec, suffix, 01691 stored_sub_tel_noise_headers[ifu_nr-1], 01692 0./0.)); 01693 kmclipm_vector_delete(ddd); ddd =NULL; 01694 01695 // save psf-image 01696 KMO_TRY_EXIT_IF_ERROR( 01697 kmo_dfs_save_image(stored_psf_data[ifu_nr-1], 01698 filename_psf, suffix, 01699 stored_sub_psf_headers[ifu_nr-1], 01700 0./0.)); 01701 01702 // save mask-image 01703 KMO_TRY_EXIT_IF_ERROR( 01704 kmo_dfs_save_image(stored_mask[ifu_nr-1], 01705 filename_mask, suffix, 01706 stored_sub_psf_headers[ifu_nr-1], 01707 0./0.)); 01708 // save reonstructed cubes 01709 if (save_cubes) { 01710 KMO_TRY_EXIT_IF_ERROR( 01711 kmo_dfs_save_cube(stored_data_cube[ifu_nr-1], 01712 filename_cubes, suffix, 01713 stored_sub_psf_headers[ifu_nr-1], 01714 0./0.)); 01715 KMO_TRY_EXIT_IF_ERROR( 01716 kmo_dfs_save_cube(stored_noise_cube[ifu_nr-1], 01717 filename_cubes, suffix, 01718 stored_sub_psf_headers[ifu_nr-1], 01719 0./0.)); 01720 } 01721 } // for j ifus (save stored) 01722 } // for i detectors (save stored) 01723 KMO_TRY_CHECK_ERROR_STATE(); 01724 01725 // // prepare for next STD input frame 01726 // cpl_propertylist_delete(main_header_tel); main_header_tel = NULL; 01727 // cpl_propertylist_delete(main_header_psf); main_header_psf = NULL; 01728 // for (i = 0; i < nr_devices * KMOS_IFUS_PER_DETECTOR; i++) { 01729 // cpl_vector_delete(stored_telluric_data[i]); stored_telluric_data[i] = NULL; 01730 // cpl_vector_delete(stored_telluric_noise[i]); stored_telluric_noise[i] = NULL; 01731 // cpl_vector_delete(stored_starspec_data[i]); stored_starspec_data[i] = NULL; 01732 // cpl_vector_delete(stored_starspec_noise[i]); stored_starspec_noise[i] = NULL; 01733 // cpl_image_delete(stored_psf_data[i]); stored_psf_data[i] = NULL; 01734 // cpl_propertylist_delete(stored_sub_tel_data_headers[i]); stored_sub_tel_data_headers[i] = NULL; 01735 // cpl_propertylist_delete(stored_sub_tel_noise_headers[i]); stored_sub_tel_noise_headers[i] = NULL; 01736 // cpl_propertylist_delete(stored_sub_psf_headers[i]); stored_sub_psf_headers[i] = NULL; 01737 // cpl_image_delete(stored_mask[i]); stored_mask[i] = NULL; 01738 // cpl_imagelist_delete(stored_data_cube[i]); stored_data_cube[i] = NULL; 01739 // cpl_imagelist_delete(stored_noise_cube[i]); stored_noise_cube[i] = NULL; 01740 // } 01741 } // if (frameCnt == 0) 01742 } 01743 KMO_CATCH 01744 { 01745 KMO_CATCH_MSG(); 01746 ret_val = -1; 01747 } 01748 01749 cpl_free(obj_sky_struct); obj_sky_struct = NULL; 01750 kmo_free_fits_desc(&desc1); 01751 kmo_free_fits_desc(&desc2); 01752 kmo_free_unused_ifus(unused_ifus_before); unused_ifus_before = NULL; 01753 kmo_free_unused_ifus(unused_ifus_after); unused_ifus_after = NULL; 01754 cpl_free(bounds); bounds = NULL; 01755 cpl_propertylist_delete(main_header_tel); main_header_tel = NULL; 01756 cpl_propertylist_delete(main_header_psf); main_header_psf = NULL; 01757 cpl_vector_delete(atmos_model); atmos_model = NULL; 01758 cpl_vector_delete(solar_spec); solar_spec = NULL; 01759 cpl_table_delete(spec_type_LUT); spec_type_LUT = NULL; 01760 cpl_vector_delete(identified_slices); identified_slices = NULL; 01761 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01762 for (i = 0; i < nr_devices * KMOS_IFUS_PER_DETECTOR; i++) { 01763 cpl_vector_delete(stored_telluric_data[i]); stored_telluric_data[i] = NULL; 01764 cpl_vector_delete(stored_telluric_noise[i]); stored_telluric_noise[i] = NULL; 01765 cpl_vector_delete(stored_starspec_data[i]); stored_starspec_data[i] = NULL; 01766 cpl_vector_delete(stored_starspec_noise[i]); stored_starspec_noise[i] = NULL; 01767 cpl_image_delete(stored_psf_data[i]); stored_psf_data[i] = NULL; 01768 cpl_propertylist_delete(stored_sub_tel_data_headers[i]); stored_sub_tel_data_headers[i] = NULL; 01769 cpl_propertylist_delete(stored_sub_tel_noise_headers[i]); stored_sub_tel_noise_headers[i] = NULL; 01770 cpl_propertylist_delete(stored_sub_psf_headers[i]); stored_sub_psf_headers[i] = NULL; 01771 cpl_image_delete(stored_mask[i]); stored_mask[i] = NULL; 01772 cpl_imagelist_delete(stored_data_cube[i]); stored_data_cube[i] = NULL; 01773 cpl_imagelist_delete(stored_noise_cube[i]); stored_noise_cube[i] = NULL; 01774 } 01775 cpl_free(stored_telluric_data); stored_telluric_data = NULL; 01776 cpl_free(stored_telluric_noise); stored_telluric_noise = NULL; 01777 cpl_free(stored_starspec_data); stored_starspec_data = NULL; 01778 cpl_free(stored_starspec_noise); stored_starspec_noise = NULL; 01779 cpl_free(stored_psf_data); stored_psf_data = NULL; 01780 cpl_free(stored_sub_tel_data_headers); stored_sub_tel_data_headers = NULL; 01781 cpl_free(stored_sub_tel_noise_headers); stored_sub_tel_noise_headers = NULL; 01782 cpl_free(stored_sub_psf_headers); stored_sub_psf_headers = NULL; 01783 cpl_free(stored_qc_throughput); stored_qc_throughput = NULL; 01784 cpl_free(suffix); suffix = NULL; 01785 cpl_free(stored_mask); stored_mask = NULL; 01786 cpl_free(stored_data_cube); stored_data_cube = NULL; 01787 cpl_free(stored_noise_cube); stored_noise_cube = NULL; 01788 cpl_free(grat_id); grat_id = NULL; 01789 cpl_frameset_delete(frameset_std); frameset_std = NULL; 01790 01791 return ret_val; 01792 } 01793
1.7.6.1