|
HAWKI Pipeline Reference Manual 1.8.10
|
00001 /* $Id: hawki_step_combine.c,v 1.25 2012/11/30 14:50:51 cgarcia Exp $ 00002 * 00003 * This file is part of the HAWKI 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: cgarcia $ 00023 * $Date: 2012/11/30 14:50:51 $ 00024 * $Revision: 1.25 $ 00025 * $Name: hawki-1_8_10 $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 Includes 00034 -----------------------------------------------------------------------------*/ 00035 00036 #include <math.h> 00037 #include <cpl.h> 00038 #include <string.h> 00039 00040 #include "irplib_utils.h" 00041 #include "irplib_calib.h" 00042 00043 #include "hawki_utils.h" 00044 #include "hawki_calib.h" 00045 #include "hawki_load.h" 00046 #include "hawki_save.h" 00047 #include "hawki_pfits.h" 00048 #include "hawki_dfs.h" 00049 #include "hawki_saa.h" 00050 #include "hawki_bkg.h" 00051 #include "hawki_distortion.h" 00052 #include "hawki_properties_tel.h" 00053 #include "hawki_image_stats.h" 00054 00055 /*----------------------------------------------------------------------------- 00056 Functions prototypes 00057 -----------------------------------------------------------------------------*/ 00058 00059 #ifdef __cplusplus 00060 extern "C" 00061 #endif 00062 int cpl_plugin_get_info(cpl_pluginlist * list); 00063 00064 static int hawki_step_combine_create(cpl_plugin *) ; 00065 static int hawki_step_combine_exec(cpl_plugin *) ; 00066 static int hawki_step_combine_destroy(cpl_plugin *) ; 00067 static int hawki_step_combine(cpl_parameterlist *, cpl_frameset *) ; 00068 00069 static int hawki_step_combine_retrieve_input_param 00070 (cpl_parameterlist * parlist); 00071 static cpl_image ** hawki_step_combine_apply_comb 00072 (cpl_frameset * obj, 00073 cpl_frameset * offsets, 00074 cpl_frameset * bpm, 00075 cpl_frameset * bkg_bpm_frames); 00076 static cpl_image ** hawki_step_combine_chip 00077 (cpl_imagelist * in, 00078 cpl_bivector * offsets, 00079 double * pos_x, 00080 double * pos_y); 00081 static int hawki_step_combine_interpolate_badpix 00082 (cpl_image * image); 00083 static int hawki_step_combine_save 00084 (cpl_image ** combined, 00085 cpl_image ** contrib_map, 00086 cpl_frameset * used_frames, 00087 cpl_parameterlist * parlist, 00088 cpl_frameset * recipe_frameset); 00089 00090 /*----------------------------------------------------------------------------- 00091 Static variables 00092 -----------------------------------------------------------------------------*/ 00093 00094 static struct 00095 { 00096 /* Inputs */ 00097 int offset_max ; 00098 int borders ; 00099 cpl_geom_combine comb_meth ; 00100 int rej_low; 00101 int rej_high; 00102 cpl_kernel resamp_kernel; 00103 } hawki_step_combine_config; 00104 00105 static struct 00106 { 00107 /* Outputs */ 00108 double mean_airmass; 00109 double combined_pos_x[HAWKI_NB_DETECTORS]; 00110 double combined_pos_y[HAWKI_NB_DETECTORS]; 00111 double combined_cumoffset_x[HAWKI_NB_DETECTORS]; 00112 double combined_cumoffset_y[HAWKI_NB_DETECTORS]; 00113 } hawki_step_combine_output; 00114 00115 static char hawki_step_combine_description[] = 00116 "hawki_step_combine -- hawki combine jitter images.\n" 00117 "The files listed in the Set Of Frames (sof-file) must be tagged:\n" 00118 "science-file.fits "HAWKI_CALPRO_DIST_CORRECTED" or\n" 00119 "science-file.fits "HAWKI_CALPRO_BKG_SUBTRACTED" or\n" 00120 "bpm-file.fits "HAWKI_CALPRO_BPM" (optional) \n" 00121 "bkg_bpm-file.fits "HAWKI_CALPRO_BKGBPM" (optional) \n" 00122 "offsets-file.fits "HAWKI_CALPRO_OFFSETS" (optional) \n" 00123 "The recipe creates as an output:\n" 00124 "hawki_step_combine.fits ("HAWKI_CALPRO_COMBINED"): \n" 00125 "The recipe does the following steps:\n" 00126 "-Allocate an image with the proper combined size \n" 00127 " (depends on parameters --comb_meth and --borders)\n" 00128 "-Retrieve the offsets either from the offsets-file.fits or from the header\n" 00129 "-For each combined pixel, the contribution of each individual frame \n" 00130 " is added using a resampling kernel. If any of the pixels involved in\n" 00131 " the resampling is a bad pixel (defined in bpm-file.fits), it is not\n" 00132 " taken into account.\n" 00133 " With the remaining pixels a minmax rejection is performed\n" 00134 "Return code:\n" 00135 "esorex exits with an error code of 0 if the recipe completes successfully\n" 00136 "or 1 otherwise"; 00137 00138 /*----------------------------------------------------------------------------- 00139 Functions code 00140 -----------------------------------------------------------------------------*/ 00141 00142 /*----------------------------------------------------------------------------*/ 00150 /*----------------------------------------------------------------------------*/ 00151 int cpl_plugin_get_info(cpl_pluginlist * list) 00152 { 00153 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ; 00154 cpl_plugin * plugin = &recipe->interface ; 00155 00156 cpl_plugin_init(plugin, 00157 CPL_PLUGIN_API, 00158 HAWKI_BINARY_VERSION, 00159 CPL_PLUGIN_TYPE_RECIPE, 00160 "hawki_step_combine", 00161 "Jitter image combination recipe", 00162 hawki_step_combine_description, 00163 "Cesar Enrique Garcia Dabo", 00164 PACKAGE_BUGREPORT, 00165 hawki_get_license(), 00166 hawki_step_combine_create, 00167 hawki_step_combine_exec, 00168 hawki_step_combine_destroy) ; 00169 00170 cpl_pluginlist_append(list, plugin) ; 00171 00172 return 0; 00173 } 00174 00175 /*----------------------------------------------------------------------------*/ 00184 /*----------------------------------------------------------------------------*/ 00185 static int hawki_step_combine_create(cpl_plugin * plugin) 00186 { 00187 cpl_recipe * recipe ; 00188 cpl_parameter * p ; 00189 00190 /* Get the recipe out of the plugin */ 00191 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00192 recipe = (cpl_recipe *)plugin ; 00193 else return -1 ; 00194 00195 /* Create the parameters list in the cpl_recipe object */ 00196 recipe->parameters = cpl_parameterlist_new() ; 00197 if (recipe->parameters == NULL) 00198 return 1; 00199 00200 /* Fill the parameters list */ 00201 /* --offset_max */ 00202 p = cpl_parameter_new_value("hawki.hawki_step_combine.offset_max", 00203 CPL_TYPE_INT, 00204 "Maximum offset allowed", 00205 "hawki.hawki_step_combine", 00206 1500) ; 00207 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "offset_max") ; 00208 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00209 cpl_parameterlist_append(recipe->parameters, p) ; 00210 00211 /* --comb_meth */ 00212 p = cpl_parameter_new_value("hawki.hawki_step_combine.comb_meth", 00213 CPL_TYPE_STRING, 00214 "Final size of combination (union / inter / first)", 00215 "hawki.hawki_step_combine", 00216 "union") ; 00217 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "comb_meth") ; 00218 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00219 cpl_parameterlist_append(recipe->parameters, p) ; 00220 00221 /* --rej */ 00222 p = cpl_parameter_new_value("hawki.hawki_step_combine.rej", 00223 CPL_TYPE_STRING, 00224 "Low and high number of rejected values", 00225 "hawki.hawki_step_combine", 00226 "1,1") ; 00227 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rej") ; 00228 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00229 cpl_parameterlist_append(recipe->parameters, p) ; 00230 00231 /* --borders */ 00232 p = cpl_parameter_new_value("hawki.hawki_step_combine.borders", 00233 CPL_TYPE_INT, 00234 "Border pixels trimmed", 00235 "hawki.hawki_step_combine", 00236 4) ; 00237 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "borders") ; 00238 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00239 cpl_parameterlist_append(recipe->parameters, p) ; 00240 00241 /* --resamp_kernel */ 00242 p = cpl_parameter_new_value("hawki.hawki_step_combine.resamp_kernel", 00243 CPL_TYPE_STRING, 00244 "Resampling kernel (default/tanh/sinc/sinc2/lanczos/hamming/hann)", 00245 "hawki.hawki_step_combine", 00246 "default") ; 00247 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "resamp_kernel") ; 00248 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00249 cpl_parameterlist_append(recipe->parameters, p) ; 00250 00251 /* Return */ 00252 return 0; 00253 } 00254 00255 /*----------------------------------------------------------------------------*/ 00261 /*----------------------------------------------------------------------------*/ 00262 static int hawki_step_combine_exec(cpl_plugin * plugin) 00263 { 00264 cpl_recipe * recipe ; 00265 00266 /* Get the recipe out of the plugin */ 00267 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00268 recipe = (cpl_recipe *)plugin ; 00269 else return -1 ; 00270 00271 /* Issue a banner */ 00272 hawki_print_banner(); 00273 00274 return hawki_step_combine(recipe->parameters, recipe->frames) ; 00275 } 00276 00277 /*----------------------------------------------------------------------------*/ 00283 /*----------------------------------------------------------------------------*/ 00284 static int hawki_step_combine_destroy(cpl_plugin * plugin) 00285 { 00286 cpl_recipe * recipe ; 00287 00288 /* Get the recipe out of the plugin */ 00289 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00290 recipe = (cpl_recipe *)plugin ; 00291 else return -1 ; 00292 00293 cpl_parameterlist_delete(recipe->parameters) ; 00294 return 0 ; 00295 } 00296 00297 /*----------------------------------------------------------------------------*/ 00304 /*----------------------------------------------------------------------------*/ 00305 static int hawki_step_combine( 00306 cpl_parameterlist * parlist, 00307 cpl_frameset * framelist) 00308 { 00309 cpl_frameset * objframes ; 00310 cpl_frameset * offsets; 00311 cpl_frameset * bpm; 00312 cpl_frameset * bpmbkg; 00313 cpl_frameset * used_frames; 00314 cpl_image ** combined_contrib; 00315 cpl_image ** combined; 00316 cpl_image ** contrib_map; 00317 int idet; 00318 00319 /* Retrieve input parameters */ 00320 if(hawki_step_combine_retrieve_input_param(parlist)) 00321 { 00322 cpl_msg_error(__func__, "Wrong parameters"); 00323 return -1; 00324 } 00325 00326 /* Identify the RAW and CALIB frames in the input frameset */ 00327 if (hawki_dfs_set_groups(framelist)) { 00328 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00329 return -1 ; 00330 } 00331 00332 /* Retrieve raw frames */ 00333 objframes = hawki_extract_frameset(framelist, HAWKI_CALPRO_DIST_CORRECTED); 00334 if (objframes == NULL) 00335 { 00336 objframes = hawki_extract_frameset 00337 (framelist, HAWKI_CALPRO_BKG_SUBTRACTED); 00338 if (objframes == NULL) 00339 { 00340 cpl_msg_error(__func__,"Cannot find objs frames in the input list (%s or %s)", 00341 HAWKI_CALPRO_DIST_CORRECTED, HAWKI_CALPRO_BKG_SUBTRACTED); 00342 return -1 ; 00343 } 00344 } 00345 used_frames = cpl_frameset_duplicate(objframes); 00346 00347 /* Retrieve the refined offsets, if provided */ 00348 offsets = hawki_extract_frameset(framelist, HAWKI_CALPRO_OFFSETS); 00349 if(offsets) 00350 cpl_frameset_insert(used_frames, cpl_frame_duplicate( 00351 cpl_frameset_get_first(offsets))); 00352 00353 /* Retrieve the general bad pixel mask, if provided */ 00354 bpm = hawki_extract_frameset(framelist, HAWKI_CALPRO_BPM); 00355 if(bpm) 00356 cpl_frameset_insert(used_frames, cpl_frame_duplicate( 00357 cpl_frameset_get_first(bpm))); 00358 00359 /* Retrieve the background bad pixel masks, if provided */ 00360 bpmbkg = hawki_extract_frameset(framelist, HAWKI_CALPRO_BKGBPM); 00361 if(bpmbkg) 00362 { 00363 int iframe; 00364 for(iframe=0; iframe < cpl_frameset_get_size(bpmbkg); iframe++) 00365 cpl_frameset_insert(used_frames, cpl_frame_duplicate( 00366 cpl_frameset_get_frame(bpmbkg,iframe))); 00367 if(cpl_frameset_get_size(bpmbkg) != cpl_frameset_get_size(objframes)) 00368 { 00369 cpl_msg_error(__func__,"Incompatible number of science and bad bkg" 00370 " images."); 00371 cpl_msg_error(__func__,"Supply as many bad bkg images as objects"); 00372 cpl_frameset_delete(objframes); 00373 cpl_frameset_delete(used_frames); 00374 cpl_frameset_delete(offsets); 00375 cpl_frameset_delete(bpm); 00376 cpl_frameset_delete(bpmbkg); 00377 return -1; 00378 } 00379 } 00380 00381 /* Apply the combination */ 00382 cpl_msg_info(__func__, "Apply the data recombination"); 00383 cpl_msg_indent_more() ; 00384 if ((combined_contrib = hawki_step_combine_apply_comb 00385 (objframes, offsets, bpm, bpmbkg)) == NULL) 00386 { 00387 cpl_msg_error(__func__, "Cannot combine the data"); 00388 cpl_frameset_delete(objframes); 00389 cpl_frameset_delete(used_frames); 00390 if(offsets != NULL) 00391 cpl_frameset_delete(offsets); 00392 if(bpm != NULL) 00393 cpl_frameset_delete(bpm); 00394 cpl_msg_indent_less() ; 00395 return -1 ; 00396 } 00397 00398 /* Get both the combination and the contribution map */ 00399 combined = combined_contrib; 00400 contrib_map = combined_contrib + HAWKI_NB_DETECTORS; 00401 cpl_msg_indent_less() ; 00402 cpl_frameset_delete(objframes); 00403 if(offsets != NULL) 00404 cpl_frameset_delete(offsets); 00405 if(bpm != NULL) 00406 cpl_frameset_delete(bpm); 00407 if(bpmbkg != NULL) 00408 cpl_frameset_delete(bpmbkg); 00409 00410 /* Save the products */ 00411 cpl_msg_info(__func__, "Save the products") ; 00412 cpl_msg_indent_more() ; 00413 if (hawki_step_combine_save(combined, contrib_map, 00414 used_frames, parlist, framelist) != 0) 00415 { 00416 cpl_msg_warning(__func__, "Some error happened saving the data. " 00417 "Check permisions or disk space") ; 00418 for(idet=0; idet< 2 * HAWKI_NB_DETECTORS; ++idet) 00419 cpl_image_delete(combined_contrib[idet]); 00420 cpl_frameset_delete(used_frames); 00421 cpl_free(combined_contrib); 00422 cpl_msg_indent_less() ; 00423 return -1 ; 00424 } 00425 cpl_msg_indent_less() ; 00426 00427 /* Return */ 00428 for(idet=0; idet< 2 * HAWKI_NB_DETECTORS; ++idet) 00429 cpl_image_delete(combined_contrib[idet]); 00430 cpl_free(combined_contrib); 00431 cpl_frameset_delete(used_frames); 00432 00433 /* Return */ 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 else return 0 ; 00441 } 00442 00443 int hawki_step_combine_retrieve_input_param 00444 (cpl_parameterlist * parlist) 00445 { 00446 cpl_parameter * par ; 00447 const char * sval ; 00448 par = NULL ; 00449 par = cpl_parameterlist_find(parlist, 00450 "hawki.hawki_step_combine.offset_max"); 00451 hawki_step_combine_config.offset_max = cpl_parameter_get_int(par); 00452 par = cpl_parameterlist_find(parlist, 00453 "hawki.hawki_step_combine.comb_meth"); 00454 sval = cpl_parameter_get_string(par); 00455 if (!strcmp(sval, "union")) 00456 hawki_step_combine_config.comb_meth = CPL_GEOM_UNION; 00457 else if (!strcmp(sval, "inter")) 00458 hawki_step_combine_config.comb_meth = CPL_GEOM_INTERSECT; 00459 else if (!strcmp(sval, "first")) 00460 hawki_step_combine_config.comb_meth = CPL_GEOM_FIRST; 00461 else 00462 { 00463 cpl_msg_error(__func__, "Invalid combine method specified"); 00464 return -1; 00465 } 00466 par = cpl_parameterlist_find(parlist, 00467 "hawki.hawki_step_combine.borders"); 00468 hawki_step_combine_config.borders = cpl_parameter_get_int(par); 00469 if(hawki_step_combine_config.borders < 0 ) 00470 { 00471 cpl_msg_error(__func__, "Borders cannot be less than zero"); 00472 return -1; 00473 } 00474 par = cpl_parameterlist_find(parlist, 00475 "hawki.hawki_step_combine.rej"); 00476 sval = cpl_parameter_get_string(par); 00477 if (sscanf(sval, "%d,%d", 00478 &hawki_step_combine_config.rej_low, 00479 &hawki_step_combine_config.rej_high)!=2) 00480 { 00481 return -1; 00482 } 00483 par = cpl_parameterlist_find(parlist, 00484 "hawki.hawki_step_combine.resamp_kernel"); 00485 sval = cpl_parameter_get_string(par); 00486 if (!strcmp(sval, "tanh")) 00487 hawki_step_combine_config.resamp_kernel = CPL_KERNEL_TANH; 00488 else if (!strcmp(sval, "sinc")) 00489 hawki_step_combine_config.resamp_kernel = CPL_KERNEL_SINC; 00490 else if (!strcmp(sval, "sinc2")) 00491 hawki_step_combine_config.resamp_kernel = CPL_KERNEL_SINC2; 00492 else if (!strcmp(sval, "lanczos")) 00493 hawki_step_combine_config.resamp_kernel = CPL_KERNEL_LANCZOS; 00494 else if (!strcmp(sval, "hamming")) 00495 hawki_step_combine_config.resamp_kernel = CPL_KERNEL_HAMMING; 00496 else if (!strcmp(sval, "hann")) 00497 hawki_step_combine_config.resamp_kernel = CPL_KERNEL_HANN; 00498 else if (!strcmp(sval, "default")) 00499 hawki_step_combine_config.resamp_kernel = CPL_KERNEL_DEFAULT; 00500 else 00501 { 00502 cpl_msg_error(__func__, "Invalid resampling kernel specified"); 00503 return -1; 00504 } 00505 00506 return 0; 00507 } 00508 00509 00510 00511 /*----------------------------------------------------------------------------*/ 00517 /*----------------------------------------------------------------------------*/ 00518 static cpl_image ** hawki_step_combine_apply_comb 00519 (cpl_frameset * obj, 00520 cpl_frameset * offsets_frames, 00521 cpl_frameset * bpm_frame, 00522 cpl_frameset * bkg_bpm_frames) 00523 { 00524 cpl_image ** combined_contrib; 00525 cpl_bivector ** offsets; 00526 cpl_mask * bpm_masks[HAWKI_NB_DETECTORS]; 00527 int idet; 00528 int ioff; 00529 00530 if(offsets_frames == NULL) 00531 { 00532 cpl_bivector * offsets_single_chip; 00533 if ((offsets_single_chip = hawki_get_header_tel_offsets(obj)) == NULL) 00534 { 00535 cpl_msg_error(__func__, "Cannot load the header offsets"); 00536 return NULL; 00537 } 00538 offsets = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_bivector *)); 00539 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00540 offsets[idet] = cpl_bivector_duplicate(offsets_single_chip); 00541 cpl_bivector_delete(offsets_single_chip); 00542 } 00543 else 00544 { 00545 offsets = hawki_load_refined_offsets 00546 (cpl_frameset_get_first(offsets_frames)); 00547 if(offsets == NULL) 00548 { 00549 cpl_msg_error(__func__, "Cannot load the refined offsets"); 00550 return NULL; 00551 } 00552 } 00553 /* Get the oposite offsets. This is to change from 00554 * telescope convention to cpl convention 00555 * WARNING: It may appear that the img_jitter function 00556 * does not apply the multiplication by -1, but it really does it in 00557 * hawki_img_jitter_saa instead of when it reads the offsets */ 00558 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00559 { 00560 cpl_vector_multiply_scalar(cpl_bivector_get_x(offsets[idet]), -1.0); 00561 cpl_vector_multiply_scalar(cpl_bivector_get_y(offsets[idet]), -1.0); 00562 } 00563 00564 /* Load the bpm */ 00565 if(bpm_frame != NULL) 00566 { 00567 cpl_imagelist * bpm_images = NULL; 00568 bpm_images = hawki_load_frame 00569 (cpl_frameset_get_first(bpm_frame), CPL_TYPE_INT); 00570 if(bpm_images == NULL) 00571 { 00572 cpl_msg_error(__func__, "Cannot load the bad pixel mask"); 00573 return NULL; 00574 } 00575 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00576 { 00577 bpm_masks[idet] = cpl_mask_threshold_image_create 00578 (cpl_imagelist_get(bpm_images, idet), 0.5, 1.5); 00579 } 00580 cpl_imagelist_delete(bpm_images); 00581 } 00582 00583 /* Create output object */ 00584 combined_contrib = cpl_malloc(2 * HAWKI_NB_DETECTORS * sizeof(cpl_image *)); 00585 00586 /* Loop on the detectors */ 00587 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00588 { 00589 cpl_imagelist * in ; 00590 cpl_imagelist * bpm_bkg_im = NULL; 00591 cpl_image ** comb_contrib_chip ; 00592 double * offs_est_x ; 00593 double * offs_est_y ; 00594 double max_x, max_y ; 00595 double off_0_x; 00596 double off_0_y; 00597 int jdet; 00598 int iframe; 00599 00600 cpl_msg_info(__func__, "Combine chip number %d", idet+1) ; 00601 cpl_msg_indent_more() ; 00602 00603 /* Print the offsets */ 00604 offs_est_x = cpl_bivector_get_x_data(offsets[idet]) ; 00605 offs_est_y = cpl_bivector_get_y_data(offsets[idet]) ; 00606 for (ioff=0 ; ioff<cpl_bivector_get_size(offsets[idet]) ; ioff++) { 00607 cpl_msg_info(__func__,"Telescope offsets (Frame %d): %g %g", ioff+1, 00608 -offs_est_x[ioff], -offs_est_y[ioff]) ; 00609 } 00610 00611 /* Subtract the first offset to all offsets */ 00612 max_x = max_y = 0.0 ; 00613 off_0_x = offs_est_x[0]; 00614 off_0_y = offs_est_y[0]; 00615 for (ioff=1 ; ioff<cpl_bivector_get_size(offsets[idet]) ; ioff++) 00616 { 00617 offs_est_x[ioff] -= offs_est_x[0] ; 00618 offs_est_y[ioff] -= offs_est_y[0] ; 00619 if (fabs(offs_est_x[ioff]) > max_x) max_x = fabs(offs_est_x[ioff]); 00620 if (fabs(offs_est_y[ioff]) > max_y) max_y = fabs(offs_est_y[ioff]); 00621 } 00622 offs_est_x[0] = offs_est_y[0] = 0.00 ; 00623 00624 /* Check if the max offset is not too big */ 00625 if (max_x > hawki_step_combine_config.offset_max || 00626 max_y > hawki_step_combine_config.offset_max) 00627 { 00628 cpl_msg_error(__func__,"Sorry, no support for offsets larger than %d", 00629 hawki_step_combine_config.offset_max); 00630 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00631 { 00632 cpl_bivector_delete(offsets[idet]); 00633 if(bpm_frame != NULL) 00634 cpl_mask_delete(bpm_masks[idet]); 00635 } 00636 for(jdet = 0; jdet < idet; ++jdet) 00637 { 00638 cpl_image_delete(combined_contrib[idet]); 00639 cpl_image_delete(combined_contrib[idet+HAWKI_NB_DETECTORS]); 00640 } 00641 cpl_free(combined_contrib); 00642 return NULL ; 00643 } 00644 00645 /* Load the input data */ 00646 cpl_msg_info(__func__, "Load the input data") ; 00647 cpl_msg_indent_more(); 00648 if ((in = hawki_load_detector(obj, idet+1, CPL_TYPE_FLOAT)) == NULL) { 00649 cpl_msg_error(__func__, "Cannot load chip %d",idet+1); 00650 //TODO: there is probably a memory leak here. It should be checked. 00651 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00652 { 00653 cpl_bivector_delete(offsets[idet]); 00654 if(bpm_frame != NULL) 00655 cpl_mask_delete(bpm_masks[idet]); 00656 } 00657 for(jdet = 0; jdet < idet; ++jdet) 00658 { 00659 cpl_image_delete(combined_contrib[idet]); 00660 cpl_image_delete(combined_contrib[idet+HAWKI_NB_DETECTORS]); 00661 } 00662 cpl_free(combined_contrib); 00663 cpl_free(offsets); 00664 cpl_msg_indent_less() ; 00665 cpl_msg_indent_less() ; 00666 return NULL ; 00667 } 00668 00669 /* Load the bad bkg images */ 00670 if(bkg_bpm_frames != NULL) 00671 { 00672 cpl_msg_info(__func__, "Load the bad bkg images"); 00673 cpl_msg_indent_more() ; 00674 if ((bpm_bkg_im = hawki_load_detector(bkg_bpm_frames, idet+1, 00675 CPL_TYPE_FLOAT)) == NULL) 00676 { 00677 cpl_msg_error(__func__, "Cannot load chip %d",idet+1); 00678 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00679 { 00680 cpl_bivector_delete(offsets[idet]); 00681 if(bpm_frame != NULL) 00682 cpl_mask_delete(bpm_masks[idet]); 00683 } 00684 for(jdet = 0; jdet < idet; ++jdet) 00685 { 00686 cpl_image_delete(combined_contrib[idet]); 00687 cpl_image_delete(combined_contrib[idet+HAWKI_NB_DETECTORS]); 00688 } 00689 cpl_free(combined_contrib); 00690 cpl_imagelist_delete(in); 00691 cpl_free(offsets); 00692 cpl_msg_indent_less() ; 00693 cpl_msg_indent_less() ; 00694 return NULL ; 00695 } 00696 cpl_msg_indent_less() ; 00697 } 00698 cpl_msg_indent_less() ; 00699 00700 /* Add the general bpm or background bpms in case they were specified */ 00701 if(bpm_frame != NULL || bkg_bpm_frames != NULL) 00702 { 00703 for(iframe = 0 ; iframe <cpl_imagelist_get_size(in) ; ++iframe) 00704 { 00705 cpl_mask * final_mask; 00706 cpl_image * target_image = cpl_imagelist_get(in, iframe); 00707 final_mask = cpl_mask_new(cpl_image_get_size_x(target_image), 00708 cpl_image_get_size_y(target_image)); 00709 //Add the common bpm 00710 if(bpm_frame != NULL) 00711 cpl_mask_or(final_mask, bpm_masks[idet]); 00712 //Add the background mask if provided 00713 if(bkg_bpm_frames != NULL) 00714 { 00715 cpl_mask * bpm_bkg_mask = 00716 cpl_mask_threshold_image_create 00717 (cpl_imagelist_get(bpm_bkg_im, iframe), 0.5, FLT_MAX); 00718 cpl_mask_or(final_mask, bpm_bkg_mask); 00719 cpl_mask_delete(bpm_bkg_mask); 00720 } 00721 cpl_image_reject_from_mask(target_image, final_mask); 00722 cpl_mask_delete(final_mask); 00723 } 00724 } 00725 00726 if(bkg_bpm_frames != NULL) 00727 cpl_imagelist_delete(bpm_bkg_im); 00728 00729 /* Apply the shift and add */ 00730 cpl_msg_info(__func__, "Shift and add") ; 00731 cpl_msg_indent_more() ; 00732 comb_contrib_chip = hawki_step_combine_chip(in, offsets[idet], 00733 &(hawki_step_combine_output.combined_pos_x[idet]), 00734 &(hawki_step_combine_output.combined_pos_y[idet])) ; 00735 if (comb_contrib_chip == NULL) 00736 { 00737 cpl_msg_error(__func__, "Cannot apply the shift and add") ; 00738 cpl_imagelist_delete(in) ; 00739 for(jdet = 0; jdet < HAWKI_NB_DETECTORS; ++jdet) 00740 cpl_bivector_delete(offsets[jdet]); 00741 { 00742 cpl_image_delete(combined_contrib[idet]); 00743 cpl_image_delete(combined_contrib[idet+HAWKI_NB_DETECTORS]); 00744 } 00745 cpl_free(combined_contrib); 00746 cpl_free(offsets); 00747 cpl_msg_indent_less() ; 00748 cpl_msg_indent_less() ; 00749 return NULL ; 00750 } 00751 00752 /* The cumoffset have the opposite criteria as cpl */ 00753 hawki_step_combine_output.combined_cumoffset_x[idet] = 00754 hawki_step_combine_output.combined_pos_x[idet] - off_0_x; 00755 hawki_step_combine_output.combined_cumoffset_y[idet] = 00756 hawki_step_combine_output.combined_pos_y[idet] - off_0_y; 00757 cpl_imagelist_delete(in) ; 00758 cpl_msg_indent_less() ; 00759 00760 /* Interpolate bad pixels */ 00761 hawki_step_combine_interpolate_badpix(comb_contrib_chip[0]); 00762 00763 /* Put the results in the image list */ 00764 combined_contrib[idet] = comb_contrib_chip[0]; 00765 combined_contrib[idet+HAWKI_NB_DETECTORS] = comb_contrib_chip[1]; 00766 cpl_free(comb_contrib_chip); 00767 cpl_msg_indent_less() ; 00768 } 00769 00770 /* Compute the mean airmass */ 00771 hawki_step_combine_output.mean_airmass = hawki_get_mean_airmass(obj); 00772 00773 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00774 { 00775 cpl_bivector_delete(offsets[idet]); 00776 if(bpm_frame != NULL) 00777 cpl_mask_delete(bpm_masks[idet]); 00778 } 00779 cpl_free(offsets); 00780 return combined_contrib; 00781 } 00782 00783 /*----------------------------------------------------------------------------*/ 00792 /*----------------------------------------------------------------------------*/ 00793 static cpl_image ** hawki_step_combine_chip( 00794 cpl_imagelist * in, 00795 cpl_bivector * offsets, 00796 double * pos_x, 00797 double * pos_y) 00798 { 00799 cpl_image ** combined_contrib; 00800 cpl_imagelist * in_ext ; 00801 cpl_image * tmp1 ; 00802 cpl_image * tmp2 ; 00803 int nfiles, nx, ny ; 00804 int i; 00805 00806 /* Check entries */ 00807 if (pos_x == NULL || pos_y == NULL) return NULL ; 00808 if (offsets == NULL) return NULL ; 00809 00810 /* Get the number of images */ 00811 nfiles = cpl_imagelist_get_size(in) ; 00812 if (cpl_bivector_get_size(offsets) != nfiles) { 00813 cpl_msg_error(__func__, "Number of refined offsets in table """ 00814 "is different than number of frames to combine"); 00815 return NULL ; 00816 } 00817 00818 /* Discard the pixels on the sides */ 00819 if (hawki_step_combine_config.borders > 0) { 00820 nx = cpl_image_get_size_x(cpl_imagelist_get(in, 0)) ; 00821 ny = cpl_image_get_size_y(cpl_imagelist_get(in, 0)) ; 00822 in_ext = cpl_imagelist_new() ; 00823 for (i=0 ; i<cpl_imagelist_get_size(in) ; i++) { 00824 tmp1 = cpl_imagelist_get(in, i) ; 00825 tmp2 = cpl_image_extract(tmp1, 00826 hawki_step_combine_config.borders+1, 00827 hawki_step_combine_config.borders+1, 00828 nx-hawki_step_combine_config.borders, 00829 ny-hawki_step_combine_config.borders) ; 00830 cpl_imagelist_set(in_ext, tmp2, i) ; 00831 } 00832 } 00833 else 00834 { 00835 in_ext = cpl_imagelist_duplicate(in); 00836 } 00837 00838 /* Apply the shift & add */ 00839 cpl_msg_info(__func__, "Recombine the images set") ; 00840 cpl_msg_indent_more() ; 00841 if ((combined_contrib=cpl_geom_img_offset_saa(in_ext, offsets, 00842 hawki_step_combine_config.resamp_kernel, 00843 hawki_step_combine_config.rej_low, 00844 hawki_step_combine_config.rej_high, 00845 hawki_step_combine_config.comb_meth, 00846 pos_x, pos_y)) == NULL) { 00847 cpl_msg_error(cpl_func, "Cannot apply the shift and add") ; 00848 cpl_msg_indent_less(); 00849 return NULL; 00850 } 00851 cpl_msg_indent_less(); 00852 *pos_x -= hawki_step_combine_config.borders; 00853 *pos_y -= hawki_step_combine_config.borders; 00854 00855 /* Free and return */ 00856 cpl_imagelist_delete(in_ext); 00857 return combined_contrib; 00858 } 00859 00860 /*----------------------------------------------------------------------------*/ 00866 /*----------------------------------------------------------------------------*/ 00867 static int hawki_step_combine_interpolate_badpix 00868 (cpl_image * image) 00869 { 00870 int nbadpixels = cpl_image_count_rejected(image); 00871 if(nbadpixels !=0) 00872 cpl_msg_info(__func__,"Number of pixels with no combined value available: %d ", 00873 nbadpixels); 00874 if(cpl_image_count_rejected(image) > 0) 00875 { 00876 //I use this even if DFS08929 is still not solved 00877 cpl_detector_interpolate_rejected(image); 00878 } 00879 return 0; 00880 } 00881 00882 /*----------------------------------------------------------------------------*/ 00891 /*----------------------------------------------------------------------------*/ 00892 static int hawki_step_combine_save 00893 (cpl_image ** combined, 00894 cpl_image ** contrib_map, 00895 cpl_frameset * used_frames, 00896 cpl_parameterlist * parlist, 00897 cpl_frameset * recipe_frameset) 00898 { 00899 cpl_propertylist ** extproplists ; 00900 const cpl_frame * ref_frame ; 00901 cpl_propertylist * wcslist ; 00902 cpl_propertylist * inputlist ; 00903 double crpix1, crpix2 ; 00904 int ext_nb ; 00905 const char * recipe_name = "hawki_step_combine" ; 00906 int idet; 00907 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00908 00909 /* Get a reference frame for the WCS keys */ 00910 ref_frame = irplib_frameset_get_first_from_group 00911 (recipe_frameset, CPL_FRAME_GROUP_RAW) ; 00912 00913 if(ref_frame == NULL) 00914 { 00915 cpl_msg_error(__func__, "Cannot get a reference frame"); 00916 return -1; 00917 } 00918 00919 /* Create the QC lists */ 00920 extproplists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 00921 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00922 { 00923 00924 /* Initialize qclists */ 00925 extproplists[idet] = cpl_propertylist_new() ; 00926 00927 /* Get the extension number */ 00928 ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), idet+1); 00929 00930 /* Handle WCS keys */ 00931 wcslist = cpl_propertylist_load_regexp( 00932 cpl_frame_get_filename(ref_frame), ext_nb, HAWKI_HEADER_WCS, 0); 00933 00934 /* Update WCS and write them */ 00935 crpix1 = cpl_propertylist_get_double(wcslist, "CRPIX1"); 00936 crpix1 += hawki_step_combine_output.combined_pos_x[idet]; 00937 cpl_propertylist_update_double(wcslist, "CRPIX1", crpix1) ; 00938 crpix2 = cpl_propertylist_get_double(wcslist, "CRPIX2"); 00939 crpix2 += hawki_step_combine_output.combined_pos_y[idet] ; 00940 cpl_propertylist_update_double(wcslist, "CRPIX2", crpix2) ; 00941 cpl_propertylist_copy_property_regexp 00942 (extproplists[idet], wcslist, HAWKI_HEADER_WCS, 0); 00943 cpl_propertylist_delete(wcslist) ; 00944 00945 /* Keywords for the relative position of the combined image */ 00946 cpl_propertylist_append_double 00947 (extproplists[idet], "ESO QC COMBINED CUMOFFSETX", 00948 hawki_step_combine_output.combined_cumoffset_x[idet]); 00949 cpl_propertylist_append_double 00950 (extproplists[idet], "ESO QC COMBINED CUMOFFSETY", 00951 hawki_step_combine_output.combined_cumoffset_y[idet]); 00952 cpl_propertylist_append_double 00953 (extproplists[idet], "ESO QC COMBINED POSX", 00954 hawki_step_combine_output.combined_pos_x[idet]); 00955 cpl_propertylist_append_double 00956 (extproplists[idet], "ESO QC COMBINED POSY", 00957 hawki_step_combine_output.combined_pos_y[idet]); 00958 cpl_propertylist_append_double 00959 (extproplists[idet], "ESO QC AIRMASS MEAN", 00960 hawki_step_combine_output.mean_airmass); 00961 00962 /* Propagate some keywords from input raw frame extensions */ 00963 inputlist = cpl_propertylist_load_regexp( 00964 cpl_frame_get_filename(ref_frame), ext_nb, 00965 HAWKI_HEADER_EXT_FORWARD, 0) ; 00966 cpl_propertylist_append(extproplists[idet], inputlist); 00967 cpl_propertylist_delete(inputlist) ; 00968 } 00969 00970 /* Write the combined image */ 00971 if(hawki_images_save(recipe_frameset, 00972 parlist, 00973 used_frames, 00974 (const cpl_image **)combined, 00975 recipe_name, 00976 HAWKI_CALPRO_COMBINED, 00977 HAWKI_PROTYPE_COMBINED, 00978 NULL, 00979 (const cpl_propertylist**)extproplists, 00980 "hawki_step_combine.fits") != 0) 00981 { 00982 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) { 00983 cpl_propertylist_delete(extproplists[idet]) ; 00984 } 00985 cpl_free(extproplists) ; 00986 return -1; 00987 } 00988 00989 /* Write the contrib map */ 00990 if(hawki_images_save(recipe_frameset, 00991 parlist, 00992 used_frames, 00993 (const cpl_image **)contrib_map, 00994 recipe_name, 00995 HAWKI_CALPRO_COMB_CONTRIB_MAP, 00996 HAWKI_PROTYPE_COMB_CONTRIB_MAP, 00997 NULL, 00998 (const cpl_propertylist**)extproplists, 00999 "hawki_step_combine_contrib_map.fits") != 0) 01000 { 01001 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) { 01002 cpl_propertylist_delete(extproplists[idet]); 01003 } 01004 cpl_free(extproplists) ; 01005 return -1; 01006 } 01007 01008 /* Free and return */ 01009 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) { 01010 cpl_propertylist_delete(extproplists[idet]) ; 01011 } 01012 cpl_free(extproplists) ; 01013 01014 if(!cpl_errorstate_is_equal(error_prevstate)) 01015 { 01016 cpl_errorstate_set(CPL_ERROR_NONE); 01017 return 1; 01018 } 01019 01020 return 0; 01021 } 01022
1.7.4