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