|
KMOS Pipeline Reference Manual
1.3.17
|
00001 /* 00002 * This file is part of the KMOS Pipeline 00003 * Copyright (C) 2002,2003 European Southern Observatory 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 */ 00019 00020 #ifdef HAVE_CONFIG_H 00021 #include <config.h> 00022 #endif 00023 00024 /*----------------------------------------------------------------------------- 00025 * Includes 00026 *----------------------------------------------------------------------------*/ 00027 00028 #include <math.h> 00029 #include <string.h> 00030 00031 #include <cpl.h> 00032 00033 #include "kmclipm_math.h" 00034 00035 #include "kmo_constants.h" 00036 #include "kmo_cpl_extensions.h" 00037 #include "kmo_utils.h" 00038 #include "kmo_functions.h" 00039 #include "kmo_priv_std_star.h" 00040 #include "kmo_priv_fit_profile.h" 00041 #include "kmo_priv_extract_spec.h" 00042 #include "kmo_priv_functions.h" 00043 #include "kmo_dfs.h" 00044 #include "kmo_error.h" 00045 #include "kmo_debug.h" 00046 #include "kmo_priv_reconstruct.h" 00047 00048 const int nr_lines_h = 10; 00049 const double lines_center_h[] = { 00050 1.7001, // HeI // triplet 00051 1.53429, // Br-18 00052 1.54400, // Br-17 00053 1.55576, // Br-16 00054 1.57018, // Br-15 00055 1.58817, // Br-14 00056 1.61105, // Br-13 00057 1.64084, // Br-12 00058 1.68077, // Br-11 00059 1.73634 // Br-10 00060 }; 00061 const double lines_width_h[] = { 00062 0.025, // HeI 00063 0.003, // Br-18 00064 0.015, // Br-17 00065 0.015, // Br-16 00066 0.015, // Br-15 00067 0.025, // Br-14 00068 0.015, // Br-13 00069 0.025, // Br-12 00070 0.025, // Br-11 00071 0.05 // Br-10 00072 }; 00073 const int nr_lines_k = 2; 00074 const double lines_center_k[] = { 00075 2.1120, // HeI // triplet 00076 2.16569 // Br-gamma 00077 }; 00078 const double lines_width_k[] = { 00079 0.01, // HeI // triplet 00080 0.015 // Br-gamma 00081 }; 00082 const int nr_lines_hk = 12; 00083 const double lines_center_hk[] = { 00084 1.7001, // HeI // triplet 00085 1.53429, // Br-18 00086 1.54400, // Br-17 00087 1.55576, // Br-16 00088 1.57018, // Br-15 00089 1.58817, // Br-14 00090 1.61105, // Br-13 00091 1.64084, // Br-12 00092 1.68077, // Br-11 00093 1.73634, // Br-10 00094 2.1120, // HeI // triplet 00095 2.16569 // Br-gamma 00096 }; 00097 const double lines_width_hk[] = { 00098 0.025, // HeI 00099 0.003, // Br-18 00100 0.015, // Br-17 00101 0.015, // Br-16 00102 0.015, // Br-15 00103 0.025, // Br-14 00104 0.015, // Br-13 00105 0.025, // Br-12 00106 0.025, // Br-11 00107 0.05, // Br-10 00108 0.015, // HeI // triplet 00109 0.015 // Br-gamma 00110 }; 00111 const int nr_lines_iz = 12; 00112 const double lines_center_iz[] = { 00113 0.84386, // Pa-18 00114 0.84679, // Pa-17 00115 0.85031, // Pa-16 00116 0.85460, // Pa-15 00117 0.85990, // Pa-14 00118 0.86657, // Pa-13 00119 0.87511, // Pa-12 00120 0.88635, // Pa-11 00121 0.90156, // Pa-10 00122 0.92297, // Pa-9 00123 0.95467, // Pa-epsilon 00124 1.00501 // Pa-delta 00125 }; 00126 const double lines_width_iz[] = { 00127 0.0008, // Pa-18 00128 0.003225, // Pa-17 00129 0.0039, // Pa-16 00130 0.0048, // Pa-15 00131 0.006, // Pa-14 00132 0.0076, // Pa-13 00133 0.001, // Pa-12 00134 0.013, // Pa-11 00135 0.01, // Pa-10 00136 0.013, // Pa-9 00137 0.02, // Pa-epsilon 00138 0.025 // Pa-delta 00139 }; 00140 const int nr_lines_yj = 7; 00141 const double lines_center_yj[] = { 00142 1.08331, // HeI 00143 1.09160, // HeI 00144 1.09389, // Pa-gamma 00145 1.19723, // HeI 00146 1.28191, // Pa-beta 00147 1.27882, // HeI 00148 1.29720 // HeI 00149 }; 00150 const double lines_width_yj[] = { 00151 .01, //0.005, // HeI 00152 .01, //0.002, // HeI 00153 0.02, // Pa-gamma 00154 0.003, // HeI 00155 0.02, // Pa-beta 00156 0.0025, // HeI 00157 0.002 // HeI 00158 }; 00159 00160 /*----------------------------------------------------------------------------- 00161 * Functions prototypes 00162 *----------------------------------------------------------------------------*/ 00163 00164 static int kmos_std_star_compute_ifu( 00165 cpl_propertylist * sub_header_orig, 00166 cpl_frame * obj_frame, 00167 cpl_frame * sky_frame, 00168 cpl_frame * flat_frame, 00169 cpl_frame * xcal_frame, 00170 cpl_frame * ycal_frame, 00171 cpl_frame * lcal_frame, 00172 cpl_frame * illum_frame, 00173 cpl_frame * atmos_frame, 00174 cpl_frame * solar_frame, 00175 int ifu_nr, 00176 cpl_propertylist * main_header_tel, 00177 gridDefinition gd, 00178 int low_bound, 00179 int high_bound, 00180 const char * fmethod, 00181 int flux, 00182 int xcal_interpolation, 00183 const char * mask_method, 00184 const char * cmethod, 00185 double cpos_rej, 00186 double cneg_rej, 00187 int citer, 00188 int cmax, 00189 int cmin, 00190 double cen_x, 00191 double cen_y, 00192 double radius, 00193 const char * filter_id, 00194 char star_type, 00195 int no_noise, 00196 int is_stdstarscipatt, 00197 skySkyStruct sky_sky_struct, 00198 double star_temp, 00199 cpl_vector ** spec_qc, 00200 cpl_propertylist ** out_sub_tel_data_header, 00201 cpl_propertylist ** out_sub_psf_header, 00202 cpl_propertylist ** out_sub_cube_data_header, 00203 cpl_imagelist ** out_data_cube, 00204 cpl_imagelist ** out_noise_cube, 00205 cpl_image ** out_psf_data, 00206 cpl_image ** out_mask, 00207 cpl_vector ** out_starspec_data, 00208 cpl_vector ** out_starspec_noise, 00209 cpl_vector ** out_noisespec, 00210 cpl_vector ** out_telluric_data, 00211 cpl_vector ** out_telluric_noise) ; 00212 static int kmos_std_star_check_inputs( 00213 cpl_frameset * frameset, 00214 const char * magnitude_txt, 00215 int * is_stdstarscipatt, 00216 int * compute_qcs, 00217 double * magnitude1, 00218 double * magnitude2) ; 00219 static int kmos_std_star_plot(void) ; 00220 static int kmos_std_star_adjust_double( 00221 cpl_propertylist * header, 00222 const char * key1, 00223 const char * key2, 00224 const char * key3) ; 00225 static int kmos_std_star_adjust_string( 00226 cpl_propertylist * header, 00227 const char * key1, 00228 const char * key2, 00229 const char * key3) ; 00230 static cpl_frameset * kmos_std_star_extract_same_grat_stds( 00231 cpl_frameset * in, 00232 int * same_gratings) ; 00233 00234 static int kmos_std_star_create(cpl_plugin *); 00235 static int kmos_std_star_exec(cpl_plugin *); 00236 static int kmos_std_star_destroy(cpl_plugin *); 00237 static int kmos_std_star(cpl_parameterlist *, cpl_frameset *); 00238 00239 /*----------------------------------------------------------------------------- 00240 * Static variables 00241 *----------------------------------------------------------------------------*/ 00242 00243 static char kmos_std_star_description[] = 00244 "This recipe creates a telluric frame and a PSF frames.\n" 00245 "Since there cannot be 1 std star per IFU in one exposure, we use several\n" 00246 "exposures in order to have at least one standard star and one sky\n" 00247 "in each IFU. The frames are organised following this logic:\n" 00248 "1. For each IFU the first standard star in the list of frames is\n" 00249 " taken. All subsequent standard star exposures for this IFU are ignored\n" 00250 "2. A closest in time sky exposure is uѕed\n" 00251 "3. IFUs not containing a standard star and a sky will be empty in the result\n" 00252 "\n" 00253 "NOISE_SPEC contains the shot noise [sqrt(counts*gain)/gain]\n" 00254 "If the exposures have been taken with KMOS_spec_cal_stdstarscipatt, an\n" 00255 "additional noise component is added: All existing sky exposures for an IFU\n" 00256 "are subtracted pairwise, spectra are extracted and the std deviation is \n" 00257 "computed\n" 00258 "\n" 00259 "-------------------------------------------------------------------------------\n" 00260 " Input files:\n" 00261 "\n" 00262 " DO KMOS \n" 00263 " category Type Explanation Required #Frames\n" 00264 " -------- ----- ----------- -------- -------\n" 00265 " STD RAW Std. star & sky exposures Y >=1 \n" 00266 " XCAL F2D x calibration frame Y 1 \n" 00267 " YCAL F2D y calibration frame Y 1 \n" 00268 " LCAL F2D Wavelength calib. frame Y 1 \n" 00269 " MASTER_FLAT F2D Master flat frame Y 1 \n" 00270 " WAVE_BAND F2L Table with start-/end-wl Y 1 \n" 00271 " ILLUM_CORR F2I Illumination correction N 0,1 \n" 00272 " SOLAR_SPEC F1S Solar spectrum N 0,1 \n" 00273 " (only for G stars) \n" 00274 " ATMOS_MODEL F1S Model atmospheric transmisson N 0,1 \n" 00275 " (only for OBAF stars in K band) \n" 00276 " SPEC_TYPE_LOOKUP F2L LUT eff. stellar temperature N 0,1 \n" 00277 "\n" 00278 " Output files: \n" 00279 "\n" 00280 " DO KMOS \n" 00281 " category Type Explanation \n" 00282 " -------- ----- ----------- \n" 00283 " TELLURIC F1I The normalised telluric spectrum \n" 00284 " (including errors) \n" 00285 " STAR_SPEC F1I The extracted star spectrum \n" 00286 " (including errors) \n" 00287 " STD_IMAGE F2I The standard star PSF images \n" 00288 " STD_MASK F2I The mask used to extract the star spec \n" 00289 " NOISE_SPEC F1I The extracted noise spectrum \n" 00290 "---------------------------------------------------------------------------\n" 00291 "\n"; 00292 00293 /*----------------------------------------------------------------------------- 00294 * Functions code 00295 *----------------------------------------------------------------------------*/ 00296 00297 /*----------------------------------------------------------------------------*/ 00301 /*----------------------------------------------------------------------------*/ 00302 00305 /*----------------------------------------------------------------------------*/ 00314 /*----------------------------------------------------------------------------*/ 00315 int cpl_plugin_get_info(cpl_pluginlist *list) 00316 { 00317 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00318 cpl_plugin *plugin = &recipe->interface; 00319 00320 cpl_plugin_init(plugin, 00321 CPL_PLUGIN_API, 00322 KMOS_BINARY_VERSION, 00323 CPL_PLUGIN_TYPE_RECIPE, 00324 "kmos_std_star", 00325 "Create the telluric correction frame.", 00326 kmos_std_star_description, 00327 "Alex Agudo Berbel, Y. Jung", 00328 "usd-help@eso.org", 00329 kmos_get_license(), 00330 kmos_std_star_create, 00331 kmos_std_star_exec, 00332 kmos_std_star_destroy); 00333 cpl_pluginlist_append(list, plugin); 00334 00335 return 0; 00336 } 00337 00338 /*----------------------------------------------------------------------------*/ 00346 /*----------------------------------------------------------------------------*/ 00347 static int kmos_std_star_create(cpl_plugin *plugin) 00348 { 00349 cpl_recipe *recipe; 00350 cpl_parameter *p; 00351 00352 /* Check that the plugin is part of a valid recipe */ 00353 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00354 recipe = (cpl_recipe *)plugin; 00355 else 00356 return -1; 00357 00358 /* Create the parameters list in the cpl_recipe object */ 00359 recipe->parameters = cpl_parameterlist_new(); 00360 00361 /* --startype */ 00362 p = cpl_parameter_new_value("kmos.kmos_std_star.startype", CPL_TYPE_STRING, 00363 "The spectral type of the star (O, B, A, F, G) e.g. G4V", 00364 "kmos.kmos_std_star", ""); 00365 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startype"); 00366 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00367 cpl_parameterlist_append(recipe->parameters, p); 00368 00369 /* --imethod */ 00370 p = cpl_parameter_new_value("kmos.kmos_std_star.imethod", CPL_TYPE_STRING, 00371 "Method to use for interpolation. " 00372 "[\"NN\" (nearest neighbour), " 00373 "\"lwNN\" (linear weighted nearest neighbor), " 00374 "\"swNN\" (square weighted nearest neighbor), " 00375 "\"MS\" (Modified Shepard's method), " 00376 "\"CS\" (Cubic spline)]", 00377 "kmos.kmos_std_star", "CS"); 00378 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "imethod"); 00379 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00380 cpl_parameterlist_append(recipe->parameters, p); 00381 00382 /* --fmethod */ 00383 p = cpl_parameter_new_value("kmos.kmos_std_star.fmethod", CPL_TYPE_STRING, 00384 "Fitting method (gauss, moffat, profile", "kmos.kmos_std_star", 00385 "gauss"); 00386 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmethod"); 00387 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00388 cpl_parameterlist_append(recipe->parameters, p); 00389 00390 /* --neighborhoodRange */ 00391 p = cpl_parameter_new_value("kmos.kmos_std_star.neighborhoodRange", 00392 CPL_TYPE_DOUBLE, 00393 "Defines the range to search for neighbors in pixels", 00394 "kmos.kmos_std_star", 1.001); 00395 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neighborhoodRange"); 00396 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00397 cpl_parameterlist_append(recipe->parameters, p); 00398 00399 /* --magnitude */ 00400 p = cpl_parameter_new_value("kmos.kmos_std_star.magnitude", CPL_TYPE_STRING, 00401 "Star magnitude (2 values in HK, eg. 12.1,13.2)", 00402 "kmos.kmos_std_star", ""); 00403 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "magnitude"); 00404 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00405 cpl_parameterlist_append(recipe->parameters, p); 00406 00407 /* --flux */ 00408 p = cpl_parameter_new_value("kmos.kmos_std_star.flux", CPL_TYPE_BOOL, 00409 "TRUE: Apply flux conservation. FALSE: otherwise", 00410 "kmos.kmos_std_star", TRUE); 00411 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux"); 00412 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00413 cpl_parameterlist_append(recipe->parameters, p); 00414 00415 /* --save_cubes */ 00416 p = cpl_parameter_new_value("kmos.kmos_std_star.save_cubes", CPL_TYPE_BOOL, 00417 "Flag to save reconstructed cubes", "kmos.kmos_std_star", FALSE); 00418 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "save_cubes"); 00419 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00420 cpl_parameterlist_append(recipe->parameters, p); 00421 00422 /* --no_noise */ 00423 p = cpl_parameter_new_value("kmos.kmos_std_star.no_noise", CPL_TYPE_BOOL, 00424 "Skip the noise computation on sky exposures", "kmos.kmos_std_star", 00425 FALSE); 00426 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "no_noise"); 00427 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00428 cpl_parameterlist_append(recipe->parameters, p); 00429 00430 /* --xcal_interpolation */ 00431 p = cpl_parameter_new_value("kmos.kmos_std_star.xcal_interpolation", 00432 CPL_TYPE_BOOL, "Flag to Interpolate xcal between rotator angles", 00433 "kmos.kmos_std_star", TRUE); 00434 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcal_interpolation"); 00435 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00436 cpl_parameterlist_append(recipe->parameters, p); 00437 00438 /* --suppress_extension */ 00439 p = cpl_parameter_new_value("kmos.kmos_std_star.suppress_extension", 00440 CPL_TYPE_BOOL, "Flag to Suppress filename extension", 00441 "kmos.kmos_std_star", FALSE); 00442 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "suppress_extension"); 00443 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00444 cpl_parameterlist_append(recipe->parameters, p); 00445 00446 /* Add parameters for band-definition */ 00447 kmos_band_pars_create(recipe->parameters, "kmos.kmos_std_star"); 00448 00449 /* --mask_method */ 00450 p = cpl_parameter_new_value("kmos.kmos_std_star.mask_method", 00451 CPL_TYPE_STRING, "Method used : mask, integrated or optimal", 00452 "kmos.kmos_std_star", "optimal"); 00453 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "mask_method"); 00454 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00455 cpl_parameterlist_append(recipe->parameters, p); 00456 00457 /* --centre */ 00458 p = cpl_parameter_new_value("kmos.kmos_std_star.centre", 00459 CPL_TYPE_STRING, "The centre of the circular mask (pixel)", 00460 "kmos.kmos_std_star", "7.5,7.5"); 00461 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "centre"); 00462 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00463 cpl_parameterlist_append(recipe->parameters, p); 00464 00465 /* --radius */ 00466 p = cpl_parameter_new_value("kmos.kmos_std_star.radius", 00467 CPL_TYPE_DOUBLE, "The radius of the circular mask (pixel)", 00468 "kmos.kmos_std_star", 3.0); 00469 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "radius"); 00470 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00471 cpl_parameterlist_append(recipe->parameters, p); 00472 00473 /* Add parameters for combining */ 00474 return kmos_combine_pars_create(recipe->parameters, "kmos.kmos_std_star", 00475 DEF_REJ_METHOD, FALSE); 00476 } 00477 00478 /*----------------------------------------------------------------------------*/ 00484 /*----------------------------------------------------------------------------*/ 00485 static int kmos_std_star_exec(cpl_plugin *plugin) 00486 { 00487 cpl_recipe *recipe; 00488 00489 /* Get the recipe out of the plugin */ 00490 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00491 recipe = (cpl_recipe *)plugin; 00492 else return -1; 00493 00494 return kmos_std_star(recipe->parameters, recipe->frames); 00495 } 00496 00497 /*----------------------------------------------------------------------------*/ 00503 /*----------------------------------------------------------------------------*/ 00504 static int kmos_std_star_destroy(cpl_plugin *plugin) 00505 { 00506 cpl_recipe *recipe; 00507 00508 /* Get the recipe out of the plugin */ 00509 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00510 recipe = (cpl_recipe *)plugin; 00511 else return -1 ; 00512 00513 cpl_parameterlist_delete(recipe->parameters); 00514 return 0 ; 00515 } 00516 00517 /*----------------------------------------------------------------------------*/ 00530 /*----------------------------------------------------------------------------*/ 00531 static int kmos_std_star(cpl_parameterlist *parlist, cpl_frameset *frameset) 00532 { 00533 const cpl_parameter * par ; 00534 /*********************/ 00535 /* Parsed Parameters */ 00536 const char * imethod ; 00537 const char * cmethod ; 00538 const char * fmethod ; 00539 const char * mask_method ; 00540 const char * centre_txt ; 00541 cpl_vector * centre ; 00542 const char * spec_type ; 00543 const char * magnitude_txt ; 00544 double cpos_rej, cneg_rej, neighborhoodRange, cen_x, cen_y, 00545 radius ; 00546 int flux, save_cubes, no_noise, citer, cmin, cmax, 00547 xcal_interpolation, suppress_extension ; 00548 /*********************/ 00549 char * suffix ; 00550 char * keyword ; 00551 char * extname ; 00552 char * fn_suffix ; 00553 const char * filter_id ; 00554 cpl_array ** unused_ifus_before ; 00555 cpl_array ** unused_ifus_after ; 00556 const int * punused_ifus ; 00557 gridDefinition gd; 00558 cpl_propertylist * tmp_header ; 00559 cpl_propertylist * main_header_tel ; 00560 cpl_propertylist * sub_header_orig ; 00561 cpl_propertylist * main_header_psf ; 00562 int * bounds ; 00563 objSkyStruct * obj_sky_struct ; 00564 skySkyStruct * sky_sky_struct ; 00565 00566 cpl_imagelist ** stored_data_cube ; 00567 cpl_imagelist ** stored_noise_cube ; 00568 cpl_image ** stored_psf_data ; 00569 cpl_image ** stored_mask ; 00570 cpl_vector ** stored_telluric_data ; 00571 cpl_vector ** stored_telluric_noise ; 00572 cpl_vector ** stored_starspec_data ; 00573 cpl_vector ** stored_starspec_noise ; 00574 cpl_vector ** stored_noisespec ; 00575 double * stored_qc_throughput ; 00576 cpl_propertylist ** stored_sub_tel_data_headers ; 00577 cpl_propertylist ** stored_sub_tel_noise_headers ; 00578 cpl_propertylist ** stored_sub_cube_data_headers ; 00579 cpl_propertylist ** stored_sub_cube_noise_headers ; 00580 cpl_propertylist ** stored_sub_psf_headers ; 00581 char filename_telluric[256], 00582 filename_starspec[256], 00583 filename_psf[256], 00584 filename_mask[256], 00585 filename_cubes[256], 00586 filename_noise[256] ; 00587 cpl_frame * obj_frame ; 00588 cpl_frame * sky_frame ; 00589 cpl_frame * xcal_frame ; 00590 cpl_frame * ycal_frame ; 00591 cpl_frame * lcal_frame ; 00592 cpl_frame * flat_frame ; 00593 cpl_frame * illum_frame ; 00594 cpl_frame * solar_frame ; 00595 cpl_frame * atmos_frame ; 00596 cpl_table * band_table ; 00597 cpl_frameset * frameset_std ; 00598 cpl_vector * spec_qc ; 00599 int is_stdstarscipatt, compute_qcs, 00600 ifu_nr, nifus, nr_std_stars ; 00601 double magnitude1, magnitude2, star_temp, exptime, 00602 throughput_mean, throughput_sdv, cdelt1, crpix1, 00603 crval1, zeropoint, tmp_data, tmp_noise, counts1, 00604 counts2, gain ; 00605 char star_type ; 00606 kmclipm_vector * ddd ; 00607 int i, j ; 00608 00609 /* Initialise */ 00610 nr_std_stars = 0 ; 00611 zeropoint = throughput_mean = throughput_sdv = -1.0 ; 00612 magnitude1 = magnitude2 = -1.0 ; 00613 00614 /* Check entries */ 00615 if (parlist == NULL || frameset == NULL) { 00616 cpl_msg_error(__func__, "Null Inputs") ; 00617 cpl_error_set(__func__, CPL_ERROR_NULL_INPUT) ; 00618 return -1 ; 00619 } 00620 00621 /* Get parameters */ 00622 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_std_star.imethod"); 00623 imethod = cpl_parameter_get_string(par) ; 00624 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_std_star.startype"); 00625 spec_type = cpl_parameter_get_string(par) ; 00626 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_std_star.fmethod"); 00627 fmethod = cpl_parameter_get_string(par) ; 00628 par = cpl_parameterlist_find_const(parlist, 00629 "kmos.kmos_std_star.neighborhoodRange"); 00630 neighborhoodRange = cpl_parameter_get_double(par) ; 00631 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_std_star.magnitude"); 00632 magnitude_txt = cpl_parameter_get_string(par) ; 00633 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_std_star.flux"); 00634 flux = cpl_parameter_get_bool(par); 00635 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_std_star.save_cubes"); 00636 save_cubes = cpl_parameter_get_bool(par); 00637 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_std_star.no_noise"); 00638 no_noise = cpl_parameter_get_bool(par); 00639 par = cpl_parameterlist_find_const(parlist, 00640 "kmos.kmos_std_star.xcal_interpolation"); 00641 xcal_interpolation = cpl_parameter_get_bool(par); 00642 par = cpl_parameterlist_find_const(parlist, 00643 "kmos.kmos_std_star.suppress_extension"); 00644 suppress_extension = cpl_parameter_get_bool(par); 00645 kmos_band_pars_load(parlist, "kmos.kmos_std_star"); 00646 par = cpl_parameterlist_find_const(parlist, 00647 "kmos.kmos_std_star.mask_method"); 00648 mask_method = cpl_parameter_get_string(par) ; 00649 if (!strcmp(mask_method, "integrated")) { 00650 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_std_star.centre"); 00651 centre_txt = cpl_parameter_get_string(par) ; 00652 centre = kmo_identify_ranges(centre_txt); 00653 if (cpl_vector_get_size(centre) != 2) { 00654 cpl_msg_error(__func__, "centre must have 2 values like a,b") ; 00655 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00656 return -1 ; 00657 } 00658 cen_x = cpl_vector_get(centre, 0); 00659 cen_y = cpl_vector_get(centre, 1); 00660 cpl_vector_delete(centre); 00661 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_std_star.radius"); 00662 radius = cpl_parameter_get_double(par) ; 00663 if (radius < 0.0) { 00664 cpl_msg_error(__func__, "radius must be greater than 0.0") ; 00665 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00666 return -1 ; 00667 } 00668 } else if (strcmp(mask_method, "optimal")) { 00669 cpl_msg_error(__func__, "Unsupported mask method: %s", mask_method) ; 00670 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00671 return -1 ; 00672 } 00673 kmos_combine_pars_load(parlist, "kmos.kmos_std_star", &cmethod, 00674 &cpos_rej, &cneg_rej, &citer, &cmin, &cmax, FALSE); 00675 00676 /* Check Parameters */ 00677 if (strcmp(cmethod, "average") && strcmp(cmethod, "median") && 00678 strcmp(cmethod, "sum") && strcmp(cmethod, "min_max") && 00679 strcmp(cmethod, "ksigma")) { 00680 cpl_msg_error(__func__, 00681 "cmethod must be average median sum min_max or ksigma") ; 00682 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00683 return -1 ; 00684 } 00685 if (strcmp(imethod, "NN") && strcmp(imethod, "lwNN") && 00686 strcmp(imethod, "swNN") && strcmp(imethod, "MS") && 00687 strcmp(imethod, "CS")) { 00688 cpl_msg_error(__func__, "imethod must be NN,lwNN,swNN,MS or CS") ; 00689 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00690 return -1 ; 00691 } 00692 if (strcmp(fmethod, "gauss") && strcmp(fmethod, "moffat")) { 00693 cpl_msg_error(__func__, "fmethod must be gauss or moffat") ; 00694 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00695 return -1 ; 00696 } 00697 if (neighborhoodRange <= 0.0) { 00698 cpl_msg_error(__func__, "neighborhoodRange must be greater than 0.0") ; 00699 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00700 return -1 ; 00701 } 00702 00703 /* Identify the RAW and CALIB frames in the input frameset */ 00704 if (kmo_dfs_set_groups(frameset, "kmos_std_star") != 1) { 00705 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00706 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00707 return -1 ; 00708 } 00709 00710 /* Check the inputs consistency */ 00711 if (kmos_std_star_check_inputs(frameset, magnitude_txt, &is_stdstarscipatt, 00712 &compute_qcs, &magnitude1, &magnitude2) != 1) { 00713 cpl_msg_error(__func__, "Input frameset is not consistent") ; 00714 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00715 return -1 ; 00716 } 00717 00718 /* Instrument setup */ 00719 suffix = kmo_dfs_get_suffix(kmo_dfs_get_frame(frameset, STD), TRUE, FALSE); 00720 cpl_msg_info("", "Detected instrument setup: %s", suffix+1); 00721 00722 /* Check which IFUs are active for all frames */ 00723 unused_ifus_before = kmo_get_unused_ifus(frameset, 0, 0); 00724 unused_ifus_after = kmo_duplicate_unused_ifus(unused_ifus_before); 00725 kmo_print_unused_ifus(unused_ifus_before, FALSE); 00726 kmo_free_unused_ifus(unused_ifus_before); 00727 00728 /* Setup grid definition, wavelength start and end are set later */ 00729 kmclipm_setup_grid(&gd, imethod, neighborhoodRange, KMOS_PIX_RESOLUTION,0.); 00730 00731 /* Get left and right bounds of IFUs from XCAL */ 00732 tmp_header = kmo_dfs_load_primary_header(frameset, XCAL); 00733 bounds = kmclipm_extract_bounds(tmp_header); 00734 cpl_propertylist_delete(tmp_header); 00735 00736 /* Extract STD frames */ 00737 frameset_std = kmos_std_star_extract_same_grat_stds(frameset, &i) ; 00738 00739 /* Get valid STD frames with objects in it and associated sky exposures */ 00740 obj_sky_struct = kmo_create_objSkyStruct(frameset_std, STD, FALSE); 00741 kmo_print_objSkyStruct(obj_sky_struct); 00742 00743 /* Check if there is at least 1 object */ 00744 if (obj_sky_struct->size == 0) { 00745 cpl_free(suffix); 00746 cpl_free(bounds); 00747 kmo_free_unused_ifus(unused_ifus_after); 00748 cpl_frameset_delete(frameset_std) ; 00749 cpl_msg_error(cpl_func, "No Object found"); 00750 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00751 return -1 ; 00752 } 00753 00754 /* Identify sky-sky-pairs for NOISE_SPEC calculation */ 00755 sky_sky_struct = kmo_create_skySkyStruct(frameset_std); 00756 00757 /* Get frame */ 00758 illum_frame = kmo_dfs_get_frame(frameset, ILLUM_CORR); 00759 flat_frame = kmo_dfs_get_frame(frameset, MASTER_FLAT); 00760 xcal_frame = kmo_dfs_get_frame(frameset, XCAL) ; 00761 ycal_frame = kmo_dfs_get_frame(frameset, YCAL) ; 00762 lcal_frame = kmo_dfs_get_frame(frameset, LCAL) ; 00763 atmos_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL); 00764 solar_frame = kmo_dfs_get_frame(frameset, SOLAR_SPEC); 00765 00766 /* Allocate intermediate memory */ 00767 nifus = KMOS_NR_DETECTORS * KMOS_IFUS_PER_DETECTOR ; 00768 stored_telluric_data = (cpl_vector**)cpl_calloc(nifus, sizeof(cpl_vector*)); 00769 stored_telluric_noise = (cpl_vector**)cpl_calloc(nifus,sizeof(cpl_vector*)); 00770 stored_starspec_data = (cpl_vector**)cpl_calloc(nifus, sizeof(cpl_vector*)); 00771 stored_starspec_noise = (cpl_vector**)cpl_calloc(nifus,sizeof(cpl_vector*)); 00772 stored_psf_data = (cpl_image**)cpl_calloc(nifus, sizeof(cpl_image*)); 00773 stored_mask = (cpl_image**)cpl_calloc(nifus, sizeof(cpl_image*)); 00774 stored_data_cube =(cpl_imagelist**)cpl_calloc(nifus,sizeof(cpl_imagelist*)); 00775 stored_noise_cube=(cpl_imagelist**)cpl_calloc(nifus,sizeof(cpl_imagelist*)); 00776 stored_qc_throughput = (double*)cpl_calloc(nifus, sizeof(double)); 00777 stored_sub_psf_headers = (cpl_propertylist**)cpl_calloc(nifus, 00778 sizeof(cpl_propertylist*)); 00779 stored_sub_tel_data_headers = (cpl_propertylist**)cpl_calloc(nifus, 00780 sizeof(cpl_propertylist*)); 00781 stored_sub_tel_noise_headers = (cpl_propertylist**)cpl_calloc(nifus, 00782 sizeof(cpl_propertylist*)); 00783 stored_sub_cube_data_headers = (cpl_propertylist**)cpl_calloc(nifus, 00784 sizeof(cpl_propertylist*)); 00785 stored_sub_cube_noise_headers=(cpl_propertylist**)cpl_calloc(nifus, 00786 sizeof(cpl_propertylist*)); 00787 stored_noisespec = (cpl_vector**)cpl_calloc(nifus, sizeof(cpl_vector*)); 00788 00789 strcpy(filename_telluric, TELLURIC); 00790 strcpy(filename_starspec, STAR_SPEC); 00791 strcpy(filename_psf, STD_IMAGE); 00792 strcpy(filename_mask, STD_MASK); 00793 strcpy(filename_cubes, STD_CUBE); 00794 strcpy(filename_noise, NOISE_SPEC); 00795 00796 /* 00797 cpl_free(stored_telluric_data); 00798 cpl_free(stored_telluric_noise); 00799 cpl_free(stored_starspec_data); 00800 cpl_free(stored_starspec_noise); 00801 cpl_free(stored_psf_data); 00802 cpl_free(stored_sub_tel_data_headers); 00803 cpl_free(stored_sub_tel_noise_headers); 00804 cpl_free(stored_noisespec); 00805 cpl_free(stored_sub_cube_data_headers); 00806 cpl_free(stored_sub_cube_noise_headers); 00807 cpl_free(stored_sub_psf_headers); 00808 cpl_free(stored_mask); 00809 cpl_free(stored_data_cube); 00810 cpl_free(stored_noise_cube); 00811 cpl_free(stored_qc_throughput) ; 00812 kmo_delete_objSkyStruct(obj_sky_struct); 00813 kmo_delete_skySkyStruct(sky_sky_struct); 00814 cpl_free(suffix); 00815 cpl_free(bounds); 00816 kmo_free_unused_ifus(unused_ifus_after); 00817 cpl_frameset_delete(frameset_std) ; 00818 return 0 ; 00819 */ 00820 00821 /* Get the first frame containing object */ 00822 obj_frame = obj_sky_struct->table[0].objFrame; 00823 main_header_tel = kmclipm_propertylist_load( 00824 cpl_frame_get_filename(obj_frame), 0); 00825 exptime = cpl_propertylist_get_double(main_header_tel, EXPTIME); 00826 00827 /* Get the star temperature */ 00828 star_temp = kmos_get_temperature(frameset, spec_type, &star_type) ; 00829 00830 /* Loop on detectors */ 00831 for (i = 1; i <= KMOS_NR_DETECTORS ; i++) { 00832 print_cal_angle_msg_once = FALSE; 00833 print_xcal_angle_msg_once = FALSE; 00834 if (i==1) { 00835 print_cal_angle_msg_once = TRUE; 00836 print_xcal_angle_msg_once = TRUE; 00837 } 00838 00839 /* Get filter for this detector ESO INS FILTi ID */ 00840 keyword = cpl_sprintf("%s%d%s", IFU_FILTID_PREFIX, i, 00841 IFU_FILTID_POSTFIX); 00842 filter_id = cpl_propertylist_get_string(main_header_tel, keyword); 00843 cpl_free(keyword); 00844 00845 band_table = kmo_dfs_load_table(frameset, WAVE_BAND, 1, 0); 00846 kmclipm_setup_grid_band_lcal(&gd, filter_id, band_table); 00847 cpl_table_delete(band_table); 00848 00849 /* Load extension header */ 00850 sub_header_orig = kmclipm_propertylist_load( 00851 cpl_frame_get_filename(obj_frame), i); 00852 00853 /* Loop on IFUs */ 00854 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 00855 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 00856 00857 /* Check if IFU valid */ 00858 00859 /* Check if there is a sky frame available for this IFU */ 00860 kmo_collapse_objSkyStruct(obj_sky_struct, ifu_nr, &obj_frame, 00861 &sky_frame); 00862 punused_ifus = cpl_array_get_data_int_const(unused_ifus_after[i-1]); 00863 /* Search for keyword ESO OCS ARMi NOTUSED */ 00864 /* If CPL_ERROR_DATA_NOT_FOUND, process standard star */ 00865 keyword = cpl_sprintf("%s%d%s", IFU_VALID_PREFIX, ifu_nr, 00866 IFU_VALID_POSTFIX); 00867 cpl_propertylist_get_string(main_header_tel, keyword); 00868 cpl_free(keyword); 00869 00870 if ((cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) && 00871 (bounds[2*(ifu_nr-1)] != -1) && 00872 (bounds[2*(ifu_nr-1)+1] != -1) && 00873 (sky_frame != NULL) && (punused_ifus[j] == 0)) { 00874 cpl_error_reset(); 00875 /* IFU is valid */ 00876 00877 /* Process IFU */ 00878 if (kmos_std_star_compute_ifu(sub_header_orig, obj_frame, 00879 sky_frame, flat_frame, xcal_frame, ycal_frame, 00880 lcal_frame, illum_frame, atmos_frame, solar_frame, 00881 ifu_nr, main_header_tel, gd, bounds[2*(ifu_nr-1)], 00882 bounds[2*(ifu_nr-1)+1], fmethod, flux, 00883 xcal_interpolation, mask_method, cmethod, cpos_rej, 00884 cneg_rej, citer, cmax, cmin, cen_x, cen_y, radius, 00885 filter_id, star_type, no_noise, is_stdstarscipatt, 00886 sky_sky_struct[ifu_nr-1], star_temp, 00887 &spec_qc, 00888 &stored_sub_tel_data_headers[ifu_nr-1], 00889 &stored_sub_psf_headers[ifu_nr-1], 00890 &stored_sub_cube_data_headers[ifu_nr-1], 00891 &stored_data_cube[ifu_nr-1], 00892 &stored_noise_cube[ifu_nr-1], 00893 &stored_psf_data[ifu_nr-1], 00894 &stored_mask[ifu_nr-1], 00895 &stored_starspec_data[ifu_nr-1], 00896 &stored_starspec_noise[ifu_nr-1], 00897 &stored_noisespec[ifu_nr-1], 00898 &stored_telluric_data[ifu_nr-1], 00899 &stored_telluric_noise[ifu_nr-1]) == -1) { 00900 stored_telluric_data[ifu_nr-1] = NULL ; 00901 stored_telluric_noise[ifu_nr-1] = NULL ; 00902 stored_starspec_data[ifu_nr-1] = NULL ; 00903 stored_starspec_noise[ifu_nr-1] = NULL ; 00904 stored_psf_data[ifu_nr-1] = NULL ; 00905 stored_mask[ifu_nr-1] = NULL ; 00906 stored_data_cube[ifu_nr-1] = NULL ; 00907 stored_noise_cube[ifu_nr-1] = NULL ; 00908 stored_noisespec[ifu_nr-1] = NULL ; 00909 00910 stored_sub_tel_data_headers[ifu_nr-1] = 00911 cpl_propertylist_duplicate(sub_header_orig); 00912 stored_sub_tel_noise_headers[ifu_nr-1] = 00913 cpl_propertylist_duplicate(sub_header_orig); 00914 stored_sub_psf_headers[ifu_nr-1] = 00915 cpl_propertylist_duplicate(sub_header_orig); 00916 stored_sub_cube_data_headers[ifu_nr-1] = 00917 cpl_propertylist_duplicate(sub_header_orig); 00918 stored_sub_cube_noise_headers[ifu_nr-1] = 00919 cpl_propertylist_duplicate(sub_header_orig); 00920 } else { 00921 /* If magnitude is provided, get zeropoint and throughput */ 00922 if (compute_qcs) { 00923 /* QC THROUGHPUT */ 00924 gain = cpl_propertylist_get_double( 00925 stored_sub_tel_data_headers[ifu_nr-1], GAIN); 00926 crpix1=cpl_propertylist_get_double( 00927 stored_sub_tel_data_headers[ifu_nr-1], CRPIX1); 00928 crval1=cpl_propertylist_get_double( 00929 stored_sub_tel_data_headers[ifu_nr-1], CRVAL1); 00930 cdelt1=cpl_propertylist_get_double( 00931 stored_sub_tel_data_headers[ifu_nr-1], CDELT1); 00932 kmo_calc_counts(spec_qc, filter_id, crpix1, crval1, 00933 cdelt1, &counts1, &counts2); 00934 counts1 /= exptime; 00935 counts2 /= exptime; 00936 stored_qc_throughput[ifu_nr-1] = 00937 kmo_calc_throughput(magnitude1, magnitude2, 00938 counts1, counts2, gain, filter_id); 00939 if (kmclipm_is_nan_or_inf( 00940 stored_qc_throughput[ifu_nr-1])) 00941 stored_qc_throughput[ifu_nr-1] = -1; 00942 kmclipm_update_property_double( 00943 stored_sub_tel_data_headers[ifu_nr-1], 00944 QC_THROUGHPUT, 00945 stored_qc_throughput[ifu_nr-1], 00946 "[] IFU throughput"); 00947 00948 /* QC ZEROPOINT */ 00949 zeropoint = kmo_calc_zeropoint(magnitude1, magnitude2, 00950 counts1, counts2, cdelt1, filter_id); 00951 if (kmclipm_is_nan_or_inf(zeropoint)) zeropoint = -1; 00952 kmclipm_update_property_double( 00953 stored_sub_tel_data_headers[ifu_nr-1], 00954 QC_ZEROPOINT, zeropoint, "[mag] IFU zeropoint"); 00955 } 00956 /* Update number of standard stars */ 00957 nr_std_stars++; 00958 cpl_vector_delete(spec_qc) ; 00959 } 00960 } else { 00961 cpl_error_reset(); 00962 /* IFU is invalid */ 00963 stored_telluric_data[ifu_nr-1] = NULL ; 00964 stored_telluric_noise[ifu_nr-1] = NULL ; 00965 stored_starspec_data[ifu_nr-1] = NULL ; 00966 stored_starspec_noise[ifu_nr-1] = NULL ; 00967 stored_psf_data[ifu_nr-1] = NULL ; 00968 stored_mask[ifu_nr-1] = NULL ; 00969 stored_data_cube[ifu_nr-1] = NULL ; 00970 stored_noise_cube[ifu_nr-1] = NULL ; 00971 stored_noisespec[ifu_nr-1] = NULL ; 00972 00973 stored_sub_tel_data_headers[ifu_nr-1] = 00974 cpl_propertylist_duplicate(sub_header_orig); 00975 stored_sub_tel_noise_headers[ifu_nr-1] = 00976 cpl_propertylist_duplicate(sub_header_orig); 00977 stored_sub_psf_headers[ifu_nr-1] = 00978 cpl_propertylist_duplicate(sub_header_orig); 00979 stored_sub_cube_data_headers[ifu_nr-1] = 00980 cpl_propertylist_duplicate(sub_header_orig); 00981 stored_sub_cube_noise_headers[ifu_nr-1] = 00982 cpl_propertylist_duplicate(sub_header_orig); 00983 } 00984 00985 /* EXTNAME for DATA */ 00986 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_DATA); 00987 kmclipm_update_property_string( 00988 stored_sub_tel_data_headers[ifu_nr-1], EXTNAME, extname, 00989 "FITS extension name"); 00990 kmclipm_update_property_string( 00991 stored_sub_psf_headers[ifu_nr-1], EXTNAME, extname, 00992 "FITS extension name"); 00993 kmclipm_update_property_string( 00994 stored_sub_cube_data_headers[ifu_nr-1], EXTNAME, 00995 extname, "FITS extension name"); 00996 cpl_free(extname); 00997 00998 /* EXTNAME for NOISE */ 00999 if (stored_sub_tel_noise_headers[ifu_nr-1] == NULL) { 01000 stored_sub_tel_noise_headers[ifu_nr-1] = 01001 cpl_propertylist_duplicate( 01002 stored_sub_tel_data_headers[ifu_nr-1]); 01003 } 01004 extname = kmo_extname_creator(ifu_frame, ifu_nr, EXT_NOISE); 01005 kmclipm_update_property_string( 01006 stored_sub_tel_noise_headers[ifu_nr-1], EXTNAME, 01007 extname, "FITS extension name"); 01008 if (stored_sub_cube_noise_headers[ifu_nr-1] == NULL) 01009 stored_sub_cube_noise_headers[ifu_nr-1] = 01010 cpl_propertylist_duplicate( 01011 stored_sub_cube_data_headers[ifu_nr-1]); 01012 kmclipm_update_property_string( 01013 stored_sub_cube_noise_headers[ifu_nr-1], EXTNAME, 01014 extname, "FITS extension name"); 01015 cpl_free(extname); 01016 } 01017 cpl_propertylist_delete(sub_header_orig); 01018 } 01019 cpl_free(bounds); 01020 01021 /* Write QC parameter: nr of std stars */ 01022 kmclipm_update_property_int(main_header_tel, QC_NR_STD_STARS, 01023 nr_std_stars, "[] Nr. of std stars"); 01024 01025 /* Update which IFUs are not used */ 01026 kmo_print_unused_ifus(unused_ifus_after, TRUE); 01027 kmo_set_unused_ifus(unused_ifus_after, main_header_tel,"kmos_std_star"); 01028 kmo_free_unused_ifus(unused_ifus_after); 01029 01030 main_header_psf = cpl_propertylist_duplicate(main_header_tel); 01031 01032 if (compute_qcs) { 01033 /* QC THROUGHPUT MEAN and QC THROUGHPUT SDV */ 01034 kmo_calc_mean_throughput(stored_qc_throughput, nifus, &throughput_mean, 01035 &throughput_sdv); 01036 kmclipm_update_property_double(main_header_tel, QC_THROUGHPUT_MEAN, 01037 throughput_mean, "[] mean throughput for all detectors"); 01038 kmclipm_update_property_double(main_header_tel, QC_THROUGHPUT_SDV, 01039 throughput_sdv, "[] stdev throughput for all detectors"); 01040 } 01041 cpl_free(stored_qc_throughput); 01042 01043 /* Save output data */ 01044 if (!suppress_extension) fn_suffix = cpl_sprintf("%s", suffix); 01045 else fn_suffix = cpl_sprintf("%s", ""); 01046 cpl_free(suffix); 01047 01048 /* Save primary extension */ 01049 kmo_dfs_save_main_header(frameset, filename_telluric, fn_suffix, 01050 obj_frame, main_header_tel, parlist, cpl_func); 01051 kmo_dfs_save_main_header(frameset, filename_starspec, fn_suffix, 01052 obj_frame, main_header_tel, parlist, cpl_func); 01053 kmo_dfs_save_main_header(frameset, filename_mask, fn_suffix, 01054 obj_frame, main_header_psf, parlist, cpl_func); 01055 kmo_dfs_save_main_header(frameset, filename_psf, fn_suffix, 01056 obj_frame, main_header_psf, parlist, cpl_func) ; 01057 if (!no_noise && is_stdstarscipatt) { 01058 kmo_dfs_save_main_header(frameset, filename_noise, fn_suffix, 01059 obj_frame, main_header_tel, parlist, cpl_func); 01060 } 01061 cpl_propertylist_delete(main_header_tel); 01062 01063 if (save_cubes) { 01064 kmo_dfs_save_main_header(frameset, filename_cubes, fn_suffix, 01065 obj_frame, main_header_psf, parlist, cpl_func); 01066 } 01067 cpl_propertylist_delete(main_header_psf); 01068 01069 /* Save stored frames */ 01070 for (i = 1; i <= KMOS_NR_DETECTORS ; i++) { 01071 for (j = 0; j < KMOS_IFUS_PER_DETECTOR; j++) { 01072 ifu_nr = (i-1)*KMOS_IFUS_PER_DETECTOR + j + 1; 01073 01074 /* Save telluric-vector */ 01075 if (stored_telluric_data[ifu_nr-1] != NULL) { 01076 ddd = kmclipm_vector_create(cpl_vector_duplicate( 01077 stored_telluric_data[ifu_nr-1])); 01078 kmo_dfs_save_vector(ddd, filename_telluric, fn_suffix, 01079 stored_sub_tel_data_headers[ifu_nr-1], 0./0.); 01080 kmclipm_vector_delete(ddd) ; 01081 } else { 01082 kmo_dfs_save_vector(NULL, filename_telluric, fn_suffix, 01083 stored_sub_tel_data_headers[ifu_nr-1], 0./0.); 01084 } 01085 if (stored_telluric_noise[ifu_nr-1] != NULL) { 01086 ddd = kmclipm_vector_create(cpl_vector_duplicate( 01087 stored_telluric_noise[ifu_nr-1])); 01088 kmo_dfs_save_vector(ddd, filename_telluric, fn_suffix, 01089 stored_sub_tel_noise_headers[ifu_nr-1], 0./0.); 01090 kmclipm_vector_delete(ddd) ; 01091 } else { 01092 kmo_dfs_save_vector(NULL, filename_telluric, fn_suffix, 01093 stored_sub_tel_noise_headers[ifu_nr-1], 0./0.); 01094 } 01095 01096 /* Save star_spec-vector */ 01097 if (stored_starspec_data[ifu_nr-1] != NULL) { 01098 ddd = kmclipm_vector_create(cpl_vector_duplicate( 01099 stored_starspec_data[ifu_nr-1])); 01100 kmo_dfs_save_vector(ddd, filename_starspec, fn_suffix, 01101 stored_sub_tel_data_headers[ifu_nr-1], 0./0.); 01102 kmclipm_vector_delete(ddd); 01103 } else { 01104 kmo_dfs_save_vector(NULL, filename_starspec, fn_suffix, 01105 stored_sub_tel_data_headers[ifu_nr-1], 0./0.); 01106 } 01107 if (stored_starspec_noise[ifu_nr-1] != NULL) { 01108 ddd = kmclipm_vector_create(cpl_vector_duplicate( 01109 stored_starspec_noise[ifu_nr-1])); 01110 kmo_dfs_save_vector(ddd, filename_starspec, fn_suffix, 01111 stored_sub_tel_noise_headers[ifu_nr-1], 0./0.); 01112 kmclipm_vector_delete(ddd); 01113 } else { 01114 kmo_dfs_save_vector(NULL, filename_starspec, fn_suffix, 01115 stored_sub_tel_noise_headers[ifu_nr-1], 0./0.); 01116 } 01117 01118 /* Save psf-image */ 01119 kmo_dfs_save_image(stored_psf_data[ifu_nr-1], filename_psf, 01120 fn_suffix, stored_sub_psf_headers[ifu_nr-1], 0./0.); 01121 01122 /* Save mask-image */ 01123 kmo_dfs_save_image(stored_mask[ifu_nr-1], filename_mask, 01124 fn_suffix, stored_sub_psf_headers[ifu_nr-1], 0./0.); 01125 01126 /* Save noise_spec-vector */ 01127 if (!no_noise && is_stdstarscipatt && stored_noisespec != NULL && 01128 stored_noisespec[ifu_nr-1] != NULL && 01129 stored_starspec_data[ifu_nr-1] != NULL) { 01130 /* QC SNR */ 01131 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 01132 filter_id, stored_starspec_data[ifu_nr-1], NULL, 01133 &tmp_data, NULL); 01134 kmo_calc_band_mean(stored_sub_tel_data_headers[ifu_nr-1], 01135 filter_id, stored_noisespec[ifu_nr-1], NULL, 01136 &tmp_noise, NULL); 01137 kmclipm_update_property_double( 01138 stored_sub_tel_data_headers[ifu_nr-1], QC_SNR, 01139 tmp_data/tmp_noise, "[] SNR"); 01140 } 01141 01142 if (!no_noise && is_stdstarscipatt) { 01143 if ((stored_noisespec != NULL) && 01144 stored_noisespec[ifu_nr-1] != NULL) { 01145 ddd = kmclipm_vector_create(cpl_vector_duplicate( 01146 stored_noisespec[ifu_nr-1])); 01147 kmo_dfs_save_vector(ddd, filename_noise, fn_suffix, 01148 stored_sub_tel_data_headers[ifu_nr-1], 0./0.); 01149 kmclipm_vector_delete(ddd); 01150 } else { 01151 kmo_dfs_save_vector(NULL, filename_noise, fn_suffix, 01152 stored_sub_tel_data_headers[ifu_nr-1], 0./0.); 01153 } 01154 } 01155 01156 /* Save reonstructed cubes */ 01157 if (save_cubes) { 01158 kmo_dfs_save_cube(stored_data_cube[ifu_nr-1], 01159 filename_cubes, fn_suffix, 01160 stored_sub_cube_data_headers[ifu_nr-1], 0./0.); 01161 kmo_dfs_save_cube(stored_noise_cube[ifu_nr-1], 01162 filename_cubes, fn_suffix, 01163 stored_sub_cube_noise_headers[ifu_nr-1], 0./0.); 01164 } 01165 } 01166 } 01167 cpl_free(fn_suffix); 01168 01169 /* DE-Allocate Warning --- Frames (e.g obj_frame) point to */ 01170 /* obj_..._struct which point to frameset_ѕtd */ 01171 kmo_delete_objSkyStruct(obj_sky_struct); 01172 kmo_delete_skySkyStruct(sky_sky_struct); 01173 cpl_frameset_delete(frameset_std); 01174 01175 for (i = 0; i < nifus ; i++) { 01176 cpl_vector_delete(stored_telluric_data[i]); 01177 cpl_vector_delete(stored_telluric_noise[i]); 01178 cpl_vector_delete(stored_starspec_data[i]); 01179 cpl_vector_delete(stored_starspec_noise[i]); 01180 cpl_image_delete(stored_psf_data[i]); 01181 cpl_propertylist_delete(stored_sub_tel_data_headers[i]); 01182 cpl_propertylist_delete(stored_sub_tel_noise_headers[i]); 01183 cpl_vector_delete(stored_noisespec[i]); 01184 cpl_propertylist_delete(stored_sub_cube_data_headers[i]); 01185 cpl_propertylist_delete(stored_sub_cube_noise_headers[i]); 01186 cpl_propertylist_delete(stored_sub_psf_headers[i]); 01187 cpl_image_delete(stored_mask[i]); 01188 cpl_imagelist_delete(stored_data_cube[i]); 01189 cpl_imagelist_delete(stored_noise_cube[i]); 01190 } 01191 cpl_free(stored_telluric_data); 01192 cpl_free(stored_telluric_noise); 01193 cpl_free(stored_starspec_data); 01194 cpl_free(stored_starspec_noise); 01195 cpl_free(stored_psf_data); 01196 cpl_free(stored_sub_tel_data_headers); 01197 cpl_free(stored_sub_tel_noise_headers); 01198 cpl_free(stored_noisespec); 01199 cpl_free(stored_sub_cube_data_headers); 01200 cpl_free(stored_sub_cube_noise_headers); 01201 cpl_free(stored_sub_psf_headers); 01202 cpl_free(stored_mask); 01203 cpl_free(stored_data_cube); 01204 cpl_free(stored_noise_cube); 01205 01206 return 0; 01207 } 01208 01211 /*----------------------------------------------------------------------------*/ 01216 /*----------------------------------------------------------------------------*/ 01217 static int kmos_std_star_compute_ifu( 01218 cpl_propertylist * sub_header_orig, 01219 cpl_frame * obj_frame, 01220 cpl_frame * sky_frame, 01221 cpl_frame * flat_frame, 01222 cpl_frame * xcal_frame, 01223 cpl_frame * ycal_frame, 01224 cpl_frame * lcal_frame, 01225 cpl_frame * illum_frame, 01226 cpl_frame * atmos_frame, 01227 cpl_frame * solar_frame, 01228 int ifu_nr, 01229 cpl_propertylist * main_header_tel, 01230 gridDefinition gd, 01231 int low_bound, 01232 int high_bound, 01233 const char * fmethod, 01234 int flux, 01235 int xcal_interpolation, 01236 const char * mask_method, 01237 const char * cmethod, 01238 double cpos_rej, 01239 double cneg_rej, 01240 int citer, 01241 int cmax, 01242 int cmin, 01243 double cen_x, 01244 double cen_y, 01245 double radius, 01246 const char * filter_id, 01247 char star_type, 01248 int no_noise, 01249 int is_stdstarscipatt, 01250 skySkyStruct sky_sky_struct, 01251 double star_temp, 01252 cpl_vector ** spec_qc, 01253 cpl_propertylist ** out_sub_tel_data_header, 01254 cpl_propertylist ** out_sub_psf_header, 01255 cpl_propertylist ** out_sub_cube_data_header, 01256 cpl_imagelist ** out_data_cube, 01257 cpl_imagelist ** out_noise_cube, 01258 cpl_image ** out_psf_data, 01259 cpl_image ** out_mask, 01260 cpl_vector ** out_starspec_data, 01261 cpl_vector ** out_starspec_noise, 01262 cpl_vector ** out_noisespec, 01263 cpl_vector ** out_telluric_data, 01264 cpl_vector ** out_telluric_noise) 01265 { 01266 char * keyword ; 01267 cpl_propertylist * tmp_head ; 01268 cpl_image * illum_corr ; 01269 cpl_propertylist * pl_psf ; 01270 double std_trace, factor_fwhm, spat_res, x_lo, y_lo, x_hi, 01271 y_hi, loc_cen_x, loc_cen_y, r ; 01272 cpl_size auto_cen_x, auto_cen_y, nx, ny ; 01273 cpl_vector * tmp_vec ; 01274 cpl_vector * tmp_spec_data ; 01275 cpl_vector * tmp_spec_noise ; 01276 cpl_vector * shot_noise ; 01277 cpl_vector * solar_spec ; 01278 double * ppp ; 01279 double gain, mean_data, mean_data2, flux_scale_factor ; 01280 double ** pvec_array ; 01281 double * ptmp_vec ; 01282 double * pstored_noisespec ; 01283 cpl_vector ** vec_array ; 01284 const double * ptmp_spec_data ; 01285 double * ptmp_spec_noise ; 01286 float * pmask ; 01287 cpl_imagelist * tmp_cube ; 01288 cpl_vector * lambda_x ; 01289 cpl_vector * atmos_model ; 01290 int i, j, k, nr_sky_pairs, npix, x, y ; 01291 01292 /* Check inputs */ 01293 01294 /* Initialise */ 01295 std_trace = -1.0 ; 01296 01297 /* Messages */ 01298 if (sky_frame != NO_CORRESPONDING_SKYFRAME) { 01299 cpl_msg_info(cpl_func, "Processing standard star in IFU %d", ifu_nr); 01300 cpl_msg_info(cpl_func, " (obj: %s, sky: %s)", 01301 cpl_frame_get_filename(obj_frame), 01302 cpl_frame_get_filename(sky_frame)); 01303 } else { 01304 sky_frame = NULL; 01305 cpl_msg_warning(cpl_func, 01306 "Processing standard star in IFU %d", ifu_nr); 01307 cpl_msg_warning(cpl_func, 01308 " (obj: %s, no corresponding sky frame)", 01309 cpl_frame_get_filename(obj_frame)); 01310 } 01311 01312 keyword = cpl_sprintf("%s%d", PRO_STD, ifu_nr); 01313 cpl_propertylist_update_int(main_header_tel, keyword, 1); 01314 cpl_free(keyword); 01315 01316 /* Compute WCS and make copies of sub_header */ 01317 tmp_head=cpl_propertylist_duplicate(sub_header_orig); 01318 kmo_calc_wcs_gd(main_header_tel, tmp_head, ifu_nr,gd); 01319 *out_sub_tel_data_header = cpl_propertylist_duplicate(tmp_head); 01320 *out_sub_psf_header = cpl_propertylist_duplicate(tmp_head); 01321 *out_sub_cube_data_header = cpl_propertylist_duplicate(tmp_head); 01322 cpl_propertylist_delete(tmp_head); 01323 01324 /* Adjust telluric-headers: copy key3 to key1 - rm key2 key3*/ 01325 kmos_std_star_adjust_double(*out_sub_tel_data_header, CRVAL1,CRVAL2,CRVAL3); 01326 kmos_std_star_adjust_double(*out_sub_tel_data_header, CRPIX1,CRPIX2,CRPIX3); 01327 kmos_std_star_adjust_double(*out_sub_tel_data_header, CDELT1,CDELT2,CDELT3); 01328 kmos_std_star_adjust_string(*out_sub_tel_data_header, CTYPE1,CTYPE2,CTYPE3); 01329 kmos_std_star_adjust_string(*out_sub_tel_data_header, CUNIT1,CUNIT2,CUNIT3); 01330 01331 /* CDx_x */ 01332 cpl_propertylist_erase(*out_sub_tel_data_header, CD1_1); 01333 cpl_propertylist_erase(*out_sub_tel_data_header, CD1_2); 01334 cpl_propertylist_erase(*out_sub_tel_data_header, CD1_3); 01335 cpl_propertylist_erase(*out_sub_tel_data_header, CD2_1); 01336 cpl_propertylist_erase(*out_sub_tel_data_header, CD2_2); 01337 cpl_propertylist_erase(*out_sub_tel_data_header, CD2_3); 01338 cpl_propertylist_erase(*out_sub_tel_data_header, CD3_1); 01339 cpl_propertylist_erase(*out_sub_tel_data_header, CD3_2); 01340 cpl_propertylist_erase(*out_sub_tel_data_header, CD3_3); 01341 01342 /* Adjust psf-headers: delete CRPIX3 etc. */ 01343 cpl_propertylist_erase(*out_sub_psf_header, CRPIX3); 01344 cpl_propertylist_erase(*out_sub_psf_header, CRPIX3); 01345 cpl_propertylist_erase(*out_sub_psf_header, CDELT3); 01346 cpl_propertylist_erase(*out_sub_psf_header, CRVAL3); 01347 cpl_propertylist_erase(*out_sub_psf_header, CTYPE3); 01348 cpl_propertylist_erase(*out_sub_psf_header, CUNIT3); 01349 cpl_propertylist_erase(*out_sub_psf_header, CD1_3); 01350 cpl_propertylist_erase(*out_sub_psf_header, CD2_3); 01351 cpl_propertylist_erase(*out_sub_psf_header, CD3_1); 01352 cpl_propertylist_erase(*out_sub_psf_header, CD3_2); 01353 cpl_propertylist_erase(*out_sub_psf_header, CD3_3); 01354 01355 /* Reconstruct */ 01356 kmo_reconstruct_sci(ifu_nr, low_bound, high_bound, obj_frame, STD, 01357 sky_frame, STD, flat_frame, xcal_frame, ycal_frame, lcal_frame, 01358 NULL, NULL, &gd, out_data_cube, out_noise_cube, flux, FALSE, 01359 xcal_interpolation, FALSE); 01360 01361 /* Illumination correction */ 01362 /* Illumination noise small versus noise - skipped */ 01363 if (illum_frame != NULL) { 01364 illum_corr = kmo_dfs_load_image_frame(illum_frame, 01365 ifu_nr, FALSE, FALSE, NULL); 01366 cpl_imagelist_divide_image(*out_data_cube, illum_corr); 01367 cpl_image_delete(illum_corr); 01368 } 01369 01370 /* QC_STD_TRACE (distance of the PSF to the centre) */ 01371 kmo_calculate_std_trace(*out_data_cube, fmethod, &std_trace); 01372 kmclipm_update_property_double(*out_sub_psf_header, QC_STD_TRACE, std_trace, 01373 "[pix] distance PSF - IFU center"); 01374 01375 /* Collapse cube and get PSF image */ 01376 kmclipm_make_image(*out_data_cube, NULL, out_psf_data, NULL, NULL, 01377 cmethod, cpos_rej, cneg_rej, citer, cmax, cmin); 01378 01379 /* Fit a 2D profile to get a mask and fwhm in x and y */ 01380 tmp_vec = kmo_fit_profile_2D(*out_psf_data, NULL, fmethod,out_mask,&pl_psf); 01381 01382 if (!strcmp(mask_method, "integrated")) { 01383 if (cen_x < 1.0 || cen_y < 1.0) { 01384 cpl_image_get_maxpos(*out_psf_data,&auto_cen_x,&auto_cen_y); 01385 loc_cen_x = (double)auto_cen_x - 1.0 ; 01386 loc_cen_y = (double)auto_cen_y - 1.0 ; 01387 } else { 01388 loc_cen_x = cen_x - 1.0 ; 01389 loc_cen_y = cen_y - 1.0 ; 01390 } 01391 kmo_image_fill(*out_mask,0.0); 01392 pmask = cpl_image_get_data_float(*out_mask); 01393 nx = cpl_image_get_size_x(*out_mask); 01394 ny = cpl_image_get_size_y(*out_mask); 01395 01396 /* draw circle */ 01397 x_lo = floor(loc_cen_x - radius); 01398 if (x_lo < 0) x_lo = 0; 01399 y_lo = floor(loc_cen_y - radius); 01400 if (y_lo < 0) y_lo = 0; 01401 x_hi = ceil(loc_cen_x + radius); 01402 if (x_hi > nx) x_hi = nx; 01403 y_hi = ceil(loc_cen_y + radius); 01404 if (y_hi > ny) y_hi = ny; 01405 for (x = x_lo; x < x_hi; x++) { 01406 for (y = y_lo; y < y_hi; y++) { 01407 r = sqrt(pow(x - loc_cen_x,2) + pow(y - loc_cen_y,2)); 01408 if (r <= radius) pmask[x + y * nx] = 1.0; 01409 } 01410 } 01411 } else { 01412 /* Normalise mask to 1 and clip values below 0.5 */ 01413 cpl_image_divide_scalar(*out_mask, cpl_image_get_max(*out_mask)); 01414 for (i = 1; i <= cpl_image_get_size_x(*out_mask); i++) { 01415 for (j = 1; j <= cpl_image_get_size_y(*out_mask); j++) { 01416 if (cpl_image_get(*out_mask, i, j, &k) < 0.5) 01417 cpl_image_set(*out_mask, i, j, 0.); 01418 else 01419 cpl_image_set(*out_mask, i, j, 1.); 01420 } 01421 } 01422 } 01423 01424 /* Update subheader with fit parameters */ 01425 cpl_propertylist_append(*out_sub_tel_data_header, pl_psf); 01426 cpl_propertylist_delete(pl_psf); 01427 01428 /* QC_SPAT_RES (RMS of fwhm_x and fwhm_y) */ 01429 factor_fwhm = 2*sqrt(2*log(2)); 01430 spat_res = pow(cpl_vector_get(tmp_vec, 4) * factor_fwhm, 2); 01431 spat_res += pow(cpl_vector_get(tmp_vec, 5)* factor_fwhm, 2); 01432 spat_res /= 2; 01433 kmclipm_update_property_double(*out_sub_psf_header, QC_SPAT_RES, 01434 sqrt(spat_res)*KMOS_PIX_RESOLUTION, 01435 "[arcsec] mean fwhm resolution of PSF"); 01436 cpl_vector_delete(tmp_vec); 01437 01438 /* Extract spectrum with mask */ 01439 /* Convert Mean to Sum (* mask area) */ 01440 tmp_spec_data = tmp_spec_noise = NULL ; 01441 kmo_priv_extract_spec(*out_data_cube, *out_noise_cube, *out_mask, 01442 &tmp_spec_data, &tmp_spec_noise); 01443 cpl_vector_multiply_scalar(tmp_spec_data, cpl_image_get_flux(*out_mask)); 01444 if (tmp_spec_noise != NULL) { 01445 cpl_vector_multiply_scalar(tmp_spec_noise, 01446 cpl_image_get_flux(*out_mask)); 01447 } 01448 01449 /* Extract spectrum of whole area for QCs */ 01450 /* Convert mean to sum (* 196, IFU area) */ 01451 tmp_vec = *spec_qc = NULL ; 01452 kmo_priv_extract_spec(*out_data_cube, *out_noise_cube, NULL, spec_qc, 01453 &tmp_vec); 01454 npix = cpl_image_get_size_x(cpl_imagelist_get(*out_data_cube, 0)) * 01455 cpl_image_get_size_y(cpl_imagelist_get(*out_data_cube, 0)) ; 01456 cpl_vector_multiply_scalar(*spec_qc, npix); 01457 if (tmp_vec != NULL) cpl_vector_multiply_scalar(tmp_vec, npix); 01458 01459 /* Shot noise */ 01460 gain = cpl_propertylist_get_double(*out_sub_tel_data_header, GAIN); 01461 01462 /* Shot_noise = sqrt(tmp_spec_data*gain)/gain */ 01463 /* set negative values and NaN's to zero before sqrt */ 01464 shot_noise = cpl_vector_duplicate(tmp_spec_data); 01465 cpl_vector_multiply_scalar(shot_noise, gain); 01466 ppp = cpl_vector_get_data(shot_noise); 01467 for (i = 0; i < cpl_vector_get_size(shot_noise); i++) { 01468 if ((ppp[i] < 0.0) || kmclipm_is_nan_or_inf(ppp[i])) 01469 ppp[i] = 0.0; 01470 } 01471 cpl_vector_sqrt(shot_noise); 01472 cpl_vector_divide_scalar(shot_noise, gain); 01473 01474 /* Scale extracted spectrum to match the one */ 01475 /* calculated over the whole area (band specific) */ 01476 kmo_calc_band_mean(*out_sub_tel_data_header, filter_id, tmp_spec_data, 01477 tmp_spec_noise, &mean_data, NULL); 01478 kmo_calc_band_mean(*out_sub_tel_data_header, filter_id, *spec_qc, tmp_vec, 01479 &mean_data2, NULL); 01480 cpl_vector_delete(tmp_vec) ; 01481 01482 flux_scale_factor = mean_data2/mean_data; 01483 01484 cpl_vector_multiply_scalar(shot_noise, flux_scale_factor); 01485 cpl_vector_multiply_scalar(tmp_spec_data,flux_scale_factor); 01486 if ((tmp_spec_noise != NULL) && (fabs(mean_data) > 1e-8)) 01487 cpl_vector_multiply_scalar(tmp_spec_noise, flux_scale_factor); 01488 01489 /* Store to save to disk later on */ 01490 *out_starspec_data = cpl_vector_duplicate(tmp_spec_data); 01491 if (tmp_spec_noise != NULL) 01492 *out_starspec_noise = cpl_vector_duplicate(tmp_spec_noise); 01493 else 01494 *out_starspec_noise = NULL ; 01495 01496 /* Noise spectra */ 01497 if (!no_noise && is_stdstarscipatt) { 01498 nr_sky_pairs = sky_sky_struct.nrSkyPairs; 01499 if (nr_sky_pairs > 2) { 01500 cpl_msg_info(__func__, "Get noise spec on sky for IFU %d", ifu_nr); 01501 vec_array = cpl_calloc(nr_sky_pairs,sizeof(cpl_vector*)); 01502 pvec_array = cpl_calloc(nr_sky_pairs, sizeof(double*)); 01503 /* Reconstruct all sky-Pairs, extract spectra */ 01504 for (i = 0; i < nr_sky_pairs; i++) { 01505 // reconstruct (sky1-sky2)/flatfield 01506 kmo_reconstruct_sci(ifu_nr, low_bound, high_bound, 01507 sky_sky_struct.skyPairs[i].skyFrame1, STD, 01508 sky_sky_struct.skyPairs[i].skyFrame2, STD, flat_frame, 01509 xcal_frame, ycal_frame, lcal_frame, NULL, NULL, &gd, 01510 &tmp_cube, NULL, FALSE, FALSE, 01511 xcal_interpolation, FALSE); 01512 01513 /* Extract spectrum using masked */ 01514 /* convert mean to sum (* mask aperture) */ 01515 kmo_priv_extract_spec(tmp_cube, NULL, *out_mask, 01516 &(vec_array[i]), NULL); 01517 cpl_vector_multiply_scalar(vec_array[i], 01518 cpl_image_get_flux(*out_mask)); 01519 01520 /* Scale extracted spectrum to match the one */ 01521 /* calculated over the whole area (band spec) */ 01522 cpl_vector_multiply_scalar(vec_array[i], flux_scale_factor); 01523 pvec_array[i] = cpl_vector_get_data(vec_array[i]); 01524 cpl_imagelist_delete(tmp_cube); 01525 } 01526 01527 /* stddev on each wavelength of all extrac spec */ 01528 *out_noisespec = cpl_vector_new(gd.l.dim); 01529 pstored_noisespec = cpl_vector_get_data(*out_noisespec); 01530 tmp_vec = cpl_vector_new(nr_sky_pairs); 01531 ptmp_vec = cpl_vector_get_data(tmp_vec); 01532 for (i = 0; i < gd.l.dim; i++) { 01533 for (j = 0; j < nr_sky_pairs; j++) 01534 ptmp_vec[j] = pvec_array[j][i]; 01535 pstored_noisespec[i] = cpl_vector_get_stdev(tmp_vec); 01536 } 01537 for (i = 0; i < nr_sky_pairs; i++) cpl_vector_delete(vec_array[i]); 01538 cpl_free(vec_array); 01539 cpl_free(pvec_array); 01540 cpl_vector_delete(tmp_vec); 01541 01542 /* total noise = sqrt (shot_noise^2+sky_noise^2) */ 01543 // and set negative values and NaN's to zero 01544 cpl_vector_power(*out_noisespec, 2.); 01545 cpl_vector_power(shot_noise, 2.); 01546 cpl_vector_add(*out_noisespec, shot_noise); 01547 ppp = cpl_vector_get_data(*out_noisespec); 01548 for (i = 0; i < cpl_vector_get_size(*out_noisespec); i++) { 01549 if ((ppp[i] < 0.0) || kmclipm_is_nan_or_inf(ppp[i])) ppp[i]=0.0; 01550 } 01551 cpl_vector_sqrt(*out_noisespec); 01552 cpl_vector_delete(shot_noise); 01553 } else { 01554 cpl_msg_warning(__func__, "Omit noise-spectra (<2 sky pairs)"); 01555 *out_noisespec = shot_noise; 01556 } 01557 } else { 01558 *out_noisespec = shot_noise; 01559 } 01560 01561 /* Spectrum correction */ 01562 /* Abscissa of output spectrum */ 01563 lambda_x = kmo_create_lambda_vec(gd.l.dim, 1, gd.l.start, gd.l.delta); 01564 01565 if (star_type=='O' || star_type=='B' || star_type=='A' || star_type=='F') { 01566 /* OBAF star */ 01567 01568 /* Remove lines if ATMOS_MODEL is provided */ 01569 if (atmos_frame != NULL) { 01570 /* Interpolate ATMOS_MODEL to same scale as data */ 01571 atmos_model = kmo_interpolate_vector_wcs(atmos_frame, lambda_x); 01572 01573 /* Remove band-specific lines */ 01574 if (!strcmp(filter_id, "H")) 01575 for (i = 0; i < nr_lines_h; i++) 01576 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, 01577 lines_center_h[i], lines_width_h[i]); 01578 else if (!strcmp(filter_id, "HK")) 01579 for (i = 0; i < nr_lines_hk; i++) 01580 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, 01581 lines_center_hk[i], lines_width_hk[i]); 01582 else if (!strcmp(filter_id, "K")) 01583 for (i = 0; i < nr_lines_k; i++) 01584 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, 01585 lines_center_k[i], lines_width_k[i]); 01586 else if (!strcmp(filter_id, "IZ")) 01587 for (i = 0; i < nr_lines_iz; i++) 01588 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, 01589 lines_center_iz[i], lines_width_iz[i]); 01590 else if (strcmp(filter_id, "YJ") == 0) 01591 for (i = 0; i < nr_lines_yj; i++) 01592 kmo_remove_line(tmp_spec_data, lambda_x, atmos_model, 01593 lines_center_yj[i], lines_width_yj[i]); 01594 01595 if (0) kmos_std_star_plot() ; 01596 cpl_vector_delete(atmos_model); 01597 } else { 01598 cpl_msg_warning(__func__, "Missing ATMOS_MODEL"); 01599 } 01600 } else if (star_type == 'G') { 01601 /* G star */ 01602 if (solar_frame != NULL) { 01603 /* Interpolate SOLAR_SPEC to same scale and divide it */ 01604 solar_spec = kmo_interpolate_vector_wcs(solar_frame, 01605 lambda_x); 01606 /* Set to zero if solar_spec isn't overlapping */ 01607 /* wavelength range of star apectrum completely */ 01608 cpl_vector_divide(tmp_spec_data, solar_spec); 01609 cpl_vector_delete(solar_spec); 01610 } else { 01611 cpl_msg_warning(__func__, "Missing SOLAR_SPEC"); 01612 } 01613 } 01614 01615 if (star_temp > 0.0) { 01616 /* Divide blackbody from tmp_spec_data */ 01617 kmo_divide_blackbody(tmp_spec_data, lambda_x, star_temp); 01618 } 01619 cpl_vector_delete(lambda_x); 01620 01621 /* Normalise telluric and its noise */ 01622 /* mean is taken in lambda defined range */ 01623 kmo_calc_band_mean(*out_sub_tel_data_header, filter_id, tmp_spec_data, 01624 tmp_spec_noise, &mean_data, NULL); 01625 cpl_vector_divide_scalar(tmp_spec_data, mean_data); 01626 01627 if (tmp_spec_noise != NULL) { 01628 /* Scale noise with the same factor as data */ 01629 cpl_vector_divide_scalar(tmp_spec_noise, mean_data); 01630 01631 /* Set noise spectrum to zero when solar_spec is short*/ 01632 ptmp_spec_data = cpl_vector_get_data_const(tmp_spec_data); 01633 ptmp_spec_noise = cpl_vector_get_data(tmp_spec_noise); 01634 for (i = 0; i < cpl_vector_get_size(tmp_spec_data);i++) 01635 if (ptmp_spec_data[i]==0.0) ptmp_spec_noise[i]=0.0; 01636 } 01637 01638 /* Store telluric & error spectrum */ 01639 *out_telluric_data = tmp_spec_data; 01640 *out_telluric_noise = tmp_spec_noise; 01641 return 0 ; 01642 } 01643 01644 /*----------------------------------------------------------------------------*/ 01654 /*----------------------------------------------------------------------------*/ 01655 static int kmos_std_star_check_inputs( 01656 cpl_frameset * frameset, 01657 const char * magnitude_txt, 01658 int * is_stdstarscipatt, 01659 int * compute_qcs, 01660 double * magnitude1, 01661 double * magnitude2) 01662 { 01663 int nb_std, nb_illum, nb_xcal, nb_ycal, nb_lcal, 01664 nb_flat, nb_wave ; 01665 cpl_frame * tmp_frame ; 01666 cpl_frameset * frameset_std ; 01667 cpl_propertylist * tmp_head ; 01668 const char * my_mag_txt ; 01669 int nr_split_mag ; 01670 char ** split_mag ; 01671 char * grat_id ; 01672 int same_gratings ; 01673 const char * tmp_str ; 01674 01675 /* Check Entries */ 01676 if (frameset == NULL || is_stdstarscipatt == NULL || compute_qcs == NULL || 01677 magnitude1 == NULL || magnitude2 == NULL) return -1; 01678 01679 /* Count frames */ 01680 nb_std = cpl_frameset_count_tags(frameset, STD) ; 01681 nb_illum = cpl_frameset_count_tags(frameset, ILLUM_CORR) ; 01682 nb_xcal = cpl_frameset_count_tags(frameset, XCAL) ; 01683 nb_ycal = cpl_frameset_count_tags(frameset, YCAL) ; 01684 nb_lcal = cpl_frameset_count_tags(frameset, LCAL) ; 01685 nb_flat = cpl_frameset_count_tags(frameset, MASTER_FLAT) ; 01686 nb_wave = cpl_frameset_count_tags(frameset, WAVE_BAND) ; 01687 01688 /* Check numbers */ 01689 if (nb_std < 1) { 01690 cpl_msg_error(__func__, "At least one STD frame is required") ; 01691 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01692 return 0 ; 01693 } 01694 if (nb_std == 1) 01695 cpl_msg_warning(__func__, "2 STD frames needed for sky subtraction") ; 01696 01697 if (nb_illum < 0 || nb_illum > 1) { 01698 cpl_msg_error(__func__, "0 or 1 ILLUM frame expected") ; 01699 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01700 return 0 ; 01701 } 01702 if (nb_xcal != 1 || nb_ycal != 1 || nb_lcal != 1) { 01703 cpl_msg_error(__func__, "1 X/Y/LCAL required") ; 01704 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01705 return 0 ; 01706 } 01707 if (nb_flat != 1) { 01708 cpl_msg_error(__func__, "1 MASTER_FLAT required") ; 01709 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01710 return 0 ; 01711 } 01712 if (nb_wave != 1) { 01713 cpl_msg_error(__func__, "1 WAVE_BAND required") ; 01714 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01715 return 0 ; 01716 } 01717 01718 /* Extract STD frames with same gratings as the first STD frame */ 01719 frameset_std=kmos_std_star_extract_same_grat_stds(frameset,&same_gratings) ; 01720 01721 /* Get infos from the first STD frame */ 01722 tmp_frame = kmo_dfs_get_frame(frameset_std, STD); 01723 tmp_head=kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame),0); 01724 grat_id = cpl_sprintf("%s", cpl_propertylist_get_string(tmp_head, 01725 "ESO INS GRAT1 ID")); 01726 if (!strcmp(cpl_propertylist_get_string(tmp_head, TPL_ID), 01727 "KMOS_spec_cal_stdstarscipatt")) *is_stdstarscipatt = TRUE ; 01728 else *is_stdstarscipatt = FALSE ; 01729 cpl_propertylist_delete(tmp_head); 01730 cpl_frameset_delete(frameset_std) ; 01731 01732 /* Check if QC are computed */ 01733 if (same_gratings) { 01734 *compute_qcs = TRUE ; 01735 // now check source of magnitude (user or keyword) 01736 tmp_frame = kmo_dfs_get_frame(frameset, STD); 01737 tmp_head=kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame),0); 01738 01739 if (!strcmp(magnitude_txt, "")) { 01740 /* No user defined magnitude */ 01741 if ((cpl_propertylist_has(tmp_head, STDSTAR_MAG)) && 01742 (cpl_propertylist_get_type(tmp_head, STDSTAR_MAG) == 01743 CPL_TYPE_STRING)) { 01744 my_mag_txt = cpl_propertylist_get_string(tmp_head, STDSTAR_MAG); 01745 split_mag = kmo_strsplit(my_mag_txt, ",", &nr_split_mag); 01746 01747 /* Check if band and number of magnitudes matches */ 01748 if (nr_split_mag == 2 && !strcmp(grat_id, "HK")) { 01749 *magnitude1 = atof(split_mag[0]); 01750 *magnitude2 = atof(split_mag[1]); 01751 cpl_msg_info("", "Magnitude in H: %g", *magnitude1); 01752 cpl_msg_info("", "Magnitude in K: %g", *magnitude2); 01753 } else if (nr_split_mag >= 1 && (!strcmp(grat_id, "K") || 01754 !strcmp(grat_id, "H") || !strcmp(grat_id, "IZ") || 01755 !strcmp(grat_id, "YJ"))) { 01756 *magnitude1 = atof(split_mag[0]); 01757 cpl_msg_info("", "Magnitude in %s: %g",grat_id,*magnitude1); 01758 } else { 01759 // keyword STDSTAR_MAG doesn't match filter 01760 *compute_qcs = FALSE; 01761 cpl_msg_warning(cpl_func, "Wrong Mag, QCs not computed") ; 01762 } 01763 kmo_strfreev(split_mag); 01764 } else { 01765 /* STDSTAR_MAG unavailable or wrong type */ 01766 *compute_qcs = FALSE; 01767 cpl_msg_warning(cpl_func, "%s is not set, QCs not computed", 01768 STDSTAR_MAG); 01769 } 01770 } else { 01771 // magnitude is user specified 01772 cpl_msg_info(cpl_func, "Magnitude entered by user, ignore header"); 01773 01774 split_mag = kmo_strsplit(magnitude_txt, ",", &nr_split_mag); 01775 switch (nr_split_mag) { 01776 case 1: 01777 *magnitude1 = atof(split_mag[0]); 01778 cpl_msg_info(cpl_func, "Magnitude in %s: %g", grat_id, 01779 *magnitude1); 01780 break; 01781 case 2: 01782 *magnitude1 = atof(split_mag[0]); 01783 *magnitude2 = atof(split_mag[1]); 01784 cpl_msg_info("", "Magnitude in H: %g", *magnitude1); 01785 cpl_msg_info("", "Magnitude in K: %g", *magnitude2); 01786 break; 01787 default: 01788 kmo_strfreev(split_mag); 01789 cpl_propertylist_delete(tmp_head); 01790 cpl_msg_error(__func__, "Wrong Magnitude Specified") ; 01791 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01792 return 0 ; 01793 } 01794 kmo_strfreev(split_mag); 01795 } 01796 cpl_propertylist_delete(tmp_head); 01797 } else { 01798 *compute_qcs = FALSE ; 01799 } 01800 01801 /* Check SOLAR_SPEC grating */ 01802 tmp_frame = kmo_dfs_get_frame(frameset, SOLAR_SPEC); 01803 if (tmp_frame != NULL) { 01804 tmp_head=kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame),0); 01805 tmp_str = cpl_propertylist_get_string(tmp_head, FILT_ID); 01806 if (strcmp(tmp_str, grat_id)) { 01807 cpl_propertylist_delete(tmp_head) ; 01808 cpl_msg_error(__func__, "Wrong SOLAR_SPEC grating") ; 01809 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01810 return 0 ; 01811 } 01812 cpl_propertylist_delete(tmp_head) ; 01813 } 01814 01815 /* Check ATMOS_MODEL grating */ 01816 tmp_frame = kmo_dfs_get_frame(frameset, ATMOS_MODEL); 01817 if (tmp_frame != NULL) { 01818 tmp_head=kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame),0); 01819 tmp_str = cpl_propertylist_get_string(tmp_head, FILT_ID); 01820 if (strcmp(tmp_str, grat_id)) { 01821 cpl_propertylist_delete(tmp_head) ; 01822 cpl_msg_error(__func__, "Wrong ATMOS_MODEL grating") ; 01823 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 01824 return 0 ; 01825 } 01826 cpl_propertylist_delete(tmp_head) ; 01827 } 01828 cpl_free(grat_id) ; 01829 01830 /* Check if filter_id and grating_id match for all detectors */ 01831 kmo_check_frameset_setup(frameset, XCAL, FALSE, FALSE, TRUE); 01832 kmo_check_frame_setup(frameset, XCAL, YCAL, TRUE, FALSE, TRUE); 01833 kmo_check_frame_setup(frameset, XCAL, LCAL, TRUE, FALSE, TRUE); 01834 kmo_check_frame_setup(frameset, XCAL, MASTER_FLAT, TRUE, FALSE, TRUE); 01835 kmo_check_frame_setup(frameset, XCAL, STD, FALSE, FALSE, TRUE); 01836 if (nb_illum == 1) 01837 kmo_check_frame_setup(frameset, XCAL, ILLUM_CORR, TRUE, FALSE, FALSE); 01838 kmo_check_frame_setup_md5_xycal(frameset); 01839 kmo_check_frame_setup_md5(frameset); 01840 return 1 ; 01841 } 01842 01843 /*----------------------------------------------------------------------------*/ 01849 /*----------------------------------------------------------------------------*/ 01850 static int kmos_std_star_plot(void) 01851 { 01852 01853 /* 01854 cpl_vector *tmp_spec_data_atmo = NULL; 01855 cpl_vector *tmp_spec_data_new = NULL; 01856 tmp_spec_data_orig=cpl_vector_duplicate(tmp_spec_data); 01857 KMO_TRY_EXIT_IF_NULL( 01858 tmp_spec_data_atmo = cpl_vector_duplicate(tmp_spec_data_orig)); 01859 KMO_TRY_EXIT_IF_NULL( 01860 tmp_spec_data_new = cpl_vector_duplicate(tmp_spec_data)); 01861 KMO_TRY_EXIT_IF_ERROR( 01862 cpl_vector_divide(tmp_spec_data_atmo, atmos_model)); 01863 01864 char *sss = cpl_sprintf("atmo_div_%s.fits", filter_id); 01865 if (i == 1) { 01866 cpl_vector_save(tmp_spec_data_atmo, sss, CPL_BPP_IEEE_DOUBLE, stored_sub_tel_data_headers[ifu_nr-1], CPL_IO_CREATE); 01867 } else { 01868 cpl_vector_save(tmp_spec_data_atmo, sss, CPL_BPP_IEEE_DOUBLE, stored_sub_tel_data_headers[ifu_nr-1], CPL_IO_EXTEND); 01869 } 01870 01871 cpl_vector *med_vec = cpl_vector_duplicate(tmp_spec_data_orig); 01872 double median = cpl_vector_get_median(med_vec); 01873 cpl_vector_delete(med_vec); 01874 int ii = 0; 01875 for (ii = 0; ii < cpl_vector_get_size(tmp_spec_data_orig); ii++) { 01876 if (cpl_vector_get(tmp_spec_data_orig, ii) < median/8) 01877 cpl_vector_set(tmp_spec_data_orig, ii, 0); 01878 if (cpl_vector_get(tmp_spec_data_atmo, ii) < median/8) 01879 cpl_vector_set(tmp_spec_data_atmo, ii, 0); 01880 if (cpl_vector_get(tmp_spec_data_new, ii) < median/8) 01881 cpl_vector_set(tmp_spec_data_new, ii, 0); 01882 01883 if (cpl_vector_get(tmp_spec_data_orig, ii) > 3*median) 01884 cpl_vector_set(tmp_spec_data_orig, ii, 3*median); 01885 if (cpl_vector_get(tmp_spec_data_atmo, ii) > 3*median) 01886 cpl_vector_set(tmp_spec_data_atmo, ii, 3*median); 01887 if (cpl_vector_get(tmp_spec_data_new, ii) > 3*median) 01888 cpl_vector_set(tmp_spec_data_new, ii, 3*median); 01889 } 01890 01891 double *pspec_dup = cpl_vector_get_data(tmp_spec_data_atmo); 01892 for (ii = 0; ii < cpl_vector_get_size(tmp_spec_data_atmo); ii++) { 01893 if (kmclipm_is_nan_or_inf(pspec_dup[ii])) { 01894 pspec_dup[ii] = 0.; 01895 } 01896 } 01897 01898 cpl_bivector *plots[3]; 01899 plots[0] = cpl_bivector_wrap_vectors((cpl_vector*)lambda_x, tmp_spec_data_orig); 01900 plots[1] = cpl_bivector_wrap_vectors((cpl_vector*)lambda_x, tmp_spec_data_atmo); 01901 plots[2] = cpl_bivector_wrap_vectors((cpl_vector*)lambda_x, tmp_spec_data_new); 01902 char *options[3] = {"w l t 'original'", 01903 "w l t 'atmo divided'", 01904 "w l t 'lines removed'"}; 01905 sss = cpl_sprintf("set title '%s-band line removal (DET #%d)';", filter_id, i); 01906 cpl_plot_bivectors(sss, 01907 (const char**)options, "", (const cpl_bivector**)plots, 3); 01908 cpl_bivector_unwrap_vectors(plots[0]); 01909 cpl_bivector_unwrap_vectors(plots[1]); 01910 cpl_bivector_unwrap_vectors(plots[2]); 01911 cpl_free(sss); sss = NULL; 01912 cpl_vector_delete(tmp_spec_data_orig); tmp_spec_data_orig = NULL; 01913 cpl_vector_delete(tmp_spec_data_atmo); tmp_spec_data_atmo = NULL; 01914 cpl_vector_delete(tmp_spec_data_new); tmp_spec_data_new = NULL; 01915 01916 */ 01917 return 0 ; 01918 } 01919 01920 /*----------------------------------------------------------------------------*/ 01926 /*----------------------------------------------------------------------------*/ 01927 static int kmos_std_star_adjust_double( 01928 cpl_propertylist * header, 01929 const char * key1, 01930 const char * key2, 01931 const char * key3) 01932 { 01933 if (header==NULL || key1==NULL || key2==NULL || key3==NULL) return -1 ; 01934 cpl_propertylist_update_double(header, key1, 01935 cpl_propertylist_get_double(header, key3)); 01936 cpl_propertylist_erase(header, key2) ; 01937 cpl_propertylist_erase(header, key3) ; 01938 return 0 ; 01939 } 01940 01941 /*----------------------------------------------------------------------------*/ 01947 /*----------------------------------------------------------------------------*/ 01948 static int kmos_std_star_adjust_string( 01949 cpl_propertylist * header, 01950 const char * key1, 01951 const char * key2, 01952 const char * key3) 01953 { 01954 if (header==NULL || key1==NULL || key2==NULL || key3==NULL) return -1 ; 01955 cpl_propertylist_update_string(header, key1, 01956 cpl_propertylist_get_string(header, key3)); 01957 cpl_propertylist_erase(header, key2) ; 01958 cpl_propertylist_erase(header, key3) ; 01959 return 0 ; 01960 } 01961 01962 /*----------------------------------------------------------------------------*/ 01970 /*----------------------------------------------------------------------------*/ 01971 static cpl_frameset * kmos_std_star_extract_same_grat_stds( 01972 cpl_frameset * in, 01973 int * same_gratings) 01974 { 01975 cpl_frameset * frameset_std ; 01976 cpl_frame * tmp_frame ; 01977 cpl_propertylist * tmp_header ; 01978 char * grat_id ; 01979 01980 /* Check entries */ 01981 if (in == NULL || same_gratings== NULL) return NULL ; 01982 01983 /* Create new frameset */ 01984 frameset_std = cpl_frameset_new(); 01985 01986 tmp_frame = kmo_dfs_get_frame(in, STD); 01987 tmp_header = kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame),0); 01988 grat_id = cpl_sprintf("%s", cpl_propertylist_get_string(tmp_header, 01989 "ESO INS GRAT1 ID")); 01990 cpl_propertylist_delete(tmp_header); 01991 cpl_frameset_insert(frameset_std, cpl_frame_duplicate(tmp_frame)); 01992 01993 tmp_frame = kmo_dfs_get_frame(in, NULL); 01994 *same_gratings = TRUE ; 01995 while (tmp_frame != NULL ) { 01996 tmp_header=kmclipm_propertylist_load(cpl_frame_get_filename(tmp_frame), 01997 0); 01998 if (!strcmp(grat_id, cpl_propertylist_get_string(tmp_header, 01999 "ESO INS GRAT1 ID"))) { 02000 cpl_frameset_insert(frameset_std, cpl_frame_duplicate(tmp_frame)); 02001 } else { 02002 *same_gratings = FALSE; 02003 } 02004 cpl_propertylist_delete(tmp_header); 02005 02006 tmp_frame = kmo_dfs_get_frame(in, NULL); 02007 } 02008 cpl_free(grat_id) ; 02009 return frameset_std ; 02010 }
1.7.6.1