|
KMOS Pipeline Reference Manual
1.0.7
|
00001 /* $Id: kmo_dark.c,v 1.17 2013/01/20 04:00:41 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/01/20 04:00:41 $ 00024 * $Revision: 1.17 $ 00025 * $Name: HEAD $ 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 "ADVANCED PARAMETERS\n" 00104 "-------------------\n" 00105 "--cpos_rej\n" 00106 "--cneg_rej\n" 00107 "--citer\n" 00108 "see --cmethod='ksigma'\n" 00109 "\n" 00110 "--cmax\n" 00111 "--cmin\n" 00112 "see --cmethod='min_max'\n" 00113 "\n" 00114 "-------------------------------------------------------------------------------\n" 00115 "Input files:\n" 00116 "\n" 00117 " DO KMOS \n" 00118 " category Type Explanation Required #Frames\n" 00119 " -------- ----- ----------- -------- -------\n" 00120 " DARK RAW Dark exposures Y 1-n \n" 00121 " (at least 3 frames recommended) \n" 00122 "\n" 00123 "Output files:\n" 00124 "\n" 00125 " DO KMOS\n" 00126 " category Type Explanation\n" 00127 " -------- ----- -----------\n" 00128 " MASTER_DARK F2D Calculated master dark frames\n" 00129 "\n" 00130 " BADPIXEL_DARK B2D Associated badpixel frames\n" 00131 "\n" 00132 "-------------------------------------------------------------------------------" 00133 "\n"; 00134 00135 /*----------------------------------------------------------------------------- 00136 * Functions code 00137 *----------------------------------------------------------------------------*/ 00138 00155 int cpl_plugin_get_info(cpl_pluginlist *list) 00156 { 00157 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe); 00158 cpl_plugin *plugin = &recipe->interface; 00159 00160 cpl_plugin_init(plugin, 00161 CPL_PLUGIN_API, 00162 KMOS_BINARY_VERSION, 00163 CPL_PLUGIN_TYPE_RECIPE, 00164 "kmo_dark", 00165 "Create master dark frame & bad pixel mask", 00166 kmo_dark_description, 00167 "Alex Agudo Berbel", 00168 "agudo@mpe.mpg.de", 00169 kmos_get_license(), 00170 kmo_dark_create, 00171 kmo_dark_exec, 00172 kmo_dark_destroy); 00173 00174 cpl_pluginlist_append(list, plugin); 00175 00176 return 0; 00177 } 00178 00186 static int kmo_dark_create(cpl_plugin *plugin) 00187 { 00188 cpl_recipe *recipe; 00189 cpl_parameter *p; 00190 00191 /* Check that the plugin is part of a valid recipe */ 00192 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00193 recipe = (cpl_recipe *)plugin; 00194 else 00195 return -1; 00196 00197 /* Create the parameters list in the cpl_recipe object */ 00198 recipe->parameters = cpl_parameterlist_new(); 00199 00200 /* Fill the parameters list */ 00201 00202 /* --pos_bad_pix_rej */ 00203 p = cpl_parameter_new_value("kmos.kmo_dark.pos_bad_pix_rej", 00204 CPL_TYPE_DOUBLE, 00205 "The positive rejection threshold for " 00206 "bad pixels", 00207 "kmos.kmo_dark", 00208 50.0); 00209 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pos_bad_pix_rej"); 00210 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00211 cpl_parameterlist_append(recipe->parameters, p); 00212 00213 /* --neg_bad_pix_rej */ 00214 p = cpl_parameter_new_value("kmos.kmo_dark.neg_bad_pix_rej", 00215 CPL_TYPE_DOUBLE, 00216 "The negative rejection threshold for " 00217 "bad pixels", 00218 "kmos.kmo_dark", 00219 50.0); 00220 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "neg_bad_pix_rej"); 00221 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00222 cpl_parameterlist_append(recipe->parameters, p); 00223 00224 return kmo_combine_pars_create(recipe->parameters, 00225 "kmos.kmo_dark", 00226 DEF_REJ_METHOD, 00227 FALSE); 00228 } 00229 00235 static int kmo_dark_exec(cpl_plugin *plugin) 00236 { 00237 cpl_recipe *recipe; 00238 00239 /* Get the recipe out of the plugin */ 00240 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00241 recipe = (cpl_recipe *)plugin; 00242 else return -1; 00243 00244 return kmo_dark(recipe->parameters, recipe->frames); 00245 } 00246 00252 static int kmo_dark_destroy(cpl_plugin *plugin) 00253 { 00254 cpl_recipe *recipe; 00255 00256 /* Get the recipe out of the plugin */ 00257 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00258 recipe = (cpl_recipe *)plugin; 00259 else return -1 ; 00260 00261 cpl_parameterlist_delete(recipe->parameters); 00262 return 0 ; 00263 } 00264 00275 static int kmo_dark(cpl_parameterlist *parlist, cpl_frameset *frameset) 00276 { 00277 cpl_imagelist *detector_in_window = NULL; 00278 00279 cpl_image *img_in_window = NULL, 00280 *combined_data = NULL, 00281 *combined_data_window = NULL, 00282 *combined_noise = NULL, 00283 *combined_noise_window = NULL, 00284 *bad_pix_mask = NULL, 00285 *bad_pix_mask_window = NULL; 00286 00287 cpl_frame *frame = NULL; 00288 00289 int ret_val = 0, 00290 nr_devices = 0, 00291 i = 0, 00292 cmax = 0, 00293 cmin = 0, 00294 citer = 0, 00295 nx = 0, 00296 ny = 0, 00297 nx_orig = 0, 00298 ny_orig = 0, 00299 nz = 0, 00300 ndit = 0; 00301 00302 double cpos_rej = 0.0, 00303 cneg_rej = 0.0, 00304 exptime = 0.0, 00305 gain = 0.0, 00306 pos_bad_pix_rej = 0.0, 00307 neg_bad_pix_rej = 0.0, 00308 qc_dark = 0.0, 00309 qc_dark_median = 0.0, 00310 qc_readnoise = 0.0, 00311 qc_readnoise_median = 0.0, 00312 qc_bad_pix_num = 0.0; 00313 00314 const char *cmethod = NULL, 00315 *my_method = NULL; 00316 00317 char filename[256], 00318 filename_bad[256], 00319 *extname = NULL; 00320 00321 cpl_propertylist *main_header = NULL, 00322 *sub_header = NULL; 00323 00324 main_fits_desc desc1, desc2; 00325 00326 char do_mode[256]; 00327 00328 KMO_TRY 00329 { 00330 kmo_init_fits_desc(&desc1); 00331 kmo_init_fits_desc(&desc2); 00332 00333 // --- check inputs --- 00334 KMO_TRY_ASSURE((parlist != NULL) && 00335 (frameset != NULL), 00336 CPL_ERROR_NULL_INPUT, 00337 "Not all input data is provided!"); 00338 00339 if (cpl_frameset_count_tags(frameset, DARK) < 3) { 00340 cpl_msg_warning(cpl_func, "It is recommended to provide at least " 00341 "3 DARK frames!"); 00342 } 00343 00344 if (cpl_frameset_count_tags(frameset, DARK) >= 1) { 00345 strcpy(do_mode, DARK); 00346 } else { 00347 strcpy(do_mode, "0"); 00348 } 00349 00350 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset, "kmo_dark") == 1, 00351 CPL_ERROR_ILLEGAL_INPUT, 00352 "Cannot identify RAW and CALIB frames!"); 00353 00354 // --- get parameters --- 00355 cpl_msg_info("", "--- Parameter setup for kmo_dark ----------"); 00356 00357 pos_bad_pix_rej = kmo_dfs_get_parameter_double(parlist, 00358 "kmos.kmo_dark.pos_bad_pix_rej"); 00359 KMO_TRY_CHECK_ERROR_STATE(); 00360 KMO_TRY_EXIT_IF_ERROR( 00361 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_dark.pos_bad_pix_rej")); 00362 00363 neg_bad_pix_rej = kmo_dfs_get_parameter_double(parlist, 00364 "kmos.kmo_dark.neg_bad_pix_rej"); 00365 KMO_TRY_CHECK_ERROR_STATE(); 00366 KMO_TRY_EXIT_IF_ERROR( 00367 kmo_dfs_print_parameter_help(parlist, "kmos.kmo_dark.neg_bad_pix_rej")); 00368 00369 KMO_TRY_EXIT_IF_ERROR( 00370 kmo_combine_pars_load(parlist, 00371 "kmos.kmo_dark", 00372 &cmethod, 00373 &cpos_rej, 00374 &cneg_rej, 00375 &citer, 00376 &cmin, 00377 &cmax, 00378 FALSE)); 00379 00380 cpl_msg_info("", "-------------------------------------------"); 00381 cpl_msg_info("", "Detected instrument setup:"); 00382 cpl_msg_info("", " not checked here"); 00383 cpl_msg_info("", "-------------------------------------------"); 00384 cpl_msg_info("", "IFU status before processing:"); 00385 cpl_msg_info("", " not checked here"); 00386 cpl_msg_info("", "-------------------------------------------"); 00387 00388 KMO_TRY_EXIT_IF_NULL( 00389 frame = kmo_dfs_get_frame(frameset, do_mode)); 00390 00391 i = 0; 00392 while (frame != NULL) { 00393 main_header = kmclipm_propertylist_load( 00394 cpl_frame_get_filename(frame), 0); 00395 00396 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00397 cpl_msg_error(cpl_func, "File '%s' not found", 00398 cpl_frame_get_filename(frame)); 00399 KMO_TRY_CHECK_ERROR_STATE(); 00400 } 00401 00402 if (i == 0) { 00403 exptime = cpl_propertylist_get_double(main_header, EXPTIME); 00404 00405 KMO_TRY_CHECK_ERROR_STATE("EXPTIME keyword in main header " 00406 "missing!"); 00407 00408 ndit = cpl_propertylist_get_int(main_header, NDIT); 00409 00410 KMO_TRY_CHECK_ERROR_STATE("NDIT keyword in main header " 00411 "missing!"); 00412 00413 strcpy(filename, MASTER_DARK); 00414 strcpy(filename_bad, BADPIXEL_DARK); 00415 00416 desc1 = kmo_identify_fits_header( 00417 cpl_frame_get_filename(frame)); 00418 00419 KMO_TRY_CHECK_ERROR_STATE_MSG("First fits file doesn't seem to " 00420 "be in KMOS-format!"); 00421 00422 KMO_TRY_ASSURE(desc1.fits_type == raw_fits, 00423 CPL_ERROR_ILLEGAL_INPUT, 00424 "First input file hasn't correct data type " 00425 "(must be a raw, unprocessed file)!"); 00426 } else { 00427 00428 desc2 = kmo_identify_fits_header( 00429 cpl_frame_get_filename(frame)); 00430 KMO_TRY_CHECK_ERROR_STATE_MSG("Fits file doesn't seem to be " 00431 "in KMOS-format!"); 00432 00433 KMO_TRY_ASSURE(desc2.fits_type == raw_fits, 00434 CPL_ERROR_ILLEGAL_INPUT, 00435 "An input file hasn't correct data type " 00436 "(must be a raw, unprocessed file)!"); 00437 00438 kmo_free_fits_desc(&desc2); 00439 } 00440 00441 // check if all lamps are off (flat and arc lamp) 00442 KMO_TRY_ASSURE(((kmo_check_lamp(main_header, INS_LAMP1_ST) == FALSE) && 00443 (kmo_check_lamp(main_header, INS_LAMP2_ST) == FALSE) && 00444 (kmo_check_lamp(main_header, INS_LAMP3_ST) == FALSE) && 00445 (kmo_check_lamp(main_header, INS_LAMP4_ST) == FALSE)) || 00446 (((kmo_check_lamp(main_header, INS_LAMP1_ST) == TRUE) || 00447 (kmo_check_lamp(main_header, INS_LAMP2_ST) == TRUE) || 00448 (kmo_check_lamp(main_header, INS_LAMP3_ST) == TRUE) || 00449 (kmo_check_lamp(main_header, INS_LAMP4_ST) == TRUE)) && 00450 (strcmp(cpl_propertylist_get_string(main_header, "ESO INS FILT1 ID"), "Block") == 0) && 00451 (strcmp(cpl_propertylist_get_string(main_header, "ESO INS FILT2 ID"), "Block") == 0) && 00452 (strcmp(cpl_propertylist_get_string(main_header, "ESO INS FILT3 ID"), "Block") == 0)), 00453 CPL_ERROR_ILLEGAL_INPUT, 00454 "All lamps must be switched off for DARK frames!"); 00455 00456 // check if EXPTIME and NDIT are the same for all frames 00457 if (cpl_propertylist_get_double(main_header, EXPTIME) != exptime) { 00458 cpl_msg_warning(cpl_func, 00459 "EXPTIME isn't the same for all " 00460 "frames: (is %g and %g). Proceeding anyway...", 00461 cpl_propertylist_get_double(main_header, 00462 EXPTIME), 00463 exptime); 00464 } 00465 00466 if (cpl_propertylist_get_int(main_header, NDIT) != ndit) { 00467 cpl_msg_warning(cpl_func, 00468 "NDIT isn't the same for all " 00469 "frames: (is %d and %d). Proceeding anyway...", 00470 cpl_propertylist_get_int(main_header, NDIT), 00471 ndit); 00472 } 00473 00474 // get next DARK frame 00475 frame = kmo_dfs_get_frame(frameset, NULL); 00476 KMO_TRY_CHECK_ERROR_STATE(); 00477 00478 cpl_propertylist_delete(main_header); main_header = NULL; 00479 i++; 00480 } 00481 00482 // --- load, update & save primary header --- 00483 KMO_TRY_EXIT_IF_NULL( 00484 frame = kmo_dfs_get_frame(frameset, do_mode)); 00485 00486 KMO_TRY_EXIT_IF_ERROR( 00487 kmo_dfs_save_main_header(frameset, filename, "", frame, 00488 NULL, parlist, cpl_func)); 00489 00490 KMO_TRY_EXIT_IF_ERROR( 00491 kmo_dfs_save_main_header(frameset, filename_bad, "", frame, 00492 NULL, parlist, cpl_func)); 00493 00494 // --- load data --- 00495 nr_devices = desc1.nr_ext; 00496 00497 my_method = cmethod; 00498 if ((cpl_frameset_count_tags(frameset, DARK) == 1) || 00499 (cpl_frameset_count_tags(frameset, COMMANDLINE) == 1)) { 00500 cpl_msg_warning(cpl_func, "cmethod is changed to 'average' " 00501 "since there is only one input frame!"); 00502 00503 my_method = "average"; 00504 } 00505 00506 // get size of input frame 00507 KMO_TRY_EXIT_IF_NULL( 00508 img_in_window = kmo_dfs_load_image(frameset, do_mode, 1, FALSE, FALSE, NULL)); 00509 nx_orig = cpl_image_get_size_x(img_in_window); 00510 ny_orig = cpl_image_get_size_y(img_in_window); 00511 cpl_image_delete(img_in_window); img_in_window = NULL; 00512 00513 KMO_TRY_ASSURE((nx_orig > 2*KMOS_BADPIX_BORDER) && 00514 (ny_orig > 2*KMOS_BADPIX_BORDER), 00515 CPL_ERROR_ILLEGAL_INPUT, 00516 "Input frames must have a height and width of at " 00517 "least 9 pixels!"); 00518 00519 // --- loop through all detectors --- 00520 for (i = 1; i <= nr_devices; i++) { 00521 cpl_msg_info("","Processing detector No. %d", i); 00522 00523 KMO_TRY_EXIT_IF_NULL( 00524 detector_in_window = cpl_imagelist_new()); 00525 00526 KMO_TRY_EXIT_IF_NULL( 00527 sub_header = kmo_dfs_load_sub_header(frameset, do_mode, 00528 i, FALSE)); 00529 00530 // load data of device i of all DARK frames into an imagelist 00531 KMO_TRY_EXIT_IF_NULL( 00532 img_in_window = kmo_dfs_load_image_window( 00533 frameset, do_mode, i, FALSE, 00534 KMOS_BADPIX_BORDER+1, 00535 KMOS_BADPIX_BORDER+1, 00536 nx_orig-KMOS_BADPIX_BORDER, 00537 ny_orig-KMOS_BADPIX_BORDER, 00538 FALSE, NULL)); 00539 00540 nx = cpl_image_get_size_x(img_in_window); 00541 ny = cpl_image_get_size_y(img_in_window); 00542 00543 nz = 0; 00544 while (img_in_window != NULL) { 00545 cpl_imagelist_set(detector_in_window, img_in_window, nz); 00546 KMO_TRY_CHECK_ERROR_STATE(); 00547 00548 // load same extension of next DARK frame 00549 img_in_window = kmo_dfs_load_image_window( 00550 frameset, NULL, i, FALSE, 00551 KMOS_BADPIX_BORDER+1, 00552 KMOS_BADPIX_BORDER+1, 00553 nx_orig-KMOS_BADPIX_BORDER, 00554 ny_orig-KMOS_BADPIX_BORDER, 00555 FALSE, NULL); 00556 KMO_TRY_CHECK_ERROR_STATE(); 00557 00558 if (img_in_window != NULL) { 00559 KMO_TRY_ASSURE((nx == cpl_image_get_size_x(img_in_window)) && 00560 (ny == cpl_image_get_size_y(img_in_window)), 00561 CPL_ERROR_ILLEGAL_INPUT, 00562 "Not all input frames have the " 00563 "same dimensions!"); 00564 } 00565 nz++; 00566 } 00567 00568 // combine imagelist (data only) and create noise 00569 KMO_TRY_EXIT_IF_ERROR( 00570 kmclipm_combine_frames(detector_in_window, 00571 NULL, 00572 NULL, 00573 my_method, 00574 cpos_rej, 00575 cneg_rej, 00576 citer, 00577 cmax, 00578 cmin, 00579 &combined_data_window, 00580 &combined_noise_window, 00581 -1.0)); 00582 00583 if (kmclipm_omit_warning_one_slice > 10) { 00584 cpl_msg_warning(cpl_func, "Previous warning (number of " 00585 "identified slices) occured %d times.", 00586 kmclipm_omit_warning_one_slice); 00587 kmclipm_omit_warning_one_slice = FALSE; 00588 } 00589 00590 // calculate preliminary mean and stdev to create the bad pixel mask 00591 qc_dark = cpl_image_get_mean(combined_data_window); 00592 KMO_TRY_CHECK_ERROR_STATE(); 00593 00594 if (nz > 2) { 00595 qc_readnoise = cpl_image_get_mean(combined_noise_window); 00596 KMO_TRY_CHECK_ERROR_STATE(); 00597 00598 KMO_TRY_ASSURE(qc_readnoise != 0.0, 00599 CPL_ERROR_ILLEGAL_INPUT, 00600 "All frames of detector %i are exactly " 00601 "the same!", i); 00602 } else if (nz == 2) { 00603 qc_readnoise = cpl_image_get_stdev(combined_noise_window); 00604 KMO_TRY_CHECK_ERROR_STATE(); 00605 00606 KMO_TRY_ASSURE(qc_readnoise != 0.0, 00607 CPL_ERROR_ILLEGAL_INPUT, 00608 "All frames of detector %i are exactly " 00609 "the same!", i); 00610 } else if (nz == 1) { 00611 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00612 KMO_TRY_CHECK_ERROR_STATE(); 00613 00614 KMO_TRY_ASSURE(qc_readnoise != 0.0, 00615 CPL_ERROR_ILLEGAL_INPUT, 00616 "The detector frame %d seems to be uniform!", i); 00617 } else { 00618 KMO_TRY_ASSURE(1 == 0, 00619 CPL_ERROR_ILLEGAL_INPUT, 00620 "detector frame must have at least one frame!"); 00621 } 00622 00623 // create bad-pixel-mask 00624 qc_bad_pix_num = kmo_create_bad_pix_dark(combined_data_window, 00625 qc_dark, 00626 qc_readnoise, 00627 pos_bad_pix_rej, 00628 neg_bad_pix_rej, 00629 &bad_pix_mask_window); 00630 KMO_TRY_CHECK_ERROR_STATE(); 00631 00632 KMO_TRY_EXIT_IF_ERROR( 00633 kmclipm_update_property_int(sub_header, 00634 QC_NR_BAD_PIX, 00635 qc_bad_pix_num, 00636 "[] nr. of bad pixels")); 00637 00638 // 00639 // calculate QC.DARK, QC.READNOISE, QC.DARK.MEDIAN, 00640 // QC.READNOISE.MEDIAN, QC.DARKCUR 00641 00642 // badpixels from combined_data_window are already rejected in 00643 // kmo_create_bad_pix_dark() 00644 KMO_TRY_EXIT_IF_ERROR( 00645 kmo_image_reject_from_mask(combined_noise_window, 00646 bad_pix_mask_window)); 00647 00648 qc_dark = cpl_image_get_mean(combined_data_window); 00649 KMO_TRY_CHECK_ERROR_STATE(); 00650 00651 // calculate mean and stddev of combined frames (with rejection) 00652 if (nz > 2) { 00653 qc_readnoise = cpl_image_get_mean(combined_noise_window) * sqrt(nz); 00654 } else if (nz == 2) { 00655 qc_readnoise = 00656 cpl_image_get_stdev(combined_noise_window) * sqrt(2.0); 00657 } else if (nz == 1) { 00658 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00659 } else { 00660 KMO_TRY_ASSURE(1 == 0, 00661 CPL_ERROR_ILLEGAL_INPUT, 00662 "detector frame must have at least one frame!"); 00663 } 00664 KMO_TRY_CHECK_ERROR_STATE(); 00665 00666 qc_dark_median = cpl_image_get_median(combined_data_window); 00667 KMO_TRY_CHECK_ERROR_STATE(); 00668 00669 if (nz > 2) { 00670 qc_readnoise_median = 00671 cpl_image_get_median(combined_noise_window) * sqrt(nz); 00672 } else if (nz == 2) { 00673 qc_readnoise_median = 00674 kmo_image_get_stdev_median(combined_noise_window) * 00675 sqrt(2.0); 00676 } else if (nz == 1) { 00677 qc_readnoise_median = 00678 kmo_image_get_stdev_median(combined_data_window); 00679 } else { 00680 KMO_TRY_ASSURE(1 == 0, 00681 CPL_ERROR_ILLEGAL_INPUT, 00682 "detector frame must have at least one frame!"); 00683 } 00684 KMO_TRY_CHECK_ERROR_STATE(); 00685 00686 KMO_TRY_EXIT_IF_ERROR( 00687 kmclipm_update_property_double(sub_header, 00688 QC_DARK, 00689 qc_dark, 00690 "[adu] mean of master dark")); 00691 KMO_TRY_EXIT_IF_ERROR( 00692 kmclipm_update_property_double(sub_header, 00693 QC_READNOISE, 00694 qc_readnoise, 00695 "[adu] mean noise of master dark")); 00696 KMO_TRY_EXIT_IF_ERROR( 00697 kmclipm_update_property_double(sub_header, 00698 QC_DARK_MEDIAN, 00699 qc_dark_median, 00700 "[adu] median of master dark")); 00701 KMO_TRY_EXIT_IF_ERROR( 00702 kmclipm_update_property_double(sub_header, 00703 QC_READNOISE_MEDIAN, 00704 qc_readnoise_median, 00705 "[adu] median noise of master dark")); 00706 00707 // load gain 00708 gain = kmo_dfs_get_property_double(sub_header, GAIN); 00709 KMO_TRY_CHECK_ERROR_STATE_MSG( 00710 "GAIN-keyword in fits-header is missing!"); 00711 00712 KMO_TRY_EXIT_IF_ERROR( 00713 kmclipm_update_property_double(sub_header, 00714 QC_DARK_CURRENT, 00715 qc_dark / exptime / gain, 00716 "[e-/s] dark current")); 00717 00718 // save dark frame 00719 KMO_TRY_EXIT_IF_NULL( 00720 extname = kmo_extname_creator(detector_frame, i, EXT_DATA)); 00721 KMO_TRY_EXIT_IF_ERROR( 00722 kmclipm_update_property_string(sub_header, EXTNAME, 00723 extname, 00724 "FITS extension name")); 00725 cpl_free(extname); extname = NULL; 00726 00727 KMO_TRY_EXIT_IF_NULL( 00728 combined_data = kmo_add_bad_pix_border(combined_data_window, 00729 TRUE)); 00730 00731 KMO_TRY_EXIT_IF_ERROR( 00732 kmo_dfs_save_image(combined_data, filename, "", sub_header, 0./0.)); 00733 00734 // save noise frame 00735 KMO_TRY_EXIT_IF_NULL( 00736 extname = kmo_extname_creator(detector_frame, i, EXT_NOISE)); 00737 KMO_TRY_EXIT_IF_ERROR( 00738 kmclipm_update_property_string(sub_header, EXTNAME, 00739 extname, 00740 "FITS extension name")); 00741 cpl_free(extname); extname = NULL; 00742 00743 KMO_TRY_EXIT_IF_NULL( 00744 combined_noise = kmo_add_bad_pix_border(combined_noise_window, 00745 TRUE)); 00746 00747 KMO_TRY_EXIT_IF_ERROR( 00748 kmo_dfs_save_image(combined_noise, filename, "", sub_header, 0./0.)); 00749 00750 // save bad_pix frame 00751 KMO_TRY_EXIT_IF_NULL( 00752 extname = kmo_extname_creator(detector_frame, i, EXT_BADPIX)); 00753 KMO_TRY_EXIT_IF_ERROR( 00754 kmclipm_update_property_string(sub_header, EXTNAME, 00755 extname, 00756 "FITS extension name")); 00757 cpl_free(extname); extname = NULL; 00758 00759 KMO_TRY_EXIT_IF_NULL( 00760 bad_pix_mask = kmo_add_bad_pix_border(bad_pix_mask_window, 00761 FALSE)); 00762 00763 KMO_TRY_EXIT_IF_ERROR( 00764 kmo_dfs_save_image(bad_pix_mask, filename_bad, "", sub_header, 0.)); 00765 00766 // free memory 00767 cpl_propertylist_delete(sub_header); sub_header = NULL; 00768 cpl_imagelist_delete(detector_in_window); detector_in_window = NULL; 00769 cpl_image_delete(combined_data); combined_data = NULL; 00770 cpl_image_delete(combined_data_window); combined_data_window = NULL; 00771 cpl_image_delete(combined_noise); combined_noise = NULL; 00772 cpl_image_delete(combined_noise_window); combined_noise_window = NULL; 00773 cpl_image_delete(bad_pix_mask); bad_pix_mask = NULL; 00774 cpl_image_delete(bad_pix_mask_window); bad_pix_mask_window = NULL; 00775 } // for i = [1, nr_devices] 00776 00777 cpl_msg_info("", "-------------------------------------------"); 00778 cpl_msg_info("", "IFU status after processing:"); 00779 cpl_msg_info("", " not checked here"); 00780 cpl_msg_info("", "-------------------------------------------"); 00781 } 00782 KMO_CATCH 00783 { 00784 KMO_CATCH_MSG(); 00785 00786 // if (desc2.sub_desc != NULL) { 00787 kmo_free_fits_desc(&desc2); 00788 // } 00789 00790 ret_val = -1; 00791 } 00792 00793 kmo_free_fits_desc(&desc1); 00794 cpl_propertylist_delete(main_header); main_header = NULL; 00795 cpl_propertylist_delete(sub_header); sub_header = NULL; 00796 cpl_imagelist_delete(detector_in_window); detector_in_window = NULL; 00797 cpl_image_delete(combined_data); combined_data = NULL; 00798 cpl_image_delete(combined_data_window); combined_data_window = NULL; 00799 cpl_image_delete(combined_noise); combined_noise = NULL; 00800 cpl_image_delete(combined_noise_window); combined_noise_window = NULL; 00801 cpl_image_delete(bad_pix_mask); bad_pix_mask = NULL; 00802 cpl_image_delete(bad_pix_mask_window); bad_pix_mask_window = NULL; 00803 00804 return ret_val; 00805 } 00806
1.7.6.1