CRIRES Pipeline Reference Manual
2.3.2
|
00001 /* $Id: crires_spec_flat.c,v 1.56 2012-09-19 14:10:27 yjung Exp $ 00002 * 00003 * This file is part of the CRIRES 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: yjung $ 00023 * $Date: 2012-09-19 14:10:27 $ 00024 * $Revision: 1.56 $ 00025 * $Name: not supported by cvs2svn $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 Includes 00034 -----------------------------------------------------------------------------*/ 00035 00036 #include "crires_recipe.h" 00037 00038 #include "crires_combine.h" 00039 00040 /*----------------------------------------------------------------------------- 00041 Define 00042 -----------------------------------------------------------------------------*/ 00043 00044 #define RECIPE_STRING "crires_spec_flat" 00045 00046 /*----------------------------------------------------------------------------- 00047 Functions prototypes 00048 -----------------------------------------------------------------------------*/ 00049 00050 static cpl_imagelist * crires_spec_flat_reduce(cpl_frameset *, const char *, 00051 const char *) ; 00052 static cpl_imagelist * crires_spec_flat_bpm(cpl_imagelist *, double, 00053 double, double) ; 00054 static int crires_spec_flat_save(const cpl_imagelist *, const cpl_imagelist *, 00055 int, cpl_frameset *, const cpl_parameterlist *, cpl_frameset *) ; 00056 static int crires_spec_flat_compare(const cpl_frame *, const cpl_frame *) ; 00057 00058 static char crires_spec_flat_description[] = 00059 "crires_spec_flat -- Flat-field recipe\n" 00060 "The files listed in the Set Of Frames (sof-file) must be tagged:\n" 00061 "raw-file.fits "CRIRES_SPEC_FLAT_RAW" or\n" 00062 "dark-file.fits "CRIRES_CALPRO_DARK" or\n" 00063 "detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE".\n" ; 00064 00065 CRIRES_RECIPE_DEFINE(crires_spec_flat, 00066 CRIRES_PARAM_THRESHOLDS | 00067 CRIRES_PARAM_BPM_RATE | 00068 CRIRES_PARAM_REPLACE | 00069 CRIRES_PARAM_CLEAN_FLAT | 00070 CRIRES_PARAM_NORM_STARTY | 00071 CRIRES_PARAM_NORM_STOPY | 00072 CRIRES_PARAM_KAPPA_SIGCLIP | 00073 CRIRES_PARAM_COLLAPSE_METH, 00074 "Flatfield recipe", 00075 crires_spec_flat_description) ; 00076 00077 /*----------------------------------------------------------------------------- 00078 Static variables 00079 -----------------------------------------------------------------------------*/ 00080 00081 static struct { 00082 /* Input */ 00083 double bpm_low ; 00084 double bpm_high ; 00085 double bpm_lines_ratio ; 00086 int replace_flag ; 00087 int clean_flat_flag ; 00088 int starty ; 00089 int stopy ; 00090 double kappa_sigclip ; 00091 crires_collapse_method coll_meth ; 00092 /* Output */ 00093 crires_illum_period period ; 00094 int bpm_nb[CRIRES_NB_DETECTORS] ; 00095 double flat_mean[CRIRES_NB_DETECTORS] ; 00096 double flat_stdev[CRIRES_NB_DETECTORS] ; 00097 double flat_flux[CRIRES_NB_DETECTORS] ; 00098 double flat_master_rms[CRIRES_NB_DETECTORS] ; 00099 } crires_spec_flat_config ; 00100 00101 /*----------------------------------------------------------------------------- 00102 Functions code 00103 -----------------------------------------------------------------------------*/ 00104 00105 /*----------------------------------------------------------------------------*/ 00112 /*----------------------------------------------------------------------------*/ 00113 static int crires_spec_flat( 00114 cpl_frameset * frameset, 00115 const cpl_parameterlist * parlist) 00116 { 00117 const char * sval ; 00118 cpl_size * labels ; 00119 cpl_size nlabels ; 00120 cpl_frameset * rawframes ; 00121 const char * dark ; 00122 const char * detlin ; 00123 cpl_imagelist * flat ; 00124 cpl_frameset * flat_one ; 00125 cpl_imagelist * bpm ; 00126 int i ; 00127 00128 /* Initialise */ 00129 rawframes = NULL ; 00130 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00131 crires_spec_flat_config.bpm_nb[i] = -1 ; 00132 crires_spec_flat_config.flat_mean[i] = -1.0 ; 00133 crires_spec_flat_config.flat_stdev[i] = -1.0 ; 00134 crires_spec_flat_config.flat_flux[i] = -1.0 ; 00135 crires_spec_flat_config.flat_master_rms[i] = -1.0 ; 00136 } 00137 00138 /* Retrieve input parameters */ 00139 sval = crires_parameterlist_get_string(parlist, RECIPE_STRING, 00140 CRIRES_PARAM_THRESHOLDS) ; 00141 if (sscanf(sval, "%lg,%lg", 00142 &crires_spec_flat_config.bpm_low, 00143 &crires_spec_flat_config.bpm_high)!=2) { 00144 return -1 ; 00145 } 00146 crires_spec_flat_config.replace_flag = crires_parameterlist_get_bool( 00147 parlist, RECIPE_STRING, CRIRES_PARAM_REPLACE) ; 00148 crires_spec_flat_config.clean_flat_flag = crires_parameterlist_get_bool( 00149 parlist, RECIPE_STRING, CRIRES_PARAM_CLEAN_FLAT) ; 00150 crires_spec_flat_config.bpm_lines_ratio = crires_parameterlist_get_double( 00151 parlist, RECIPE_STRING, CRIRES_PARAM_BPM_RATE) ; 00152 crires_spec_flat_config.starty = crires_parameterlist_get_int(parlist, 00153 RECIPE_STRING, CRIRES_PARAM_NORM_STARTY) ; 00154 crires_spec_flat_config.stopy = crires_parameterlist_get_int(parlist, 00155 RECIPE_STRING, CRIRES_PARAM_NORM_STOPY) ; 00156 crires_spec_flat_config.kappa_sigclip = crires_parameterlist_get_double( 00157 parlist, RECIPE_STRING, CRIRES_PARAM_KAPPA_SIGCLIP) ; 00158 sval = crires_parameterlist_get_string(parlist, RECIPE_STRING, 00159 CRIRES_PARAM_COLLAPSE_METH) ; 00160 if (!strcmp(sval, "avg")) 00161 crires_spec_flat_config.coll_meth = CRIRES_COLLAPSE_AVG ; 00162 else if (!strcmp(sval, "med")) 00163 crires_spec_flat_config.coll_meth = CRIRES_COLLAPSE_MED ; 00164 else if (!strcmp(sval, "sig")) 00165 crires_spec_flat_config.coll_meth = CRIRES_COLLAPSE_SIG ; 00166 else { 00167 cpl_msg_error(__func__, "Invalid collapse method specified"); 00168 return -1; 00169 } 00170 00171 /* Identify the RAW and CALIB frames in the input frameset */ 00172 if (crires_dfs_set_groups(frameset, "crires_spec_flat")) { 00173 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00174 return -1 ; 00175 } 00176 00177 /* Retrieve calibration data */ 00178 dark = crires_extract_filename(frameset, CRIRES_CALPRO_DARK) ; 00179 detlin = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ; 00180 00181 /* Retrieve raw frames */ 00182 if ((rawframes = crires_extract_frameset(frameset, 00183 CRIRES_SPEC_FLAT_RAW)) == NULL) { 00184 cpl_msg_error(__func__, "No raw frame in input") ; 00185 return -1 ; 00186 } 00187 00188 /* Get the detector illumination period */ 00189 crires_spec_flat_config.period = 00190 crires_get_detector_illum_period( 00191 cpl_frame_get_filename(cpl_frameset_get_position(rawframes, 0))) ; 00192 if (crires_spec_flat_config.period == CRIRES_ILLUM_UNKNOWN) { 00193 cpl_msg_error(__func__, 00194 "Cannot determine the detector illumination period") ; 00195 cpl_frameset_delete(rawframes) ; 00196 return -1 ; 00197 } else { 00198 crires_display_detector_illum(crires_spec_flat_config.period) ; 00199 } 00200 00201 /* Labelise all input frames */ 00202 if ((labels = cpl_frameset_labelise(rawframes, crires_spec_flat_compare, 00203 &nlabels)) == NULL) { 00204 cpl_msg_error(__func__, "Cannot labelise input frames") ; 00205 cpl_frameset_delete(rawframes) ; 00206 return -1 ; 00207 } 00208 00209 /* Extract settings and reduce each of them */ 00210 for (i=0 ; i<(int)nlabels ; i++) { 00211 /* Reduce data set nb i */ 00212 cpl_msg_info(__func__, "Reduce data set %d / %"CPL_SIZE_FORMAT, 00213 i+1, nlabels); 00214 cpl_msg_indent_more() ; 00215 flat_one = cpl_frameset_extract(rawframes, labels, (cpl_size)i) ; 00216 flat = crires_spec_flat_reduce(flat_one, dark, detlin) ; 00217 cpl_msg_indent_less() ; 00218 00219 /* Save the products */ 00220 cpl_msg_info(__func__, "Save the products") ; 00221 cpl_msg_indent_more() ; 00222 if (flat == NULL) { 00223 cpl_msg_warning(__func__, "Cannot reduce set nb %d", i+1) ; 00224 } else { 00225 if ((bpm = crires_spec_flat_bpm(flat, 00226 crires_spec_flat_config.bpm_low, 00227 crires_spec_flat_config.bpm_high, 00228 crires_spec_flat_config.bpm_lines_ratio)) == NULL) { 00229 cpl_msg_warning(__func__, "Cannot create bad pixels map") ; 00230 } 00231 crires_spec_flat_save(flat, bpm, i+1, flat_one, parlist, frameset) ; 00232 cpl_imagelist_delete(flat) ; 00233 cpl_imagelist_delete(bpm) ; 00234 } 00235 cpl_msg_indent_less() ; 00236 cpl_frameset_delete(flat_one) ; 00237 } 00238 cpl_frameset_delete(rawframes) ; 00239 cpl_free(labels) ; 00240 00241 /* Return */ 00242 if (cpl_error_get_code()) return -1 ; 00243 else return 0 ; 00244 } 00245 00246 /*----------------------------------------------------------------------------*/ 00254 /*----------------------------------------------------------------------------*/ 00255 static cpl_imagelist * crires_spec_flat_reduce( 00256 cpl_frameset * flatframes, 00257 const char * dark, 00258 const char * detlin) 00259 { 00260 cpl_propertylist * plist ; 00261 cpl_frame * ref_frame ; 00262 const char * fname ; 00263 int nframes ; 00264 double dit_frame, dit_dark ; 00265 cpl_imagelist * in ; 00266 cpl_imagelist * out ; 00267 cpl_vector * medians ; 00268 double median ; 00269 cpl_image * ima ; 00270 int nx, ny, starty, stopy, ly ; 00271 int i, j ; 00272 00273 /* Test entries */ 00274 if (flatframes == NULL) return NULL ; 00275 00276 /* Initialize */ 00277 nframes = cpl_frameset_get_size(flatframes) ; 00278 ly = -1 ; 00279 00280 /* Get the DIT from the RAW frame */ 00281 ref_frame = cpl_frameset_get_position(flatframes, 0) ; 00282 fname = cpl_frame_get_filename(ref_frame) ; 00283 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame), 00284 0)) == NULL) { 00285 cpl_msg_error(__func__, "Getting header from RAW file"); 00286 cpl_msg_indent_less() ; 00287 return NULL ; 00288 } 00289 dit_frame = crires_pfits_get_dit(plist) ; 00290 cpl_propertylist_delete(plist) ; 00291 if (cpl_error_get_code()) { 00292 cpl_msg_error(__func__, "Cannot get the DIT from RAW file") ; 00293 cpl_msg_indent_less() ; 00294 return NULL ; 00295 } 00296 cpl_msg_info(__func__, "DIT value: %g sec.", dit_frame) ; 00297 00298 /* Verify the DIT of the dark */ 00299 if (dark != NULL) { 00300 cpl_msg_info(__func__, "Verify the dark DIT") ; 00301 cpl_msg_indent_more() ; 00302 if ((plist=cpl_propertylist_load(dark, 0)) == NULL) { 00303 cpl_msg_error(__func__, "Getting header from DARK"); 00304 cpl_msg_indent_less() ; 00305 return NULL ; 00306 } 00307 dit_dark = crires_pfits_get_dit(plist) ; 00308 cpl_propertylist_delete(plist) ; 00309 if (cpl_error_get_code()) { 00310 cpl_msg_error(__func__, "Cannot get the DIT from DARK") ; 00311 cpl_msg_indent_less() ; 00312 return NULL ; 00313 } 00314 if (fabs(dit_dark-dit_frame) > 1e-5) { 00315 cpl_msg_error(__func__, "Mismatch RAW DIT (%g) / DARK DIT (%g)", 00316 dit_frame, dit_dark) ; 00317 cpl_msg_indent_less() ; 00318 return NULL ; 00319 } 00320 cpl_msg_indent_less() ; 00321 } 00322 00323 /* Create the image list */ 00324 out = cpl_imagelist_new() ; 00325 00326 /* Loop on the detectors */ 00327 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00328 cpl_msg_info(__func__, "Compute the MASTER FLAT for chip nb %d", i+1) ; 00329 cpl_msg_indent_more() ; 00330 00331 /* Load the data */ 00332 in = crires_load_frameset(flatframes, crires_spec_flat_config.period, 00333 i+1, CPL_TYPE_FLOAT) ; 00334 nx = cpl_image_get_size_x(cpl_imagelist_get(in, 0)) ; 00335 ny = cpl_image_get_size_y(cpl_imagelist_get(in, 0)) ; 00336 00337 /* Correct for dark and non-linearity */ 00338 if (crires_calib_chip_list(in, crires_spec_flat_config.period, i+1, 00339 NULL, dark, NULL, detlin, dit_frame, -1, -1, -1)) { 00340 cpl_msg_error(__func__, "Cannot apply the calibrations") ; 00341 cpl_imagelist_delete(in) ; 00342 return NULL ; 00343 } 00344 00345 /* Create medians vector */ 00346 medians = cpl_vector_new(nframes) ; 00347 00348 /* Handle Vignetting */ 00349 if (i+1 == 1) 00350 ly = crires_get_detector_ly1(crires_spec_flat_config.period) ; 00351 if (i+1 == 2) 00352 ly = crires_get_detector_ly2(crires_spec_flat_config.period) ; 00353 if (i+1 == 3) 00354 ly = crires_get_detector_ly3(crires_spec_flat_config.period) ; 00355 if (i+1 == 4) 00356 ly = crires_get_detector_ly4(crires_spec_flat_config.period) ; 00357 /* If ly not found, use the bottom of the image */ 00358 if (ly < 0) ly = 1 ; 00359 00360 starty = crires_spec_flat_config.starty ; 00361 if (starty < 0) { 00362 starty = 1 ; 00363 } else { 00364 starty -= (ly - 1) ; 00365 } 00366 stopy = crires_spec_flat_config.stopy ; 00367 if (stopy < 0) { 00368 stopy = ny ; 00369 } else { 00370 stopy -= (ly - 1) ; 00371 } 00372 00373 /* Loop on all the frames */ 00374 cpl_msg_info(__func__, "Normalise with the median") ; 00375 for (j=0 ; j<nframes ; j++) { 00376 median = cpl_image_get_median_window(cpl_imagelist_get(in, j), 00377 1, starty, nx, stopy) ; 00378 if (cpl_error_get_code()) { 00379 cpl_msg_error(__func__, "Invalid bounds Y : %d-%d", ly, 00380 ly+ny-1) ; 00381 cpl_imagelist_delete(in) ; 00382 cpl_vector_delete(medians) ; 00383 return NULL ; 00384 } 00385 cpl_vector_set(medians, j, median) ; 00386 cpl_image_divide_scalar(cpl_imagelist_get(in, j), median) ; 00387 } 00388 00389 /* Fill QCs */ 00390 crires_spec_flat_config.flat_mean[i] = cpl_vector_get_mean(medians) ; 00391 if (cpl_vector_get_size(medians) > 1) 00392 crires_spec_flat_config.flat_stdev[i]=cpl_vector_get_stdev(medians); 00393 else 00394 crires_spec_flat_config.flat_stdev[i] = -1.0 ; 00395 crires_spec_flat_config.flat_flux[i] = 00396 crires_spec_flat_config.flat_mean[i] / dit_frame ; 00397 00398 /* Collapse the frames */ 00399 if ((ima = crires_combine_collapse_imagelist(in, medians, 00400 crires_spec_flat_config.kappa_sigclip, 00401 i+1, 00402 crires_spec_flat_config.coll_meth)) == NULL) { 00403 cpl_msg_error(__func__, "Cannot average the flats") ; 00404 cpl_imagelist_delete(in) ; 00405 cpl_vector_delete(medians) ; 00406 return NULL ; 00407 } 00408 cpl_vector_delete(medians) ; 00409 cpl_imagelist_delete(in) ; 00410 00411 /* Add QC */ 00412 crires_spec_flat_config.flat_master_rms[i] = 00413 cpl_image_get_stdev(ima) ; 00414 00415 /* Set the image in the list */ 00416 cpl_imagelist_set(out, ima, i) ; 00417 cpl_msg_indent_less() ; 00418 } 00419 00420 return out ; 00421 } 00422 00423 /*----------------------------------------------------------------------------*/ 00432 /*----------------------------------------------------------------------------*/ 00433 static cpl_imagelist * crires_spec_flat_bpm( 00434 cpl_imagelist * flat, 00435 double low, 00436 double high, 00437 double bad_per_line_limit) 00438 { 00439 cpl_imagelist * bpm ; 00440 int nima ; 00441 cpl_image * bpm_cur ; 00442 cpl_mask * mask_cur ; 00443 cpl_binary * pmask_cur ; 00444 int nx, ny, cur_bp_nb ; 00445 int i, j, k ; 00446 00447 /* Test entries */ 00448 if (flat == NULL) return NULL ; 00449 00450 /* Initialise */ 00451 nima = cpl_imagelist_get_size(flat) ; 00452 00453 /* Create the output image list */ 00454 bpm = cpl_imagelist_new() ; 00455 00456 /* Loop on the images */ 00457 for (i=0 ; i<nima ; i++) { 00458 /* Threshold to get the BPMs */ 00459 if ((mask_cur = cpl_mask_threshold_image_create( 00460 cpl_imagelist_get(flat, i), low, high)) == NULL) { 00461 cpl_msg_error(__func__, "Cannot create bad pixels map") ; 00462 cpl_imagelist_delete(bpm) ; 00463 return NULL ; 00464 } 00465 cpl_mask_not(mask_cur) ; 00466 00467 /* 00468 Post processing : Big zones of bad pixels are not considered as 00469 bad pixels. Each line containing more than 00470 100*bad_per_line_limit percent bad pixels is reset to contain 00471 anly good pixels. 00472 */ 00473 nx = cpl_mask_get_size_x(mask_cur) ; 00474 ny = cpl_mask_get_size_y(mask_cur) ; 00475 pmask_cur = cpl_mask_get_data(mask_cur) ; 00476 for (j=0 ; j<ny ; j++) { 00477 cur_bp_nb = cpl_mask_count_window(mask_cur, 1, j+1, nx, j+1) ; 00478 /* Check if the line has too many bad pixels */ 00479 if (cur_bp_nb > bad_per_line_limit * nx) { 00480 /* Reset the bad pixels on the current line */ 00481 for (k=0 ; k<nx ; k++) { 00482 pmask_cur[k+j*nx] = CPL_BINARY_0 ; 00483 } 00484 } 00485 } 00486 00487 /* Convert mask to image */ 00488 bpm_cur = cpl_image_new_from_mask(mask_cur) ; 00489 crires_spec_flat_config.bpm_nb[i] = cpl_mask_count(mask_cur) ; 00490 cpl_imagelist_set(bpm, bpm_cur, i) ; 00491 00492 /* Clean the flat using the computed BPM */ 00493 if (crires_spec_flat_config.clean_flat_flag) { 00494 cpl_image_reject_from_mask(cpl_imagelist_get(flat, i), mask_cur) ; 00495 cpl_detector_interpolate_rejected(cpl_imagelist_get(flat, i)) ; 00496 } 00497 cpl_mask_delete(mask_cur) ; 00498 00499 /* Set the flat to 1 outside of the bounds */ 00500 if (crires_spec_flat_config.replace_flag) { 00501 cpl_image_threshold(cpl_imagelist_get(flat, i), 00502 low, high, 1.0, 1.0) ; 00503 } 00504 } 00505 return bpm ; 00506 } 00507 00508 /*----------------------------------------------------------------------------*/ 00518 /*----------------------------------------------------------------------------*/ 00519 static int crires_spec_flat_save( 00520 const cpl_imagelist * flat, 00521 const cpl_imagelist * bpm, 00522 int set_nb, 00523 cpl_frameset * set, 00524 const cpl_parameterlist * parlist, 00525 cpl_frameset * set_tot) 00526 { 00527 cpl_propertylist ** qclists ; 00528 const cpl_frame * ref_frame ; 00529 char * filename ; 00530 cpl_propertylist * inputlist ; 00531 const char * recipe_name = "crires_spec_flat" ; 00532 int i ; 00533 00534 /* Get the reference frame */ 00535 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ; 00536 00537 /* Create the QC lists */ 00538 qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 00539 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00540 qclists[i] = cpl_propertylist_new() ; 00541 cpl_propertylist_append_int(qclists[i], "ESO QC NBBAD", 00542 crires_spec_flat_config.bpm_nb[i]) ; 00543 cpl_propertylist_append_double(qclists[i], "ESO QC FLAT MEAN", 00544 crires_spec_flat_config.flat_mean[i]) ; 00545 cpl_propertylist_append_double(qclists[i], "ESO QC FLAT STDEV", 00546 crires_spec_flat_config.flat_stdev[i]) ; 00547 cpl_propertylist_append_double(qclists[i], "ESO QC FLAT FLUX", 00548 crires_spec_flat_config.flat_flux[i]) ; 00549 cpl_propertylist_append_double(qclists[i], "ESO QC FLAT MASTER RMS", 00550 crires_spec_flat_config.flat_master_rms[i]) ; 00551 00552 /* Propagate some keywords from input raw frame extensions */ 00553 inputlist = cpl_propertylist_load_regexp( 00554 cpl_frame_get_filename(ref_frame), i+1, 00555 CRIRES_HEADER_EXT_FORWARD, 0) ; 00556 cpl_propertylist_copy_property_regexp(qclists[i], inputlist, 00557 CRIRES_HEADER_EXT_FORWARD, 0) ; 00558 cpl_propertylist_delete(inputlist) ; 00559 } 00560 00561 /* Write the flat image */ 00562 filename = cpl_sprintf("%s_set%02d.fits", recipe_name, set_nb) ; 00563 crires_image_save(set_tot, 00564 parlist, 00565 set, 00566 flat, 00567 recipe_name, 00568 CRIRES_CALPRO_FLAT, 00569 CRIRES_PROTYPE_FLAT, 00570 crires_spec_flat_config.period, 00571 NULL, 00572 (const cpl_propertylist**)qclists, 00573 PACKAGE "/" PACKAGE_VERSION, 00574 filename) ; 00575 cpl_free(filename) ; 00576 00577 /* Write the BPM */ 00578 if (bpm != NULL) { 00579 filename = cpl_sprintf("%s_set%02d_bpm.fits", recipe_name, set_nb) ; 00580 crires_image_save(set_tot, 00581 parlist, 00582 set, 00583 bpm, 00584 recipe_name, 00585 CRIRES_CALPRO_BPM, 00586 CRIRES_PROTYPE_BPM, 00587 crires_spec_flat_config.period, 00588 NULL, 00589 (const cpl_propertylist**)qclists, 00590 PACKAGE "/" PACKAGE_VERSION, 00591 filename) ; 00592 cpl_free(filename) ; 00593 } 00594 00595 /* Free and return */ 00596 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00597 cpl_propertylist_delete(qclists[i]) ; 00598 } 00599 cpl_free(qclists) ; 00600 return 0; 00601 } 00602 00603 /*----------------------------------------------------------------------------*/ 00610 /*----------------------------------------------------------------------------*/ 00611 static int crires_spec_flat_compare( 00612 const cpl_frame * frame1, 00613 const cpl_frame * frame2) 00614 { 00615 int comparison ; 00616 cpl_propertylist * plist1 ; 00617 cpl_propertylist * plist2 ; 00618 double dval1, dval2 ; 00619 00620 /* Test entries */ 00621 if (frame1==NULL || frame2==NULL) return -1 ; 00622 00623 /* Get property lists */ 00624 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),0))==NULL){ 00625 cpl_msg_error(__func__, "getting header from reference frame"); 00626 return -1 ; 00627 } 00628 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),0))==NULL){ 00629 cpl_msg_error(__func__, "getting header from reference frame"); 00630 cpl_propertylist_delete(plist1) ; 00631 return -1 ; 00632 } 00633 00634 /* Test status */ 00635 if (cpl_error_get_code()) { 00636 cpl_propertylist_delete(plist1) ; 00637 cpl_propertylist_delete(plist2) ; 00638 return -1 ; 00639 } 00640 00641 comparison = 1 ; 00642 00643 /* Compare the DIT used */ 00644 dval1 = crires_pfits_get_dit(plist1) ; 00645 dval2 = crires_pfits_get_dit(plist2) ; 00646 if (cpl_error_get_code()) { 00647 cpl_msg_error(__func__, "Cannot get the DIT"); 00648 cpl_propertylist_delete(plist1) ; 00649 cpl_propertylist_delete(plist2) ; 00650 return -1 ; 00651 } 00652 if (fabs(dval1-dval2) > 1e-3) comparison = 0 ; 00653 00654 /* Compare the WLEN REF used */ 00655 dval1 = crires_pfits_get_refwlen(plist1) ; 00656 dval2 = crires_pfits_get_refwlen(plist2) ; 00657 if (cpl_error_get_code()) { 00658 cpl_msg_error(__func__, "Cannot get the reference wavelength"); 00659 cpl_propertylist_delete(plist1) ; 00660 cpl_propertylist_delete(plist2) ; 00661 return -1 ; 00662 } 00663 if (fabs(dval1-dval2) > 1e-3) comparison = 0 ; 00664 00665 /* Compare the SHUT1 POS used */ 00666 dval1 = crires_pfits_get_bafflepos(plist1) ; 00667 dval2 = crires_pfits_get_bafflepos(plist2) ; 00668 if (cpl_error_get_code()) { 00669 cpl_msg_error(__func__, "Cannot get the baffle position"); 00670 cpl_propertylist_delete(plist1) ; 00671 cpl_propertylist_delete(plist2) ; 00672 return -1 ; 00673 } 00674 if (fabs(dval1-dval2) > 1e-3) comparison = 0 ; 00675 00676 cpl_propertylist_delete(plist1) ; 00677 cpl_propertylist_delete(plist2) ; 00678 return comparison ; 00679 } 00680