|
HAWKI Pipeline Reference Manual 1.8.1
|
00001 /* $Id: hawki_step_compute_bkg.c,v 1.16 2011/02/11 10:57:57 cgarcia Exp $ 00002 * 00003 * This file is part of the HAWKI Pipeline 00004 * Copyright (C) 2008 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: cgarcia $ 00023 * $Date: 2011/02/11 10:57:57 $ 00024 * $Revision: 1.16 $ 00025 * $Name: hawki-1_8_1 $ 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 #include <cpl.h> 00039 00040 #include "hawki_utils.h" 00041 #include "hawki_distortion.h" 00042 #include "hawki_load.h" 00043 #include "hawki_save.h" 00044 #include "hawki_pfits.h" 00045 #include "hawki_dfs.h" 00046 #include "hawki_bkg.h" 00047 #include "hawki_calib.h" 00048 00049 /*----------------------------------------------------------------------------- 00050 Structs 00051 -----------------------------------------------------------------------------*/ 00052 00053 static struct 00054 { 00055 /* Configuration values */ 00056 int nmin_comb; 00057 int nhalf_window; 00058 int rejlow; 00059 int rejhigh; 00060 00061 } hawki_step_compute_bkg_config; 00062 00063 /*----------------------------------------------------------------------------- 00064 Functions prototypes 00065 -----------------------------------------------------------------------------*/ 00066 00067 static int hawki_step_compute_bkg_create(cpl_plugin *) ; 00068 static int hawki_step_compute_bkg_exec(cpl_plugin *) ; 00069 static int hawki_step_compute_bkg_destroy(cpl_plugin *) ; 00070 static int hawki_step_compute_bkg(cpl_parameterlist *, cpl_frameset *) ; 00071 00072 static int hawki_step_compute_bkg_from_objects_qc_save 00073 (cpl_frameset * objframes, 00074 cpl_frameset * maskframes, 00075 cpl_frameset * offsetsframes, 00076 cpl_frameset * x_distortionframes, 00077 cpl_frameset * y_distortionframes, 00078 cpl_parameterlist * parlist, 00079 cpl_frameset * recipe_framelist); 00080 static int hawki_step_compute_bkg_from_objects_median_save 00081 (cpl_frameset * objframes, 00082 cpl_parameterlist * recipe_parlist, 00083 cpl_frameset * recipe_framelist); 00084 static int hawki_step_compute_bkg_from_sky_median_save 00085 (cpl_frameset * skyframes, 00086 cpl_parameterlist * recipe_parlist, 00087 cpl_frameset * recipe_framelist); 00088 static int hawki_step_compute_bkg_interpolate_badpix 00089 (cpl_image * image); 00090 static int hawki_step_compute_bkg_from_objects_running_median_save 00091 (cpl_frameset * objframes, 00092 cpl_frameset * maskframes, 00093 cpl_frameset * offsetframes, 00094 cpl_frameset * x_distortionframes, 00095 cpl_frameset * y_distortionframes, 00096 cpl_parameterlist * recipe_parlist, 00097 cpl_frameset * recipe_framelist); 00098 static int hawki_step_compute_bkg_from_running_median_nonmasked_save 00099 (const cpl_frameset * objframes, 00100 int nhalf_window, 00101 int rejlow, 00102 int rejhigh, 00103 cpl_frameset * recipe_framelist, 00104 cpl_parameterlist * recipe_parlist); 00105 static int hawki_step_compute_bkg_from_running_median_masked_save 00106 (const cpl_frameset * objframes, 00107 cpl_frame * maskframe, 00108 cpl_bivector ** offsets, 00109 cpl_frame * x_distortionframe, 00110 cpl_frame * y_distortionframe, 00111 int nhalf_window, 00112 int rejlow, 00113 int rejhigh, 00114 cpl_frameset * recipe_framelist, 00115 cpl_parameterlist * recipe_parlist); 00116 00117 00118 int hawki_step_compute_bkg_retrieve_input_param 00119 (cpl_parameterlist * parlist); 00120 00121 /*----------------------------------------------------------------------------- 00122 Static variables 00123 -----------------------------------------------------------------------------*/ 00124 00125 static char hawki_step_compute_bkg_description[] = 00126 "hawki_step_compute_bkg -- hawki background computation utility.\n" 00127 "This recipe will create the associated background images\n" 00128 "for a given set of object images. If there are sky images, these will\n" 00129 "be used to compute the background, otherwise, the background is computed\n" 00130 "using a running mean on the object images. An optional mask can be supplied\n" 00131 "for the running mean.\n" 00132 "The files listed in the Set Of Frames (sof-file) must be tagged:\n" 00133 "obj_basic_cal-file.fits "HAWKI_CALPRO_BASICCALIBRATED" or\n" 00134 "sky_basic_cal-file.fits "HAWKI_CALPRO_SKY_BASICCALIBRATED" \n" 00135 "and optionally for object masking:\n" 00136 "object_mask-file.fits "HAWKI_CALPRO_OBJ_MASK" \n" 00137 "offsets.fits "HAWKI_CALPRO_OFFSETS" \n" 00138 "distortion_x.fits "HAWKI_CALPRO_DISTORTION_X" \n" 00139 "distortion_y.fits "HAWKI_CALPRO_DISTORTION_Y" \n"; 00140 00141 /*----------------------------------------------------------------------------- 00142 Functions code 00143 -----------------------------------------------------------------------------*/ 00144 00145 /*----------------------------------------------------------------------------*/ 00153 /*----------------------------------------------------------------------------*/ 00154 int cpl_plugin_get_info(cpl_pluginlist * list) 00155 { 00156 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ; 00157 cpl_plugin * plugin = &recipe->interface ; 00158 00159 cpl_plugin_init(plugin, 00160 CPL_PLUGIN_API, 00161 HAWKI_BINARY_VERSION, 00162 CPL_PLUGIN_TYPE_RECIPE, 00163 "hawki_step_compute_bkg", 00164 "Background computing utility", 00165 hawki_step_compute_bkg_description, 00166 "Cesar Enrique Garcia Dabo", 00167 PACKAGE_BUGREPORT, 00168 hawki_get_license(), 00169 hawki_step_compute_bkg_create, 00170 hawki_step_compute_bkg_exec, 00171 hawki_step_compute_bkg_destroy); 00172 00173 cpl_pluginlist_append(list, plugin); 00174 00175 return 0; 00176 } 00177 00178 /*----------------------------------------------------------------------------*/ 00187 /*----------------------------------------------------------------------------*/ 00188 static int hawki_step_compute_bkg_create(cpl_plugin * plugin) 00189 { 00190 cpl_recipe * recipe; 00191 cpl_parameter * p; 00192 00193 /* Get the recipe out of the plugin */ 00194 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00195 recipe = (cpl_recipe *)plugin ; 00196 else return -1 ; 00197 00198 /* Create the parameters list in the cpl_recipe object */ 00199 recipe->parameters = cpl_parameterlist_new() ; 00200 00201 /* Fill the parameters list */ 00202 /* --nmin_comb */ 00203 p = cpl_parameter_new_value 00204 ("hawki.hawki_step_compute_bkg.nmin_comb", 00205 CPL_TYPE_INT, 00206 "Minimum number of jitter frames to use the running median", 00207 "hawki.hawki_step_compute_bkg", 00208 10) ; 00209 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nmin_comb") ; 00210 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00211 cpl_parameterlist_append(recipe->parameters, p) ; 00212 00213 /* --nhalf_window */ 00214 p = cpl_parameter_new_value 00215 ("hawki.hawki_step_compute_bkg.nhalf_window", 00216 CPL_TYPE_INT, 00217 "Number of images at both sides of the current ima to use for bkg in running median", 00218 "hawki.hawki_step_compute_bkg", 00219 7); 00220 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nhalf_window") ; 00221 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00222 cpl_parameterlist_append(recipe->parameters, p) ; 00223 00224 /* --rejlow */ 00225 p = cpl_parameter_new_value 00226 ("hawki.hawki_step_compute_bkg.rejlow", 00227 CPL_TYPE_INT, 00228 "The number of frames with low level to reject", 00229 "hawki.hawki_step_compute_bkg", 00230 2) ; 00231 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rejlow") ; 00232 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00233 cpl_parameterlist_append(recipe->parameters, p) ; 00234 00235 /* --rejhigh */ 00236 p = cpl_parameter_new_value 00237 ("hawki.hawki_step_compute_bkg.rejhigh", 00238 CPL_TYPE_INT, 00239 "The number of frames with high level to reject", 00240 "hawki.hawki_step_compute_bkg", 00241 2) ; 00242 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rejhigh") ; 00243 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00244 cpl_parameterlist_append(recipe->parameters, p) ; 00245 00246 /* Return */ 00247 return 0; 00248 } 00249 00250 /*----------------------------------------------------------------------------*/ 00256 /*----------------------------------------------------------------------------*/ 00257 static int hawki_step_compute_bkg_exec(cpl_plugin * plugin) 00258 { 00259 cpl_recipe * recipe ; 00260 00261 /* Get the recipe out of the plugin */ 00262 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00263 recipe = (cpl_recipe *)plugin ; 00264 else return -1 ; 00265 00266 /* Issue a banner */ 00267 hawki_print_banner(); 00268 00269 return hawki_step_compute_bkg(recipe->parameters, recipe->frames) ; 00270 } 00271 00272 /*----------------------------------------------------------------------------*/ 00278 /*----------------------------------------------------------------------------*/ 00279 static int hawki_step_compute_bkg_destroy(cpl_plugin * plugin) 00280 { 00281 cpl_recipe * recipe ; 00282 00283 /* Get the recipe out of the plugin */ 00284 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00285 recipe = (cpl_recipe *)plugin ; 00286 else return -1 ; 00287 00288 cpl_parameterlist_delete(recipe->parameters) ; 00289 return 0 ; 00290 } 00291 00292 /*----------------------------------------------------------------------------*/ 00299 /*----------------------------------------------------------------------------*/ 00300 static int hawki_step_compute_bkg( 00301 cpl_parameterlist * parlist, 00302 cpl_frameset * framelist) 00303 { 00304 cpl_frameset * objframes = NULL; 00305 cpl_frameset * skyframes; 00306 cpl_frameset * maskframes; 00307 cpl_frameset * x_distortionframes; 00308 cpl_frameset * y_distortionframes; 00309 cpl_frameset * offsetsframes = NULL; 00310 00311 /* Get the recipe parameters */ 00312 hawki_step_compute_bkg_retrieve_input_param(parlist); 00313 00314 /* Identify the RAW and CALIB frames in the input frameset */ 00315 if (hawki_dfs_set_groups(framelist)) 00316 { 00317 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00318 return -1 ; 00319 } 00320 00321 /* Identifying objects and sky data frames */ 00322 cpl_msg_info(__func__, "Identifying objects and sky data"); 00323 objframes = hawki_extract_frameset 00324 (framelist, HAWKI_CALPRO_BASICCALIBRATED); 00325 skyframes = hawki_extract_frameset 00326 (framelist, HAWKI_CALPRO_SKY_BASICCALIBRATED); 00327 if (objframes == NULL && skyframes == NULL) 00328 { 00329 cpl_msg_error(__func__, "No object (%s) or sky (%s) frames provided", 00330 HAWKI_CALPRO_BASICCALIBRATED, HAWKI_CALPRO_SKY_BASICCALIBRATED); 00331 return -1 ; 00332 } 00333 00334 /* Retrieve the mask */ 00335 maskframes = hawki_extract_frameset 00336 (framelist, HAWKI_CALPRO_OBJ_MASK); 00337 if(maskframes != NULL) 00338 { 00339 offsetsframes = hawki_extract_frameset 00340 (framelist, HAWKI_CALPRO_OFFSETS); 00341 x_distortionframes = hawki_extract_frameset 00342 (framelist, HAWKI_CALPRO_DISTORTION_X); 00343 y_distortionframes = hawki_extract_frameset 00344 (framelist, HAWKI_CALPRO_DISTORTION_Y); 00345 if((x_distortionframes == NULL && y_distortionframes != NULL) || 00346 (x_distortionframes != NULL && y_distortionframes == NULL)) 00347 { 00348 cpl_msg_error(__func__, "One X-distortion frame (%s) and one Y-distortion (%s)" 00349 "must be provided", HAWKI_CALPRO_DISTORTION_X, HAWKI_CALPRO_DISTORTION_Y); 00350 cpl_frameset_delete(skyframes); 00351 cpl_frameset_delete(maskframes); 00352 cpl_frameset_delete(x_distortionframes); 00353 cpl_frameset_delete(y_distortionframes); 00354 return -1 ; 00355 } 00356 } 00357 00358 /* Compute the background */ 00359 if(skyframes == NULL) 00360 hawki_step_compute_bkg_from_objects_qc_save 00361 (objframes, 00362 maskframes, offsetsframes, x_distortionframes, y_distortionframes, 00363 parlist, framelist); 00364 else 00365 hawki_step_compute_bkg_from_sky_median_save 00366 (skyframes, 00367 parlist, framelist); 00368 00369 /* Free resources */ 00370 if(skyframes != NULL) 00371 cpl_frameset_delete(skyframes); 00372 if(objframes != NULL) 00373 cpl_frameset_delete(objframes); 00374 if(maskframes != NULL) 00375 { 00376 cpl_frameset_delete(maskframes); 00377 if(x_distortionframes != NULL) 00378 cpl_frameset_delete(x_distortionframes); 00379 if(y_distortionframes != NULL) 00380 cpl_frameset_delete(y_distortionframes); 00381 if(offsetsframes != NULL) 00382 cpl_frameset_delete(offsetsframes); 00383 } 00384 00385 /* return */ 00386 if (cpl_error_get_code()) return -1 ; 00387 else return 0 ; 00388 } 00389 00390 /*----------------------------------------------------------------------------*/ 00400 /*----------------------------------------------------------------------------*/ 00401 static int hawki_step_compute_bkg_from_objects_qc_save 00402 (cpl_frameset * objframes, 00403 cpl_frameset * maskframes, 00404 cpl_frameset * offsetsframes, 00405 cpl_frameset * x_distortionframes, 00406 cpl_frameset * y_distortionframes, 00407 cpl_parameterlist * parlist, 00408 cpl_frameset * recipe_framelist) 00409 { 00410 int nobjs; 00411 00412 /* Select the algorithm based on the number of frames */ 00413 nobjs = cpl_frameset_get_size(objframes); 00414 cpl_msg_info(__func__,"Number of object frames: %d",nobjs); 00415 if (hawki_step_compute_bkg_config.nmin_comb > nobjs) 00416 { 00417 /* TODO: Support for masks in this case?? */ 00418 cpl_msg_info(__func__, 00419 "Number of obj frames min required for running median"); 00420 cpl_msg_info(__func__, "Using simple median of object images"); 00421 hawki_step_compute_bkg_from_objects_median_save 00422 (objframes, parlist, recipe_framelist); 00423 } 00424 else 00425 { 00426 cpl_msg_info(__func__, "Using running median of object images"); 00427 hawki_step_compute_bkg_from_objects_running_median_save 00428 (objframes, maskframes, offsetsframes, 00429 x_distortionframes, y_distortionframes, 00430 parlist, recipe_framelist); 00431 } 00432 if (cpl_error_get_code()) 00433 { 00434 cpl_msg_error(__func__, 00435 "HAWK-I pipeline could not recover from previous errors"); 00436 return -1 ; 00437 } 00438 return 0; 00439 } 00440 00441 /*----------------------------------------------------------------------------*/ 00451 /*----------------------------------------------------------------------------*/ 00452 static int hawki_step_compute_bkg_from_objects_median_save 00453 (cpl_frameset * objframes, 00454 cpl_parameterlist * recipe_parlist, 00455 cpl_frameset * recipe_framelist) 00456 { 00457 cpl_imagelist * bkg; 00458 const char * recipe_name = "hawki_step_compute_bkg"; 00459 00460 00461 /* Logging */ 00462 cpl_msg_info(__func__,"Computing background from median of object images"); 00463 00464 /* Allocating for the background image */ 00465 bkg = cpl_imagelist_new(); 00466 00467 /* Computing the background */ 00468 if(hawki_bkg_from_objects_median(objframes, bkg) != 0) 00469 { 00470 cpl_msg_error(__func__,"Could not compute the median of objects"); 00471 cpl_imagelist_delete(bkg); 00472 return -1; 00473 } 00474 00475 /* Save the products */ 00476 cpl_msg_info(__func__, "Saving the products") ; 00477 if(hawki_imagelist_save(recipe_framelist, 00478 recipe_parlist, 00479 objframes, 00480 (const cpl_imagelist *)bkg, 00481 recipe_name, 00482 HAWKI_CALPRO_BKGIMAGE, 00483 HAWKI_PROTYPE_BKGIMAGE, 00484 NULL, 00485 NULL, 00486 "hawki_step_compute_bkg_01.fits") != CPL_ERROR_NONE) 00487 { 00488 cpl_msg_warning(__func__,"Some data could not be saved. " 00489 "Check permisions or disk space"); 00490 } 00491 00492 /* Free and return */ 00493 cpl_imagelist_delete(bkg); 00494 return 0; 00495 } 00496 00497 /*----------------------------------------------------------------------------*/ 00507 /*----------------------------------------------------------------------------*/ 00508 static int hawki_step_compute_bkg_from_sky_median_save 00509 (cpl_frameset * skyframes, 00510 cpl_parameterlist * recipe_parlist, 00511 cpl_frameset * recipe_framelist) 00512 { 00513 cpl_imagelist * bkg; 00514 const char * recipe_name = "hawki_step_compute_bkg"; 00515 00516 /* Logging */ 00517 cpl_msg_info(__func__,"Computing background from sky images"); 00518 00519 /* Allocating for the background image */ 00520 bkg = cpl_imagelist_new(); 00521 00522 /* Computing the background */ 00523 if(hawki_bkg_from_sky_median(skyframes, bkg)!= 0) 00524 { 00525 cpl_msg_error(__func__,"Could not compute the median of sky images"); 00526 cpl_imagelist_delete(bkg); 00527 return -1; 00528 } 00529 00530 /* Save the products */ 00531 cpl_msg_info(__func__, "Saving the products") ; 00532 if(hawki_imagelist_save(recipe_framelist, 00533 recipe_parlist, 00534 skyframes, 00535 (const cpl_imagelist *)bkg, 00536 recipe_name, 00537 HAWKI_CALPRO_BKGIMAGE, 00538 HAWKI_PROTYPE_BKGIMAGE, 00539 NULL, 00540 NULL, 00541 "hawki_step_compute_bkg_01.fits") != CPL_ERROR_NONE) 00542 { 00543 cpl_msg_warning(__func__,"Some data could not be saved. " 00544 "Check permisions or disk space"); 00545 } 00546 00547 /* Free and return */ 00548 cpl_imagelist_delete(bkg); 00549 return 0; 00550 } 00551 00552 static int hawki_step_compute_bkg_from_objects_running_median_save 00553 (cpl_frameset * objframes, 00554 cpl_frameset * maskframes, 00555 cpl_frameset * offsetframes, 00556 cpl_frameset * x_distortionframes, 00557 cpl_frameset * y_distortionframes, 00558 cpl_parameterlist * recipe_parlist, 00559 cpl_frameset * recipe_framelist) 00560 { 00561 00562 /* Logging */ 00563 cpl_msg_info(__func__,"Computing background from running mean of objects"); 00564 cpl_msg_indent_more(); 00565 00566 /* Actually calling the functions that computes all the background */ 00567 if(maskframes == NULL) 00568 { 00569 cpl_msg_info(__func__,"Not using masked objects"); 00570 if(hawki_step_compute_bkg_from_running_median_nonmasked_save 00571 (objframes, 00572 hawki_step_compute_bkg_config.nhalf_window, 00573 hawki_step_compute_bkg_config.rejlow, 00574 hawki_step_compute_bkg_config.rejhigh, 00575 recipe_framelist, 00576 recipe_parlist) !=0) 00577 { 00578 cpl_msg_error(__func__,"Could not compute objects running median"); 00579 return -1; 00580 } 00581 } 00582 else 00583 { 00584 cpl_frame * maskframe; 00585 cpl_bivector ** offsets; /* Detector order */ 00586 cpl_frame * x_distortionframe; 00587 cpl_frame * y_distortionframe; 00588 int idet; 00589 00590 cpl_msg_info(__func__,"Using masked objects"); 00591 00592 maskframe = cpl_frameset_get_first(maskframes); 00593 if(x_distortionframes == NULL && y_distortionframes == NULL ) 00594 { 00595 x_distortionframe = NULL; 00596 y_distortionframe = NULL; 00597 } 00598 else 00599 { 00600 x_distortionframe = cpl_frameset_get_first(x_distortionframes); 00601 y_distortionframe = cpl_frameset_get_first(y_distortionframes); 00602 } 00603 00604 /* Get the offsets */ 00605 if(offsetframes == NULL) 00606 { 00607 cpl_bivector * offsets_all_chips; 00608 00609 cpl_msg_info(__func__,"Using header nominal offsets"); 00610 offsets_all_chips = hawki_get_header_tel_offsets(objframes); 00611 if (offsets_all_chips == NULL) 00612 { 00613 cpl_msg_error(__func__, "Cannot load the header offsets"); 00614 return -1; 00615 } 00616 offsets = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_bivector *)); 00617 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00618 { 00619 offsets[idet] = cpl_bivector_duplicate(offsets_all_chips); 00620 /* Get the oposite offsets. This is to change from 00621 * telescope convention to cpl convention */ 00622 cpl_vector_multiply_scalar 00623 (cpl_bivector_get_x(offsets[idet]), -1.0); 00624 cpl_vector_multiply_scalar 00625 (cpl_bivector_get_y(offsets[idet]), -1.0); 00626 } 00627 cpl_bivector_delete(offsets_all_chips); 00628 } 00629 else 00630 { 00631 cpl_msg_info(__func__,"Using refined offsets"); 00632 offsets = hawki_load_refined_offsets 00633 (cpl_frameset_get_first(offsetframes)); 00634 if(offsets == NULL) 00635 { 00636 cpl_msg_error(__func__, "Cannot load the refined offsets"); 00637 return -1; 00638 } 00639 } 00640 00641 if(hawki_step_compute_bkg_from_running_median_masked_save 00642 (objframes, 00643 maskframe, 00644 offsets, 00645 x_distortionframe, 00646 y_distortionframe, 00647 hawki_step_compute_bkg_config.nhalf_window, 00648 hawki_step_compute_bkg_config.rejlow, 00649 hawki_step_compute_bkg_config.rejhigh, 00650 recipe_framelist, 00651 recipe_parlist) !=0) 00652 { 00653 cpl_msg_error(__func__,"Could not compute objects running median"); 00654 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00655 cpl_bivector_delete(offsets[idet]); 00656 cpl_free(offsets); 00657 cpl_msg_indent_less(); 00658 return -1; 00659 } 00660 00661 /* Free */ 00662 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00663 cpl_bivector_delete(offsets[idet]); 00664 cpl_free(offsets); 00665 } 00666 cpl_msg_indent_less(); 00667 00668 00669 /* Freeing and exit */ 00670 return 0; 00671 } 00672 00673 int hawki_step_compute_bkg_from_running_median_nonmasked_save 00674 (const cpl_frameset * objframes, 00675 int nhalf_window, 00676 int rejlow, 00677 int rejhigh, 00678 cpl_frameset * recipe_framelist, 00679 cpl_parameterlist * recipe_parlist) 00680 { 00681 int iext; 00682 int iobj; 00683 int nobj; 00684 const char * recipe_name = "hawki_step_compute_bkg"; 00685 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00686 00687 /* Preparing the files to save */ 00688 cpl_msg_info(__func__,"Preparing the output files"); 00689 nobj = cpl_frameset_get_size(objframes); 00690 for (iobj=0 ; iobj<nobj ; ++iobj) 00691 { 00692 cpl_frameset * used_frameset; 00693 const cpl_frame * target_frame; 00694 char filename[256]; 00695 snprintf(filename, 256, "hawki_step_compute_bkg_%03d.fits", iobj + 1); 00696 target_frame = cpl_frameset_get_frame_const(objframes, iobj); 00697 used_frameset = cpl_frameset_new(); 00698 cpl_frameset_insert(used_frameset, cpl_frame_duplicate(target_frame)); 00699 hawki_main_header_save(recipe_framelist, 00700 recipe_parlist, 00701 used_frameset, 00702 recipe_name, 00703 HAWKI_CALPRO_BKGIMAGE, 00704 HAWKI_PROTYPE_BKGIMAGE, 00705 NULL, 00706 filename); 00707 snprintf(filename, 256, "hawki_step_compute_bkg_bpm_%03d.fits", iobj + 1); 00708 hawki_main_header_save(recipe_framelist, 00709 recipe_parlist, 00710 used_frameset, 00711 recipe_name, 00712 HAWKI_CALPRO_BKGBPM, 00713 HAWKI_PROTYPE_BKGBPM, 00714 NULL, 00715 filename); 00716 cpl_frameset_delete(used_frameset); 00717 } 00718 00719 /* Loop on extensions */ 00720 cpl_msg_indent_more(); 00721 for(iext = 0; iext < HAWKI_NB_DETECTORS; ++iext) 00722 { 00723 cpl_imagelist * img_serie; 00724 cpl_vector * medians; 00725 00726 /* Info message */ 00727 cpl_msg_info(__func__,"Working on extension %d", iext + 1); 00728 00729 /* Loading the object frame */ 00730 img_serie = hawki_load_extensions(objframes, iext + 1, CPL_TYPE_FLOAT); 00731 if(img_serie== NULL) 00732 { 00733 cpl_msg_error(__func__, "Error reading object image") ; 00734 return -1; 00735 } 00736 00737 /* Pre-compute median value in each plane */ 00738 medians = cpl_vector_new(nobj); 00739 for (iobj=0 ; iobj<nobj ; iobj++) 00740 { 00741 cpl_vector_set 00742 (medians, 00743 iobj, 00744 cpl_image_get_median(cpl_imagelist_get(img_serie, iobj))) ; 00745 } 00746 00747 cpl_msg_indent_more(); 00748 for(iobj = 0 ; iobj < nobj ; ++iobj) 00749 { 00750 int nx; 00751 int ny; 00752 cpl_image * this_bkg_image; 00753 cpl_image * this_bkg_image_mask; 00754 char filename[256]; 00755 00756 /* Info message */ 00757 cpl_msg_info(__func__,"Computing bkg for image %d", iobj + 1); 00758 00759 /* Creates the background image */ 00760 nx = cpl_image_get_size_x(cpl_imagelist_get(img_serie, 0)); 00761 ny = cpl_image_get_size_y(cpl_imagelist_get(img_serie, 0)); 00762 this_bkg_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT); 00763 00764 /* Actually computing the running mean */ 00765 if(hawki_bkg_from_running_mean_detector 00766 (img_serie, 00767 medians, 00768 iobj, 00769 nhalf_window, 00770 rejlow, 00771 rejhigh, 00772 this_bkg_image) != 0) 00773 { 00774 cpl_msg_error(__func__, "Cannot compute bkg"); 00775 cpl_vector_delete(medians); 00776 cpl_imagelist_delete(img_serie); 00777 cpl_image_delete(this_bkg_image); 00778 return -1; 00779 } 00780 00781 /* Save the extension bad pixel mask */ 00782 this_bkg_image_mask = 00783 cpl_image_new_from_mask(cpl_image_get_bpm(this_bkg_image)); 00784 snprintf(filename, 256, "hawki_step_compute_bkg_bpm_%03d.fits",iobj +1); 00785 hawki_image_ext_save 00786 (objframes, 00787 this_bkg_image_mask, 00788 iext + 1, 00789 NULL, 00790 filename); 00791 00792 /* Interpolate bad pixels */ 00793 hawki_step_compute_bkg_interpolate_badpix(this_bkg_image); 00794 00795 /* Save this extension */ 00796 snprintf(filename, 256, "hawki_step_compute_bkg_%03d.fits",iobj +1); 00797 hawki_image_ext_save 00798 (objframes, 00799 this_bkg_image, 00800 iext + 1, 00801 NULL, 00802 filename); 00803 00804 /* Free */ 00805 cpl_image_delete(this_bkg_image); 00806 cpl_image_delete(this_bkg_image_mask); 00807 } 00808 cpl_msg_indent_less(); 00809 00810 /* Freeing */ 00811 cpl_vector_delete(medians); 00812 cpl_imagelist_delete(img_serie); 00813 } 00814 cpl_msg_indent_less(); 00815 if(!cpl_errorstate_is_equal(error_prevstate)) 00816 { 00817 cpl_msg_warning(__func__,"Probably some data could not be saved. " 00818 "Check permisions or disk space"); 00819 cpl_errorstate_set(CPL_ERROR_NONE); 00820 return 1; 00821 } 00822 return 0; 00823 } 00824 00825 int hawki_step_compute_bkg_from_running_median_masked_save 00826 (const cpl_frameset * objframes, 00827 cpl_frame * maskframe, 00828 cpl_bivector ** offsets, 00829 cpl_frame * x_distortionframe, 00830 cpl_frame * y_distortionframe, 00831 int nhalf_window, 00832 int rejlow, 00833 int rejhigh, 00834 cpl_frameset * recipe_framelist, 00835 cpl_parameterlist * recipe_parlist) 00836 { 00837 int iext; /* 0 to HAWKI_NB_DETECTORS-1 */ 00838 int idet; /* 1 to HAWKI_NB_DETECTORS */ 00839 int iobj; /* 0 to obj-1 */ 00840 int nobj; 00841 const char * recipe_name = "hawki_step_compute_bkg"; 00842 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00843 cpl_frameset * calib_frameset; 00844 00845 00846 //Add all the used frames 00847 calib_frameset = cpl_frameset_new(); 00848 cpl_frameset_insert(calib_frameset, cpl_frame_duplicate(maskframe)); 00849 if(x_distortionframe != NULL) 00850 cpl_frameset_insert(calib_frameset, cpl_frame_duplicate(x_distortionframe)); 00851 if(y_distortionframe != NULL) 00852 cpl_frameset_insert(calib_frameset, cpl_frame_duplicate(y_distortionframe)); 00853 00854 /* Preparing the files to save */ 00855 cpl_msg_info(__func__,"Preparing the final files"); 00856 nobj = cpl_frameset_get_size(objframes); 00857 for (iobj=0 ; iobj<nobj ; ++iobj) 00858 { 00859 cpl_frameset * used_frameset; 00860 const cpl_frame * target_frame; 00861 char filename[256]; 00862 snprintf(filename, 256, "hawki_step_compute_bkg_%03d.fits", iobj + 1); 00863 target_frame = cpl_frameset_get_frame_const(objframes, iobj); 00864 used_frameset = cpl_frameset_duplicate(calib_frameset); 00865 cpl_frameset_insert(used_frameset, cpl_frame_duplicate(target_frame)); 00866 cpl_frameset_insert(calib_frameset, cpl_frame_duplicate(maskframe)); 00867 hawki_main_header_save(recipe_framelist, 00868 recipe_parlist, 00869 used_frameset, 00870 recipe_name, 00871 HAWKI_CALPRO_BKGIMAGE, 00872 HAWKI_PROTYPE_BKGIMAGE, 00873 NULL, 00874 filename); 00875 snprintf(filename, 256, "hawki_step_compute_bkg_bpm_%03d.fits", iobj + 1); 00876 hawki_main_header_save(recipe_framelist, 00877 recipe_parlist, 00878 used_frameset, 00879 recipe_name, 00880 HAWKI_CALPRO_BKGBPM, 00881 HAWKI_PROTYPE_BKGBPM, 00882 NULL, 00883 filename); 00884 cpl_frameset_delete(used_frameset); 00885 } 00886 cpl_frameset_delete(calib_frameset); 00887 00888 /* Loop on extensions */ 00889 cpl_msg_indent_more(); 00890 for(iext = 0; iext < HAWKI_NB_DETECTORS; ++iext) 00891 { 00892 cpl_imagelist * img_serie; 00893 cpl_vector * medians; 00894 cpl_image * mask; 00895 hawki_distortion * inv_distortion = NULL; 00896 cpl_propertylist * prop_list; 00897 cpl_image * dist_x = NULL; 00898 cpl_image * dist_y = NULL; 00899 double mask_off_x; 00900 double mask_off_y; 00901 00902 cpl_msg_info(__func__,"Working on extension %d", iext + 1); 00903 cpl_msg_indent_more(); 00904 00905 /* Loading the object frames */ 00906 img_serie = hawki_load_extensions(objframes, iext + 1, CPL_TYPE_FLOAT); 00907 if(img_serie== NULL) 00908 { 00909 cpl_msg_error(__func__, "Error reading object image") ; 00910 cpl_msg_indent_less(); 00911 return -1; 00912 } 00913 nobj = cpl_imagelist_get_size(img_serie); 00914 00915 /* Loading the mask frame */ 00916 mask = hawki_load_frame_extension(maskframe, iext + 1, CPL_TYPE_FLOAT); 00917 if(mask == NULL) 00918 { 00919 cpl_msg_error(__func__, "Error reading mask image"); 00920 cpl_msg_indent_less(); 00921 cpl_msg_indent_less(); 00922 return -1; 00923 } 00924 idet = 00925 hawki_get_detector_from_ext(cpl_frame_get_filename(maskframe), iext+1); 00926 prop_list = 00927 cpl_propertylist_load(cpl_frame_get_filename(maskframe), iext + 1); 00928 mask_off_x = hawki_pfits_get_comb_cumoffsetx(prop_list); 00929 mask_off_y = hawki_pfits_get_comb_cumoffsety(prop_list); 00930 /* Change the offsets to cpl convention */ 00931 mask_off_x *= -1; 00932 mask_off_y *= -1; 00933 if(!cpl_errorstate_is_equal(CPL_ERROR_NONE)) 00934 { 00935 cpl_msg_error(__func__,"Could not get the offsets from mask file.\n" 00936 "Keywords %s are missing","ESO QC COMBINED CUMOFFSET{X,Y}"); 00937 cpl_imagelist_delete(img_serie); 00938 cpl_image_delete(mask); 00939 cpl_msg_indent_less(); 00940 cpl_msg_indent_less(); 00941 cpl_propertylist_delete(prop_list); 00942 return -1; 00943 } 00944 cpl_msg_info(__func__,"Mask offsets: %f %f", mask_off_x, mask_off_y); 00945 00946 if(x_distortionframe != NULL && y_distortionframe != NULL) 00947 { 00948 int nx; 00949 int ny; 00950 00951 /* Load the distortion */ 00952 if ((inv_distortion = hawki_distortion_load 00953 (x_distortionframe, y_distortionframe, idet)) == NULL) 00954 { 00955 cpl_imagelist_delete(img_serie); 00956 cpl_propertylist_delete(prop_list); 00957 cpl_image_delete(mask); 00958 cpl_msg_error(__func__, 00959 "Cannot load distortion for chip %d",idet); 00960 cpl_msg_indent_less(); 00961 cpl_msg_indent_less(); 00962 return -1 ; 00963 } 00964 /* Multiply distortion by -1, to get the inverse distortion */ 00965 cpl_image_multiply_scalar(inv_distortion->dist_x, -1.); 00966 cpl_image_multiply_scalar(inv_distortion->dist_y, -1.); 00967 /* Create the distortion maps */ 00968 nx = cpl_image_get_size_x(mask); 00969 ny = cpl_image_get_size_y(mask); 00970 dist_x = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE); 00971 dist_y = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE); 00972 if (hawki_distortion_create_maps_detector 00973 (inv_distortion, dist_x, dist_y)) 00974 { 00975 cpl_msg_error(__func__, "Cannot create the distortion maps") ; 00976 cpl_imagelist_delete(img_serie); 00977 cpl_propertylist_delete(prop_list); 00978 cpl_image_delete(mask); 00979 cpl_image_delete(dist_x); 00980 cpl_image_delete(dist_y); 00981 hawki_distortion_delete(inv_distortion); 00982 cpl_msg_indent_less(); 00983 cpl_msg_indent_less(); 00984 return -1; 00985 } 00986 00987 } 00988 00989 /* Creating a different mask for each object, using the offsets 00990 * and the distortion (if applies) */ 00991 cpl_msg_info(__func__,"Constructing the masks"); 00992 for (iobj=0 ; iobj<nobj ; iobj++) 00993 { 00994 cpl_image * mask_shifted; 00995 cpl_image * mask_trim; 00996 cpl_mask * mask_final; 00997 cpl_image * target_image; 00998 cpl_vector * off_x; 00999 cpl_vector * off_y; 01000 01001 /* Retrieve the offsets. Warning, it is in chip order */ 01002 off_x = cpl_bivector_get_x(offsets[idet-1]); 01003 off_y = cpl_bivector_get_y(offsets[idet-1]); 01004 01005 target_image = cpl_imagelist_get(img_serie, iobj); 01006 mask_shifted = cpl_image_duplicate(mask); 01007 cpl_image_shift(mask_shifted, 01008 -(int)(cpl_vector_get(off_x, iobj) - mask_off_x), 01009 -(int)(cpl_vector_get(off_y, iobj) - mask_off_y)); 01010 if(x_distortionframe != NULL && y_distortionframe != NULL) 01011 { 01012 cpl_image * mask_distcorr; 01013 01014 /* Dedistort the mask */ 01015 mask_distcorr = hawki_distortion_correct_detector 01016 (mask_shifted, dist_x, dist_y); 01017 if(mask_distcorr == NULL) 01018 { 01019 cpl_msg_error(__func__, "Cannot correct the distortion") ; 01020 cpl_image_delete(dist_x); 01021 cpl_image_delete(dist_y); 01022 cpl_image_delete(mask_shifted); 01023 cpl_imagelist_delete(img_serie); 01024 cpl_image_delete(mask); 01025 cpl_propertylist_delete(prop_list); 01026 hawki_distortion_delete(inv_distortion); 01027 cpl_msg_indent_less(); 01028 cpl_msg_indent_less(); 01029 return -1 ; 01030 } 01031 mask_trim = cpl_image_extract 01032 (mask_distcorr, 1, 1, 01033 cpl_image_get_size_x(target_image), 01034 cpl_image_get_size_y(target_image)); 01035 cpl_image_delete(mask_distcorr); 01036 } 01037 else 01038 { 01039 mask_trim = cpl_image_extract 01040 (mask_shifted, 1, 1, 01041 cpl_image_get_size_x(target_image), 01042 cpl_image_get_size_y(target_image)); 01043 } 01044 mask_final = 01045 cpl_mask_threshold_image_create(mask_trim, 0.5, FLT_MAX); 01046 /* TODO: Add the current bpm to this mask? */ 01047 cpl_image_reject_from_mask 01048 (target_image, mask_final); 01049 cpl_image_delete(mask_shifted); 01050 cpl_image_delete(mask_trim); 01051 cpl_mask_delete(mask_final); 01052 } 01053 01054 /* Pre-compute median value in each plane */ 01055 cpl_msg_info(__func__,"Computing the medians"); 01056 medians = cpl_vector_new(nobj); 01057 for (iobj=0 ; iobj<nobj ; iobj++) 01058 { 01059 cpl_vector_set 01060 (medians, 01061 iobj, 01062 cpl_image_get_median(cpl_imagelist_get(img_serie, iobj))) ; 01063 } 01064 01065 /* Object loop to get the bkg */ 01066 cpl_msg_info(__func__,"Computing backgrounds"); 01067 cpl_msg_indent_more(); 01068 for(iobj = 0 ; iobj < nobj ; ++iobj) 01069 { 01070 int nx; 01071 int ny; 01072 cpl_image * this_bkg_image; 01073 cpl_image * this_bkg_image_mask; 01074 char filename[256]; 01075 01076 /* Creates the background image */ 01077 cpl_msg_info(__func__,"Computing bkg for image %d", iobj + 1); 01078 nx = cpl_image_get_size_x(cpl_imagelist_get(img_serie, 0)); 01079 ny = cpl_image_get_size_y(cpl_imagelist_get(img_serie, 0)); 01080 this_bkg_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT); 01081 01082 /* Actually computing the running mean */ 01083 if(hawki_bkg_from_running_mean_detector 01084 (img_serie, 01085 medians, 01086 iobj, 01087 nhalf_window, 01088 rejlow, 01089 rejhigh, 01090 this_bkg_image) != 0) 01091 { 01092 cpl_msg_error(__func__, "Cannot compute bkg"); 01093 cpl_image_delete(this_bkg_image); 01094 cpl_vector_delete(medians); 01095 cpl_imagelist_delete(img_serie); 01096 cpl_image_delete(mask); 01097 cpl_propertylist_delete(prop_list); 01098 if(x_distortionframe != NULL && y_distortionframe != NULL) 01099 { 01100 hawki_distortion_delete(inv_distortion); 01101 cpl_image_delete(dist_x); 01102 cpl_image_delete(dist_y); 01103 } 01104 cpl_msg_indent_less(); 01105 cpl_msg_indent_less(); 01106 cpl_msg_indent_less(); 01107 return -1; 01108 } 01109 01110 /* Save the extension bad pixel mask */ 01111 this_bkg_image_mask = 01112 cpl_image_new_from_mask(cpl_image_get_bpm(this_bkg_image)); 01113 snprintf(filename, 256, "hawki_step_compute_bkg_bpm_%03d.fits",iobj +1); 01114 hawki_image_ext_save 01115 (objframes, 01116 this_bkg_image_mask, 01117 iext + 1, 01118 NULL, 01119 filename); 01120 01121 /* Interpolate bad pixels */ 01122 hawki_step_compute_bkg_interpolate_badpix(this_bkg_image); 01123 01124 /* Save this extension */ 01125 snprintf(filename, 256, "hawki_step_compute_bkg_%03d.fits",iobj +1); 01126 hawki_image_ext_save 01127 (objframes, 01128 this_bkg_image, 01129 iext + 1, 01130 NULL, 01131 filename); 01132 01133 /* Free */ 01134 cpl_image_delete(this_bkg_image); 01135 cpl_image_delete(this_bkg_image_mask); 01136 } 01137 cpl_msg_indent_less(); 01138 01139 /* Freeing */ 01140 cpl_vector_delete(medians); 01141 cpl_imagelist_delete(img_serie); 01142 cpl_image_delete(mask); 01143 cpl_propertylist_delete(prop_list); 01144 if(x_distortionframe != NULL && y_distortionframe != NULL) 01145 { 01146 hawki_distortion_delete(inv_distortion); 01147 cpl_image_delete(dist_x); 01148 cpl_image_delete(dist_y); 01149 } 01150 cpl_msg_indent_less(); 01151 } 01152 cpl_msg_indent_less(); 01153 if(!cpl_errorstate_is_equal(error_prevstate)) 01154 { 01155 cpl_msg_warning(__func__,"Probably some data could not be saved. " 01156 "Check permissions or disk space"); 01157 cpl_errorstate_set(CPL_ERROR_NONE); 01158 return 1; 01159 } 01160 return 0; 01161 } 01162 01163 /*----------------------------------------------------------------------------*/ 01169 /*----------------------------------------------------------------------------*/ 01170 static int hawki_step_compute_bkg_interpolate_badpix 01171 (cpl_image * image) 01172 { 01173 int nbadpixels = cpl_image_count_rejected(image); 01174 if(nbadpixels !=0) 01175 cpl_msg_info(__func__,"Number of pixels with no background available: %d ", 01176 nbadpixels); 01177 if(cpl_image_count_rejected(image) > 0) 01178 { 01179 int ipix,npix; 01180 double median = cpl_image_get_median(image); 01181 const cpl_binary * bpm = cpl_mask_get_data_const 01182 (cpl_image_get_bpm(image)); 01183 float * image_p = (float*)cpl_image_get_data(image); 01184 cpl_msg_warning(__func__,"Substituting pixels with no bkg with median of image %f",median); 01185 npix = cpl_image_get_size_x(image) * cpl_image_get_size_y(image); 01186 for(ipix = 0; ipix < npix; ipix++) 01187 { 01188 if (bpm[ipix]) 01189 { 01190 image_p[ipix] = median; 01191 } 01192 } 01193 //This cannot be used until DFS08929 is solved 01194 //cpl_detector_interpolate_rejected(image); 01195 } 01196 return 0; 01197 } 01198 01199 int hawki_step_compute_bkg_retrieve_input_param 01200 (cpl_parameterlist * parlist) 01201 { 01202 cpl_parameter * par ; 01203 01204 par = NULL ; 01205 par = cpl_parameterlist_find 01206 (parlist, "hawki.hawki_step_compute_bkg.nmin_comb"); 01207 hawki_step_compute_bkg_config.nmin_comb = cpl_parameter_get_int(par); 01208 01209 par = cpl_parameterlist_find 01210 (parlist, "hawki.hawki_step_compute_bkg.nhalf_window"); 01211 hawki_step_compute_bkg_config.nhalf_window = cpl_parameter_get_int(par); 01212 01213 par = cpl_parameterlist_find 01214 (parlist, "hawki.hawki_step_compute_bkg.rejlow"); 01215 hawki_step_compute_bkg_config.rejlow = cpl_parameter_get_int(par); 01216 01217 par = cpl_parameterlist_find 01218 (parlist, "hawki.hawki_step_compute_bkg.rejhigh"); 01219 hawki_step_compute_bkg_config.rejhigh = cpl_parameter_get_int(par); 01220 01221 return 0; 01222 }
1.7.3