|
KMOS Pipeline Reference Manual
1.2.8
|
00001 /* $Id: kmo_dark.c,v 1.21 2013-07-02 09:37:22 aagudo Exp $ 00002 * 00003 * This file is part of the KMOS 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: aagudo $ 00023 * $Date: 2013-07-02 09:37:22 $ 00024 * $Revision: 1.21 $ 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 <string.h> 00037 #include <math.h> 00038 00039 #include <cpl.h> 00040 00041 #include "kmo_utils.h" 00042 #include "kmo_dfs.h" 00043 #include "kmo_error.h" 00044 #include "kmo_constants.h" 00045 #include "kmo_priv_dark.h" 00046 #include "kmo_priv_functions.h" 00047 #include "kmo_cpl_extensions.h" 00048 #include "kmo_debug.h" 00049 00050 /*----------------------------------------------------------------------------- 00051 * Functions prototypes 00052 *----------------------------------------------------------------------------*/ 00053 00054 static int kmo_dark_create(cpl_plugin *); 00055 static int kmo_dark_exec(cpl_plugin *); 00056 static int kmo_dark_destroy(cpl_plugin *); 00057 static int kmo_dark(cpl_parameterlist *, cpl_frameset *); 00058 00059 /*----------------------------------------------------------------------------- 00060 * Static variables 00061 *----------------------------------------------------------------------------*/ 00062 00063 static char kmo_dark_description[] = 00064 "This recipe calculates the master dark frame.\n" 00065 "\n" 00066 "It is recommended to provide three or more dark exposures to produce a reason-\n" 00067 "able master with associated noise.\n" 00068 "\n" 00069 "BASIC PARAMETERS\n" 00070 "----------------\n" 00071 "--pos_bad_pix_rej\n" 00072 "--neg_bad_pix_rej\n" 00073 "Bad pixels above and below defined positive/negative threshold levels will be\n" 00074 "flagged and output to the BADPIX_DARK frame (which will go into the kmo_flat\n" 00075 "recipe). The number of bad pixels is returned as a QC1 parameter. The two para-\n" 00076 "meters can be used to change these thresholds.\n" 00077 "\n" 00078 "--cmethod\n" 00079 "Following methods of frame combination are available:\n" 00080 " * 'ksigma' (Default)\n" 00081 " An iterative sigma clipping. For each position all pixels in the spectrum\n" 00082 " are examined. If they deviate significantly, they will be rejected according\n" 00083 " to the conditions:\n" 00084 " val > mean + stdev * cpos_rej\n" 00085 " and\n" 00086 " val < mean - stdev * cneg_rej\n" 00087 " where --cpos_rej, --cneg_rej and --citer are the corresponding configuration\n" 00088 " parameters. In the first iteration median and percentile level are used.\n" 00089 "\n" 00090 " * 'median'\n" 00091 " At each pixel position the median is calculated.\n" 00092 "\n" 00093 " * 'average'\n" 00094 " At each pixel position the average is calculated.\n" 00095 "\n" 00096 " * 'sum'\n" 00097 " At each pixel position the sum is calculated.\n" 00098 "\n" 00099 " * 'min_max'\n" 00100 " The specified number of minimum and maximum pixel values will be rejected.\n" 00101 " --cmax and --cmin apply to this method.\n" 00102 "\n" 00103 "--file_extension" 00104 "Set this parameter to TRUE if the EXPTIME keyword should be appended to\n" 00105 "the output filenames.\n" 00106 "\n" 00107 "ADVANCED PARAMETERS\n" 00108 "-------------------\n" 00109 "--cpos_rej\n" 00110 "--cneg_rej\n" 00111 "--citer\n" 00112 "see --cmethod='ksigma'\n" 00113 "\n" 00114 "--cmax\n" 00115 "--cmin\n" 00116 "see --cmethod='min_max'\n" 00117 "\n" 00118 "-------------------------------------------------------------------------------\n" 00119 "Input files:\n" 00120 "\n" 00121 " DO KMOS \n" 00122 " category Type Explanation Required #Frames\n" 00123 " -------- ----- ----------- -------- -------\n" 00124 " DARK RAW Dark exposures Y 1-n \n" 00125 " (at least 3 frames recommended) \n" 00126 "\n" 00127 "Output files:\n" 00128 "\n" 00129 " DO KMOS\n" 00130 " category Type Explanation\n" 00131 " -------- ----- -----------\n" 00132 " MASTER_DARK F2D Calculated master dark frames\n" 00133 "\n" 00134 " BADPIXEL_DARK B2D Associated badpixel frames\n" 00135 "\n" 00136 "-------------------------------------------------------------------------------" 00137 "\n"; 00138 00139 /*----------------------------------------------------------------------------- 00140 * Functions code 00141 *----------------------------------------------------------------------------*/ 00142 00159 int cpl_plugin_get_info(cpl_pluginlist *list) 00160 { 00161 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00162 cpl_plugin *plugin = &recipe->interface; 00163 00164 cpl_plugin_init(plugin, 00165 CPL_PLUGIN_API, 00166 KMOS_BINARY_VERSION, 00167 CPL_PLUGIN_TYPE_RECIPE, 00168 "kmo_dark", 00169 "Create master dark frame & bad pixel mask", 00170 kmo_dark_description, 00171 "Alex Agudo Berbel", 00172 "kmos-spark@mpe.mpg.de", 00173 kmos_get_license(), 00174 kmo_dark_create, 00175 kmo_dark_exec, 00176 kmo_dark_destroy); 00177 00178 cpl_pluginlist_append(list, plugin); 00179 00180 return 0; 00181 } 00182 00190 static int kmo_dark_create(cpl_plugin *plugin) 00191 { 00192 cpl_recipe *recipe; 00193 cpl_parameter *p; 00194 00195 /* Check that the plugin is part of a valid recipe */ 00196 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00197 recipe = (cpl_recipe *)plugin; 00198 else 00199 return -1; 00200 00201 /* Create the parameters list in the cpl_recipe object */ 00202 recipe->parameters = cpl_parameterlist_new(); 00203 00204 /* Fill the parameters list */ 00205 00206 /* --pos_bad_pix_rej */ 00207 p = cpl_parameter_new_value("kmos.kmo_dark.pos_bad_pix_rej", 00208 CPL_TYPE_DOUBLE, 00209 "The positive rejection threshold for " 00210 "bad pixels", 00211 "kmos.kmo_dark", 00212 50.0); 00213 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pos_bad_pix_rej"); 00214 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00215 cpl_parameterlist_append(recipe->parameters, p); 00216 00217 /* --neg_bad_pix_rej */ 00218 p = cpl_parameter_new_value("kmos.kmo_dark.neg_bad_pix_rej", 00219 CPL_TYPE_DOUBLE, 00220 "The negative rejection threshold for " 00221 "bad pixels", 00222 "kmos.kmo_dark", 00223 50.0); 00224 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neg_bad_pix_rej"); 00225 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00226 cpl_parameterlist_append(recipe->parameters, p); 00227 00228 /* --file_extension */ 00229 p = cpl_parameter_new_value("kmos.kmo_dark.file_extension", 00230 CPL_TYPE_BOOL, 00231 "Controls if EXPTIME keyword should be appended " 00232 "to product filenames.", 00233 "kmos.kmo_dark", 00234 FALSE); 00235 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "file_extension"); 00236 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00237 cpl_parameterlist_append(recipe->parameters, p); 00238 00239 return kmo_combine_pars_create(recipe->parameters, 00240 "kmos.kmo_dark", 00241 DEF_REJ_METHOD, 00242 FALSE); 00243 } 00244 00250 static int kmo_dark_exec(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 return kmo_dark(recipe->parameters, recipe->frames); 00260 } 00261 00267 static int kmo_dark_destroy(cpl_plugin *plugin) 00268 { 00269 cpl_recipe *recipe; 00270 00271 /* Get the recipe out of the plugin */ 00272 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00273 recipe = (cpl_recipe *)plugin; 00274 else return -1 ; 00275 00276 cpl_parameterlist_delete(recipe->parameters); 00277 return 0 ; 00278 } 00279 00290 static int kmo_dark(cpl_parameterlist *parlist, cpl_frameset *frameset) 00291 { 00292 cpl_imagelist *detector_in_window = NULL; 00293 00294 cpl_image *img_in_window = NULL, 00295 *combined_data = NULL, 00296 *combined_data_window = NULL, 00297 *combined_noise = NULL, 00298 *combined_noise_window = NULL, 00299 *bad_pix_mask = NULL, 00300 *bad_pix_mask_window = NULL; 00301 00302 cpl_frame *frame = NULL; 00303 00304 int ret_val = 0, 00305 nr_devices = 0, 00306 i = 0, 00307 cmax = 0, 00308 cmin = 0, 00309 citer = 0, 00310 nx = 0, 00311 ny = 0, 00312 nx_orig = 0, 00313 ny_orig = 0, 00314 nz = 0, 00315 ndit = 0, 00316 file_extension = FALSE; 00317 00318 double cpos_rej = 0.0, 00319 cneg_rej = 0.0, 00320 exptime = 0.0, 00321 gain = 0.0, 00322 pos_bad_pix_rej = 0.0, 00323 neg_bad_pix_rej = 0.0, 00324 qc_dark = 0.0, 00325 qc_dark_median = 0.0, 00326 qc_readnoise = 0.0, 00327 qc_readnoise_median = 0.0, 00328 qc_bad_pix_num = 0.0; 00329 00330 const char *cmethod = NULL, 00331 *my_method = NULL; 00332 00333 char *filename = NULL, 00334 *filename_bad = NULL, 00335 *extname = NULL; 00336 00337 cpl_propertylist *main_header = NULL, 00338 *sub_header = NULL; 00339 00340 main_fits_desc desc1, desc2; 00341 00342 char do_mode[256]; 00343 00344 KMO_TRY 00345 { 00346 kmo_init_fits_desc(&desc1); 00347 kmo_init_fits_desc(&desc2); 00348 00349 // --- check inputs --- 00350 KMO_TRY_ASSURE((parlist != NULL) && 00351 (frameset != NULL), 00352 CPL_ERROR_NULL_INPUT, 00353 "Not all input data is provided!"); 00354 00355 if (cpl_frameset_count_tags(frameset, DARK) < 3) { 00356 cpl_msg_warning(cpl_func, "It is recommended to provide at least " 00357 "3 DARK frames!"); 00358 } 00359 00360 if (cpl_frameset_count_tags(frameset, DARK) >= 1) { 00361 strcpy(do_mode, DARK); 00362 } else { 00363 strcpy(do_mode, "0"); 00364 } 00365 00366 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_dark") == 1, 00367 CPL_ERROR_ILLEGAL_INPUT, 00368 "Cannot identify RAW and CALIB frames!"); 00369 00370 // --- get parameters --- 00371 cpl_msg_info("", "--- Parameter setup for kmo_dark ----------"); 00372 00373 pos_bad_pix_rej = kmo_dfs_get_parameter_double(parlist, 00374 "kmos.kmo_dark.pos_bad_pix_rej"); 00375 KMO_TRY_CHECK_ERROR_STATE(); 00376 KMO_TRY_EXIT_IF_ERROR( 00377 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_dark.pos_bad_pix_rej")); 00378 00379 neg_bad_pix_rej = kmo_dfs_get_parameter_double(parlist, 00380 "kmos.kmo_dark.neg_bad_pix_rej"); 00381 KMO_TRY_CHECK_ERROR_STATE(); 00382 KMO_TRY_EXIT_IF_ERROR( 00383 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_dark.neg_bad_pix_rej")); 00384 00385 file_extension = kmo_dfs_get_parameter_bool(parlist, 00386 "kmos.kmo_dark.file_extension"); 00387 KMO_TRY_CHECK_ERROR_STATE(); 00388 KMO_TRY_EXIT_IF_ERROR( 00389 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_dark.file_extension")); 00390 00391 KMO_TRY_ASSURE((file_extension == TRUE) || 00392 (file_extension == FALSE), 00393 CPL_ERROR_ILLEGAL_INPUT, 00394 "extension must be TRUE or FALSE!"); 00395 00396 KMO_TRY_EXIT_IF_ERROR( 00397 kmo_combine_pars_load(parlist, 00398 "kmos.kmo_dark", 00399 &cmethod, 00400 &cpos_rej, 00401 &cneg_rej, 00402 &citer, 00403 &cmin, 00404 &cmax, 00405 FALSE)); 00406 00407 cpl_msg_info("", "-------------------------------------------"); 00408 cpl_msg_info("", "Detected instrument setup:"); 00409 cpl_msg_info("", " not checked here"); 00410 cpl_msg_info("", "-------------------------------------------"); 00411 cpl_msg_info("", "IFU status before processing:"); 00412 cpl_msg_info("", " not checked here"); 00413 cpl_msg_info("", "-------------------------------------------"); 00414 00415 KMO_TRY_EXIT_IF_NULL( 00416 frame = kmo_dfs_get_frame(frameset, do_mode)); 00417 00418 i = 0; 00419 while (frame != NULL) { 00420 main_header = kmclipm_propertylist_load( 00421 cpl_frame_get_filename(frame), 0); 00422 00423 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00424 cpl_msg_error(cpl_func, "File '%s' not found", 00425 cpl_frame_get_filename(frame)); 00426 KMO_TRY_CHECK_ERROR_STATE(); 00427 } 00428 00429 if (i == 0) { 00430 exptime = cpl_propertylist_get_double(main_header, EXPTIME); 00431 00432 KMO_TRY_CHECK_ERROR_STATE("EXPTIME keyword in main header " 00433 "missing!"); 00434 00435 ndit = cpl_propertylist_get_int(main_header, NDIT); 00436 00437 KMO_TRY_CHECK_ERROR_STATE("NDIT keyword in main header " 00438 "missing!"); 00439 00440 if (file_extension) { 00441 // delete trailing zeros (if zero right after decimal point, delete point as well) 00442 char *exptimeStr = cpl_sprintf("%g", exptime); 00443 char *p = 0; 00444 for(p=exptimeStr; *p; ++p) { 00445 if('.' == *p) { 00446 while(*++p); 00447 while('0'==*--p) *p = '\0'; 00448 if(*p == '.') *p = '\0'; 00449 break; 00450 } 00451 } 00452 00453 filename = cpl_sprintf("%s_%s", MASTER_DARK, exptimeStr); 00454 filename_bad = cpl_sprintf("%s_%s", BADPIXEL_DARK, exptimeStr); 00455 cpl_free(exptimeStr); exptimeStr = NULL; 00456 } else { 00457 filename = cpl_sprintf("%s", MASTER_DARK); 00458 filename_bad = cpl_sprintf("%s", BADPIXEL_DARK); 00459 } 00460 00461 00462 desc1 = kmo_identify_fits_header( 00463 cpl_frame_get_filename(frame)); 00464 00465 KMO_TRY_CHECK_ERROR_STATE_MSG("First fits file doesn't seem to " 00466 "be in KMOS-format!"); 00467 00468 KMO_TRY_ASSURE(desc1.fits_type == raw_fits, 00469 CPL_ERROR_ILLEGAL_INPUT, 00470 "First input file hasn't correct data type " 00471 "(must be a raw, unprocessed file)!"); 00472 } else { 00473 00474 desc2 = kmo_identify_fits_header( 00475 cpl_frame_get_filename(frame)); 00476 KMO_TRY_CHECK_ERROR_STATE_MSG("Fits file doesn't seem to be " 00477 "in KMOS-format!"); 00478 00479 KMO_TRY_ASSURE(desc2.fits_type == raw_fits, 00480 CPL_ERROR_ILLEGAL_INPUT, 00481 "An input file hasn't correct data type " 00482 "(must be a raw, unprocessed file)!"); 00483 00484 kmo_free_fits_desc(&desc2); 00485 } 00486 00487 // check if all lamps are off (flat and arc lamp) 00488 KMO_TRY_ASSURE(((kmo_check_lamp(main_header, INS_LAMP1_ST) == FALSE) && 00489 (kmo_check_lamp(main_header, INS_LAMP2_ST) == FALSE) && 00490 (kmo_check_lamp(main_header, INS_LAMP3_ST) == FALSE) && 00491 (kmo_check_lamp(main_header, INS_LAMP4_ST) == FALSE)) || 00492 (((kmo_check_lamp(main_header, INS_LAMP1_ST) == TRUE) || 00493 (kmo_check_lamp(main_header, INS_LAMP2_ST) == TRUE) || 00494 (kmo_check_lamp(main_header, INS_LAMP3_ST) == TRUE) || 00495 (kmo_check_lamp(main_header, INS_LAMP4_ST) == TRUE)) && 00496 (strcmp(cpl_propertylist_get_string(main_header, "ESO INS FILT1 ID"), "Block") == 0) && 00497 (strcmp(cpl_propertylist_get_string(main_header, "ESO INS FILT2 ID"), "Block") == 0) && 00498 (strcmp(cpl_propertylist_get_string(main_header, "ESO INS FILT3 ID"), "Block") == 0)), 00499 CPL_ERROR_ILLEGAL_INPUT, 00500 "All lamps must be switched off for DARK frames!"); 00501 00502 // check if EXPTIME and NDIT are the same for all frames 00503 if (cpl_propertylist_get_double(main_header, EXPTIME) != exptime) { 00504 cpl_msg_warning(cpl_func, 00505 "EXPTIME isn't the same for all " 00506 "frames: (is %g and %g). Proceeding anyway...", 00507 cpl_propertylist_get_double(main_header, 00508 EXPTIME), 00509 exptime); 00510 } 00511 00512 if (cpl_propertylist_get_int(main_header, NDIT) != ndit) { 00513 cpl_msg_warning(cpl_func, 00514 "NDIT isn't the same for all " 00515 "frames: (is %d and %d). Proceeding anyway...", 00516 cpl_propertylist_get_int(main_header, NDIT), 00517 ndit); 00518 } 00519 00520 // get next DARK frame 00521 frame = kmo_dfs_get_frame(frameset, NULL); 00522 KMO_TRY_CHECK_ERROR_STATE(); 00523 00524 cpl_propertylist_delete(main_header); main_header = NULL; 00525 i++; 00526 } 00527 00528 // --- load, update & save primary header --- 00529 KMO_TRY_EXIT_IF_NULL( 00530 frame = kmo_dfs_get_frame(frameset, do_mode)); 00531 00532 KMO_TRY_EXIT_IF_ERROR( 00533 kmo_dfs_save_main_header(frameset, filename, "", frame, 00534 NULL, parlist, cpl_func)); 00535 00536 KMO_TRY_EXIT_IF_ERROR( 00537 kmo_dfs_save_main_header(frameset, filename_bad, "", frame, 00538 NULL, parlist, cpl_func)); 00539 00540 // --- load data --- 00541 nr_devices = desc1.nr_ext; 00542 00543 my_method = cmethod; 00544 if ((cpl_frameset_count_tags(frameset, DARK) == 1) || 00545 (cpl_frameset_count_tags(frameset, COMMANDLINE) == 1)) { 00546 cpl_msg_warning(cpl_func, "cmethod is changed to 'average' " 00547 "since there is only one input frame!"); 00548 00549 my_method = "average"; 00550 } 00551 00552 // get size of input frame 00553 KMO_TRY_EXIT_IF_NULL( 00554 img_in_window = kmo_dfs_load_image(frameset, do_mode, 1, FALSE, FALSE, NULL)); 00555 nx_orig = cpl_image_get_size_x(img_in_window); 00556 ny_orig = cpl_image_get_size_y(img_in_window); 00557 cpl_image_delete(img_in_window); img_in_window = NULL; 00558 00559 KMO_TRY_ASSURE((nx_orig > 2*KMOS_BADPIX_BORDER) && 00560 (ny_orig > 2*KMOS_BADPIX_BORDER), 00561 CPL_ERROR_ILLEGAL_INPUT, 00562 "Input frames must have a height and width of at " 00563 "least 9 pixels!"); 00564 00565 // --- loop through all detectors --- 00566 for (i = 1; i <= nr_devices; i++) { 00567 cpl_msg_info("","Processing detector No. %d", i); 00568 00569 KMO_TRY_EXIT_IF_NULL( 00570 detector_in_window = cpl_imagelist_new()); 00571 00572 KMO_TRY_EXIT_IF_NULL( 00573 sub_header = kmo_dfs_load_sub_header(frameset, do_mode, 00574 i, FALSE)); 00575 00576 // load data of device i of all DARK frames into an imagelist 00577 KMO_TRY_EXIT_IF_NULL( 00578 img_in_window = kmo_dfs_load_image_window( 00579 frameset, do_mode, i, FALSE, 00580 KMOS_BADPIX_BORDER+1, 00581 KMOS_BADPIX_BORDER+1, 00582 nx_orig-KMOS_BADPIX_BORDER, 00583 ny_orig-KMOS_BADPIX_BORDER, 00584 FALSE, NULL)); 00585 00586 nx = cpl_image_get_size_x(img_in_window); 00587 ny = cpl_image_get_size_y(img_in_window); 00588 00589 nz = 0; 00590 while (img_in_window != NULL) { 00591 cpl_imagelist_set(detector_in_window, img_in_window, nz); 00592 KMO_TRY_CHECK_ERROR_STATE(); 00593 00594 // load same extension of next DARK frame 00595 img_in_window = kmo_dfs_load_image_window( 00596 frameset, NULL, i, FALSE, 00597 KMOS_BADPIX_BORDER+1, 00598 KMOS_BADPIX_BORDER+1, 00599 nx_orig-KMOS_BADPIX_BORDER, 00600 ny_orig-KMOS_BADPIX_BORDER, 00601 FALSE, NULL); 00602 KMO_TRY_CHECK_ERROR_STATE(); 00603 00604 if (img_in_window != NULL) { 00605 KMO_TRY_ASSURE((nx == cpl_image_get_size_x(img_in_window)) && 00606 (ny == cpl_image_get_size_y(img_in_window)), 00607 CPL_ERROR_ILLEGAL_INPUT, 00608 "Not all input frames have the " 00609 "same dimensions!"); 00610 } 00611 nz++; 00612 } 00613 00614 // combine imagelist (data only) and create noise 00615 KMO_TRY_EXIT_IF_ERROR( 00616 kmclipm_combine_frames(detector_in_window, 00617 NULL, 00618 NULL, 00619 my_method, 00620 cpos_rej, 00621 cneg_rej, 00622 citer, 00623 cmax, 00624 cmin, 00625 &combined_data_window, 00626 &combined_noise_window, 00627 -1.0)); 00628 00629 if (kmclipm_omit_warning_one_slice > 10) { 00630 // AA: commmented this out: Too unclear for the user, no benefit to know about this number 00631 // cpl_msg_warning(cpl_func, "Previous warning (number of " 00632 // "identified slices) occured %d times.", 00633 // kmclipm_omit_warning_one_slice); 00634 kmclipm_omit_warning_one_slice = FALSE; 00635 } 00636 00637 // calculate preliminary mean and stdev to create the bad pixel mask 00638 qc_dark = cpl_image_get_mean(combined_data_window); 00639 KMO_TRY_CHECK_ERROR_STATE(); 00640 00641 if (nz > 2) { 00642 qc_readnoise = cpl_image_get_mean(combined_noise_window); 00643 KMO_TRY_CHECK_ERROR_STATE(); 00644 00645 KMO_TRY_ASSURE(qc_readnoise != 0.0, 00646 CPL_ERROR_ILLEGAL_INPUT, 00647 "All frames of detector %i are exactly " 00648 "the same!", i); 00649 } else if (nz == 2) { 00650 qc_readnoise = cpl_image_get_stdev(combined_noise_window); 00651 KMO_TRY_CHECK_ERROR_STATE(); 00652 00653 KMO_TRY_ASSURE(qc_readnoise != 0.0, 00654 CPL_ERROR_ILLEGAL_INPUT, 00655 "All frames of detector %i are exactly " 00656 "the same!", i); 00657 } else if (nz == 1) { 00658 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00659 KMO_TRY_CHECK_ERROR_STATE(); 00660 00661 KMO_TRY_ASSURE(qc_readnoise != 0.0, 00662 CPL_ERROR_ILLEGAL_INPUT, 00663 "The detector frame %d seems to be uniform!", i); 00664 } else { 00665 KMO_TRY_ASSURE(1 == 0, 00666 CPL_ERROR_ILLEGAL_INPUT, 00667 "detector frame must have at least one frame!"); 00668 } 00669 00670 // create bad-pixel-mask 00671 qc_bad_pix_num = kmo_create_bad_pix_dark(combined_data_window, 00672 qc_dark, 00673 qc_readnoise, 00674 pos_bad_pix_rej, 00675 neg_bad_pix_rej, 00676 &bad_pix_mask_window); 00677 KMO_TRY_CHECK_ERROR_STATE(); 00678 00679 KMO_TRY_EXIT_IF_ERROR( 00680 kmclipm_update_property_int(sub_header, 00681 QC_NR_BAD_PIX, 00682 qc_bad_pix_num, 00683 "[] nr. of bad pixels")); 00684 00685 // 00686 // calculate QC.DARK, QC.READNOISE, QC.DARK.MEDIAN, 00687 // QC.READNOISE.MEDIAN, QC.DARKCUR 00688 00689 // badpixels from combined_data_window are already rejected in 00690 // kmo_create_bad_pix_dark() 00691 KMO_TRY_EXIT_IF_ERROR( 00692 kmo_image_reject_from_mask(combined_noise_window, 00693 bad_pix_mask_window)); 00694 00695 qc_dark = cpl_image_get_mean(combined_data_window); 00696 KMO_TRY_CHECK_ERROR_STATE(); 00697 00698 // calculate mean and stddev of combined frames (with rejection) 00699 if (nz > 2) { 00700 qc_readnoise = cpl_image_get_mean(combined_noise_window) * sqrt(nz); 00701 } else if (nz == 2) { 00702 qc_readnoise = 00703 cpl_image_get_stdev(combined_noise_window) * sqrt(2.0); 00704 } else if (nz == 1) { 00705 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00706 } else { 00707 KMO_TRY_ASSURE(1 == 0, 00708 CPL_ERROR_ILLEGAL_INPUT, 00709 "detector frame must have at least one frame!"); 00710 } 00711 KMO_TRY_CHECK_ERROR_STATE(); 00712 00713 qc_dark_median = cpl_image_get_median(combined_data_window); 00714 KMO_TRY_CHECK_ERROR_STATE(); 00715 00716 if (nz > 2) { 00717 qc_readnoise_median = 00718 cpl_image_get_median(combined_noise_window) * sqrt(nz); 00719 } else if (nz == 2) { 00720 qc_readnoise_median = 00721 kmo_image_get_stdev_median(combined_noise_window) * 00722 sqrt(2.0); 00723 } else if (nz == 1) { 00724 qc_readnoise_median = 00725 kmo_image_get_stdev_median(combined_data_window); 00726 } else { 00727 KMO_TRY_ASSURE(1 == 0, 00728 CPL_ERROR_ILLEGAL_INPUT, 00729 "detector frame must have at least one frame!"); 00730 } 00731 KMO_TRY_CHECK_ERROR_STATE(); 00732 00733 KMO_TRY_EXIT_IF_ERROR( 00734 kmclipm_update_property_double(sub_header, 00735 QC_DARK, 00736 qc_dark, 00737 "[adu] mean of master dark")); 00738 KMO_TRY_EXIT_IF_ERROR( 00739 kmclipm_update_property_double(sub_header, 00740 QC_READNOISE, 00741 qc_readnoise, 00742 "[adu] mean noise of master dark")); 00743 KMO_TRY_EXIT_IF_ERROR( 00744 kmclipm_update_property_double(sub_header, 00745 QC_DARK_MEDIAN, 00746 qc_dark_median, 00747 "[adu] median of master dark")); 00748 KMO_TRY_EXIT_IF_ERROR( 00749 kmclipm_update_property_double(sub_header, 00750 QC_READNOISE_MEDIAN, 00751 qc_readnoise_median, 00752 "[adu] median noise of master dark")); 00753 00754 // load gain 00755 gain = kmo_dfs_get_property_double(sub_header, GAIN); 00756 KMO_TRY_CHECK_ERROR_STATE_MSG( 00757 "GAIN-keyword in fits-header is missing!"); 00758 00759 KMO_TRY_EXIT_IF_ERROR( 00760 kmclipm_update_property_double(sub_header, 00761 QC_DARK_CURRENT, 00762 qc_dark / exptime / gain, 00763 "[e-/s] dark current")); 00764 00765 // save dark frame 00766 KMO_TRY_EXIT_IF_NULL( 00767 extname = kmo_extname_creator(detector_frame, i, EXT_DATA)); 00768 KMO_TRY_EXIT_IF_ERROR( 00769 kmclipm_update_property_string(sub_header, EXTNAME, 00770 extname, 00771 "FITS extension name")); 00772 cpl_free(extname); extname = NULL; 00773 00774 KMO_TRY_EXIT_IF_NULL( 00775 combined_data = kmo_add_bad_pix_border(combined_data_window, 00776 TRUE)); 00777 00778 KMO_TRY_EXIT_IF_ERROR( 00779 kmo_dfs_save_image(combined_data, filename, "", sub_header, 0./0.)); 00780 00781 // save noise frame 00782 KMO_TRY_EXIT_IF_NULL( 00783 extname = kmo_extname_creator(detector_frame, i, EXT_NOISE)); 00784 KMO_TRY_EXIT_IF_ERROR( 00785 kmclipm_update_property_string(sub_header, EXTNAME, 00786 extname, 00787 "FITS extension name")); 00788 cpl_free(extname); extname = NULL; 00789 00790 KMO_TRY_EXIT_IF_NULL( 00791 combined_noise = kmo_add_bad_pix_border(combined_noise_window, 00792 TRUE)); 00793 00794 KMO_TRY_EXIT_IF_ERROR( 00795 kmo_dfs_save_image(combined_noise, filename, "", sub_header, 0./0.)); 00796 00797 // save bad_pix frame 00798 KMO_TRY_EXIT_IF_NULL( 00799 extname = kmo_extname_creator(detector_frame, i, EXT_BADPIX)); 00800 KMO_TRY_EXIT_IF_ERROR( 00801 kmclipm_update_property_string(sub_header, EXTNAME, 00802 extname, 00803 "FITS extension name")); 00804 cpl_free(extname); extname = NULL; 00805 00806 KMO_TRY_EXIT_IF_NULL( 00807 bad_pix_mask = kmo_add_bad_pix_border(bad_pix_mask_window, 00808 FALSE)); 00809 00810 KMO_TRY_EXIT_IF_ERROR( 00811 kmo_dfs_save_image(bad_pix_mask, filename_bad, "", sub_header, 0.)); 00812 00813 // free memory 00814 cpl_propertylist_delete(sub_header); sub_header = NULL; 00815 cpl_imagelist_delete(detector_in_window); detector_in_window = NULL; 00816 cpl_image_delete(combined_data); combined_data = NULL; 00817 cpl_image_delete(combined_data_window); combined_data_window = NULL; 00818 cpl_image_delete(combined_noise); combined_noise = NULL; 00819 cpl_image_delete(combined_noise_window); combined_noise_window = NULL; 00820 cpl_image_delete(bad_pix_mask); bad_pix_mask = NULL; 00821 cpl_image_delete(bad_pix_mask_window); bad_pix_mask_window = NULL; 00822 } // for i = [1, nr_devices] 00823 00824 cpl_msg_info("", "-------------------------------------------"); 00825 cpl_msg_info("", "IFU status after processing:"); 00826 cpl_msg_info("", " not checked here"); 00827 cpl_msg_info("", "-------------------------------------------"); 00828 } 00829 KMO_CATCH 00830 { 00831 KMO_CATCH_MSG(); 00832 00833 // if (desc2.sub_desc != NULL) { 00834 kmo_free_fits_desc(&desc2); 00835 // } 00836 00837 ret_val = -1; 00838 } 00839 00840 kmo_free_fits_desc(&desc1); 00841 cpl_free(filename); filename = NULL; 00842 cpl_free(filename_bad); filename_bad = NULL; 00843 cpl_propertylist_delete(main_header); main_header = NULL; 00844 cpl_propertylist_delete(sub_header); sub_header = NULL; 00845 cpl_imagelist_delete(detector_in_window); detector_in_window = NULL; 00846 cpl_image_delete(combined_data); combined_data = NULL; 00847 cpl_image_delete(combined_data_window); combined_data_window = NULL; 00848 cpl_image_delete(combined_noise); combined_noise = NULL; 00849 cpl_image_delete(combined_noise_window); combined_noise_window = NULL; 00850 cpl_image_delete(bad_pix_mask); bad_pix_mask = NULL; 00851 cpl_image_delete(bad_pix_mask_window); bad_pix_mask_window = NULL; 00852 00853 return ret_val; 00854 } 00855
1.7.6.1