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