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