|
KMOS Pipeline Reference Manual
1.3.15
|
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 <string.h> 00029 #include <math.h> 00030 00031 #include <cpl.h> 00032 00033 #include "kmo_utils.h" 00034 #include "kmos_pfits.h" 00035 #include "kmo_dfs.h" 00036 #include "kmo_error.h" 00037 #include "kmo_constants.h" 00038 #include "kmo_priv_dark.h" 00039 #include "kmo_priv_combine.h" 00040 #include "kmo_priv_functions.h" 00041 #include "kmo_cpl_extensions.h" 00042 #include "kmo_debug.h" 00043 #include "kmos_oscan.h" 00044 00045 /*----------------------------------------------------------------------------- 00046 * Functions prototypes 00047 *----------------------------------------------------------------------------*/ 00048 00049 static int kmos_dark_check_inputs(cpl_frameset *, int *, int *, int *, int *, 00050 double *); 00051 00052 static int kmos_dark_create(cpl_plugin *); 00053 static int kmos_dark_exec(cpl_plugin *); 00054 static int kmos_dark_destroy(cpl_plugin *); 00055 static int kmos_dark(cpl_parameterlist *, cpl_frameset *); 00056 00057 /*----------------------------------------------------------------------------- 00058 * Static variables 00059 *----------------------------------------------------------------------------*/ 00060 00061 static char kmos_dark_description[] = 00062 "This recipe calculates the master dark frame.\n" 00063 "\n" 00064 "It is recommended to provide three or more dark exposures to produce a\n" 00065 "reasonable master with associated noise.\n" 00066 "\n" 00067 "---------------------------------------------------------------------------\n" 00068 "Input files:\n" 00069 " DO CATG Type Explanation Required #Frames\n" 00070 " ------- ----- ----------- -------- -------\n" 00071 " DARK RAW Dark exposures Y 1-n \n" 00072 " (at least 3 frames recommended) \n" 00073 "\n" 00074 "Output files:\n" 00075 " DO CATG Type Explanation\n" 00076 " ------- ----- -----------\n" 00077 " MASTER_DARK F2D Calculated master dark frames\n" 00078 " BADPIXEL_DARK B2D Associated badpixel frames\n" 00079 "---------------------------------------------------------------------------" 00080 "\n"; 00081 00082 /*----------------------------------------------------------------------------*/ 00086 /*----------------------------------------------------------------------------*/ 00087 00090 /*----------------------------------------------------------------------------- 00091 * Functions code 00092 *----------------------------------------------------------------------------*/ 00093 00094 /*----------------------------------------------------------------------------*/ 00103 /*----------------------------------------------------------------------------*/ 00104 int cpl_plugin_get_info(cpl_pluginlist *list) 00105 { 00106 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00107 cpl_plugin *plugin = &recipe->interface; 00108 00109 cpl_plugin_init(plugin, 00110 CPL_PLUGIN_API, 00111 KMOS_BINARY_VERSION, 00112 CPL_PLUGIN_TYPE_RECIPE, 00113 "kmos_dark", 00114 "Create master dark frame & bad pixel mask", 00115 kmos_dark_description, 00116 "Alex Agudo Berbel, Yves Jung", 00117 "usd-help@eso.org", 00118 kmos_get_license(), 00119 kmos_dark_create, 00120 kmos_dark_exec, 00121 kmos_dark_destroy); 00122 00123 cpl_pluginlist_append(list, plugin); 00124 00125 return 0; 00126 } 00127 00128 /*----------------------------------------------------------------------------*/ 00136 /*----------------------------------------------------------------------------*/ 00137 static int kmos_dark_create(cpl_plugin *plugin) 00138 { 00139 cpl_recipe *recipe; 00140 cpl_parameter *p; 00141 00142 /* Check that the plugin is part of a valid recipe */ 00143 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00144 recipe = (cpl_recipe *)plugin; 00145 else 00146 return -1; 00147 00148 /* Create the parameters list in the cpl_recipe object */ 00149 recipe->parameters = cpl_parameterlist_new(); 00150 00151 /* Fill the parameters list */ 00152 /* --oscan */ 00153 p = cpl_parameter_new_value("kmos.kmos_dark.oscan", 00154 CPL_TYPE_BOOL, "Apply Overscan Correction", 00155 "kmos.kmos_dark", TRUE); 00156 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "oscan"); 00157 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00158 cpl_parameterlist_append(recipe->parameters, p); 00159 00160 /* --pos_bad_pix_rej */ 00161 p = cpl_parameter_new_value("kmos.kmos_dark.pos_bad_pix_rej", 00162 CPL_TYPE_DOUBLE, "The positive rejection threshold for bad pixels", 00163 "kmos.kmos_dark", 50.0); 00164 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pos_bad_pix_rej"); 00165 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00166 cpl_parameterlist_append(recipe->parameters, p); 00167 00168 /* --neg_bad_pix_rej */ 00169 p = cpl_parameter_new_value("kmos.kmos_dark.neg_bad_pix_rej", 00170 CPL_TYPE_DOUBLE, "The negative rejection threshold for bad pixels", 00171 "kmos.kmos_dark", 50.0); 00172 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neg_bad_pix_rej"); 00173 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00174 cpl_parameterlist_append(recipe->parameters, p); 00175 00176 /* --file_extension */ 00177 p = cpl_parameter_new_value("kmos.kmos_dark.file_extension", CPL_TYPE_BOOL, 00178 "Controls if EXPTIME should be appended to product filenames", 00179 "kmos.kmos_dark", FALSE); 00180 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "file_extension"); 00181 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00182 cpl_parameterlist_append(recipe->parameters, p); 00183 00184 return kmos_combine_pars_create(recipe->parameters, "kmos.kmos_dark", 00185 DEF_REJ_METHOD, FALSE); 00186 } 00187 00188 /*----------------------------------------------------------------------------*/ 00194 /*----------------------------------------------------------------------------*/ 00195 static int kmos_dark_exec(cpl_plugin *plugin) 00196 { 00197 cpl_recipe *recipe; 00198 00199 /* Get the recipe out of the plugin */ 00200 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00201 recipe = (cpl_recipe *)plugin; 00202 else return -1; 00203 00204 return kmos_dark(recipe->parameters, recipe->frames); 00205 } 00206 00207 /*----------------------------------------------------------------------------*/ 00213 /*----------------------------------------------------------------------------*/ 00214 static int kmos_dark_destroy(cpl_plugin *plugin) 00215 { 00216 cpl_recipe *recipe; 00217 00218 /* Get the recipe out of the plugin */ 00219 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00220 recipe = (cpl_recipe *)plugin; 00221 else return -1 ; 00222 00223 cpl_parameterlist_delete(recipe->parameters); 00224 return 0 ; 00225 } 00226 00227 /*----------------------------------------------------------------------------*/ 00237 /*----------------------------------------------------------------------------*/ 00238 static int kmos_dark(cpl_parameterlist * parlist, cpl_frameset * frameset) 00239 { 00240 const cpl_parameter * par ; 00241 int nx, ny, nz, next, ndit ; 00242 const char * cmethod ; 00243 const char * my_method ; 00244 cpl_frame * frame ; 00245 int file_extension, citer, cmin, cmax, oscan ; 00246 double pos_bad_pix_rej, neg_bad_pix_rej, cneg_rej, 00247 cpos_rej, exptime, gain, qc_dark, qc_dark_median, 00248 qc_readnoise, qc_readnoise_median, qc_bad_pix_num ; 00249 char * filename ; 00250 char * filename_bad ; 00251 char * extname ; 00252 char * exptimeStr ; 00253 cpl_imagelist * detector_in_window ; 00254 cpl_image * img_in ; 00255 cpl_image * img_in_oscan ; 00256 cpl_image * img_in_window ; 00257 cpl_image * combined_data_window ; 00258 cpl_image * combined_data ; 00259 cpl_image * combined_noise_window ; 00260 cpl_image * combined_noise ; 00261 cpl_image * bad_pix_mask_window ; 00262 cpl_image * bad_pix_mask ; 00263 cpl_propertylist * sub_header ; 00264 int i ; 00265 00266 /* Check entries */ 00267 if (parlist == NULL || frameset == NULL) { 00268 cpl_msg_error(__func__, "Null Inputs") ; 00269 cpl_error_set(__func__, CPL_ERROR_NULL_INPUT) ; 00270 return -1 ; 00271 } 00272 00273 /* Inistialise */ 00274 nx = ny = next = -1 ; 00275 exptime = -1.0 ; 00276 00277 /* Get Parameters */ 00278 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_dark.oscan"); 00279 oscan = cpl_parameter_get_bool(par); 00280 par=cpl_parameterlist_find_const(parlist, "kmos.kmos_dark.pos_bad_pix_rej"); 00281 pos_bad_pix_rej = cpl_parameter_get_double(par); 00282 par=cpl_parameterlist_find_const(parlist, "kmos.kmos_dark.neg_bad_pix_rej"); 00283 neg_bad_pix_rej = cpl_parameter_get_double(par); 00284 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_dark.file_extension"); 00285 file_extension = cpl_parameter_get_bool(par); 00286 kmos_combine_pars_load(parlist, "kmos.kmos_dark", &cmethod, &cpos_rej, 00287 &cneg_rej, &citer, &cmin, &cmax, FALSE); 00288 00289 /* Identify the RAW and CALIB frames in the input frameset */ 00290 if (kmo_dfs_set_groups(frameset, "kmos_dark") != 1) { 00291 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00292 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00293 return -1 ; 00294 } 00295 00296 /* Check the inputs consistency */ 00297 if (kmos_dark_check_inputs(frameset, &nx, &ny, &ndit, &next,&exptime) != 1){ 00298 cpl_msg_error(__func__, "Input frameset is not consistent") ; 00299 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00300 return -1 ; 00301 } 00302 00303 /* Use average method in case there is only 1 input */ 00304 my_method = cmethod; 00305 if (cpl_frameset_count_tags(frameset, DARK) == 1) { 00306 cpl_msg_warning(cpl_func, 00307 "cmethod is set to 'average' since there is only 1 input"); 00308 my_method = "average"; 00309 } 00310 00311 /* Compute output file names */ 00312 if (file_extension) { 00313 /* Delete trailing zeros */ 00314 /* If zero right after decimal point,delete point as well */ 00315 exptimeStr = cpl_sprintf("%g", exptime); 00316 char *p = 0; 00317 for(p=exptimeStr; *p; ++p) { 00318 if('.' == *p) { 00319 while(*++p); 00320 while('0'==*--p) *p = '\0'; 00321 if(*p == '.') *p = '\0'; 00322 break; 00323 } 00324 } 00325 filename = cpl_sprintf("%s_%s", MASTER_DARK, exptimeStr); 00326 filename_bad = cpl_sprintf("%s_%s", BADPIXEL_DARK, exptimeStr); 00327 cpl_free(exptimeStr); 00328 } else { 00329 filename = cpl_sprintf("%s", MASTER_DARK); 00330 filename_bad = cpl_sprintf("%s", BADPIXEL_DARK); 00331 } 00332 00333 /* Create primary header products */ 00334 frame = kmo_dfs_get_frame(frameset, DARK); 00335 kmo_dfs_save_main_header(frameset, filename, "", frame, NULL, parlist, 00336 cpl_func); 00337 kmo_dfs_save_main_header(frameset, filename_bad, "", frame, NULL, parlist, 00338 cpl_func); 00339 00340 /* Loop on detectors */ 00341 for (i = 1; i <= next ; i++) { 00342 cpl_msg_info(cpl_func, "Processing detector No. %d", i); 00343 cpl_msg_indent_more() ; 00344 00345 detector_in_window = cpl_imagelist_new(); 00346 frame = kmo_dfs_get_frame(frameset, DARK); 00347 nz = 0; 00348 while (frame != NULL) { 00349 /* Load current detector DARK frames into an imagelist */ 00350 img_in = cpl_image_load(cpl_frame_get_filename(frame), 00351 CPL_TYPE_FLOAT, 0, i) ; 00352 if (img_in == NULL) { 00353 cpl_free(filename) ; 00354 cpl_free(filename_bad) ; 00355 cpl_imagelist_delete(detector_in_window) ; 00356 cpl_msg_error(__func__, "Cannot load frame %d", nz+1) ; 00357 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00358 cpl_msg_indent_less() ; 00359 return -1 ; 00360 } 00361 00362 /* Overscan Correction */ 00363 if (oscan) { 00364 img_in_oscan = kmos_oscan_correct(img_in) ; 00365 if (img_in_oscan == NULL) { 00366 cpl_free(filename) ; 00367 cpl_free(filename_bad) ; 00368 cpl_imagelist_delete(detector_in_window) ; 00369 cpl_image_delete(img_in); 00370 cpl_msg_error(__func__, "Cannot correct Overscan") ; 00371 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00372 cpl_msg_indent_less() ; 00373 return -1 ; 00374 } 00375 cpl_image_delete(img_in) ; 00376 img_in = img_in_oscan ; 00377 } 00378 00379 /* Cut the borderѕ */ 00380 img_in_window = cpl_image_extract(img_in, KMOS_BADPIX_BORDER+1, 00381 KMOS_BADPIX_BORDER+1, nx-KMOS_BADPIX_BORDER, 00382 ny-KMOS_BADPIX_BORDER) ; 00383 cpl_image_delete(img_in) ; 00384 00385 cpl_imagelist_set(detector_in_window, img_in_window, nz); 00386 nz++; 00387 00388 /* Get next DARK frame */ 00389 frame = kmo_dfs_get_frame(frameset, NULL); 00390 } 00391 00392 /* Combine imagelist and create noise */ 00393 kmos_combine_frames(detector_in_window, my_method, 00394 cpos_rej, cneg_rej, citer, cmax, cmin, &combined_data_window, 00395 &combined_noise_window, -1.0); 00396 cpl_imagelist_delete(detector_in_window) ; 00397 00398 if (kmclipm_omit_warning_one_slice > 10) 00399 kmclipm_omit_warning_one_slice = FALSE; 00400 00401 /* Calculate preliminary mean and stdev to create the BPM */ 00402 qc_dark = cpl_image_get_mean(combined_data_window); 00403 00404 /* Check the noise frame (NULL or ALL pixels are bad) */ 00405 if (combined_noise_window == NULL || 00406 cpl_image_count_rejected(combined_noise_window) == 00407 cpl_image_get_size_x(combined_noise_window)* 00408 cpl_image_get_size_y(combined_noise_window)) { 00409 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00410 } else { 00411 if (nz > 2) 00412 qc_readnoise = cpl_image_get_mean(combined_noise_window); 00413 else if (nz == 2) 00414 qc_readnoise = cpl_image_get_stdev(combined_noise_window); 00415 else if (nz == 1) 00416 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00417 else { 00418 cpl_msg_error(__func__, "Not enough frames: %d", nz) ; 00419 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00420 cpl_free(filename) ; 00421 cpl_free(filename_bad) ; 00422 cpl_image_delete(combined_data_window); 00423 cpl_image_delete(combined_noise_window); 00424 cpl_msg_indent_less() ; 00425 return -1 ; 00426 } 00427 } 00428 00429 /* Create bad-pixel-mask */ 00430 qc_bad_pix_num = kmo_create_bad_pix_dark(combined_data_window, 00431 qc_dark, qc_readnoise, pos_bad_pix_rej, neg_bad_pix_rej, 00432 &bad_pix_mask_window); 00433 00434 sub_header = kmo_dfs_load_sub_header(frameset, DARK, i, FALSE); 00435 kmclipm_update_property_int(sub_header, QC_NR_BAD_PIX, qc_bad_pix_num, 00436 "[] nr. of bad pixels"); 00437 00438 /* Calculate QC.DARK, QC.READNOISE, QC.DARK.MEDIAN, */ 00439 /* QC.READNOISE.MEDIAN, QC.DARKCUR */ 00440 00441 /* Badpixels from combined_data_window are already rejected */ 00442 /* by kmo_create_bad_pix_dark() */ 00443 kmo_image_reject_from_mask(combined_noise_window, bad_pix_mask_window); 00444 qc_dark = cpl_image_get_mean(combined_data_window); 00445 qc_dark_median = cpl_image_get_median(combined_data_window); 00446 00447 /* Check the noise frame (NULL or ALL pixels are bad) */ 00448 /* Calculate mean and stddev of combined frames (with rejection) */ 00449 if (combined_noise_window == NULL || 00450 cpl_image_count_rejected(combined_noise_window) == 00451 cpl_image_get_size_x(combined_noise_window)* 00452 cpl_image_get_size_y(combined_noise_window)) { 00453 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00454 qc_readnoise_median = 00455 kmo_image_get_stdev_median(combined_data_window); 00456 } else { 00457 if (nz > 2) { 00458 qc_readnoise = 00459 cpl_image_get_mean(combined_noise_window) * sqrt(nz) ; 00460 qc_readnoise_median = 00461 cpl_image_get_median(combined_noise_window) * sqrt(nz); 00462 } else if (nz == 2) { 00463 qc_readnoise = 00464 cpl_image_get_stdev(combined_noise_window) * sqrt(nz) ; 00465 qc_readnoise_median = sqrt(nz) * 00466 kmo_image_get_stdev_median(combined_noise_window) ; 00467 } else if (nz == 1) { 00468 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00469 qc_readnoise_median = 00470 kmo_image_get_stdev_median(combined_data_window); 00471 } else { 00472 cpl_msg_error(__func__, "Not enough frames: %d", nz) ; 00473 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00474 cpl_free(filename) ; 00475 cpl_free(filename_bad) ; 00476 cpl_image_delete(combined_data_window); 00477 cpl_image_delete(combined_noise_window); 00478 cpl_image_delete(bad_pix_mask_window); 00479 cpl_propertylist_delete(sub_header); 00480 cpl_msg_indent_less() ; 00481 return -1 ; 00482 } 00483 } 00484 00485 kmclipm_update_property_double(sub_header, QC_DARK, qc_dark, 00486 "[adu] mean of master dark"); 00487 kmclipm_update_property_double(sub_header, QC_READNOISE, qc_readnoise, 00488 "[adu] mean noise of master dark"); 00489 kmclipm_update_property_double(sub_header, QC_DARK_MEDIAN, 00490 qc_dark_median, "[adu] median of master dark"); 00491 kmclipm_update_property_double(sub_header, QC_READNOISE_MEDIAN, 00492 qc_readnoise_median, "[adu] median noise of master dark"); 00493 00494 /* Load gain */ 00495 gain = kmo_dfs_get_property_double(sub_header, GAIN); 00496 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00497 cpl_msg_error(__func__, "GAIN is missing in header") ; 00498 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00499 cpl_free(filename) ; 00500 cpl_free(filename_bad) ; 00501 cpl_image_delete(combined_data_window); 00502 cpl_image_delete(combined_noise_window); 00503 cpl_image_delete(bad_pix_mask_window); 00504 cpl_propertylist_delete(sub_header); 00505 cpl_msg_indent_less() ; 00506 return -1 ; 00507 } 00508 00509 kmclipm_update_property_double(sub_header, QC_DARK_CURRENT, 00510 qc_dark / exptime / gain, "[e-/s] dark current"); 00511 00512 /* Save dark frame */ 00513 extname = kmo_extname_creator(detector_frame, i, EXT_DATA); 00514 kmclipm_update_property_string(sub_header, EXTNAME, extname, 00515 "FITS extension name"); 00516 cpl_free(extname); 00517 00518 combined_data = kmo_add_bad_pix_border(combined_data_window, TRUE); 00519 cpl_image_delete(combined_data_window); 00520 00521 kmo_dfs_save_image(combined_data, filename, "", sub_header, 0./0.); 00522 cpl_image_delete(combined_data); 00523 00524 /* Save noise frame */ 00525 extname = kmo_extname_creator(detector_frame, i, EXT_NOISE); 00526 kmclipm_update_property_string(sub_header, EXTNAME, extname, 00527 "FITS extension name"); 00528 cpl_free(extname); 00529 00530 combined_noise = kmo_add_bad_pix_border(combined_noise_window, TRUE); 00531 cpl_image_delete(combined_noise_window); 00532 00533 kmo_dfs_save_image(combined_noise, filename, "", sub_header, 0./0.); 00534 cpl_image_delete(combined_noise); 00535 00536 /* Save bad_pix frame */ 00537 extname = kmo_extname_creator(detector_frame, i, EXT_BADPIX); 00538 kmclipm_update_property_string(sub_header, EXTNAME, extname, 00539 "FITS extension name"); 00540 cpl_free(extname); 00541 00542 bad_pix_mask = kmo_add_bad_pix_border(bad_pix_mask_window, FALSE); 00543 cpl_image_delete(bad_pix_mask_window); 00544 00545 kmo_dfs_save_image(bad_pix_mask, filename_bad, "", sub_header, 0.); 00546 cpl_image_delete(bad_pix_mask); 00547 00548 cpl_propertylist_delete(sub_header); 00549 00550 cpl_msg_indent_less() ; 00551 } 00552 00553 /* Free and Return */ 00554 cpl_free(filename); 00555 cpl_free(filename_bad); 00556 return CPL_ERROR_NONE; 00557 } 00558 00561 /*----------------------------------------------------------------------------*/ 00572 /*----------------------------------------------------------------------------*/ 00573 static int kmos_dark_check_inputs( 00574 cpl_frameset * frameset, 00575 int * nx, 00576 int * ny, 00577 int * ndit, 00578 int * next, 00579 double * exptime) 00580 { 00581 cpl_frame * frame ; 00582 cpl_propertylist * eh ; 00583 cpl_propertylist * main_header ; 00584 int nx_cur, ny_cur, ndit_cur, ne_cur ; 00585 double exptime_cur ; 00586 int i, j ; 00587 00588 /* Check Entries */ 00589 if (nx == NULL || ny == NULL || frameset == NULL || exptime == NULL || 00590 ndit == NULL || next == NULL) { 00591 return -1; 00592 } 00593 00594 /* More than 3 frames is recommended */ 00595 if (cpl_frameset_count_tags(frameset, DARK) < 3) { 00596 cpl_msg_warning(cpl_func, "3 DARK frames or more are recommended"); 00597 } 00598 00599 /* Loop on the frames - Check Main Headers consistency */ 00600 i = 0; 00601 frame = kmo_dfs_get_frame(frameset, DARK); 00602 while (frame != NULL) { 00603 /* Get Frame nb of extensions */ 00604 ne_cur = cpl_frame_get_nextensions(frame); 00605 00606 /* Read Frame header */ 00607 main_header = cpl_propertylist_load(cpl_frame_get_filename(frame),0); 00608 ndit_cur = kmos_pfits_get_ndit(main_header) ; 00609 exptime_cur = kmos_pfits_get_exptime(main_header) ; 00610 cpl_propertylist_delete(main_header) ; 00611 00612 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00613 cpl_msg_error(__func__, "Cannot retrieve keywords from header") ; 00614 return -1 ; 00615 } 00616 00617 if (i == 0) { 00618 *exptime = exptime_cur ; 00619 *ndit = ndit_cur ; 00620 *next = ne_cur ; 00621 } else { 00622 if (ndit_cur != *ndit || ne_cur != *next || 00623 fabs(exptime_cur-(*exptime)) >1e-3) { 00624 cpl_msg_error(__func__, "Header keywords are inconsistent") ; 00625 return -1 ; 00626 } 00627 } 00628 00629 /* Get next DARK frame */ 00630 frame = kmo_dfs_get_frame(frameset, NULL); 00631 i++; 00632 } 00633 00634 /* Loop on the frames - Check Extension Headers consistency */ 00635 i = 0; 00636 frame = kmo_dfs_get_frame(frameset, DARK); 00637 while (frame != NULL) { 00638 /* Loop on extensions */ 00639 for (j=1 ; j<=*next ; j++) { 00640 /* Read extension header */ 00641 eh = cpl_propertylist_load(cpl_frame_get_filename(frame), j); 00642 nx_cur = kmos_pfits_get_naxis1(eh) ; 00643 ny_cur = kmos_pfits_get_naxis2(eh) ; 00644 cpl_propertylist_delete(eh) ; 00645 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00646 cpl_msg_error(__func__, "Cannot retrieve keywords from header"); 00647 return -1 ; 00648 } 00649 00650 if (i == 0 && j == 1) { 00651 *nx = nx_cur ; 00652 *ny = ny_cur ; 00653 } else { 00654 if (nx_cur != *nx || ny_cur != *ny) { 00655 cpl_msg_error(__func__, "Header keywords are inconsistent"); 00656 return -1 ; 00657 } 00658 } 00659 } 00660 00661 /* Get next DARK frame */ 00662 frame = kmo_dfs_get_frame(frameset, NULL); 00663 i++; 00664 } 00665 00666 /* Check Sizeѕ */ 00667 if (*nx <= 2*KMOS_BADPIX_BORDER || *ny <= 2*KMOS_BADPIX_BORDER) { 00668 cpl_msg_error(__func__, "Input frames x/y size must be > 9 pixels"); 00669 return -1 ; 00670 } 00671 00672 /* Return */ 00673 return 1 ; 00674 } 00675 00676 00677
1.7.6.1