|
KMOS Pipeline Reference Manual
1.1.0
|
00001 /* $Id: kmo_std_star.c,v 1.47 2013/03/18 11:52:13 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/03/18 11:52:13 $ 00024 * $Revision: 1.47 $ 00025 * $Name: HEAD $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 * Includes 00034 *----------------------------------------------------------------------------*/ 00035 00036 #include <math.h> 00037 #include <string.h> 00038 00039 #include <cpl.h> 00040 #include "kmclipm_math.h" 00041 00042 #include "kmo_constants.h" 00043 #include "kmo_cpl_extensions.h" 00044 #include "kmo_utils.h" 00045 #include "kmo_functions.h" 00046 #include "kmo_priv_std_star.h" 00047 #include "kmo_priv_fit_profile.h" 00048 #include "kmo_priv_extract_spec.h" 00049 #include "kmo_priv_functions.h" 00050 #include "kmo_dfs.h" 00051 #include "kmo_error.h" 00052 #include "kmo_debug.h" 00053 #include "kmo_priv_reconstruct.h" 00054 00055 /*----------------------------------------------------------------------------- 00056 * Functions prototypes 00057 *----------------------------------------------------------------------------*/ 00058 00059 static int kmo_std_star_create(cpl_plugin *); 00060 static int kmo_std_star_exec(cpl_plugin *); 00061 static int kmo_std_star_destroy(cpl_plugin *); 00062 static int kmo_std_star(cpl_parameterlist *, cpl_frameset *); 00063 00064 /*----------------------------------------------------------------------------- 00065 * Static variables 00066 *----------------------------------------------------------------------------*/ 00067 00068 static char kmo_std_star_description[] = 00069 "This recipe creates a telluric calibration frame and a PSF frame. It must be\n" 00070 "called after the kmo_illumination-recipe.\n" 00071 "Since there won’t be enough standard stars to observe for all IFUs in one ex-\n" 00072 "posure, one has to do several exposures in a way that there is at least one\n" 00073 "standard star and one sky exposure in each IFU. A internal data organiser will\n" 00074 "analyse the provided exposures and select the appropriate frames as follows:\n" 00075 "1. For each IFU the first standard star in the list of provided exposures is\n" 00076 " taken. All subsequent standard star exposures for this IFU will be ignored\n" 00077 "2. A corresponding sky exposure will be chosen which will be as close in time\n" 00078 " to the standard star exposure as possible.\n" 00079 "3. For any IFUs not containing a standard star and a sky exposure an empty\n" 00080 " frame will be returned.\n" 00081 "\n" 00082 "BASIC PARAMETERS:\n" 00083 "-----------------\n" 00084 "--startype\n" 00085 "The star type of the observed object . This value applies to all objects exa-\n" 00086 "mined in the input frames. Examples would be “A3I”, “G3IV” or “K0I”. The first\n" 00087 "letter defines the star type, the second letter the spectral class and the last\n" 00088 "letters the luminosity class.\n" 00089 "\n" 00090 "--magnitude\n" 00091 "The magnitude of the observed object..\n" 00092 "\n" 00093 "--fmethod\n" 00094 "The type of function that should be fitted spatially to the collapsed image.\n" 00095 "This fit is used to create a mask to extract the spectrum of the object. Valid\n" 00096 "values are “gauss” and “moffat”.\n" 00097 "\n" 00098 "--imethod\n" 00099 "The interpolation method used for reconstruction. As default 'CS' is selected.\n" 00100 "Note that no error spectra will be generated for this interpolation method.\n" 00101 "Select a nearest neighbour method otherwise\n" 00102 "\n" 00103 "--range\n" 00104 "The spectral range [um] to combine when collapsing the reconstructed cubes.\n" 00105 "\n" 00106 "--save-cubes\n" 00107 "Set to TRUE if the intermediate reconstructed cubes (eventually divided by " 00108 "illumination correction) should be saved as well. Default is FALSE.\n" 00109 "\n" 00110 "ADVANCED PARAMETERS\n" 00111 "-------------------\n" 00112 "--flux\n" 00113 "Specify if flux conservation should be applied.\n" 00114 "\n" 00115 "--neighborhoodRange\n" 00116 "Defines the range to search for neighbors during reconstruction\n" 00117 "\n" 00118 "--b_samples\n" 00119 "The number of samples in spectral direction for the reconstructed cube.\n" 00120 "Ideally this number should be greater than 2048, the detector size.\n" 00121 "\n" 00122 "--b_start\n" 00123 "--b_end\n" 00124 "Used to define manually the start and end wavelength for the reconstructed\n" 00125 "cube. By default the internally defined values are used.\n" 00126 "\n" 00127 "--cmethod\n" 00128 "Following methods of frame combination are available:\n" 00129 " * 'ksigma' (Default)\n" 00130 " An iterative sigma clipping. For each position all pixels in the spectrum\n" 00131 " are examined. If they deviate significantly, they will be rejected according\n" 00132 " to the conditions:\n" 00133 " val > mean + stdev * cpos_rej\n" 00134 " and\n" 00135 " val < mean - stdev * cneg_rej\n" 00136 " where --cpos_rej, --cneg_rej and --citer are the corresponding configuration\n" 00137 " parameters. In the first iteration median and percentile level are used.\n" 00138 "\n" 00139 " * 'median'\n" 00140 " At each pixel position the median is calculated.\n" 00141 "\n" 00142 " * 'average'\n" 00143 " At each pixel position the average is calculated.\n" 00144 "\n" 00145 " * 'sum'\n" 00146 " At each pixel position the sum is calculated.\n" 00147 "\n" 00148 " * 'min_max'\n" 00149 " The specified number of minimum and maximum pixel values will be rejected.\n" 00150 " --cmax and --cmin apply to this method.\n" 00151 "\n" 00152 "--cpos_rej\n" 00153 "--cneg_rej\n" 00154 "--citer\n" 00155 "see --cmethod='ksigma'\n" 00156 "\n" 00157 "--cmax\n" 00158 "--cmin\n" 00159 "see --cmethod='min_max'\n" 00160 "\n" 00161 "-------------------------------------------------------------------------------\n" 00162 " Input files:\n" 00163 "\n" 00164 " DO KMOS \n" 00165 " category Type Explanation Required #Frames\n" 00166 " -------- ----- ----------- -------- -------\n" 00167 " STD RAW Std. star & sky exposures Y >=1 \n" 00168 " XCAL F2D x calibration frame Y 1 \n" 00169 " YCAL F2D y calibration frame Y 1 \n" 00170 " LCAL F2D Wavelength calib. frame Y 1 \n" 00171 " MASTER_FLAT F2D Master flat frame Y 1 \n" 00172 " WAVE_BAND F2L Table with start-/end-wavelengths Y 1 \n" 00173 " ILLUM_CORR F2I Illumination correction N 0,1 \n" 00174 " SOLAR_SPEC F1S Solar spectrum N 0,1 \n" 00175 " (only for G stars) \n" 00176 " ATMOS_MODEL F1S Model atmospheric transmisson N 0,1 \n" 00177 " (only for OBAF stars in K band) \n" 00178 " SPEC_TYPE_LOOKUP F2L LUT eff. stellar temperature N 0,1 \n" 00179 "\n" 00180 " Output files:\n" 00181 "\n" 00182 " DO KMOS\n" 00183 " category Type Explanation\n" 00184 " -------- ----- -----------\n" 00185 " TELLURIC F1I normalised telluric spectrum \n" 00186 " (including errors) \n" 00187 " STD_IMAGE F2I Standard star PSF images \n" 00188 "-------------------------------------------------------------------------------\n" 00189 "\n"; 00190 00191 /*----------------------------------------------------------------------------- 00192 * Functions code 00193 *----------------------------------------------------------------------------*/ 00194 00211 int cpl_plugin_get_info(cpl_pluginlist *list) 00212 { 00213 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00214 cpl_plugin *plugin = &recipe->interface; 00215 00216 cpl_plugin_init(plugin, 00217 CPL_PLUGIN_API, 00218 KMOS_BINARY_VERSION, 00219 CPL_PLUGIN_TYPE_RECIPE, 00220 "kmo_std_star", 00221 "Create the telluric correction frame.", 00222 kmo_std_star_description, 00223 "Alex Agudo Berbel", 00224 "agudo@mpe.mpg.de", 00225 kmos_get_license(), 00226 kmo_std_star_create, 00227 kmo_std_star_exec, 00228 kmo_std_star_destroy); 00229 00230 cpl_pluginlist_append(list, plugin); 00231 00232 return 0; 00233 } 00234 00242 static int kmo_std_star_create(cpl_plugin *plugin) 00243 { 00244 cpl_recipe *recipe; 00245 cpl_parameter *p; 00246 00247 /* Check that the plugin is part of a valid recipe */ 00248 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00249 recipe = (cpl_recipe *)plugin; 00250 else 00251 return -1; 00252 00253 /* Create the parameters list in the cpl_recipe object */ 00254 recipe->parameters = cpl_parameterlist_new(); 00255 00256 /* Fill the parameters list */ 00257 p = cpl_parameter_new_value("kmos.kmo_std_star.startype", 00258 CPL_TYPE_STRING, 00259 "The spectral type of the star (O, B, A, F, G)" 00260 " Format: G4V etc.", 00261 "kmos.kmo_std_star", 00262 ""); 00263 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startype"); 00264 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00265 cpl_parameterlist_append(recipe->parameters, p); 00266 00267 /* --imethod */ 00268 p = cpl_parameter_new_value("kmos.kmo_std_star.imethod", 00269 CPL_TYPE_STRING, 00270 "Method to use for interpolation. " 00271 "[\"NN\" (nearest neighbour), " 00272 "\"lwNN\" (linear weighted nearest neighbor), " 00273 "\"swNN\" (square weighted nearest neighbor), " 00274 "\"MS\" (Modified Shepard's method), " 00275 "\"CS\" (Cubic spline)]", 00276 "kmos.kmo_std_star", 00277 "CS"); 00278 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00279 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00280 cpl_parameterlist_append(recipe->parameters, p); 00281 00282 /* --fmethod */ 00283 p = cpl_parameter_new_value("kmos.kmo_std_star.fmethod", 00284 CPL_TYPE_STRING, 00285 "Either fit a 'gauss' or 'moffat' profile.", 00286 "kmos.kmo_std_star", 00287 "gauss"); 00288 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00289 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00290 cpl_parameterlist_append(recipe->parameters, p); 00291 00292 /* --neighborhoodRange */ 00293 p = cpl_parameter_new_value("kmos.kmo_std_star.neighborhoodRange", 00294 CPL_TYPE_DOUBLE, 00295 "Defines the range to search for neighbors " 00296 "in pixels", 00297 "kmos.kmo_std_star", 00298 1.001); 00299 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00300 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00301 cpl_parameterlist_append(recipe->parameters, p); 00302 00303 /* --magnitude */ 00304 p = cpl_parameter_new_value("kmos.kmo_std_star.magnitude", 00305 CPL_TYPE_STRING, 00306 "The magnitude of the std star. For HK two " 00307 "values have to provided (eg. 12.1,13.2)", 00308 "kmos.kmo_std_star", 00309 ""); 00310 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "magnitude"); 00311 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00312 cpl_parameterlist_append(recipe->parameters, p); 00313 00314 /* --flux */ 00315 p = cpl_parameter_new_value("kmos.kmo_std_star.flux", 00316 CPL_TYPE_BOOL, 00317 "TRUE: Apply flux conservation. FALSE: otherwise", 00318 "kmos.kmo_std_star", 00319 TRUE); 00320 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00321 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00322 cpl_parameterlist_append(recipe->parameters, p); 00323 00324 /* --save-cubes */ 00325 p = cpl_parameter_new_value("kmos.kmo_std_star.save-cubes", 00326 CPL_TYPE_BOOL, 00327 "TRUE: Save reconstructed cubes, FALSE: otherwise", 00328 "kmos.kmo_std_star", 00329 FALSE); 00330 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save-cubes"); 00331 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00332 cpl_parameterlist_append(recipe->parameters, p); 00333 00334 // add parameters for band-definition 00335 kmo_band_pars_create(recipe->parameters, 00336 "kmos.kmo_std_star"); 00337 00338 // add parameters for combining 00339 return kmo_combine_pars_create(recipe->parameters, 00340 "kmos.kmo_std_star", 00341 DEF_REJ_METHOD, 00342 FALSE); 00343 } 00344 00350 static int kmo_std_star_exec(cpl_plugin *plugin) 00351 { 00352 cpl_recipe *recipe; 00353 00354 /* Get the recipe out of the plugin */ 00355 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00356 recipe = (cpl_recipe *)plugin; 00357 else return -1; 00358 00359 return kmo_std_star(recipe->parameters, recipe->frames); 00360 } 00361 00367 static int kmo_std_star_destroy(cpl_plugin *plugin) 00368 { 00369 cpl_recipe *recipe; 00370 00371 /* Get the recipe out of the plugin */ 00372 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00373 recipe = (cpl_recipe *)plugin; 00374 else return -1 ; 00375 00376 cpl_parameterlist_delete(recipe->parameters); 00377 return 0 ; 00378 } 00379 00394 static int kmo_std_star(cpl_parameterlist *parlist, cpl_frameset *frameset) 00395 { 00396 cpl_imagelist **stored_data_cube = NULL, 00397 **stored_noise_cube = NULL; 00398 00399 cpl_image **stored_psf_data = NULL, 00400 *illum_corr = NULL, 00401 **stored_mask = NULL, 00402 *lcal = NULL; 00403 00404 cpl_frame *xcal_frame = NULL, 00405 *ycal_frame = NULL, 00406 *lcal_frame = NULL, 00407 *flat_frame = NULL, 00408 *illum_frame = NULL, 00409 *obj_frame = NULL, 00410 *sky_frame = NULL, 00411 *tmp_frame = NULL; 00412 00413 cpl_vector *solar_spec = NULL, 00414 *atmos_model = NULL, 00415 **stored_telluric_data = NULL, 00416 **stored_telluric_noise = NULL, 00417 **stored_starspec_data = NULL, 00418 **stored_starspec_noise = NULL, 00419 *tmp_spec_data = NULL, 00420 *spec_qc = NULL, 00421 *tmp_spec_noise = NULL, 00422 *identified_slices = NULL, 00423 *tmp_vec = NULL, 00424 *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_cube_data_headers = NULL, 00482 **stored_sub_cube_noise_headers = NULL, 00483 **stored_sub_psf_headers = NULL, 00484 *pl_psf = 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 KMO_TRY_EXIT_IF_ERROR( 00983 kmo_check_frame_setup_md5(frameset)); 00984 00985 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00986 cpl_msg_info("", "(grating 1, 2 & 3, rotation angle)"); 00987 00988 // check which IFUs are active for all frames 00989 KMO_TRY_EXIT_IF_NULL( 00990 unused_ifus_before = kmo_get_unused_ifus(frameset, 0, 0)); 00991 00992 KMO_TRY_EXIT_IF_NULL( 00993 unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before)); 00994 00995 kmo_print_unused_ifus(unused_ifus_before, FALSE); 00996 00997 /* --- load data --- */ 00998 00999 if ((cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) == 1) && 01000 ((strlen(spec_class) > 0) || (strlen(lum_class) > 0))) 01001 { 01002 // get star temperature out of SPEC_TYPE_LOOKUP table 01003 KMO_TRY_EXIT_IF_NULL( 01004 spec_type_LUT = kmo_dfs_load_table(frameset, SPEC_TYPE_LOOKUP, 1, 0)); 01005 star_temperature = kmo_get_temperature(spec_type_LUT, spec_class, lum_class); 01006 KMO_TRY_CHECK_ERROR_STATE(); 01007 } else if (cpl_frameset_count_tags(frameset, SPEC_TYPE_LOOKUP) != 1) { 01008 cpl_msg_warning("","No SPEC_TYPE_LOOKUP was provided! Can't divide blackbody."); 01009 } else if ((strlen(spec_class) == 0) || (strlen(lum_class) == 0)) { 01010 // cpl_msg_warning("","No startype was provided! Can't " 01011 // "divide blackbody."); 01012 } 01013 01014 // allocate intermediate memory 01015 KMO_TRY_EXIT_IF_NULL( 01016 stored_telluric_data = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01017 sizeof(cpl_vector*))); 01018 KMO_TRY_EXIT_IF_NULL( 01019 stored_telluric_noise = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01020 sizeof(cpl_vector*))); 01021 KMO_TRY_EXIT_IF_NULL( 01022 stored_starspec_data = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01023 sizeof(cpl_vector*))); 01024 KMO_TRY_EXIT_IF_NULL( 01025 stored_starspec_noise = (cpl_vector**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01026 sizeof(cpl_vector*))); 01027 KMO_TRY_EXIT_IF_NULL( 01028 stored_psf_data = (cpl_image**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01029 sizeof(cpl_image*))); 01030 KMO_TRY_EXIT_IF_NULL( 01031 stored_mask = (cpl_image**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01032 sizeof(cpl_image*))); 01033 KMO_TRY_EXIT_IF_NULL( 01034 stored_data_cube = (cpl_imagelist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01035 sizeof(cpl_imagelist*))); 01036 KMO_TRY_EXIT_IF_NULL( 01037 stored_noise_cube = (cpl_imagelist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01038 sizeof(cpl_imagelist*))); 01039 KMO_TRY_EXIT_IF_NULL( 01040 stored_qc_throughput = (double*)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01041 sizeof(double))); 01042 KMO_TRY_EXIT_IF_NULL( 01043 stored_sub_psf_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_data_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01047 sizeof(cpl_propertylist*))); 01048 KMO_TRY_EXIT_IF_NULL( 01049 stored_sub_tel_noise_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01050 sizeof(cpl_propertylist*))); 01051 01052 if (save_cubes) { 01053 KMO_TRY_EXIT_IF_NULL( 01054 stored_sub_cube_data_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01055 sizeof(cpl_propertylist*))); 01056 KMO_TRY_EXIT_IF_NULL( 01057 stored_sub_cube_noise_headers = (cpl_propertylist**)cpl_calloc(nr_devices*KMOS_IFUS_PER_DETECTOR, 01058 sizeof(cpl_propertylist*))); 01059 } 01060 01061 // get bounds 01062 KMO_TRY_EXIT_IF_NULL( 01063 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(xcal_frame), 0)); 01064 KMO_TRY_EXIT_IF_NULL( 01065 bounds = kmclipm_extract_bounds(tmp_header)); 01066 cpl_propertylist_delete(tmp_header); tmp_header = NULL; 01067 01068 // setup grid definition, wavelength start and end points will be set 01069 // in the detector loop 01070 KMO_TRY_EXIT_IF_ERROR( 01071 kmclipm_setup_grid(&gd, imethod, neighborhoodRange)); 01072 01073 // get valid STD frames with objects in it and associated sky exposures 01074 KMO_TRY_EXIT_IF_NULL( 01075 obj_sky_struct = kmo_get_obj_sky_frame_table(frameset_std, &frameCnt, STD)); 01076 01077 // loop the object-sky pairs 01078 if (frameCnt == 0) { 01079 cpl_msg_warning(cpl_func,"Not a single frame contains an object"); 01080 } else { 01081 strcpy(filename_telluric, TELLURIC); 01082 strcpy(filename_starspec, STAR_SPEC); 01083 strcpy(filename_psf, STD_IMAGE); 01084 strcpy(filename_mask, STD_MASK); 01085 strcpy(filename_cubes, STD_CUBE); 01086 01087 obj_frame = obj_sky_struct[nr_exp].objectFrame; 01088 KMO_TRY_EXIT_IF_NULL( 01089 main_header_tel = kmclipm_propertylist_load(cpl_frame_get_filename(obj_frame), 0)); 01090 01091 exptime = cpl_propertylist_get_double(main_header_tel, EXPTIME); 01092 KMO_TRY_CHECK_ERROR_STATE(); 01093 01094 // load, process & store frames 01095 01096 for (i = 1; i <= nr_devices; i++) { 01097 // extract LCAL image close to ROTANGLE 0. assuming that the wavelength range 01098 // doesn't differ too much with different ROTANGLEs. 01099 double rotangle_found; 01100 KMO_TRY_EXIT_IF_NULL( 01101 lcal = kmo_dfs_load_cal_image(frameset, LCAL, i, FALSE, 0., FALSE, NULL, 01102 &rotangle_found)); 01103 01104 if (tmp_band_method != NULL) { 01105 band_method = atoi(tmp_band_method); 01106 } 01107 01108 // get filter for this detector 01109 // ESO INS FILTi ID 01110 KMO_TRY_EXIT_IF_NULL( 01111 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, i, IFU_FILTID_POSTFIX)); 01112 filter_id = cpl_propertylist_get_string(main_header_tel, keyword); 01113 cpl_free(keyword); keyword = NULL; 01114 01115 KMO_TRY_EXIT_IF_NULL( 01116 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0)); 01117 KMO_TRY_EXIT_IF_ERROR( 01118 kmclipm_setup_grid_band_lcal(&gd, lcal, filter_id, 01119 band_method, band_table)); 01120 cpl_image_delete(lcal); lcal = NULL; 01121 cpl_table_delete(band_table); band_table = NULL; 01122 01123 // load sub_header of original F2D image 01124 KMO_TRY_EXIT_IF_NULL( 01125 sub_header_orig = kmclipm_propertylist_load( cpl_frame_get_filename(obj_frame), i)); 01126 01127 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 01128 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 01129 // check if IFU is valid according to main header keywords & 01130 // calibration files 01131 // AND check if there is a sky frame available for this IFU 01132 01133 kmo_collapse_object_sky_frame_table(frameCnt, obj_sky_struct, ifu_nr, 01134 &obj_frame, &sky_frame); 01135 01136 KMO_TRY_EXIT_IF_NULL( 01137 punused_ifus = cpl_array_get_data_int_const(unused_ifus_after[i-1])); 01138 01139 // Search for keyword ESO OCS ARMi NOTUSED 01140 // If not present (CPL_ERROR_DATA_NOT_FOUND) we will eventually 01141 // process standard star 01142 KMO_TRY_EXIT_IF_NULL( 01143 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, IFU_VALID_POSTFIX)); 01144 tmp_str = cpl_propertylist_get_string(main_header_tel, keyword); 01145 cpl_free(keyword); keyword = NULL; 01146 01147 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 01148 (bounds[2*(ifu_nr-1)] != -1) && 01149 (bounds[2*(ifu_nr-1)+1] != -1) && 01150 (sky_frame != NULL) && 01151 (punused_ifus[j] == 0)) 01152 { 01153 cpl_error_reset(); 01154 // IFU is valid 01155 01156 if (sky_frame != NO_CORRESPONDING_SKYFRAME) { 01157 cpl_msg_info("","Processing standard star in IFU %d\n" 01158 "(std. star in file: %s,\n" 01159 " sky in file: %s)", ifu_nr, 01160 cpl_frame_get_filename(obj_frame), 01161 cpl_frame_get_filename(sky_frame)); 01162 } else { 01163 sky_frame = NULL; 01164 cpl_msg_warning("","Processing standard star in IFU %d\n" 01165 "(std. star in file: %s, no corresponding sky frame", 01166 ifu_nr, cpl_frame_get_filename(obj_frame)); 01167 } 01168 01169 nr_std_stars++; 01170 01171 // calculate WCS and make copies of sub_header 01172 KMO_TRY_EXIT_IF_NULL( 01173 tmp_sub_header = cpl_propertylist_duplicate(sub_header_orig)); 01174 KMO_TRY_EXIT_IF_ERROR( 01175 kmo_calc_wcs(main_header_tel, tmp_sub_header, 01176 ifu_nr, gd.l.start, gd.l.delta)); 01177 KMO_TRY_EXIT_IF_NULL( 01178 stored_sub_tel_data_headers[ifu_nr-1] = 01179 cpl_propertylist_duplicate(tmp_sub_header)); 01180 KMO_TRY_EXIT_IF_NULL( 01181 stored_sub_psf_headers[ifu_nr-1] = 01182 cpl_propertylist_duplicate(tmp_sub_header)); 01183 if (save_cubes) { 01184 KMO_TRY_EXIT_IF_NULL( 01185 stored_sub_cube_data_headers[ifu_nr-1] = 01186 cpl_propertylist_duplicate(tmp_sub_header)); 01187 } 01188 cpl_propertylist_delete(tmp_sub_header); 01189 tmp_sub_header = NULL; 01190 01191 // 01192 // adjust telluric-headers: copy CRPIX3 to CRPIX1, 01193 // 01194 cpl_propertylist_update_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL1, 01195 cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL3)); 01196 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRVAL2); 01197 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRVAL3); 01198 KMO_TRY_CHECK_ERROR_STATE(); 01199 01200 // CRPIX 01201 cpl_propertylist_update_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX1, 01202 cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX3)); 01203 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRPIX2); 01204 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CRPIX3); 01205 KMO_TRY_CHECK_ERROR_STATE(); 01206 01207 // CDELT 01208 cdelt3 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT3); 01209 cpl_propertylist_update_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT1, 01210 cdelt3); 01211 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CDELT2); 01212 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CDELT3); 01213 KMO_TRY_CHECK_ERROR_STATE(); 01214 01215 // CTYPE 01216 cpl_propertylist_update_string(stored_sub_tel_data_headers[ifu_nr-1], CTYPE1, 01217 cpl_propertylist_get_string(stored_sub_tel_data_headers[ifu_nr-1], CTYPE3)); 01218 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CTYPE2); 01219 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CTYPE3); 01220 KMO_TRY_CHECK_ERROR_STATE(); 01221 01222 // CUNIT 01223 cpl_propertylist_update_string(stored_sub_tel_data_headers[ifu_nr-1], CUNIT1, 01224 cpl_propertylist_get_string(stored_sub_tel_data_headers[ifu_nr-1], CUNIT3)); 01225 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CUNIT2); 01226 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CUNIT3); 01227 01228 // CDx_x 01229 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_1); 01230 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_2); 01231 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD1_3); 01232 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_1); 01233 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_2); 01234 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD2_3); 01235 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_1); 01236 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_2); 01237 cpl_propertylist_erase(stored_sub_tel_data_headers[ifu_nr-1], CD3_3); 01238 KMO_TRY_CHECK_ERROR_STATE(); 01239 01240 // 01241 // adjust psf-headers: delete CRPIX3 etc. 01242 // 01243 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRPIX3); 01244 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRPIX3); 01245 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CDELT3); 01246 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CRVAL3); 01247 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CTYPE3); 01248 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CUNIT3); 01249 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD1_3); 01250 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD2_3); 01251 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD3_1); 01252 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD3_2); 01253 cpl_propertylist_erase(stored_sub_psf_headers[ifu_nr-1], CD3_3); 01254 KMO_TRY_CHECK_ERROR_STATE(); 01255 01256 KMO_TRY_EXIT_IF_ERROR( 01257 kmo_reconstruct_sci(ifu_nr, 01258 bounds[2*(ifu_nr-1)], 01259 bounds[2*(ifu_nr-1)+1], 01260 obj_frame, 01261 STD, 01262 sky_frame, 01263 STD, 01264 flat_frame, 01265 xcal_frame, 01266 ycal_frame, 01267 lcal_frame, 01268 &gd, 01269 &stored_data_cube[ifu_nr-1], 01270 &stored_noise_cube[ifu_nr-1], 01271 flux)); 01272 01273 // divide illumination correction from the data_cube 01274 // (illumination noise will be very small versus 01275 // noise_cube, so it is skipped here) 01276 if (cpl_frameset_count_tags(frameset, ILLUM_CORR) == 1) { 01277 KMO_TRY_EXIT_IF_NULL( 01278 illum_corr = kmo_dfs_load_image_frame(illum_frame, ifu_nr, 01279 FALSE, FALSE, NULL)); 01280 KMO_TRY_EXIT_IF_ERROR( 01281 cpl_imagelist_divide_image(stored_data_cube[ifu_nr-1], illum_corr)); 01282 cpl_image_delete(illum_corr); illum_corr = NULL; 01283 } 01284 01285 // calculate QC_STD_TRACE 01286 // (the distance of the PSF to the centre) 01287 KMO_TRY_EXIT_IF_ERROR( 01288 kmo_calculate_std_trace(stored_data_cube[ifu_nr-1], fmethod, &std_trace)); 01289 01290 KMO_TRY_EXIT_IF_ERROR( 01291 kmclipm_update_property_double(stored_sub_psf_headers[ifu_nr-1], 01292 QC_STD_TRACE, std_trace, 01293 "[pix] distance of PSF and centre of IFU")); 01294 01295 KMO_TRY_EXIT_IF_NULL( 01296 identified_slices = cpl_vector_new(cpl_imagelist_get_size(stored_data_cube[ifu_nr-1]))); 01297 KMO_TRY_EXIT_IF_ERROR( 01298 cpl_vector_fill(identified_slices, 1.0)); 01299 01300 // collapse cube and get PSF image 01301 KMO_TRY_EXIT_IF_ERROR( 01302 kmclipm_make_image(stored_data_cube[ifu_nr-1], NULL, 01303 &stored_psf_data[ifu_nr-1], NULL, 01304 identified_slices, 01305 cmethod, 01306 cpos_rej, cneg_rej, citer, 01307 cmax, cmin)); 01308 cpl_vector_delete(identified_slices); 01309 identified_slices= NULL; 01310 01311 // fit a 2D profile to get a mask and fwhm in x and y, 01312 KMO_TRY_EXIT_IF_NULL( 01313 tmp_vec = kmo_fit_profile_2D(stored_psf_data[ifu_nr-1], 01314 NULL, 01315 fmethod, 01316 &stored_mask[ifu_nr-1], 01317 &pl_psf)); 01318 01319 // normalise mask to 1 and clip values below 0.5 01320 cpl_image_divide_scalar(stored_mask[ifu_nr-1], cpl_image_get_max(stored_mask[ifu_nr-1])); 01321 KMO_TRY_CHECK_ERROR_STATE(); 01322 01323 int dummy=0; 01324 for (int gx = 1; gx <= cpl_image_get_size_x(stored_mask[ifu_nr-1]); gx++) { 01325 for (int gy = 1; gy <= cpl_image_get_size_y(stored_mask[ifu_nr-1]); gy++) { 01326 if (cpl_image_get(stored_mask[ifu_nr-1], gx, gy, &dummy) < 0.5) { 01327 cpl_image_set(stored_mask[ifu_nr-1], gx, gy, 0.); 01328 } else { 01329 cpl_image_set(stored_mask[ifu_nr-1], gx, gy, 1.); 01330 } 01331 } 01332 } 01333 KMO_TRY_CHECK_ERROR_STATE(); 01334 01335 // update subheader with fit parameters 01336 KMO_TRY_EXIT_IF_ERROR( 01337 cpl_propertylist_append(stored_sub_tel_data_headers[ifu_nr-1], pl_psf)); 01338 cpl_propertylist_delete(pl_psf); pl_psf = NULL; 01339 01340 // store QC_SPAT_RES (RMS of fwhm_x and fwhm_y) 01341 double factor_fwhm = 2*sqrt(2*log(2)); 01342 double spat_res = pow(cpl_vector_get(tmp_vec, 4) * factor_fwhm, 2); 01343 spat_res += pow(cpl_vector_get(tmp_vec, 5) * factor_fwhm, 2); 01344 spat_res /= 2; 01345 KMO_TRY_EXIT_IF_ERROR( 01346 kmclipm_update_property_double(stored_sub_psf_headers[ifu_nr-1], 01347 QC_SPAT_RES, 01348 sqrt(spat_res)*KMOS_PIX_RESOLUTION, 01349 "[arcsec] mean fwhm resolution of PSF")); 01350 cpl_vector_delete(tmp_vec); tmp_vec = NULL; 01351 01352 // extract spectrum in masked area 01353 KMO_TRY_EXIT_IF_ERROR( 01354 kmo_priv_extract_spec(stored_data_cube[ifu_nr-1], 01355 stored_noise_cube[ifu_nr-1], 01356 stored_mask[ifu_nr-1], 01357 &tmp_spec_data, 01358 &tmp_spec_noise)); 01359 01360 // store to save to disk later on 01361 stored_starspec_data[ifu_nr-1] = cpl_vector_duplicate(tmp_spec_data); 01362 if (tmp_spec_noise != NULL) { 01363 stored_starspec_noise[ifu_nr-1] = cpl_vector_duplicate(tmp_spec_noise); 01364 } 01365 KMO_TRY_CHECK_ERROR_STATE(); 01366 01367 // extract spectrum of whole are for QC THRUHput and ZEROPOINT 01368 KMO_TRY_EXIT_IF_ERROR( 01369 kmo_priv_extract_spec(stored_data_cube[ifu_nr-1], 01370 NULL, 01371 NULL, 01372 &spec_qc, 01373 NULL)); 01374 01375 // calculate abscissa of output spectrum 01376 KMO_TRY_EXIT_IF_NULL( 01377 solar_x = kmo_create_lambda_vec(gd.l.dim, 1, 01378 gd.l.start, 01379 gd.l.delta)); 01380 // 01381 // spectrum correction 01382 // 01383 if ((strcmp(star_type, "O") == 0) || 01384 (strcmp(star_type, "B") == 0) || 01385 (strcmp(star_type, "A") == 0) || 01386 (strcmp(star_type, "F") == 0)) 01387 { 01388 // we have a OBAF star 01389 if (strcmp(filter_id, "K") == 0) { 01390 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 01391 // interpolate ATMOS_MODEL to same scale 01392 // as data 01393 KMO_TRY_EXIT_IF_NULL( 01394 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL)); 01395 01396 // check if ATMOS_MODEL is the K one 01397 KMO_TRY_EXIT_IF_NULL( 01398 tmp_sub_header = 01399 kmclipm_propertylist_load( cpl_frame_get_filename(tmp_frame), 0)); 01400 KMO_TRY_EXIT_IF_NULL( 01401 tmp_str = cpl_propertylist_get_string(tmp_sub_header, FILT_ID)); 01402 KMO_TRY_ASSURE(strcmp("K", tmp_str) == 0, 01403 CPL_ERROR_ILLEGAL_INPUT, 01404 "ATMOS model must have primary " 01405 "keyword '%s' equal 'K'!!!", 01406 FILT_ID); 01407 cpl_propertylist_delete(tmp_sub_header); 01408 tmp_sub_header = NULL; 01409 01410 KMO_TRY_EXIT_IF_NULL( 01411 atmos_model = kmo_interpolate_vector_wcs(tmp_frame, solar_x)); 01412 01413 KMO_TRY_EXIT_IF_ERROR( 01414 kmo_remove_brg_line(tmp_spec_data, solar_x, atmos_model)); 01415 01416 cpl_vector_delete(atmos_model);atmos_model = NULL; 01417 } else { 01418 cpl_msg_warning("", "No atmospheric model (ATMOS_MODEL) provided! " 01419 "Can't remove Br-gamma-line."); 01420 } 01421 } else { 01422 if (k_band_warning == FALSE) { 01423 if (cpl_frameset_count_tags(frameset, ATMOS_MODEL) == 1) { 01424 cpl_msg_warning("", "The atmospheric model is ignored for all " 01425 "bands except K band (i.e. the Br-gamma " 01426 "line won't be removed')"); 01427 k_band_warning = TRUE; 01428 } 01429 } 01430 } 01431 } else if (strcmp(star_type, "G") == 0) { 01432 // we have a G star 01433 if (cpl_frameset_count_tags(frameset, SOLAR_SPEC) == 1) { 01434 // interpolate SOLAR_SPEC to same scale as data 01435 // and divide it 01436 KMO_TRY_EXIT_IF_NULL( 01437 tmp_frame = kmo_dfs_get_frame(frameset, SOLAR_SPEC)); 01438 01439 // check if SOLAR_SPEC is the filter_id-one 01440 KMO_TRY_EXIT_IF_NULL( 01441 tmp_sub_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 0)); 01442 KMO_TRY_EXIT_IF_NULL( 01443 tmp_str = cpl_propertylist_get_string(tmp_sub_header, FILT_ID)); 01444 KMO_TRY_ASSURE(strcmp(filter_id, tmp_str) == 0, 01445 CPL_ERROR_ILLEGAL_INPUT, 01446 "SOLAR_SPEC model must have primary " 01447 "keyword '%s' equal '%s'!!!", 01448 FILT_ID, filter_id); 01449 cpl_propertylist_delete(tmp_sub_header); tmp_sub_header = NULL; 01450 01451 KMO_TRY_EXIT_IF_NULL( 01452 solar_spec = kmo_interpolate_vector_wcs(tmp_frame, solar_x)); 01453 01454 // values are set to zero if solar_spec isn't 01455 // overlapping wavelength range of star apectrum 01456 // completely 01457 KMO_TRY_EXIT_IF_ERROR( 01458 cpl_vector_divide(tmp_spec_data, solar_spec)); 01459 cpl_vector_delete(solar_spec); solar_spec = NULL; 01460 } else { 01461 if (print_warning_once == TRUE) { 01462 cpl_msg_warning("","No solar spectrum (SOLAR_SPEC) provided! " 01463 "Can't divide it from extracted " 01464 "standard star spectrum!"); 01465 print_warning_once = FALSE; 01466 } 01467 } 01468 } else { 01469 // cpl_msg_warning("","No startype was provided! Can't" 01470 // " divide solar spectrum for G stars " 01471 // "or fit a profile to atmospheric " 01472 // "transmission for OBAF stars."); 01473 } 01474 01475 if (star_temperature > 0.0) { 01476 // divide blackbody from tmp_spec_data 01477 KMO_TRY_EXIT_IF_ERROR( 01478 kmo_divide_blackbody(tmp_spec_data, solar_x, star_temperature)); 01479 } 01480 01481 cpl_vector_delete(solar_x); solar_x = NULL; 01482 01483 // normalise telluric and its noise 01484 // mean is taken in lambda defined range 01485 KMO_TRY_EXIT_IF_ERROR( 01486 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 01487 filter_id, 01488 tmp_spec_data, 01489 tmp_spec_noise, 01490 &mean_data, 01491 &mean_noise)); 01492 01493 KMO_TRY_EXIT_IF_ERROR( 01494 cpl_vector_divide_scalar(tmp_spec_data, mean_data)); 01495 01496 if (tmp_spec_noise != NULL) { 01497 KMO_TRY_EXIT_IF_ERROR( 01498 cpl_vector_divide_scalar(tmp_spec_noise, mean_noise)); 01499 01500 // set noise spectrum also to zero when solar_spec is too short 01501 KMO_TRY_EXIT_IF_NULL( 01502 ptmp_spec_data = cpl_vector_get_data_const(tmp_spec_data)); 01503 KMO_TRY_EXIT_IF_NULL( 01504 ptmp_spec_noise = cpl_vector_get_data(tmp_spec_noise)); 01505 for (int i = 0; i < cpl_vector_get_size(tmp_spec_data); i++) { 01506 if (ptmp_spec_data[i] == 0.0) { 01507 ptmp_spec_noise[i] = 0.0; 01508 } 01509 } 01510 } 01511 KMO_TRY_CHECK_ERROR_STATE(); 01512 01513 // store telluric & error spectrum 01514 stored_telluric_data[ifu_nr-1] = tmp_spec_data; 01515 stored_telluric_noise[ifu_nr-1] = tmp_spec_noise; 01516 01517 // if magnitude is provided 01518 // calculate zeropoint and throughput 01519 if (has_magnitude) { 01520 // calculate QC THROUGHPUT 01521 crpix1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRPIX1); 01522 crval1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CRVAL1); 01523 cdelt1 = cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], CDELT1); 01524 KMO_TRY_CHECK_ERROR_STATE(); 01525 01526 KMO_TRY_EXIT_IF_ERROR( 01527 kmo_calc_counts(spec_qc, filter_id, 01528 crpix1, crval1, cdelt1, 01529 &counts1, &counts2)); 01530 KMO_TRY_CHECK_ERROR_STATE(); 01531 01532 counts1 /= exptime; 01533 counts2 /= exptime; 01534 01535 stored_qc_throughput[ifu_nr-1] = 01536 kmo_calc_throughput(magnitude1, magnitude2, counts1, counts2, 01537 cpl_propertylist_get_double(stored_sub_tel_data_headers[ifu_nr-1], GAIN), 01538 filter_id); 01539 KMO_TRY_CHECK_ERROR_STATE(); 01540 01541 if (kmclipm_is_nan_or_inf(stored_qc_throughput[ifu_nr-1])) { 01542 stored_qc_throughput[ifu_nr-1] = -1; 01543 } 01544 KMO_TRY_EXIT_IF_ERROR( 01545 kmclipm_update_property_double(stored_sub_tel_data_headers[ifu_nr-1], 01546 QC_THROUGHPUT, 01547 stored_qc_throughput[ifu_nr-1], 01548 "[] IFU throughput")); 01549 01550 // calculate QC ZEROPOINT 01551 zeropoint = kmo_calc_zeropoint(magnitude1, magnitude2, counts1, counts2, cdelt3, filter_id); 01552 if (kmclipm_is_nan_or_inf(zeropoint)) { 01553 zeropoint = -1; 01554 } 01555 KMO_TRY_CHECK_ERROR_STATE(); 01556 01557 KMO_TRY_EXIT_IF_ERROR( 01558 kmclipm_update_property_double(stored_sub_tel_data_headers[ifu_nr-1], 01559 QC_ZEROPOINT, 01560 zeropoint, 01561 "[mag] IFU zeropoint")); 01562 } 01563 cpl_vector_delete(spec_qc);spec_qc = NULL; 01564 } else { 01565 cpl_error_reset(); 01566 // IFU is invalid 01567 KMO_TRY_EXIT_IF_NULL( 01568 stored_sub_tel_data_headers[ifu_nr-1] = 01569 cpl_propertylist_duplicate(sub_header_orig)); 01570 KMO_TRY_EXIT_IF_NULL( 01571 stored_sub_tel_noise_headers[ifu_nr-1] = 01572 cpl_propertylist_duplicate(sub_header_orig)); 01573 KMO_TRY_EXIT_IF_NULL( 01574 stored_sub_psf_headers[ifu_nr-1] = 01575 cpl_propertylist_duplicate(sub_header_orig)); 01576 if (save_cubes) { 01577 KMO_TRY_EXIT_IF_NULL( 01578 stored_sub_cube_data_headers[ifu_nr-1] = 01579 cpl_propertylist_duplicate(sub_header_orig)); 01580 KMO_TRY_EXIT_IF_NULL( 01581 stored_sub_cube_noise_headers[ifu_nr-1] = 01582 cpl_propertylist_duplicate(sub_header_orig)); 01583 } 01584 } 01585 01586 // create EXTNAME keyword as DATA 01587 KMO_TRY_EXIT_IF_NULL( 01588 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_DATA)); 01589 KMO_TRY_EXIT_IF_ERROR( 01590 kmclipm_update_property_string(stored_sub_tel_data_headers[ifu_nr-1], 01591 EXTNAME, extname, "FITS extension name")); 01592 KMO_TRY_EXIT_IF_ERROR( 01593 kmclipm_update_property_string(stored_sub_psf_headers[ifu_nr-1], 01594 EXTNAME, extname, "FITS extension name")); 01595 if (save_cubes) { 01596 KMO_TRY_EXIT_IF_ERROR( 01597 kmclipm_update_property_string(stored_sub_cube_data_headers[ifu_nr-1], 01598 EXTNAME, extname, "FITS extension name")); 01599 } 01600 cpl_free(extname); extname = NULL; 01601 01602 // create EXTNAME keyword as NOISE 01603 if (stored_sub_tel_noise_headers[ifu_nr-1] == NULL) { 01604 KMO_TRY_EXIT_IF_NULL( 01605 stored_sub_tel_noise_headers[ifu_nr-1] = 01606 cpl_propertylist_duplicate( 01607 stored_sub_tel_data_headers[ifu_nr-1])); 01608 } 01609 KMO_TRY_EXIT_IF_NULL( 01610 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE)); 01611 KMO_TRY_EXIT_IF_ERROR( 01612 kmclipm_update_property_string(stored_sub_tel_noise_headers[ifu_nr-1], 01613 EXTNAME, extname, "FITS extension name")); 01614 if (save_cubes) { 01615 KMO_TRY_EXIT_IF_NULL( 01616 stored_sub_cube_noise_headers[ifu_nr-1] = 01617 cpl_propertylist_duplicate( 01618 stored_sub_cube_data_headers[ifu_nr-1])); 01619 KMO_TRY_EXIT_IF_ERROR( 01620 kmclipm_update_property_string(stored_sub_cube_noise_headers[ifu_nr-1], 01621 EXTNAME, extname, "FITS extension name")); 01622 } 01623 cpl_free(extname); extname = NULL; 01624 } // for j ifus (load, process & store) 01625 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01626 } // for i detectors (load, process & store) 01627 KMO_TRY_CHECK_ERROR_STATE(); 01628 01629 // write QC parameter: nr of std stars 01630 KMO_TRY_EXIT_IF_ERROR( 01631 kmclipm_update_property_int(main_header_tel, QC_NR_STD_STARS, 01632 nr_std_stars, "[] Nr. of std stars")); 01633 01634 // update which IFUs are not used 01635 kmo_print_unused_ifus(unused_ifus_after, TRUE); 01636 01637 KMO_TRY_EXIT_IF_ERROR( 01638 kmo_set_unused_ifus(unused_ifus_after, main_header_tel, "kmo_std_star")); 01639 01640 KMO_TRY_EXIT_IF_NULL( 01641 main_header_psf = cpl_propertylist_duplicate(main_header_tel)); 01642 01643 if (has_magnitude) { 01644 // calculate QC THROUGHPUT MEAN and QC THROUGHPUT SDV 01645 // and update main header 01646 KMO_TRY_EXIT_IF_ERROR( 01647 kmo_calc_mean_throughput(stored_qc_throughput, 01648 nr_devices * KMOS_IFUS_PER_DETECTOR, 01649 &throughput_mean, 01650 &throughput_sdv)); 01651 KMO_TRY_EXIT_IF_ERROR( 01652 kmclipm_update_property_double(main_header_tel, QC_THROUGHPUT_MEAN, 01653 throughput_mean, "[] mean throughput for all detectors")); 01654 KMO_TRY_EXIT_IF_ERROR( 01655 kmclipm_update_property_double(main_header_tel, QC_THROUGHPUT_SDV, 01656 throughput_sdv, "[] stdev throughput for all detectors")); 01657 } 01658 KMO_TRY_CHECK_ERROR_STATE(); 01659 01660 // 01661 // save output data 01662 // 01663 01664 // save primary extension 01665 cpl_msg_info("","Saving STD exposure No. %d", nr_exp+1); 01666 KMO_TRY_EXIT_IF_ERROR( 01667 kmo_dfs_save_main_header(frameset, filename_telluric, suffix, 01668 obj_frame, main_header_tel, parlist, 01669 cpl_func)); 01670 KMO_TRY_EXIT_IF_ERROR( 01671 kmo_dfs_save_main_header(frameset, filename_starspec, suffix, 01672 obj_frame, main_header_tel, parlist, 01673 cpl_func)); 01674 KMO_TRY_EXIT_IF_ERROR( 01675 kmo_dfs_save_main_header(frameset, filename_mask, suffix, 01676 obj_frame, main_header_psf, parlist, 01677 cpl_func)); 01678 KMO_TRY_EXIT_IF_ERROR( 01679 kmo_dfs_save_main_header(frameset, filename_psf, suffix, 01680 obj_frame, main_header_psf, parlist, 01681 cpl_func)); 01682 if (save_cubes) { 01683 KMO_TRY_EXIT_IF_ERROR( 01684 kmo_dfs_save_main_header(frameset, filename_cubes, suffix, 01685 obj_frame, main_header_psf, parlist, 01686 cpl_func)); 01687 } 01688 01689 // save stored frames 01690 for (i = 1; i <= nr_devices; i++) { 01691 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 01692 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 01693 01694 // save telluric-vector 01695 kmclipm_vector *ddd = NULL; 01696 if (stored_telluric_data[ifu_nr-1] != NULL) 01697 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_telluric_data[ifu_nr-1])); 01698 KMO_TRY_EXIT_IF_ERROR( 01699 kmo_dfs_save_vector(ddd, filename_telluric, suffix, 01700 stored_sub_tel_data_headers[ifu_nr-1], 01701 0./0.)); 01702 kmclipm_vector_delete(ddd); ddd =NULL; 01703 01704 if (stored_telluric_noise[ifu_nr-1] != NULL) 01705 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_telluric_noise[ifu_nr-1])); 01706 KMO_TRY_EXIT_IF_ERROR( 01707 kmo_dfs_save_vector(ddd, filename_telluric, suffix, 01708 stored_sub_tel_noise_headers[ifu_nr-1], 01709 0./0.)); 01710 kmclipm_vector_delete(ddd); ddd =NULL; 01711 01712 // save star_spec-vector 01713 if (stored_starspec_data[ifu_nr-1] != NULL) 01714 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_starspec_data[ifu_nr-1])); 01715 KMO_TRY_EXIT_IF_ERROR( 01716 kmo_dfs_save_vector(ddd, filename_starspec, suffix, 01717 stored_sub_tel_data_headers[ifu_nr-1], 01718 0./0.)); 01719 kmclipm_vector_delete(ddd); ddd =NULL; 01720 01721 if (stored_starspec_noise[ifu_nr-1] != NULL) 01722 ddd = kmclipm_vector_create(cpl_vector_duplicate(stored_starspec_noise[ifu_nr-1])); 01723 KMO_TRY_EXIT_IF_ERROR( 01724 kmo_dfs_save_vector(ddd, filename_starspec, suffix, 01725 stored_sub_tel_noise_headers[ifu_nr-1], 01726 0./0.)); 01727 kmclipm_vector_delete(ddd); ddd =NULL; 01728 01729 // save psf-image 01730 KMO_TRY_EXIT_IF_ERROR( 01731 kmo_dfs_save_image(stored_psf_data[ifu_nr-1], 01732 filename_psf, suffix, 01733 stored_sub_psf_headers[ifu_nr-1], 01734 0./0.)); 01735 01736 // save mask-image 01737 KMO_TRY_EXIT_IF_ERROR( 01738 kmo_dfs_save_image(stored_mask[ifu_nr-1], 01739 filename_mask, suffix, 01740 stored_sub_psf_headers[ifu_nr-1], 01741 0./0.)); 01742 // save reonstructed cubes 01743 if (save_cubes) { 01744 KMO_TRY_EXIT_IF_ERROR( 01745 kmo_dfs_save_cube(stored_data_cube[ifu_nr-1], 01746 filename_cubes, suffix, 01747 stored_sub_cube_data_headers[ifu_nr-1], 01748 0./0.)); 01749 KMO_TRY_EXIT_IF_ERROR( 01750 kmo_dfs_save_cube(stored_noise_cube[ifu_nr-1], 01751 filename_cubes, suffix, 01752 stored_sub_cube_noise_headers[ifu_nr-1], 01753 0./0.)); 01754 } 01755 } // for j ifus (save stored) 01756 } // for i detectors (save stored) 01757 KMO_TRY_CHECK_ERROR_STATE(); 01758 } // if (frameCnt == 0) 01759 } 01760 KMO_CATCH 01761 { 01762 KMO_CATCH_MSG(); 01763 ret_val = -1; 01764 } 01765 01766 cpl_free(obj_sky_struct); obj_sky_struct = NULL; 01767 kmo_free_fits_desc(&desc1); 01768 kmo_free_fits_desc(&desc2); 01769 kmo_free_unused_ifus(unused_ifus_before); unused_ifus_before = NULL; 01770 kmo_free_unused_ifus(unused_ifus_after); unused_ifus_after = NULL; 01771 cpl_free(bounds); bounds = NULL; 01772 cpl_propertylist_delete(main_header_tel); main_header_tel = NULL; 01773 cpl_propertylist_delete(main_header_psf); main_header_psf = NULL; 01774 cpl_vector_delete(atmos_model); atmos_model = NULL; 01775 cpl_vector_delete(solar_spec); solar_spec = NULL; 01776 cpl_table_delete(spec_type_LUT); spec_type_LUT = NULL; 01777 cpl_vector_delete(identified_slices); identified_slices = NULL; 01778 cpl_propertylist_delete(sub_header_orig); sub_header_orig = NULL; 01779 for (i = 0; i < nr_devices * KMOS_IFUS_PER_DETECTOR; i++) { 01780 cpl_vector_delete(stored_telluric_data[i]); stored_telluric_data[i] = NULL; 01781 cpl_vector_delete(stored_telluric_noise[i]); stored_telluric_noise[i] = NULL; 01782 cpl_vector_delete(stored_starspec_data[i]); stored_starspec_data[i] = NULL; 01783 cpl_vector_delete(stored_starspec_noise[i]); stored_starspec_noise[i] = NULL; 01784 cpl_image_delete(stored_psf_data[i]); stored_psf_data[i] = NULL; 01785 cpl_propertylist_delete(stored_sub_tel_data_headers[i]); stored_sub_tel_data_headers[i] = NULL; 01786 cpl_propertylist_delete(stored_sub_tel_noise_headers[i]); stored_sub_tel_noise_headers[i] = NULL; 01787 if (save_cubes) { 01788 cpl_propertylist_delete(stored_sub_cube_data_headers[i]); stored_sub_cube_data_headers[i] = NULL; 01789 cpl_propertylist_delete(stored_sub_cube_noise_headers[i]); stored_sub_cube_noise_headers[i] = NULL; 01790 } 01791 cpl_propertylist_delete(stored_sub_psf_headers[i]); stored_sub_psf_headers[i] = NULL; 01792 cpl_image_delete(stored_mask[i]); stored_mask[i] = NULL; 01793 cpl_imagelist_delete(stored_data_cube[i]); stored_data_cube[i] = NULL; 01794 cpl_imagelist_delete(stored_noise_cube[i]); stored_noise_cube[i] = NULL; 01795 } 01796 cpl_free(stored_telluric_data); stored_telluric_data = NULL; 01797 cpl_free(stored_telluric_noise); stored_telluric_noise = NULL; 01798 cpl_free(stored_starspec_data); stored_starspec_data = NULL; 01799 cpl_free(stored_starspec_noise); stored_starspec_noise = NULL; 01800 cpl_free(stored_psf_data); stored_psf_data = NULL; 01801 cpl_free(stored_sub_tel_data_headers); stored_sub_tel_data_headers = NULL; 01802 cpl_free(stored_sub_tel_noise_headers); stored_sub_tel_noise_headers = NULL; 01803 if (save_cubes) { 01804 cpl_free(stored_sub_cube_data_headers); stored_sub_cube_data_headers = NULL; 01805 cpl_free(stored_sub_cube_noise_headers); stored_sub_cube_noise_headers = NULL; 01806 } 01807 cpl_free(stored_sub_psf_headers); stored_sub_psf_headers = NULL; 01808 cpl_free(stored_qc_throughput); stored_qc_throughput = NULL; 01809 cpl_free(suffix); suffix = NULL; 01810 cpl_free(stored_mask); stored_mask = NULL; 01811 cpl_free(stored_data_cube); stored_data_cube = NULL; 01812 cpl_free(stored_noise_cube); stored_noise_cube = NULL; 01813 cpl_free(grat_id); grat_id = NULL; 01814 cpl_frameset_delete(frameset_std); frameset_std = NULL; 01815 01816 return ret_val; 01817 } 01818
1.7.6.1