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