|
KMOS Pipeline Reference Manual
1.0.8
|
00001 /* $Id: kmo_dark.c,v 1.18 2013/02/19 10:51:08 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/02/19 10:51:08 $ 00024 * $Revision: 1.18 $ 00025 * $Name: kmosp_v1_0_8__20130220 $ 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 "agudo@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 filename = cpl_sprintf("%s_%d", MASTER_DARK, (int)exptime); 00442 filename_bad = cpl_sprintf("%s_%d", BADPIXEL_DARK, (int)exptime); 00443 } else { 00444 filename = cpl_sprintf("%s", MASTER_DARK); 00445 filename_bad = cpl_sprintf("%s", BADPIXEL_DARK); 00446 } 00447 00448 00449 desc1 = kmo_identify_fits_header( 00450 cpl_frame_get_filename(frame)); 00451 00452 KMO_TRY_CHECK_ERROR_STATE_MSG("First fits file doesn't seem to " 00453 "be in KMOS-format!"); 00454 00455 KMO_TRY_ASSURE(desc1.fits_type == raw_fits, 00456 CPL_ERROR_ILLEGAL_INPUT, 00457 "First input file hasn't correct data type " 00458 "(must be a raw, unprocessed file)!"); 00459 } else { 00460 00461 desc2 = kmo_identify_fits_header( 00462 cpl_frame_get_filename(frame)); 00463 KMO_TRY_CHECK_ERROR_STATE_MSG("Fits file doesn't seem to be " 00464 "in KMOS-format!"); 00465 00466 KMO_TRY_ASSURE(desc2.fits_type == raw_fits, 00467 CPL_ERROR_ILLEGAL_INPUT, 00468 "An input file hasn't correct data type " 00469 "(must be a raw, unprocessed file)!"); 00470 00471 kmo_free_fits_desc(&desc2); 00472 } 00473 00474 // check if all lamps are off (flat and arc lamp) 00475 KMO_TRY_ASSURE(((kmo_check_lamp(main_header, INS_LAMP1_ST) == FALSE) && 00476 (kmo_check_lamp(main_header, INS_LAMP2_ST) == FALSE) && 00477 (kmo_check_lamp(main_header, INS_LAMP3_ST) == FALSE) && 00478 (kmo_check_lamp(main_header, INS_LAMP4_ST) == FALSE)) || 00479 (((kmo_check_lamp(main_header, INS_LAMP1_ST) == TRUE) || 00480 (kmo_check_lamp(main_header, INS_LAMP2_ST) == TRUE) || 00481 (kmo_check_lamp(main_header, INS_LAMP3_ST) == TRUE) || 00482 (kmo_check_lamp(main_header, INS_LAMP4_ST) == TRUE)) && 00483 (strcmp(cpl_propertylist_get_string(main_header, "ESO INS FILT1 ID"), "Block") == 0) && 00484 (strcmp(cpl_propertylist_get_string(main_header, "ESO INS FILT2 ID"), "Block") == 0) && 00485 (strcmp(cpl_propertylist_get_string(main_header, "ESO INS FILT3 ID"), "Block") == 0)), 00486 CPL_ERROR_ILLEGAL_INPUT, 00487 "All lamps must be switched off for DARK frames!"); 00488 00489 // check if EXPTIME and NDIT are the same for all frames 00490 if (cpl_propertylist_get_double(main_header, EXPTIME) != exptime) { 00491 cpl_msg_warning(cpl_func, 00492 "EXPTIME isn't the same for all " 00493 "frames: (is %g and %g). Proceeding anyway...", 00494 cpl_propertylist_get_double(main_header, 00495 EXPTIME), 00496 exptime); 00497 } 00498 00499 if (cpl_propertylist_get_int(main_header, NDIT) != ndit) { 00500 cpl_msg_warning(cpl_func, 00501 "NDIT isn't the same for all " 00502 "frames: (is %d and %d). Proceeding anyway...", 00503 cpl_propertylist_get_int(main_header, NDIT), 00504 ndit); 00505 } 00506 00507 // get next DARK frame 00508 frame = kmo_dfs_get_frame(frameset, NULL); 00509 KMO_TRY_CHECK_ERROR_STATE(); 00510 00511 cpl_propertylist_delete(main_header); main_header = NULL; 00512 i++; 00513 } 00514 00515 // --- load, update & save primary header --- 00516 KMO_TRY_EXIT_IF_NULL( 00517 frame = kmo_dfs_get_frame(frameset, do_mode)); 00518 00519 KMO_TRY_EXIT_IF_ERROR( 00520 kmo_dfs_save_main_header(frameset, filename, "", frame, 00521 NULL, parlist, cpl_func)); 00522 00523 KMO_TRY_EXIT_IF_ERROR( 00524 kmo_dfs_save_main_header(frameset, filename_bad, "", frame, 00525 NULL, parlist, cpl_func)); 00526 00527 // --- load data --- 00528 nr_devices = desc1.nr_ext; 00529 00530 my_method = cmethod; 00531 if ((cpl_frameset_count_tags(frameset, DARK) == 1) || 00532 (cpl_frameset_count_tags(frameset, COMMANDLINE) == 1)) { 00533 cpl_msg_warning(cpl_func, "cmethod is changed to 'average' " 00534 "since there is only one input frame!"); 00535 00536 my_method = "average"; 00537 } 00538 00539 // get size of input frame 00540 KMO_TRY_EXIT_IF_NULL( 00541 img_in_window = kmo_dfs_load_image(frameset, do_mode, 1, FALSE, FALSE, NULL)); 00542 nx_orig = cpl_image_get_size_x(img_in_window); 00543 ny_orig = cpl_image_get_size_y(img_in_window); 00544 cpl_image_delete(img_in_window); img_in_window = NULL; 00545 00546 KMO_TRY_ASSURE((nx_orig > 2*KMOS_BADPIX_BORDER) && 00547 (ny_orig > 2*KMOS_BADPIX_BORDER), 00548 CPL_ERROR_ILLEGAL_INPUT, 00549 "Input frames must have a height and width of at " 00550 "least 9 pixels!"); 00551 00552 // --- loop through all detectors --- 00553 for (i = 1; i <= nr_devices; i++) { 00554 cpl_msg_info("","Processing detector No. %d", i); 00555 00556 KMO_TRY_EXIT_IF_NULL( 00557 detector_in_window = cpl_imagelist_new()); 00558 00559 KMO_TRY_EXIT_IF_NULL( 00560 sub_header = kmo_dfs_load_sub_header(frameset, do_mode, 00561 i, FALSE)); 00562 00563 // load data of device i of all DARK frames into an imagelist 00564 KMO_TRY_EXIT_IF_NULL( 00565 img_in_window = kmo_dfs_load_image_window( 00566 frameset, do_mode, i, FALSE, 00567 KMOS_BADPIX_BORDER+1, 00568 KMOS_BADPIX_BORDER+1, 00569 nx_orig-KMOS_BADPIX_BORDER, 00570 ny_orig-KMOS_BADPIX_BORDER, 00571 FALSE, NULL)); 00572 00573 nx = cpl_image_get_size_x(img_in_window); 00574 ny = cpl_image_get_size_y(img_in_window); 00575 00576 nz = 0; 00577 while (img_in_window != NULL) { 00578 cpl_imagelist_set(detector_in_window, img_in_window, nz); 00579 KMO_TRY_CHECK_ERROR_STATE(); 00580 00581 // load same extension of next DARK frame 00582 img_in_window = kmo_dfs_load_image_window( 00583 frameset, NULL, i, FALSE, 00584 KMOS_BADPIX_BORDER+1, 00585 KMOS_BADPIX_BORDER+1, 00586 nx_orig-KMOS_BADPIX_BORDER, 00587 ny_orig-KMOS_BADPIX_BORDER, 00588 FALSE, NULL); 00589 KMO_TRY_CHECK_ERROR_STATE(); 00590 00591 if (img_in_window != NULL) { 00592 KMO_TRY_ASSURE((nx == cpl_image_get_size_x(img_in_window)) && 00593 (ny == cpl_image_get_size_y(img_in_window)), 00594 CPL_ERROR_ILLEGAL_INPUT, 00595 "Not all input frames have the " 00596 "same dimensions!"); 00597 } 00598 nz++; 00599 } 00600 00601 // combine imagelist (data only) and create noise 00602 KMO_TRY_EXIT_IF_ERROR( 00603 kmclipm_combine_frames(detector_in_window, 00604 NULL, 00605 NULL, 00606 my_method, 00607 cpos_rej, 00608 cneg_rej, 00609 citer, 00610 cmax, 00611 cmin, 00612 &combined_data_window, 00613 &combined_noise_window, 00614 -1.0)); 00615 00616 if (kmclipm_omit_warning_one_slice > 10) { 00617 cpl_msg_warning(cpl_func, "Previous warning (number of " 00618 "identified slices) occured %d times.", 00619 kmclipm_omit_warning_one_slice); 00620 kmclipm_omit_warning_one_slice = FALSE; 00621 } 00622 00623 // calculate preliminary mean and stdev to create the bad pixel mask 00624 qc_dark = cpl_image_get_mean(combined_data_window); 00625 KMO_TRY_CHECK_ERROR_STATE(); 00626 00627 if (nz > 2) { 00628 qc_readnoise = cpl_image_get_mean(combined_noise_window); 00629 KMO_TRY_CHECK_ERROR_STATE(); 00630 00631 KMO_TRY_ASSURE(qc_readnoise != 0.0, 00632 CPL_ERROR_ILLEGAL_INPUT, 00633 "All frames of detector %i are exactly " 00634 "the same!", i); 00635 } else if (nz == 2) { 00636 qc_readnoise = cpl_image_get_stdev(combined_noise_window); 00637 KMO_TRY_CHECK_ERROR_STATE(); 00638 00639 KMO_TRY_ASSURE(qc_readnoise != 0.0, 00640 CPL_ERROR_ILLEGAL_INPUT, 00641 "All frames of detector %i are exactly " 00642 "the same!", i); 00643 } else if (nz == 1) { 00644 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00645 KMO_TRY_CHECK_ERROR_STATE(); 00646 00647 KMO_TRY_ASSURE(qc_readnoise != 0.0, 00648 CPL_ERROR_ILLEGAL_INPUT, 00649 "The detector frame %d seems to be uniform!", i); 00650 } else { 00651 KMO_TRY_ASSURE(1 == 0, 00652 CPL_ERROR_ILLEGAL_INPUT, 00653 "detector frame must have at least one frame!"); 00654 } 00655 00656 // create bad-pixel-mask 00657 qc_bad_pix_num = kmo_create_bad_pix_dark(combined_data_window, 00658 qc_dark, 00659 qc_readnoise, 00660 pos_bad_pix_rej, 00661 neg_bad_pix_rej, 00662 &bad_pix_mask_window); 00663 KMO_TRY_CHECK_ERROR_STATE(); 00664 00665 KMO_TRY_EXIT_IF_ERROR( 00666 kmclipm_update_property_int(sub_header, 00667 QC_NR_BAD_PIX, 00668 qc_bad_pix_num, 00669 "[] nr. of bad pixels")); 00670 00671 // 00672 // calculate QC.DARK, QC.READNOISE, QC.DARK.MEDIAN, 00673 // QC.READNOISE.MEDIAN, QC.DARKCUR 00674 00675 // badpixels from combined_data_window are already rejected in 00676 // kmo_create_bad_pix_dark() 00677 KMO_TRY_EXIT_IF_ERROR( 00678 kmo_image_reject_from_mask(combined_noise_window, 00679 bad_pix_mask_window)); 00680 00681 qc_dark = cpl_image_get_mean(combined_data_window); 00682 KMO_TRY_CHECK_ERROR_STATE(); 00683 00684 // calculate mean and stddev of combined frames (with rejection) 00685 if (nz > 2) { 00686 qc_readnoise = cpl_image_get_mean(combined_noise_window) * sqrt(nz); 00687 } else if (nz == 2) { 00688 qc_readnoise = 00689 cpl_image_get_stdev(combined_noise_window) * sqrt(2.0); 00690 } else if (nz == 1) { 00691 qc_readnoise = cpl_image_get_stdev(combined_data_window); 00692 } else { 00693 KMO_TRY_ASSURE(1 == 0, 00694 CPL_ERROR_ILLEGAL_INPUT, 00695 "detector frame must have at least one frame!"); 00696 } 00697 KMO_TRY_CHECK_ERROR_STATE(); 00698 00699 qc_dark_median = cpl_image_get_median(combined_data_window); 00700 KMO_TRY_CHECK_ERROR_STATE(); 00701 00702 if (nz > 2) { 00703 qc_readnoise_median = 00704 cpl_image_get_median(combined_noise_window) * sqrt(nz); 00705 } else if (nz == 2) { 00706 qc_readnoise_median = 00707 kmo_image_get_stdev_median(combined_noise_window) * 00708 sqrt(2.0); 00709 } else if (nz == 1) { 00710 qc_readnoise_median = 00711 kmo_image_get_stdev_median(combined_data_window); 00712 } else { 00713 KMO_TRY_ASSURE(1 == 0, 00714 CPL_ERROR_ILLEGAL_INPUT, 00715 "detector frame must have at least one frame!"); 00716 } 00717 KMO_TRY_CHECK_ERROR_STATE(); 00718 00719 KMO_TRY_EXIT_IF_ERROR( 00720 kmclipm_update_property_double(sub_header, 00721 QC_DARK, 00722 qc_dark, 00723 "[adu] mean of master dark")); 00724 KMO_TRY_EXIT_IF_ERROR( 00725 kmclipm_update_property_double(sub_header, 00726 QC_READNOISE, 00727 qc_readnoise, 00728 "[adu] mean noise of master dark")); 00729 KMO_TRY_EXIT_IF_ERROR( 00730 kmclipm_update_property_double(sub_header, 00731 QC_DARK_MEDIAN, 00732 qc_dark_median, 00733 "[adu] median of master dark")); 00734 KMO_TRY_EXIT_IF_ERROR( 00735 kmclipm_update_property_double(sub_header, 00736 QC_READNOISE_MEDIAN, 00737 qc_readnoise_median, 00738 "[adu] median noise of master dark")); 00739 00740 // load gain 00741 gain = kmo_dfs_get_property_double(sub_header, GAIN); 00742 KMO_TRY_CHECK_ERROR_STATE_MSG( 00743 "GAIN-keyword in fits-header is missing!"); 00744 00745 KMO_TRY_EXIT_IF_ERROR( 00746 kmclipm_update_property_double(sub_header, 00747 QC_DARK_CURRENT, 00748 qc_dark / exptime / gain, 00749 "[e-/s] dark current")); 00750 00751 // save dark frame 00752 KMO_TRY_EXIT_IF_NULL( 00753 extname = kmo_extname_creator(detector_frame, i, EXT_DATA)); 00754 KMO_TRY_EXIT_IF_ERROR( 00755 kmclipm_update_property_string(sub_header, EXTNAME, 00756 extname, 00757 "FITS extension name")); 00758 cpl_free(extname); extname = NULL; 00759 00760 KMO_TRY_EXIT_IF_NULL( 00761 combined_data = kmo_add_bad_pix_border(combined_data_window, 00762 TRUE)); 00763 00764 KMO_TRY_EXIT_IF_ERROR( 00765 kmo_dfs_save_image(combined_data, filename, "", sub_header, 0./0.)); 00766 00767 // save noise frame 00768 KMO_TRY_EXIT_IF_NULL( 00769 extname = kmo_extname_creator(detector_frame, i, EXT_NOISE)); 00770 KMO_TRY_EXIT_IF_ERROR( 00771 kmclipm_update_property_string(sub_header, EXTNAME, 00772 extname, 00773 "FITS extension name")); 00774 cpl_free(extname); extname = NULL; 00775 00776 KMO_TRY_EXIT_IF_NULL( 00777 combined_noise = kmo_add_bad_pix_border(combined_noise_window, 00778 TRUE)); 00779 00780 KMO_TRY_EXIT_IF_ERROR( 00781 kmo_dfs_save_image(combined_noise, filename, "", sub_header, 0./0.)); 00782 00783 // save bad_pix frame 00784 KMO_TRY_EXIT_IF_NULL( 00785 extname = kmo_extname_creator(detector_frame, i, EXT_BADPIX)); 00786 KMO_TRY_EXIT_IF_ERROR( 00787 kmclipm_update_property_string(sub_header, EXTNAME, 00788 extname, 00789 "FITS extension name")); 00790 cpl_free(extname); extname = NULL; 00791 00792 KMO_TRY_EXIT_IF_NULL( 00793 bad_pix_mask = kmo_add_bad_pix_border(bad_pix_mask_window, 00794 FALSE)); 00795 00796 KMO_TRY_EXIT_IF_ERROR( 00797 kmo_dfs_save_image(bad_pix_mask, filename_bad, "", sub_header, 0.)); 00798 00799 // free memory 00800 cpl_propertylist_delete(sub_header); sub_header = NULL; 00801 cpl_imagelist_delete(detector_in_window); detector_in_window = NULL; 00802 cpl_image_delete(combined_data); combined_data = NULL; 00803 cpl_image_delete(combined_data_window); combined_data_window = NULL; 00804 cpl_image_delete(combined_noise); combined_noise = NULL; 00805 cpl_image_delete(combined_noise_window); combined_noise_window = NULL; 00806 cpl_image_delete(bad_pix_mask); bad_pix_mask = NULL; 00807 cpl_image_delete(bad_pix_mask_window); bad_pix_mask_window = NULL; 00808 } // for i = [1, nr_devices] 00809 00810 cpl_msg_info("", "-------------------------------------------"); 00811 cpl_msg_info("", "IFU status after processing:"); 00812 cpl_msg_info("", " not checked here"); 00813 cpl_msg_info("", "-------------------------------------------"); 00814 } 00815 KMO_CATCH 00816 { 00817 KMO_CATCH_MSG(); 00818 00819 // if (desc2.sub_desc != NULL) { 00820 kmo_free_fits_desc(&desc2); 00821 // } 00822 00823 ret_val = -1; 00824 } 00825 00826 kmo_free_fits_desc(&desc1); 00827 cpl_free(filename); filename = NULL; 00828 cpl_free(filename_bad); filename_bad = NULL; 00829 cpl_propertylist_delete(main_header); main_header = NULL; 00830 cpl_propertylist_delete(sub_header); sub_header = NULL; 00831 cpl_imagelist_delete(detector_in_window); detector_in_window = NULL; 00832 cpl_image_delete(combined_data); combined_data = NULL; 00833 cpl_image_delete(combined_data_window); combined_data_window = NULL; 00834 cpl_image_delete(combined_noise); combined_noise = NULL; 00835 cpl_image_delete(combined_noise_window); combined_noise_window = NULL; 00836 cpl_image_delete(bad_pix_mask); bad_pix_mask = NULL; 00837 cpl_image_delete(bad_pix_mask_window); bad_pix_mask_window = NULL; 00838 00839 return ret_val; 00840 } 00841
1.7.6.1