|
KMOS Pipeline Reference Manual
1.3.7
|
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, ne, 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 /* Get Parameters */ 00308 par=cpl_parameterlist_find_const(parlist, "kmos.kmos_dark.pos_bad_pix_rej"); 00309 pos_bad_pix_rej = cpl_parameter_get_double(par); 00310 par=cpl_parameterlist_find_const(parlist, "kmos.kmos_dark.neg_bad_pix_rej"); 00311 neg_bad_pix_rej = cpl_parameter_get_double(par); 00312 par = cpl_parameterlist_find_const(parlist,"kmos.kmos_dark.file_extension"); 00313 file_extension = cpl_parameter_get_bool(par); 00314 kmos_combine_pars_load(parlist, "kmos.kmos_dark", &cmethod, &cpos_rej, 00315 &cneg_rej, &citer, &cmin, &cmax, FALSE); 00316 00317 /* Identify the RAW and CALIB frames in the input frameset */ 00318 if (kmo_dfs_set_groups(frameset, "kmos_dark") != 1) { 00319 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00320 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00321 return -1 ; 00322 } 00323 00324 /* Check the inputs consistency */ 00325 if (kmos_dark_check_inputs(frameset, &nx, &ny, &ndit, &ne, &exptime) != 1) { 00326 cpl_msg_error(__func__, "Input frameset is not consistent") ; 00327 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00328 return -1 ; 00329 } 00330 00331 /* Use average method in case there is only 1 input */ 00332 my_method = cmethod; 00333 if (cpl_frameset_count_tags(frameset, DARK) == 1) { 00334 cpl_msg_warning(cpl_func, 00335 "cmethod is set to 'average' since there is only 1 input"); 00336 my_method = "average"; 00337 } 00338 00339 /* Compute output file names */ 00340 if (file_extension) { 00341 /* Delete trailing zeros */ 00342 /* If zero right after decimal point,delete point as well */ 00343 exptimeStr = cpl_sprintf("%g", exptime); 00344 char *p = 0; 00345 for(p=exptimeStr; *p; ++p) { 00346 if('.' == *p) { 00347 while(*++p); 00348 while('0'==*--p) *p = '\0'; 00349 if(*p == '.') *p = '\0'; 00350 break; 00351 } 00352 } 00353 filename = cpl_sprintf("%s_%s", MASTER_DARK, exptimeStr); 00354 filename_bad = cpl_sprintf("%s_%s", BADPIXEL_DARK, exptimeStr); 00355 cpl_free(exptimeStr); 00356 } else { 00357 filename = cpl_sprintf("%s", MASTER_DARK); 00358 filename_bad = cpl_sprintf("%s", BADPIXEL_DARK); 00359 } 00360 00361 /* Create primary header products */ 00362 frame = kmo_dfs_get_frame(frameset, DARK); 00363 kmo_dfs_save_main_header(frameset, filename, "", frame, NULL, parlist, 00364 cpl_func); 00365 kmo_dfs_save_main_header(frameset, filename_bad, "", frame, NULL, parlist, 00366 cpl_func); 00367 00368 /* Loop on detectors */ 00369 for (i = 1; i <= ne ; i++) { 00370 cpl_msg_info(cpl_func, "Processing detector No. %d", i); 00371 cpl_msg_indent_more() ; 00372 00373 detector_in_window = cpl_imagelist_new(); 00374 frame = kmo_dfs_get_frame(frameset, DARK); 00375 nz = 0; 00376 while (frame != NULL) { 00377 /* Load current detector DARK frames into an imagelist */ 00378 img_in_window = cpl_image_load_window(cpl_frame_get_filename(frame), 00379 CPL_TYPE_FLOAT, 0, i, KMOS_BADPIX_BORDER+1, 00380 KMOS_BADPIX_BORDER+1, nx-KMOS_BADPIX_BORDER, 00381 ny-KMOS_BADPIX_BORDER) ; 00382 if (img_in_window == NULL) { 00383 cpl_free(filename) ; 00384 cpl_free(filename_bad) ; 00385 cpl_imagelist_delete(detector_in_window) ; 00386 cpl_msg_error(__func__, "Cannot load frame %d", nz+1) ; 00387 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00388 cpl_msg_indent_less() ; 00389 return -1 ; 00390 } 00391 cpl_imagelist_set(detector_in_window, img_in_window, nz); 00392 nz++; 00393 00394 /* Get next DARK frame */ 00395 frame = kmo_dfs_get_frame(frameset, NULL); 00396 } 00397 00398 /* Combine imagelist and create noise */ 00399 kmos_combine_frames(detector_in_window, my_method, 00400 cpos_rej, cneg_rej, citer, cmax, cmin, &combined_data_window, 00401 &combined_noise_window, -1.0); 00402 cpl_imagelist_delete(detector_in_window) ; 00403 00404 if (kmclipm_omit_warning_one_slice > 10) 00405 kmclipm_omit_warning_one_slice = FALSE; 00406 00407 /* Calculate preliminary mean and stdev to create the BPM */ 00408 qc_dark = cpl_image_get_mean(combined_data_window); 00409 00410 /* Check the noise frame (NULL or ALL pixels are bad) */ 00411 if (combined_noise_window == NULL || 00412 cpl_image_count_rejected(combined_noise_window) == 00413 cpl_image_get_size_x(combined_noise_window)* 00414 cpl_image_get_size_y(combined_noise_window)) { 00415 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00416 } else { 00417 if (nz > 2) 00418 qc_readnoise = cpl_image_get_mean(combined_noise_window); 00419 else if (nz == 2) 00420 qc_readnoise = cpl_image_get_stdev(combined_noise_window); 00421 else if (nz == 1) 00422 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00423 else { 00424 cpl_msg_error(__func__, "Not enough frames: %d", nz) ; 00425 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00426 cpl_free(filename) ; 00427 cpl_free(filename_bad) ; 00428 cpl_image_delete(combined_data_window); 00429 cpl_image_delete(combined_noise_window); 00430 cpl_msg_indent_less() ; 00431 return -1 ; 00432 } 00433 } 00434 00435 /* Create bad-pixel-mask */ 00436 qc_bad_pix_num = kmo_create_bad_pix_dark(combined_data_window, 00437 qc_dark, qc_readnoise, pos_bad_pix_rej, neg_bad_pix_rej, 00438 &bad_pix_mask_window); 00439 00440 sub_header = kmo_dfs_load_sub_header(frameset, DARK, i, FALSE); 00441 kmclipm_update_property_int(sub_header, QC_NR_BAD_PIX, qc_bad_pix_num, 00442 "[] nr. of bad pixels"); 00443 00444 /* Calculate QC.DARK, QC.READNOISE, QC.DARK.MEDIAN, */ 00445 /* QC.READNOISE.MEDIAN, QC.DARKCUR */ 00446 00447 /* Badpixels from combined_data_window are already rejected */ 00448 /* by kmo_create_bad_pix_dark() */ 00449 kmo_image_reject_from_mask(combined_noise_window, bad_pix_mask_window); 00450 qc_dark = cpl_image_get_mean(combined_data_window); 00451 qc_dark_median = cpl_image_get_median(combined_data_window); 00452 00453 /* Check the noise frame (NULL or ALL pixels are bad) */ 00454 /* Calculate mean and stddev of combined frames (with rejection) */ 00455 if (combined_noise_window == NULL || 00456 cpl_image_count_rejected(combined_noise_window) == 00457 cpl_image_get_size_x(combined_noise_window)* 00458 cpl_image_get_size_y(combined_noise_window)) { 00459 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00460 qc_readnoise_median = 00461 kmo_image_get_stdev_median(combined_data_window); 00462 } else { 00463 if (nz > 2) { 00464 qc_readnoise = 00465 cpl_image_get_mean(combined_noise_window) * sqrt(nz) ; 00466 qc_readnoise_median = 00467 cpl_image_get_median(combined_noise_window) * sqrt(nz); 00468 } else if (nz == 2) { 00469 qc_readnoise = 00470 cpl_image_get_stdev(combined_noise_window) * sqrt(nz) ; 00471 qc_readnoise_median = sqrt(nz) * 00472 kmo_image_get_stdev_median(combined_noise_window) ; 00473 } else if (nz == 1) { 00474 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00475 qc_readnoise_median = 00476 kmo_image_get_stdev_median(combined_data_window); 00477 } else { 00478 cpl_msg_error(__func__, "Not enough frames: %d", nz) ; 00479 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00480 cpl_free(filename) ; 00481 cpl_free(filename_bad) ; 00482 cpl_image_delete(combined_data_window); 00483 cpl_image_delete(combined_noise_window); 00484 cpl_image_delete(bad_pix_mask_window); 00485 cpl_propertylist_delete(sub_header); 00486 cpl_msg_indent_less() ; 00487 return -1 ; 00488 } 00489 } 00490 00491 kmclipm_update_property_double(sub_header, QC_DARK, qc_dark, 00492 "[adu] mean of master dark"); 00493 kmclipm_update_property_double(sub_header, QC_READNOISE, qc_readnoise, 00494 "[adu] mean noise of master dark"); 00495 kmclipm_update_property_double(sub_header, QC_DARK_MEDIAN, 00496 qc_dark_median, "[adu] median of master dark"); 00497 kmclipm_update_property_double(sub_header, QC_READNOISE_MEDIAN, 00498 qc_readnoise_median, "[adu] median noise of master dark"); 00499 00500 /* Load gain */ 00501 gain = kmo_dfs_get_property_double(sub_header, GAIN); 00502 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00503 cpl_msg_error(__func__, "GAIN is missing in header") ; 00504 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ; 00505 cpl_free(filename) ; 00506 cpl_free(filename_bad) ; 00507 cpl_image_delete(combined_data_window); 00508 cpl_image_delete(combined_noise_window); 00509 cpl_image_delete(bad_pix_mask_window); 00510 cpl_propertylist_delete(sub_header); 00511 cpl_msg_indent_less() ; 00512 return -1 ; 00513 } 00514 00515 kmclipm_update_property_double(sub_header, QC_DARK_CURRENT, 00516 qc_dark / exptime / gain, "[e-/s] dark current"); 00517 00518 /* Save dark frame */ 00519 extname = kmo_extname_creator(detector_frame, i, EXT_DATA); 00520 kmclipm_update_property_string(sub_header, EXTNAME, extname, 00521 "FITS extension name"); 00522 cpl_free(extname); 00523 00524 combined_data = kmo_add_bad_pix_border(combined_data_window, TRUE); 00525 cpl_image_delete(combined_data_window); 00526 00527 kmo_dfs_save_image(combined_data, filename, "", sub_header, 0./0.); 00528 cpl_image_delete(combined_data); 00529 00530 /* Save noise frame */ 00531 extname = kmo_extname_creator(detector_frame, i, EXT_NOISE); 00532 kmclipm_update_property_string(sub_header, EXTNAME, extname, 00533 "FITS extension name"); 00534 cpl_free(extname); 00535 00536 combined_noise = kmo_add_bad_pix_border(combined_noise_window, TRUE); 00537 cpl_image_delete(combined_noise_window); 00538 00539 kmo_dfs_save_image(combined_noise, filename, "", sub_header, 0./0.); 00540 cpl_image_delete(combined_noise); 00541 00542 /* Save bad_pix frame */ 00543 extname = kmo_extname_creator(detector_frame, i, EXT_BADPIX); 00544 kmclipm_update_property_string(sub_header, EXTNAME, extname, 00545 "FITS extension name"); 00546 cpl_free(extname); 00547 00548 bad_pix_mask = kmo_add_bad_pix_border(bad_pix_mask_window, FALSE); 00549 cpl_image_delete(bad_pix_mask_window); 00550 00551 kmo_dfs_save_image(bad_pix_mask, filename_bad, "", sub_header, 0.); 00552 cpl_image_delete(bad_pix_mask); 00553 00554 cpl_propertylist_delete(sub_header); 00555 00556 cpl_msg_indent_less() ; 00557 } 00558 00559 /* Free and Return */ 00560 cpl_free(filename); 00561 cpl_free(filename_bad); 00562 return CPL_ERROR_NONE; 00563 } 00564 00567 /*----------------------------------------------------------------------------*/ 00578 /*----------------------------------------------------------------------------*/ 00579 static int kmos_dark_check_inputs( 00580 cpl_frameset * frameset, 00581 int * nx, 00582 int * ny, 00583 int * ndit, 00584 int * ne, 00585 double * exptime) 00586 { 00587 cpl_frame * frame ; 00588 cpl_propertylist * eh ; 00589 cpl_propertylist * main_header ; 00590 int nx_cur, ny_cur, ndit_cur, ne_cur ; 00591 double exptime_cur ; 00592 int i, j ; 00593 00594 /* Check Entries */ 00595 if (nx == NULL || ny == NULL || frameset == NULL || exptime == NULL || 00596 ndit == NULL || ne == NULL) { 00597 return -1; 00598 } 00599 00600 /* More than 3 frames is recommended */ 00601 if (cpl_frameset_count_tags(frameset, DARK) < 3) { 00602 cpl_msg_warning(cpl_func, "3 DARK frames or more are recommended"); 00603 } 00604 00605 /* Loop on the frames - Check Main Headers consistency */ 00606 i = 0; 00607 frame = kmo_dfs_get_frame(frameset, DARK); 00608 while (frame != NULL) { 00609 /* Get Frame nb of extensions */ 00610 ne_cur = cpl_frame_get_nextensions(frame); 00611 00612 /* Read Frame header */ 00613 main_header = cpl_propertylist_load(cpl_frame_get_filename(frame),0); 00614 ndit_cur = kmos_pfits_get_ndit(main_header) ; 00615 exptime_cur = kmos_pfits_get_exptime(main_header) ; 00616 cpl_propertylist_delete(main_header) ; 00617 00618 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00619 cpl_msg_error(__func__, "Cannot retrieve keywords from header") ; 00620 return -1 ; 00621 } 00622 00623 if (i == 0) { 00624 *exptime = exptime_cur ; 00625 *ndit = ndit_cur ; 00626 *ne = ne_cur ; 00627 } else { 00628 if (ndit_cur != *ndit || ne_cur != *ne || 00629 fabs(exptime_cur-(*exptime)) >1e-3) { 00630 cpl_msg_error(__func__, "Header keywords are inconsistent") ; 00631 return -1 ; 00632 } 00633 } 00634 00635 /* Get next DARK frame */ 00636 frame = kmo_dfs_get_frame(frameset, NULL); 00637 i++; 00638 } 00639 00640 /* Loop on the frames - Check Extension Headers consistency */ 00641 i = 0; 00642 frame = kmo_dfs_get_frame(frameset, DARK); 00643 while (frame != NULL) { 00644 /* Loop on extensions */ 00645 for (j=1 ; j<=*ne ; j++) { 00646 /* Read extension header */ 00647 eh = cpl_propertylist_load(cpl_frame_get_filename(frame), j); 00648 nx_cur = kmos_pfits_get_naxis1(eh) ; 00649 ny_cur = kmos_pfits_get_naxis2(eh) ; 00650 cpl_propertylist_delete(eh) ; 00651 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00652 cpl_msg_error(__func__, "Cannot retrieve keywords from header"); 00653 return -1 ; 00654 } 00655 00656 if (i == 0 && j == 1) { 00657 *nx = nx_cur ; 00658 *ny = ny_cur ; 00659 } else { 00660 if (nx_cur != *nx || ny_cur != *ny) { 00661 cpl_msg_error(__func__, "Header keywords are inconsistent"); 00662 return -1 ; 00663 } 00664 } 00665 } 00666 00667 /* Get next DARK frame */ 00668 frame = kmo_dfs_get_frame(frameset, NULL); 00669 i++; 00670 } 00671 00672 /* Check Sizeѕ */ 00673 if (*nx <= 2*KMOS_BADPIX_BORDER || *ny <= 2*KMOS_BADPIX_BORDER) { 00674 cpl_msg_error(__func__, "Input frames x/y size must be > 9 pixels"); 00675 return -1 ; 00676 } 00677 00678 /* Return */ 00679 return 1 ; 00680 } 00681 00682 00683
1.7.6.1