HAWKI Pipeline Reference Manual 1.8.12
|
00001 /* $Id: hawki_sci_jitter.c,v 1.34 2013/01/15 09:58:25 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: 2013/01/15 09:58:25 $ 00024 * $Revision: 1.34 $ 00025 * $Name: hawki-1_8_12 $ 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 #include "hawki_obj_det.h" 00055 00056 /*----------------------------------------------------------------------------- 00057 Define 00058 -----------------------------------------------------------------------------*/ 00059 00060 #define NEGLIG_OFF_DIFF 0.1 00061 #define SQR(x) ((x)*(x)) 00062 00063 /*----------------------------------------------------------------------------- 00064 Functions prototypes 00065 -----------------------------------------------------------------------------*/ 00066 00067 #ifdef __cplusplus 00068 extern "C" 00069 #endif 00070 int cpl_plugin_get_info(cpl_pluginlist * list); 00071 00072 static int hawki_sci_jitter_create(cpl_plugin *) ; 00073 static int hawki_sci_jitter_exec(cpl_plugin *) ; 00074 static int hawki_sci_jitter_destroy(cpl_plugin *) ; 00075 static int hawki_sci_jitter(cpl_parameterlist *, cpl_frameset *) ; 00076 00077 static int hawki_sci_jitter_retrieve_input_param 00078 (cpl_parameterlist * parlist); 00079 static cpl_image ** hawki_sci_jitter_reduce 00080 (cpl_frameset * jitters, 00081 cpl_frameset * sky, 00082 const char * flat, 00083 const char * dark, 00084 const char * bpm, 00085 cpl_table ** bkg_stats); 00086 static int hawki_sci_jitter_sky 00087 (cpl_imagelist * jitters, 00088 cpl_imagelist * skys, 00089 cpl_table ** bkg_stats, 00090 int idet); 00091 static int hawki_sci_jitter_sky_running 00092 (cpl_imagelist * in, 00093 cpl_table ** bkg_stats, 00094 int idet); 00095 static cpl_image ** hawki_sci_jitter_saa(cpl_imagelist **, cpl_bivector *, 00096 double *, double *); 00097 static int hawki_sci_jitter_qc 00098 (cpl_frameset * science_frames, 00099 cpl_image ** combined, 00100 cpl_table ** obj_charac); 00101 static int hawki_sci_jitter_read_calib 00102 (const char * flat, 00103 const char * dark, 00104 const char * bpm, 00105 cpl_image ** flat_image, 00106 cpl_image ** dark_image, 00107 cpl_image ** bpm_image, 00108 int idet); 00109 static int hawki_sci_jitter_save 00110 (cpl_image ** combined, 00111 cpl_image * stitched, 00112 cpl_table ** objs_charac, 00113 cpl_table ** raw_jitter_stats, 00114 cpl_table ** bkg_stats, 00115 const cpl_table * raw_obj_tel_info, 00116 cpl_frameset * science_frames, 00117 cpl_frameset * calib_frames, 00118 cpl_parameterlist * parlist, 00119 cpl_frameset * set); 00120 int hawki_sci_jitter_whole_image_algo 00121 (cpl_frameset * obj, 00122 cpl_table ** raw_jitter_stats, 00123 cpl_table * raw_obj_tel_info, 00124 cpl_parameterlist * parlist, 00125 cpl_frameset * recipe_set); 00126 int hawki_sci_jitter_save_stats 00127 (cpl_table ** raw_jitter_stats, 00128 cpl_table * raw_obj_tel_info, 00129 cpl_frameset * jitter_frames, 00130 cpl_parameterlist * parlist, 00131 cpl_frameset * recipe_set); 00132 00133 /*----------------------------------------------------------------------------- 00134 Static variables 00135 -----------------------------------------------------------------------------*/ 00136 00137 static struct 00138 { 00139 /* Inputs */ 00140 const char * offsets ; 00141 const char * objects ; 00142 int offset_max ; 00143 int sky_minnb ; 00144 int sky_halfw ; 00145 int sky_rejmin ; 00146 int sky_rejmax ; 00147 int refine ; 00148 int sx ; 00149 int sy ; 00150 int mx ; 00151 int my ; 00152 int borders ; 00153 cpl_geom_combine comb_meth ; 00154 int rej_low ; 00155 int rej_high ; 00156 int max_njitter; 00157 } hawki_sci_jitter_config; 00158 00159 static struct 00160 { 00161 /* Outputs */ 00162 double pixscale; 00163 double dit; 00164 double mean_airmass; 00165 double iq[HAWKI_NB_DETECTORS]; 00166 int nbobjs[HAWKI_NB_DETECTORS]; 00167 double fwhm_pix[HAWKI_NB_DETECTORS]; 00168 double fwhm_arcsec[HAWKI_NB_DETECTORS]; 00169 double fwhm_mode[HAWKI_NB_DETECTORS]; 00170 double combined_pos_x[HAWKI_NB_DETECTORS]; 00171 double combined_pos_y[HAWKI_NB_DETECTORS]; 00172 double combined_cumoffset_x[HAWKI_NB_DETECTORS]; 00173 double combined_cumoffset_y[HAWKI_NB_DETECTORS]; 00174 int ncomb[HAWKI_NB_DETECTORS]; 00175 } hawki_sci_jitter_output; 00176 00177 static char hawki_sci_jitter_description[] = 00178 "hawki_sci_jitter -- hawki imaging jitter recipe.\n\n" 00179 "The input of the recipe files listed in the Set Of Frames (sof-file)\n" 00180 "must be tagged as:\n" 00181 "raw-file.fits "HAWKI_IMG_JITTER_RAW" or\n" 00182 "raw-file.fits "HAWKI_IMG_JITTER_SKY_RAW" or\n" 00183 "flat-file.fits "HAWKI_CALPRO_FLAT" or\n" 00184 "dark-file.fits "HAWKI_CALPRO_DARK" \n" 00185 "bpm-file.fits "HAWKI_CALPRO_BPM"\n" 00186 "distortion_x-file.fits "HAWKI_CALPRO_DISTORTION_X"\n" 00187 "distortion_y-file.fits "HAWKI_CALPRO_DISTORTION_Y"\n\n" 00188 "The recipe creates as an output:\n" 00189 "hawki_sci_jitter.fits ("HAWKI_CALPRO_COMBINED")\n" 00190 "hawki_sci_jitter_stitched.fits ("HAWKI_CALPRO_STITCHED")\n" 00191 "hawki_sci_jitter_stars.fits ("HAWKI_CALPRO_OBJ_PARAM"): Detected objects properties\n" 00192 "hawki_sci_jitter_stats.fits ("HAWKI_CALPRO_JITTER_STATS"): Stats of the individual images\n" 00193 "hawki_sci_jitter_bkg_stats.fits ("HAWKI_CALPRO_JITTER_BKG_STATS"): Statistics on the bkg\n\n" 00194 "The recipe performs the following steps:\n" 00195 "1) Frame statistics\n" 00196 "2) Basic reduction (using "HAWKI_CALPRO_FLAT" and "HAWKI_CALPRO_BPM")\n" 00197 "3) Background computation (the algorithm depends on parameter --sky_par) \n" 00198 "4) Offset refinement (uses parameters --off, --refine and --xcorr)\n" 00199 "5) Stacking of jitter frames (uses --comb_meth, --rej,\n" 00200 " --offset_max, --borders, --max_njitter)\n" 00201 "6) Stitching of the four detectors into one image\n" 00202 "7) Object detection in the stacked image\n\n" 00203 "Return code:\n" 00204 "esorex exits with an error code of 0 if the recipe completes successfully\n" 00205 "or 1 otherwise"; 00206 00207 /*----------------------------------------------------------------------------- 00208 Functions code 00209 -----------------------------------------------------------------------------*/ 00210 00211 /*----------------------------------------------------------------------------*/ 00219 /*----------------------------------------------------------------------------*/ 00220 int cpl_plugin_get_info(cpl_pluginlist * list) 00221 { 00222 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ; 00223 cpl_plugin * plugin = &recipe->interface ; 00224 00225 cpl_plugin_init(plugin, 00226 CPL_PLUGIN_API, 00227 HAWKI_BINARY_VERSION, 00228 CPL_PLUGIN_TYPE_RECIPE, 00229 "hawki_sci_jitter", 00230 "Jitter recipe", 00231 hawki_sci_jitter_description, 00232 "Cesar Enrique Garcia", 00233 PACKAGE_BUGREPORT, 00234 hawki_get_license(), 00235 hawki_sci_jitter_create, 00236 hawki_sci_jitter_exec, 00237 hawki_sci_jitter_destroy) ; 00238 00239 cpl_pluginlist_append(list, plugin) ; 00240 00241 return 0; 00242 } 00243 00244 /*----------------------------------------------------------------------------*/ 00253 /*----------------------------------------------------------------------------*/ 00254 static int hawki_sci_jitter_create(cpl_plugin * plugin) 00255 { 00256 cpl_recipe * recipe ; 00257 cpl_parameter * p ; 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 /* Create the parameters list in the cpl_recipe object */ 00265 recipe->parameters = cpl_parameterlist_new() ; 00266 if (recipe->parameters == NULL) 00267 return 1; 00268 00269 /* Fill the parameters list */ 00270 /* --offsets */ 00271 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.offsets", 00272 CPL_TYPE_STRING, "offsets file", "hawki.hawki_sci_jitter", NULL) ; 00273 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "offsets") ; 00274 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00275 cpl_parameterlist_append(recipe->parameters, p) ; 00276 00277 /* --objects */ 00278 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.objects", 00279 CPL_TYPE_STRING, "objects file", "hawki.hawki_sci_jitter", NULL) ; 00280 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "objects") ; 00281 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00282 cpl_parameterlist_append(recipe->parameters, p) ; 00283 00284 /* --offset_max */ 00285 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.offset_max", 00286 CPL_TYPE_INT, 00287 "Maximum offset allowed", 00288 "hawki.hawki_sci_jitter", 00289 1500) ; 00290 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "offset_max") ; 00291 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00292 cpl_parameterlist_append(recipe->parameters, p) ; 00293 00294 /* --sky_par */ 00295 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.sky_par", 00296 CPL_TYPE_STRING, 00297 "Rejection parameters for sky filtering", 00298 "hawki.hawki_sci_jitter", 00299 "10,7,3,3") ; 00300 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sky_par") ; 00301 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00302 cpl_parameterlist_append(recipe->parameters, p) ; 00303 00304 /* --refine */ 00305 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.refine", 00306 CPL_TYPE_BOOL, "refine offsets", "hawki.hawki_sci_jitter", 00307 FALSE); 00308 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "refine") ; 00309 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00310 cpl_parameterlist_append(recipe->parameters, p) ; 00311 00312 /* --xcorr */ 00313 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.xcorr", 00314 CPL_TYPE_STRING, 00315 "Cross correlation search and measure sizes", 00316 "hawki.hawki_sci_jitter", 00317 "20,20,25,25") ; 00318 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcorr") ; 00319 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00320 cpl_parameterlist_append(recipe->parameters, p) ; 00321 00322 /* --comb_meth */ 00323 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.comb_meth", 00324 CPL_TYPE_STRING, "union / inter / first", "hawki.hawki_sci_jitter", 00325 "union") ; 00326 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "comb_meth") ; 00327 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00328 cpl_parameterlist_append(recipe->parameters, p) ; 00329 00330 /* --rej */ 00331 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.rej", 00332 CPL_TYPE_STRING, 00333 "Low and high number of rejected values", 00334 "hawki.hawki_sci_jitter", 00335 "1,1") ; 00336 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rej") ; 00337 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00338 cpl_parameterlist_append(recipe->parameters, p) ; 00339 00340 /* --borders */ 00341 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.borders", 00342 CPL_TYPE_INT, 00343 "Borders rejected", 00344 "hawki.hawki_sci_jitter", 00345 4) ; 00346 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "borders") ; 00347 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00348 cpl_parameterlist_append(recipe->parameters, p) ; 00349 00350 /* --max_njitter */ 00351 p = cpl_parameter_new_value("hawki.hawki_sci_jitter.max_njitter", 00352 CPL_TYPE_INT, 00353 "Maximum numbers of jitter frames to combine", 00354 "hawki.hawki_sci_jitter", 00355 -1); 00356 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "max_njitter"); 00357 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00358 cpl_parameterlist_append(recipe->parameters, p); 00359 00360 /* Return */ 00361 return 0; 00362 } 00363 00364 /*----------------------------------------------------------------------------*/ 00370 /*----------------------------------------------------------------------------*/ 00371 static int hawki_sci_jitter_exec(cpl_plugin * plugin) 00372 { 00373 cpl_recipe * recipe ; 00374 00375 /* Get the recipe out of the plugin */ 00376 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00377 recipe = (cpl_recipe *)plugin ; 00378 else return -1 ; 00379 00380 /* Issue a banner */ 00381 hawki_print_banner(); 00382 00383 return hawki_sci_jitter(recipe->parameters, recipe->frames) ; 00384 } 00385 00386 /*----------------------------------------------------------------------------*/ 00392 /*----------------------------------------------------------------------------*/ 00393 static int hawki_sci_jitter_destroy(cpl_plugin * plugin) 00394 { 00395 cpl_recipe * recipe ; 00396 00397 /* Get the recipe out of the plugin */ 00398 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00399 recipe = (cpl_recipe *)plugin ; 00400 else return -1 ; 00401 00402 cpl_parameterlist_delete(recipe->parameters) ; 00403 return 0 ; 00404 } 00405 00406 /*----------------------------------------------------------------------------*/ 00413 /*----------------------------------------------------------------------------*/ 00414 static int hawki_sci_jitter( 00415 cpl_parameterlist * parlist, 00416 cpl_frameset * framelist) 00417 { 00418 const char * flat; 00419 const char * dark; 00420 const char * bpm; 00421 const cpl_frame * distx; 00422 const cpl_frame * disty; 00423 cpl_frameset * jitterframes ; 00424 cpl_frameset * skyframes ; 00425 cpl_frameset * science_frames; 00426 cpl_frameset * calib_frames; 00427 cpl_image ** combined ; 00428 cpl_table ** obj_charac; 00429 cpl_table ** raw_jitter_stats; 00430 cpl_table ** bkg_stats; 00431 cpl_table * raw_obj_tel_info; 00432 cpl_image * stitched ; 00433 int i; 00434 00435 /* Initialise */ 00436 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00437 { 00438 hawki_sci_jitter_output.iq[i] = -1.0 ; 00439 hawki_sci_jitter_output.nbobjs[i] = -1 ; 00440 hawki_sci_jitter_output.fwhm_pix[i] = -1.0 ; 00441 hawki_sci_jitter_output.fwhm_arcsec[i] = -1.0 ; 00442 hawki_sci_jitter_output.fwhm_mode[i] = -1.0 ; 00443 hawki_sci_jitter_output.combined_pos_x[i] = -1.0 ; 00444 hawki_sci_jitter_output.combined_pos_y[i] = -1.0 ; 00445 hawki_sci_jitter_output.combined_cumoffset_x[i] = -1.0 ; 00446 hawki_sci_jitter_output.combined_cumoffset_y[i] = -1.0 ; 00447 } 00448 hawki_sci_jitter_output.pixscale = -1.0 ; 00449 hawki_sci_jitter_output.dit = -1.0 ; 00450 hawki_sci_jitter_config.offsets = NULL ; 00451 hawki_sci_jitter_config.objects = NULL ; 00452 calib_frames = cpl_frameset_new(); 00453 00454 /* Retrieve input parameters */ 00455 if(hawki_sci_jitter_retrieve_input_param(parlist)) 00456 { 00457 cpl_msg_error(cpl_func, "Wrong parameters"); 00458 cpl_frameset_delete(calib_frames); 00459 return -1; 00460 } 00461 00462 /* Identify the RAW and CALIB frames in the input frameset */ 00463 if (hawki_dfs_set_groups(framelist)) { 00464 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames") ; 00465 cpl_frameset_delete(calib_frames); 00466 return -1 ; 00467 } 00468 00469 /* Retrieve calibration data */ 00470 flat = hawki_extract_first_filename(framelist, HAWKI_CALPRO_FLAT) ; 00471 dark = hawki_extract_first_filename(framelist, HAWKI_CALPRO_DARK); 00472 bpm = hawki_extract_first_filename(framelist, HAWKI_CALPRO_BPM) ; 00473 distx = cpl_frameset_find_const(framelist, HAWKI_CALPRO_DISTORTION_X); 00474 disty = cpl_frameset_find_const(framelist, HAWKI_CALPRO_DISTORTION_Y); 00475 if((distx == NULL && disty !=NULL) || (distx != NULL && disty ==NULL)) 00476 { 00477 cpl_msg_error(cpl_func, "Both distortion in X (%s) and Y (%s) must be provided", 00478 HAWKI_CALPRO_DISTORTION_X, HAWKI_CALPRO_DISTORTION_Y); 00479 cpl_frameset_delete(calib_frames); 00480 return -1 ; 00481 } 00482 if(flat) 00483 cpl_frameset_insert(calib_frames, cpl_frame_duplicate( 00484 cpl_frameset_find_const(framelist, HAWKI_CALPRO_FLAT))); 00485 if(dark) 00486 cpl_frameset_insert(calib_frames, cpl_frame_duplicate( 00487 cpl_frameset_find_const(framelist, HAWKI_CALPRO_DARK))); 00488 if(bpm) 00489 cpl_frameset_insert(calib_frames, cpl_frame_duplicate( 00490 cpl_frameset_find_const(framelist, HAWKI_CALPRO_BPM))); 00491 if(distx) 00492 { 00493 cpl_frameset_insert(calib_frames, cpl_frame_duplicate(distx)); 00494 cpl_frameset_insert(calib_frames, cpl_frame_duplicate(disty)); 00495 } 00496 00497 00498 /* Retrieve raw frames */ 00499 jitterframes = hawki_extract_frameset(framelist, HAWKI_IMG_JITTER_RAW) ; 00500 if (jitterframes == NULL) { 00501 cpl_msg_error(cpl_func, "Cannot find jitter frames in the input list (%s)", 00502 HAWKI_IMG_JITTER_RAW); 00503 cpl_frameset_delete(calib_frames); 00504 return -1 ; 00505 } 00506 science_frames = cpl_frameset_duplicate(jitterframes); 00507 skyframes = hawki_extract_frameset(framelist, HAWKI_IMG_JITTER_SKY_RAW) ; 00508 if (skyframes != NULL) 00509 { 00510 int isky; 00511 for(isky = 0; isky< cpl_frameset_get_size(skyframes); ++isky) 00512 cpl_frameset_insert(science_frames, 00513 cpl_frame_duplicate(cpl_frameset_get_frame(skyframes, isky))); 00514 } 00515 00516 /* Create the statistics table */ 00517 raw_jitter_stats = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table *)); 00518 for( i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00519 { 00520 raw_jitter_stats[i] = cpl_table_new(cpl_frameset_get_size(jitterframes)); 00521 } 00522 hawki_image_stats_initialize(raw_jitter_stats); 00523 bkg_stats = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table *)); 00524 for( i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00525 { 00526 bkg_stats[i] = cpl_table_new(cpl_frameset_get_size(jitterframes)); 00527 } 00528 hawki_image_stats_initialize(bkg_stats); 00529 00530 /* Create the telescope statistics parameters from the raw images */ 00531 raw_obj_tel_info = cpl_table_new(cpl_frameset_get_size(jitterframes)); 00532 /* Add the proper columns of the pcs table */ 00533 if(hawki_prop_tel_initialize(raw_obj_tel_info)) 00534 { 00535 cpl_msg_error(cpl_func,"Could not initialize the pcs table"); 00536 cpl_frameset_delete(jitterframes) ; 00537 for( i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00538 { 00539 cpl_table_delete(raw_jitter_stats[i]) ; 00540 cpl_table_delete(bkg_stats[i]) ; 00541 } 00542 cpl_free(raw_jitter_stats) ; 00543 cpl_free(bkg_stats) ; 00544 cpl_table_delete(raw_obj_tel_info); 00545 if (skyframes) cpl_frameset_delete(skyframes) ; 00546 cpl_frameset_delete(calib_frames); 00547 cpl_msg_indent_less() ; 00548 return -1; 00549 } 00550 00551 /* Do the algorithms that need the whole image */ 00552 hawki_sci_jitter_whole_image_algo(jitterframes, 00553 raw_jitter_stats, 00554 raw_obj_tel_info, 00555 parlist, 00556 framelist); 00557 00558 /* Apply the reduction */ 00559 /* Do the algorithms that can be applied to subsection of the images */ 00560 cpl_msg_info(cpl_func, "Apply the data combination") ; 00561 cpl_msg_indent_more() ; 00562 if ((combined = hawki_sci_jitter_reduce(jitterframes, skyframes, flat, dark, 00563 bpm, bkg_stats)) == NULL) 00564 { 00565 cpl_msg_error(cpl_func, "Cannot recombine the data"); 00566 cpl_frameset_delete(jitterframes); 00567 for( i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00568 { 00569 cpl_table_delete(raw_jitter_stats[i]) ; 00570 cpl_table_delete(bkg_stats[i]) ; 00571 } 00572 cpl_free(raw_jitter_stats) ; 00573 cpl_free(bkg_stats) ; 00574 cpl_table_delete(raw_obj_tel_info); 00575 if (skyframes) cpl_frameset_delete(skyframes) ; 00576 cpl_frameset_delete(calib_frames); 00577 cpl_msg_indent_less() ; 00578 return -1 ; 00579 } 00580 cpl_msg_indent_less() ; 00581 00582 /* Compute QC parameters from the combined image */ 00583 cpl_msg_info(cpl_func, "Compute QC parameters from the combined images") ; 00584 cpl_msg_indent_more() ; 00585 obj_charac = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table*)) ; 00586 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00587 { 00588 obj_charac[i] = cpl_table_new(0); 00589 } 00590 if ((hawki_sci_jitter_qc(jitterframes, combined, obj_charac)) != 0) 00591 { 00592 cpl_msg_warning(cpl_func, "Cannot compute all parameters") ; 00593 } 00594 cpl_msg_indent_less(); 00595 cpl_frameset_delete(jitterframes); 00596 if (skyframes) cpl_frameset_delete(skyframes); 00597 00598 00599 /* Correct for the distortion */ 00600 if (distx && disty) 00601 { 00602 cpl_msg_info(cpl_func, "Applying the distortion correction") ; 00603 cpl_msg_indent_more() ; 00604 if (hawki_distortion_correct_alldetectors(combined, distx, disty) == -1) 00605 { 00606 cpl_msg_error(cpl_func, "Cannot correct the distortion") ; 00607 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00608 cpl_image_delete(combined[i]) ; 00609 cpl_free(combined) ; 00610 if (obj_charac) { 00611 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00612 cpl_table_delete(obj_charac[i]) ; 00613 cpl_free(obj_charac); 00614 } 00615 cpl_table_delete(raw_obj_tel_info); 00616 for( i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00617 { 00618 cpl_table_delete(raw_jitter_stats[i]); 00619 cpl_table_delete(bkg_stats[i]); 00620 } 00621 cpl_free(raw_jitter_stats); 00622 cpl_free(bkg_stats); 00623 cpl_frameset_delete(calib_frames); 00624 cpl_frameset_delete(science_frames); 00625 cpl_msg_indent_less() ; 00626 return -1; 00627 } 00628 cpl_msg_indent_less() ; 00629 } 00630 00631 /* Compute the stitched image */ 00632 cpl_msg_info(cpl_func, "Compute the stiched image") ; 00633 if ((stitched = hawki_images_stitch(combined, 00634 hawki_sci_jitter_output.combined_pos_x, 00635 hawki_sci_jitter_output.combined_pos_y)) == NULL) 00636 { 00637 cpl_msg_error(cpl_func, "Cannot stitch the images") ; 00638 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00639 cpl_image_delete(combined[i]) ; 00640 cpl_free(combined) ; 00641 if (obj_charac) { 00642 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00643 cpl_table_delete(obj_charac[i]) ; 00644 cpl_free(obj_charac); 00645 } 00646 cpl_table_delete(raw_obj_tel_info); 00647 for( i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00648 { 00649 cpl_table_delete(raw_jitter_stats[i]); 00650 cpl_table_delete(bkg_stats[i]); 00651 } 00652 cpl_free(raw_jitter_stats); 00653 cpl_free(bkg_stats); 00654 cpl_frameset_delete(calib_frames); 00655 cpl_frameset_delete(science_frames); 00656 return -1; 00657 } 00658 00659 /* Save the products */ 00660 cpl_msg_info(cpl_func, "Save the products") ; 00661 cpl_msg_indent_more() ; 00662 if (hawki_sci_jitter_save(combined, stitched, obj_charac, 00663 raw_jitter_stats, bkg_stats, 00664 raw_obj_tel_info, 00665 science_frames, 00666 calib_frames, 00667 parlist, framelist) == -1) 00668 cpl_msg_warning(cpl_func,"Some data could not be saved. " 00669 "Check permisions or disk space"); 00670 00671 /* Return */ 00672 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00673 cpl_image_delete(combined[i]) ; 00674 cpl_free(combined) ; 00675 if (obj_charac) { 00676 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00677 cpl_table_delete(obj_charac[i]) ; 00678 cpl_free(obj_charac); 00679 } 00680 if (stitched) cpl_image_delete(stitched) ; 00681 cpl_table_delete(raw_obj_tel_info); 00682 for( i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00683 { 00684 cpl_table_delete(raw_jitter_stats[i]); 00685 cpl_table_delete(bkg_stats[i]); 00686 } 00687 cpl_free(raw_jitter_stats); 00688 cpl_free(bkg_stats); 00689 cpl_frameset_delete(calib_frames); 00690 cpl_frameset_delete(science_frames); 00691 cpl_msg_indent_less() ; 00692 00693 /* Return */ 00694 if (cpl_error_get_code()) 00695 { 00696 cpl_msg_error(cpl_func, 00697 "HAWK-I pipeline could not recover from previous errors"); 00698 return -1 ; 00699 } 00700 else return 0 ; 00701 } 00702 00703 int hawki_sci_jitter_retrieve_input_param 00704 (cpl_parameterlist * parlist) 00705 { 00706 cpl_parameter * par ; 00707 const char * sval ; 00708 par = NULL ; 00709 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.offsets"); 00710 hawki_sci_jitter_config.offsets = cpl_parameter_get_string(par); 00711 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.objects"); 00712 hawki_sci_jitter_config.objects = cpl_parameter_get_string(par); 00713 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.offset_max"); 00714 hawki_sci_jitter_config.offset_max = cpl_parameter_get_int(par); 00715 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.sky_par"); 00716 sval = cpl_parameter_get_string(par); 00717 if (sscanf(sval, "%d,%d,%d,%d", 00718 &hawki_sci_jitter_config.sky_minnb, 00719 &hawki_sci_jitter_config.sky_halfw, 00720 &hawki_sci_jitter_config.sky_rejmin, 00721 &hawki_sci_jitter_config.sky_rejmax)!=4) 00722 { 00723 return -1; 00724 } 00725 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.xcorr"); 00726 sval = cpl_parameter_get_string(par); 00727 if (sscanf(sval, "%d,%d,%d,%d", 00728 &hawki_sci_jitter_config.sx, 00729 &hawki_sci_jitter_config.sy, 00730 &hawki_sci_jitter_config.mx, 00731 &hawki_sci_jitter_config.my)!=4) 00732 { 00733 return -1; 00734 } 00735 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.refine"); 00736 hawki_sci_jitter_config.refine = cpl_parameter_get_bool(par); 00737 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.comb_meth"); 00738 sval = cpl_parameter_get_string(par); 00739 if (!strcmp(sval, "union")) 00740 hawki_sci_jitter_config.comb_meth = CPL_GEOM_UNION; 00741 else if (!strcmp(sval, "inter")) 00742 hawki_sci_jitter_config.comb_meth = CPL_GEOM_INTERSECT; 00743 else if (!strcmp(sval, "first")) 00744 hawki_sci_jitter_config.comb_meth = CPL_GEOM_FIRST; 00745 else 00746 { 00747 cpl_msg_error(cpl_func, "Invalid combine method specified"); 00748 return -1; 00749 } 00750 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.borders"); 00751 hawki_sci_jitter_config.borders = cpl_parameter_get_int(par); 00752 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.rej"); 00753 sval = cpl_parameter_get_string(par); 00754 if (sscanf(sval, "%d,%d", 00755 &hawki_sci_jitter_config.rej_low, 00756 &hawki_sci_jitter_config.rej_high)!=2) 00757 { 00758 return -1; 00759 } 00760 par = cpl_parameterlist_find(parlist, "hawki.hawki_sci_jitter.max_njitter"); 00761 hawki_sci_jitter_config.max_njitter = cpl_parameter_get_int(par); 00762 return 0; 00763 } 00764 00765 00766 00767 /*----------------------------------------------------------------------------*/ 00778 /*----------------------------------------------------------------------------*/ 00779 static cpl_image ** hawki_sci_jitter_reduce 00780 (cpl_frameset * jitters, 00781 cpl_frameset * sky, 00782 const char * flat, 00783 const char * dark, 00784 const char * bpm, 00785 cpl_table ** bkg_stats) 00786 { 00787 cpl_frame * frame ; 00788 cpl_propertylist * plist ; 00789 cpl_image ** comb_chip ; 00790 cpl_image ** combined ; 00791 cpl_bivector * offsets ; 00792 cpl_vector * offset_x_sort; 00793 cpl_vector * offset_y_sort; 00794 double * offs_est_x ; 00795 double * offs_est_y ; 00796 double off_0_x; 00797 double off_0_y; 00798 double max_x, max_y ; 00799 int idet; 00800 int ioff; 00801 00802 /* Get the header infos */ 00803 frame = cpl_frameset_get_frame(jitters, 0) ; 00804 plist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0) ; 00805 hawki_sci_jitter_output.pixscale = hawki_pfits_get_pixscale(plist) ; 00806 hawki_sci_jitter_output.dit = hawki_pfits_get_dit(plist) ; 00807 cpl_propertylist_delete(plist) ; 00808 if (cpl_error_get_code()) { 00809 cpl_msg_error(cpl_func, "Missing keyword in FITS header") ; 00810 return NULL ; 00811 } 00812 00813 /* Check that DIT/NDIT and NDSAMPLES are the same for all the frames */ 00814 if(!hawki_utils_check_equal_double_keys(jitters, &hawki_pfits_get_dit) || 00815 !hawki_utils_check_equal_int_keys(jitters, &hawki_pfits_get_ndit)|| 00816 !hawki_utils_check_equal_int_keys(jitters, &hawki_pfits_get_ndsamples)) 00817 { 00818 cpl_msg_error(__func__, "Not all input science have the same " 00819 "DIT/NDIT/NDSAMPLES values"); 00820 cpl_msg_indent_less() ; 00821 return NULL; 00822 } 00823 00824 /* Check that pointing is the same for all the frames */ 00825 if(!hawki_utils_check_equal_double_keys(jitters, &hawki_pfits_get_targ_alpha_hhmmss) || 00826 !hawki_utils_check_equal_double_keys(jitters, &hawki_pfits_get_targ_delta_ddmmss)) 00827 { 00828 cpl_msg_error(__func__, "Not all input science frames belong to the " 00829 "same pointing/target. Check keywords TEL TARG ALPHA/DELTA"); 00830 cpl_msg_indent_less() ; 00831 return NULL; 00832 } 00833 00834 /* Get the offsets */ 00835 if ((offsets = hawki_get_header_tel_offsets(jitters)) == NULL) { 00836 cpl_msg_error(cpl_func, "Cannot load the offsets") ; 00837 return NULL ; 00838 } 00839 offs_est_x = cpl_bivector_get_x_data(offsets) ; 00840 offs_est_y = cpl_bivector_get_y_data(offsets) ; 00841 00842 /* Print the header offsets */ 00843 for (ioff=0 ; ioff<cpl_bivector_get_size(offsets) ; ioff++) { 00844 cpl_msg_info(cpl_func, "Telescope offsets (Frame %d): %g %g", ioff+1, 00845 offs_est_x[ioff], offs_est_y[ioff]) ; 00846 } 00847 00848 /* Subtract the first offset to all offsets */ 00849 off_0_x = -offs_est_x[0]; // This is to get the cpl convention 00850 off_0_y = -offs_est_y[0]; 00851 for (ioff=1 ; ioff<cpl_bivector_get_size(offsets) ; ioff++) 00852 { 00853 offs_est_x[ioff] -= offs_est_x[0] ; 00854 offs_est_y[ioff] -= offs_est_y[0] ; 00855 } 00856 offs_est_x[0] = offs_est_y[0] = 0.00 ; 00857 00858 /* Check if the max offset is not too big */ 00859 /* The criteria is that for a given frame, the closest frame cannot be 00860 * further than hawki_sci_jitter_config.offset_max (in both dimensions) */ 00861 offset_x_sort = cpl_vector_duplicate(cpl_bivector_get_x(offsets)); 00862 offset_y_sort = cpl_vector_duplicate(cpl_bivector_get_y(offsets)); 00863 cpl_vector_sort(offset_x_sort, +1); 00864 cpl_vector_sort(offset_y_sort, +1); 00865 for (ioff=0 ; ioff<cpl_bivector_get_size(offsets) - 1 ; ioff++) 00866 { 00867 double diff_x, diff_y; 00868 diff_x = cpl_vector_get(offset_x_sort,ioff+1)-cpl_vector_get(offset_x_sort,ioff); 00869 cpl_vector_set(offset_x_sort, ioff, diff_x); 00870 diff_y = cpl_vector_get(offset_y_sort,ioff+1)-cpl_vector_get(offset_y_sort,ioff); 00871 cpl_vector_set(offset_y_sort, ioff, diff_y); 00872 } 00873 cpl_vector_set(offset_x_sort, cpl_bivector_get_size(offsets)-1, 0.); 00874 cpl_vector_set(offset_y_sort, cpl_bivector_get_size(offsets)-1, 0.); 00875 max_x = cpl_vector_get_max(offset_x_sort); 00876 max_y = cpl_vector_get_max(offset_y_sort); 00877 cpl_vector_delete(offset_x_sort); 00878 cpl_vector_delete(offset_y_sort); 00879 00880 if (max_x > hawki_sci_jitter_config.offset_max || 00881 max_y > hawki_sci_jitter_config.offset_max) 00882 { 00883 cpl_msg_error(cpl_func, "Sorry, no support for frames further than %d from its closest neighbour", 00884 hawki_sci_jitter_config.offset_max) ; 00885 cpl_bivector_delete(offsets); 00886 return NULL ; 00887 } 00888 00889 /* Create output object */ 00890 combined = cpl_malloc(HAWKI_NB_DETECTORS*sizeof(cpl_image*)) ; 00891 00892 /* Loop on the detectors */ 00893 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00894 { 00895 cpl_frameset * selected_jitter; 00896 cpl_bivector * selected_offsets; 00897 cpl_image * flat_ima = NULL; 00898 cpl_image * dark_ima = NULL; 00899 cpl_image * bpm_ima = NULL; 00900 cpl_imagelist * in = NULL; 00901 cpl_imagelist * in_sky = NULL; 00902 int nrejected; 00903 00904 cpl_msg_info(cpl_func, "Combine chip number %d", idet+1) ; 00905 cpl_msg_indent_more() ; 00906 00907 /* Apply frame selection based on offset values */ 00908 selected_jitter = cpl_frameset_duplicate(jitters); 00909 selected_offsets = cpl_bivector_duplicate(offsets); 00910 if(hawki_sci_jitter_config.max_njitter != -1) 00911 { 00912 if(hawki_sci_jitter_config.max_njitter < 00913 cpl_frameset_get_size(selected_jitter)) 00914 { 00915 while(cpl_frameset_get_size(selected_jitter) > 00916 hawki_sci_jitter_config.max_njitter) 00917 { 00918 int irm = cpl_frameset_get_size(selected_jitter) - 1; 00919 cpl_frameset_erase_frame 00920 (selected_jitter, 00921 cpl_frameset_get_frame(selected_jitter,irm)); 00922 } 00923 cpl_vector_set_size(cpl_bivector_get_x(selected_offsets), 00924 hawki_sci_jitter_config.max_njitter); 00925 cpl_vector_set_size(cpl_bivector_get_y(selected_offsets), 00926 hawki_sci_jitter_config.max_njitter); 00927 } 00928 } 00929 hawki_sci_jitter_output.ncomb[idet] = 00930 cpl_frameset_get_size(selected_jitter); 00931 nrejected = cpl_frameset_get_size(selected_jitter) - 00932 cpl_frameset_get_size(jitters); 00933 if(nrejected != 0) 00934 cpl_msg_info(cpl_func,"%d frames reject due to large offsets", 00935 nrejected); 00936 00937 00938 /* Load the input data */ 00939 cpl_msg_info(cpl_func, "Load the input data") ; 00940 cpl_msg_indent_more() ; 00941 if ((in = hawki_load_detector(selected_jitter, 00942 idet+1, CPL_TYPE_FLOAT)) == NULL) { 00943 cpl_msg_error(cpl_func, "Cannot load chip %d", idet+1) ; 00944 cpl_free(combined) ; 00945 cpl_bivector_delete(offsets) ; 00946 cpl_msg_indent_less() ; 00947 cpl_msg_indent_less() ; 00948 return NULL ; 00949 } 00950 if (sky) { 00951 if ((in_sky = hawki_load_detector(sky, idet+1, CPL_TYPE_FLOAT)) == NULL) 00952 { 00953 cpl_msg_warning(cpl_func, "Cannot load sky for chip %d",idet+1); 00954 } 00955 } else in_sky = NULL ; 00956 cpl_msg_indent_less() ; 00957 00958 /* Read the calibrations */ 00959 cpl_msg_info(cpl_func, "Load the calibration data") ; 00960 if(hawki_sci_jitter_read_calib(flat, dark, bpm, 00961 &flat_ima, &dark_ima, &bpm_ima, 00962 idet) != 0) 00963 { 00964 cpl_msg_error(cpl_func, "Cannot read some of the calibrations"); 00965 cpl_imagelist_delete(in); 00966 cpl_free(combined); 00967 if (in_sky) cpl_imagelist_delete(in_sky); 00968 cpl_bivector_delete(offsets); 00969 cpl_msg_indent_less(); 00970 cpl_msg_indent_less(); 00971 return NULL ; 00972 } 00973 00974 /* Apply the calibrations */ 00975 if (flat || dark || bpm ) 00976 { 00977 cpl_msg_info(cpl_func, "Apply the calibrations") ; 00978 cpl_msg_indent_more() ; 00979 /* Basic calibration of the OBJECTS */ 00980 if (hawki_flat_dark_bpm_detector_calib 00981 (in, flat_ima, dark_ima, bpm_ima) == -1) 00982 { 00983 cpl_msg_error(cpl_func, "Cannot calibrate the objects") ; 00984 cpl_imagelist_delete(in) ; 00985 cpl_free(combined) ; 00986 if (in_sky) cpl_imagelist_delete(in_sky) ; 00987 cpl_bivector_delete(offsets) ; 00988 cpl_image_delete(flat_ima); 00989 cpl_image_delete(dark_ima); 00990 cpl_image_delete(bpm_ima); 00991 cpl_msg_indent_less() ; 00992 cpl_msg_indent_less() ; 00993 return NULL ; 00994 } 00995 /* Basic calibration of the SKY */ 00996 if (in_sky) { 00997 if (hawki_flat_dark_bpm_detector_calib 00998 (in_sky, flat_ima, dark_ima, bpm_ima) == -1) 00999 { 01000 cpl_msg_warning(cpl_func, "Cannot calibrate the sky") ; 01001 cpl_imagelist_delete(in_sky) ; 01002 in_sky = NULL ; 01003 } 01004 } 01005 cpl_msg_indent_less() ; 01006 } 01007 cpl_image_delete(flat_ima); 01008 cpl_image_delete(dark_ima); 01009 cpl_image_delete(bpm_ima); 01010 01011 /* Apply the sky correction */ 01012 cpl_msg_info(cpl_func, "Sky estimation and correction") ; 01013 cpl_msg_indent_more() ; 01014 if (hawki_sci_jitter_sky(in, in_sky, bkg_stats, idet) == -1) 01015 { 01016 cpl_msg_error(cpl_func, "Cannot estimate the sky") ; 01017 cpl_imagelist_delete(in) ; 01018 if (in_sky) cpl_imagelist_delete(in_sky) ; 01019 cpl_free(combined) ; 01020 cpl_bivector_delete(offsets) ; 01021 cpl_msg_indent_less() ; 01022 cpl_msg_indent_less() ; 01023 return NULL ; 01024 } 01025 if (in_sky) cpl_imagelist_delete(in_sky) ; 01026 cpl_msg_indent_less() ; 01027 01028 /* Apply the shift and add */ 01029 cpl_msg_info(cpl_func, "Shift and stacking") ; 01030 cpl_msg_indent_more() ; 01031 comb_chip = hawki_sci_jitter_saa(&in, selected_offsets, 01032 &(hawki_sci_jitter_output.combined_pos_x[idet]), 01033 &(hawki_sci_jitter_output.combined_pos_y[idet])) ; 01034 hawki_sci_jitter_output.combined_cumoffset_x[idet] = 01035 hawki_sci_jitter_output.combined_pos_x[idet] - off_0_x; 01036 hawki_sci_jitter_output.combined_cumoffset_y[idet] = 01037 hawki_sci_jitter_output.combined_pos_y[idet] - off_0_y; 01038 if (comb_chip == NULL) { 01039 cpl_msg_error(cpl_func, "Cannot apply the shift and add") ; 01040 cpl_imagelist_delete(in) ; 01041 cpl_free(combined) ; 01042 cpl_bivector_delete(offsets) ; 01043 cpl_msg_indent_less() ; 01044 cpl_msg_indent_less() ; 01045 return NULL ; 01046 } 01047 cpl_imagelist_delete(in) ; 01048 cpl_msg_indent_less() ; 01049 01050 /* Put the results in the image list */ 01051 combined[idet] = comb_chip[0] ; 01052 cpl_image_delete(comb_chip[1]) ; 01053 cpl_free(comb_chip) ; 01054 cpl_msg_indent_less() ; 01055 01056 /* Free */ 01057 cpl_frameset_delete(selected_jitter); 01058 cpl_bivector_delete(selected_offsets); 01059 } 01060 cpl_bivector_delete(offsets) ; 01061 01062 return combined ; 01063 } 01064 01065 /*----------------------------------------------------------------------------*/ 01072 /*----------------------------------------------------------------------------*/ 01073 static int hawki_sci_jitter_sky 01074 (cpl_imagelist * objs, 01075 cpl_imagelist * skys, 01076 cpl_table ** bkg_stats, 01077 int idet) 01078 { 01079 cpl_image * sky ; 01080 int nframes; 01081 double median ; 01082 cpl_image * cur_ima ; 01083 int i ; 01084 01085 /* Initialise */ 01086 nframes = cpl_imagelist_get_size(objs) ; 01087 01088 /* Compute the sky frame */ 01089 if (skys != NULL) { 01090 cpl_msg_info(cpl_func, "Median of sky images") ; 01091 /* Use sky images */ 01092 if ((sky = cpl_imagelist_collapse_median_create(skys)) == NULL) { 01093 cpl_msg_error(cpl_func, "Cannot compute the median of sky images") ; 01094 return -1; 01095 } 01096 01097 /* Statistics on the background */ 01098 if(bkg_stats != NULL) 01099 { 01100 cpl_table_set_size(bkg_stats[idet], 1); 01101 hawki_image_stats_fill_from_image 01102 (bkg_stats, sky, 01103 1, 01104 1, 01105 cpl_image_get_size_x(sky), 01106 cpl_image_get_size_y(sky), 01107 idet, 0); 01108 } 01109 01110 /* Correct the objects images */ 01111 if (cpl_imagelist_subtract_image(objs, sky) != CPL_ERROR_NONE) { 01112 cpl_msg_error(cpl_func, "Cannot corr. the obj images from the sky"); 01113 cpl_image_delete(sky) ; 01114 return -1; 01115 } 01116 cpl_image_delete(sky) ; 01117 /* Normalise the object planes */ 01118 for (i=0 ; i<nframes ; i++) { 01119 cur_ima = cpl_imagelist_get(objs, i) ; 01120 median = cpl_image_get_median(cur_ima) ; 01121 cpl_image_subtract_scalar(cur_ima, median) ; 01122 } 01123 } else if (hawki_sci_jitter_config.sky_minnb > nframes) { 01124 cpl_msg_info(cpl_func, "Median of object images") ; 01125 /* Use objs images */ 01126 if ((sky = cpl_imagelist_collapse_median_create(objs)) == NULL) { 01127 cpl_msg_error(cpl_func, "Cannot compute the median of obj images") ; 01128 return -1; 01129 } 01130 01131 /* Statistics on the background */ 01132 if(bkg_stats != NULL) 01133 { 01134 cpl_table_set_size(bkg_stats[idet], 1); 01135 hawki_image_stats_fill_from_image 01136 (bkg_stats, sky, 01137 1, 01138 1, 01139 cpl_image_get_size_x(sky), 01140 cpl_image_get_size_y(sky), 01141 idet, 0); 01142 } 01143 01144 /* Correct the objects images */ 01145 if (cpl_imagelist_subtract_image(objs, sky) != CPL_ERROR_NONE) { 01146 cpl_msg_error(cpl_func, "Cannot corr. the obj images from the sky"); 01147 cpl_image_delete(sky) ; 01148 return -1; 01149 } 01150 /* Normalise the object planes */ 01151 for (i=0 ; i<nframes ; i++) { 01152 cur_ima = cpl_imagelist_get(objs, i) ; 01153 median = cpl_image_get_median(cur_ima) ; 01154 cpl_image_subtract_scalar(cur_ima, median) ; 01155 } 01156 /* Delete sky image */ 01157 cpl_image_delete(sky) ; 01158 } else { 01159 cpl_msg_info(cpl_func, "Computing running median on jitter images") ; 01160 /* Use objects images */ 01161 if (hawki_sci_jitter_sky_running(objs, bkg_stats, idet) == -1) 01162 { 01163 cpl_msg_error(cpl_func, 01164 "Cannot apply the running median"); 01165 return -1; 01166 } 01167 } 01168 return 0; 01169 } 01170 01171 /*----------------------------------------------------------------------------*/ 01190 /*----------------------------------------------------------------------------*/ 01191 static int hawki_sci_jitter_sky_running 01192 (cpl_imagelist * in, 01193 cpl_table ** bkg_stats, 01194 int idet) 01195 { 01196 int rejmin, rejmax, halfw; 01197 cpl_imagelist * result_buffer; 01198 int ni, nx, ny; 01199 cpl_vector * medians; 01200 cpl_image * cur_ima; 01201 cpl_image * tmp_ima; 01202 double one_med; 01203 int i, k; 01204 int first_buffered = 0; 01205 int next_not_to_be_used; 01206 01207 /* Test entries */ 01208 if (in==NULL) return -1; 01209 01210 /* Initialise */ 01211 rejmin = hawki_sci_jitter_config.sky_rejmin ; 01212 rejmax = hawki_sci_jitter_config.sky_rejmax ; 01213 halfw = hawki_sci_jitter_config.sky_halfw ; 01214 ni = cpl_imagelist_get_size(in) ; 01215 cur_ima = cpl_imagelist_get(in, 0) ; 01216 nx = cpl_image_get_size_x(cur_ima) ; 01217 ny = cpl_image_get_size_y(cur_ima) ; 01218 01219 /* Tests on validity of rejection parameters */ 01220 if (((rejmin+rejmax)>=halfw) || (halfw<1) || (rejmin<0) || (rejmax<0)) { 01221 cpl_msg_error(cpl_func, "cannot compute running median with " 01222 "rejection parameters %d (%d-%d)", 01223 halfw, rejmin, rejmax); 01224 return -1; 01225 } 01226 /* Pre-compute median value in each plane */ 01227 medians = cpl_vector_new(ni) ; 01228 for (i=0 ; i<ni ; i++) { 01229 cur_ima = cpl_imagelist_get(in, i) ; 01230 cpl_vector_set(medians, i, cpl_image_get_median(cur_ima)) ; 01231 } 01232 /* Allocate output cube */ 01233 result_buffer = cpl_imagelist_new() ; 01234 01235 /* Allocate output bg stats */ 01236 cpl_table_set_size(bkg_stats[idet], ni); 01237 01238 /* Main loop over input planes */ 01239 for (k=0 ; k<ni ; k++) 01240 { 01241 cpl_image * bkg; 01242 01243 /* Create the background image, to later compute stats */ 01244 bkg = cpl_image_new(nx, ny, CPL_TYPE_FLOAT); 01245 01246 hawki_bkg_from_running_mean 01247 (in, medians, k, halfw, rejmin, rejmax, bkg); 01248 01249 /* Subtract the background from the current image */ 01250 tmp_ima = cpl_image_subtract_create(cpl_imagelist_get(in, k), bkg); 01251 01252 /* Statistics on the background */ 01253 if(bkg_stats != NULL) 01254 { 01255 hawki_image_stats_fill_from_image 01256 (bkg_stats, bkg, 01257 1, 1, nx, ny, 01258 idet, k); 01259 } 01260 cpl_image_delete(bkg); 01261 01262 /* Place the new image in a result buffer */ 01263 cpl_imagelist_set(result_buffer, tmp_ima, 01264 cpl_imagelist_get_size(result_buffer)); 01265 01266 /* Empty the buffer as much as possible */ 01267 next_not_to_be_used = k - halfw; 01268 while(next_not_to_be_used >= first_buffered) 01269 { 01270 cpl_imagelist_set(in, cpl_imagelist_unset(result_buffer, 0), 01271 first_buffered); 01272 first_buffered++; 01273 } 01274 } 01275 /* Empty the buffer finally */ 01276 next_not_to_be_used = ni - 1; 01277 while(next_not_to_be_used >= first_buffered) 01278 { 01279 cpl_imagelist_set(in, cpl_imagelist_unset(result_buffer, 0), 01280 first_buffered); 01281 first_buffered++; 01282 } 01283 cpl_imagelist_delete(result_buffer); 01284 cpl_vector_delete(medians); 01285 01286 /* Subtract median from each frame */ 01287 for (i=0 ; i<ni ; i++) { 01288 cur_ima = cpl_imagelist_get(in, i); 01289 one_med = cpl_image_get_median(cur_ima) ; 01290 cpl_image_subtract_scalar(cur_ima, one_med) ; 01291 } 01292 return 0; 01293 } 01294 01295 /*----------------------------------------------------------------------------*/ 01304 /*----------------------------------------------------------------------------*/ 01305 static cpl_image ** hawki_sci_jitter_saa( 01306 cpl_imagelist ** in, 01307 cpl_bivector * offsets, 01308 double * pos_x, 01309 double * pos_y) 01310 { 01311 cpl_bivector * offs_est; 01312 cpl_bivector * offs_used; 01313 cpl_bivector * objs ; 01314 cpl_image ** combined ; 01315 int nfiles, ngood, nima, nx, ny ; 01316 int i; 01317 01318 /* Check entries */ 01319 if (pos_x == NULL || pos_y == NULL) return NULL ; 01320 if (offsets == NULL) return NULL ; 01321 01322 /* Get the number of images */ 01323 nfiles = cpl_imagelist_get_size(*in) ; 01324 if (cpl_bivector_get_size(offsets) != nfiles) { 01325 cpl_msg_error(cpl_func, "Invalid input objects sizes") ; 01326 return NULL ; 01327 } 01328 01329 /* Get the offsets estimation of each input file pair */ 01330 cpl_msg_info(cpl_func, "Get the offsets estimation") ; 01331 offs_est = NULL ; 01332 if (hawki_sci_jitter_config.offsets && 01333 hawki_sci_jitter_config.offsets[0] != (char)0) { 01334 /* A file has been provided on the command line */ 01335 offs_est = cpl_bivector_read((char*)hawki_sci_jitter_config.offsets); 01336 if ((offs_est==NULL)||(cpl_bivector_get_size(offs_est)!=nfiles)) { 01337 cpl_msg_error(cpl_func, "Cannot get offsets from %s", 01338 hawki_sci_jitter_config.offsets) ; 01339 return NULL ; 01340 } 01341 } else { 01342 /* Use the offsets from the header */ 01343 offs_est = cpl_bivector_duplicate(offsets) ; 01344 cpl_vector_multiply_scalar(cpl_bivector_get_x(offs_est), -1.0) ; 01345 cpl_vector_multiply_scalar(cpl_bivector_get_y(offs_est), -1.0) ; 01346 } 01347 01348 /* Read the provided objects file if provided */ 01349 objs = NULL ; 01350 if (hawki_sci_jitter_config.refine && 01351 hawki_sci_jitter_config.objects && 01352 hawki_sci_jitter_config.objects[0] != (char)0) { 01353 cpl_msg_info(cpl_func, "Get the user provided correlation objects") ; 01354 /* A file has been provided on the command line */ 01355 objs = cpl_bivector_read((char*)hawki_sci_jitter_config.objects) ; 01356 if (objs==NULL) { 01357 cpl_msg_error(cpl_func, "Cannot get objects from %s", 01358 hawki_sci_jitter_config.objects) ; 01359 cpl_bivector_delete(offs_est) ; 01360 return NULL ; 01361 } 01362 } 01363 01364 /* Get a correlation point from the difference of the first images */ 01365 if (hawki_sci_jitter_config.refine && objs == NULL) { 01366 cpl_apertures * aperts; 01367 cpl_image * detect_image; 01368 cpl_vector * thresh_vect; 01369 double * objs_x ; 01370 double * objs_y ; 01371 cpl_msg_info(cpl_func, "Get a cross-correlation point") ; 01372 thresh_vect = cpl_vector_new(4) ; 01373 cpl_vector_set(thresh_vect, 0, 5.0) ; 01374 cpl_vector_set(thresh_vect, 1, 2.0) ; 01375 cpl_vector_set(thresh_vect, 2, 1.0) ; 01376 cpl_vector_set(thresh_vect, 3, 0.5) ; 01377 detect_image = cpl_imagelist_get(*in, 0); 01378 if ((aperts = cpl_apertures_extract_window(detect_image, thresh_vect, 01379 400, 400, 1600, 1600, NULL)) == NULL) { 01380 cpl_msg_error(cpl_func, "Cannot find any cross-correlation point") ; 01381 cpl_bivector_delete(offs_est) ; 01382 cpl_vector_delete(thresh_vect) ; 01383 return NULL ; 01384 } 01385 cpl_vector_delete(thresh_vect) ; 01386 cpl_apertures_sort_by_npix(aperts) ; 01387 objs = cpl_bivector_new(1) ; 01388 objs_x = cpl_bivector_get_x_data(objs) ; 01389 objs_y = cpl_bivector_get_y_data(objs) ; 01390 objs_x[0] = cpl_apertures_get_pos_x(aperts, 1) ; 01391 objs_y[0] = cpl_apertures_get_pos_y(aperts, 1) ; 01392 cpl_apertures_delete(aperts) ; 01393 if (objs == NULL) { 01394 cpl_msg_error(cpl_func, "Cannot find any cross-correlation point") ; 01395 cpl_bivector_delete(offs_est) ; 01396 return NULL ; 01397 } 01398 cpl_msg_info(cpl_func, 01399 "Correlation point: %g %g\n", objs_x[0], objs_y[0]); 01400 } 01401 01402 /* Refine the offsets */ 01403 if (hawki_sci_jitter_config.refine) { 01404 cpl_bivector * offs_refined; 01405 double * offs_refined_x; 01406 double * offs_refined_y; 01407 double * offs_est_x; 01408 double * offs_est_y; 01409 cpl_vector * correl ; 01410 double * correl_data ; 01411 cpl_msg_info(cpl_func, "Refine the offsets"); 01412 cpl_msg_indent_more() ; 01413 nima = cpl_imagelist_get_size(*in) ; 01414 correl = cpl_vector_new(nima) ; 01415 if ((offs_refined = cpl_geom_img_offset_fine(*in, offs_est, objs, 01416 hawki_sci_jitter_config.sx, 01417 hawki_sci_jitter_config.sy, 01418 hawki_sci_jitter_config.mx, 01419 hawki_sci_jitter_config.my, 01420 correl)) == NULL) { 01421 cpl_msg_error(cpl_func, "Cannot refine the offsets"); 01422 cpl_bivector_delete(offs_est) ; 01423 if (objs != NULL) cpl_bivector_delete(objs) ; 01424 cpl_vector_delete(correl) ; 01425 return NULL ; 01426 } 01427 if (objs != NULL) cpl_bivector_delete(objs) ; 01428 01429 /* Display the results */ 01430 offs_est_x = cpl_bivector_get_x_data(offs_est); 01431 offs_est_y = cpl_bivector_get_y_data(offs_est); 01432 offs_refined_x = cpl_bivector_get_x_data(offs_refined); 01433 offs_refined_y = cpl_bivector_get_y_data(offs_refined) ; 01434 correl_data = cpl_vector_get_data(correl) ; 01435 cpl_msg_info(cpl_func, "Refined offsets [correlation factor]") ; 01436 ngood = 0 ; 01437 for (i=0 ; i<nima ; i++) { 01438 cpl_msg_info(cpl_func, "#%02d: %8.2f %8.2f [%12.2f]", 01439 i+1, offs_refined_x[i], offs_refined_y[i], correl_data[i]); 01440 if (correl_data[i] > -0.5) ngood++ ; 01441 } 01442 if (ngood == 0) { 01443 cpl_msg_error(cpl_func, "No frame correctly correlated") ; 01444 cpl_bivector_delete(offs_est); 01445 cpl_bivector_delete(offs_refined); 01446 cpl_vector_delete(correl); 01447 return NULL ; 01448 } 01449 cpl_msg_indent_less(); 01450 01451 /* Replace bad correlated images with the nominal offsets */ 01452 cpl_msg_info(cpl_func, "Using nominal offsets for badly " 01453 "correlated images (%d out of %d)", nima-ngood, nima); 01454 for (i=0 ; i<nima ; i++) { 01455 if (correl_data[i] < -0.5) { 01456 offs_refined_x[i] = offs_est_x[i]; 01457 offs_refined_y[i] = offs_est_y[i]; 01458 } 01459 } 01460 offs_used = cpl_bivector_duplicate(offs_refined); 01461 cpl_bivector_delete(offs_est); 01462 cpl_bivector_delete(offs_refined); 01463 cpl_vector_delete(correl); 01464 } 01465 else 01466 { 01467 offs_used = cpl_bivector_duplicate(offs_est); 01468 cpl_bivector_delete(offs_est); 01469 } 01470 01471 /* Discard the pixels on the sides */ 01472 if (hawki_sci_jitter_config.borders > 0) { 01473 cpl_imagelist * in_ext ; 01474 cpl_image * tmp1 ; 01475 cpl_image * tmp2 ; 01476 nx = cpl_image_get_size_x(cpl_imagelist_get(*in, 0)) ; 01477 ny = cpl_image_get_size_y(cpl_imagelist_get(*in, 0)) ; 01478 in_ext = cpl_imagelist_new() ; 01479 while(cpl_imagelist_get_size(*in) > 0) 01480 { 01481 tmp1 = cpl_imagelist_unset(*in, 0); 01482 tmp2 = cpl_image_extract(tmp1, 01483 hawki_sci_jitter_config.borders+1, 01484 hawki_sci_jitter_config.borders+1, 01485 nx-hawki_sci_jitter_config.borders, 01486 ny-hawki_sci_jitter_config.borders) ; 01487 cpl_image_delete(tmp1); 01488 cpl_imagelist_set(in_ext, tmp2, cpl_imagelist_get_size(in_ext)) ; 01489 } 01490 cpl_imagelist_delete(*in) ; 01491 *in = in_ext ; 01492 } 01493 01494 /* Apply the shift & add */ 01495 cpl_msg_info(cpl_func, "Recombine the images set") ; 01496 cpl_msg_indent_more() ; 01497 if ((combined=cpl_geom_img_offset_saa(*in, offs_used, 01498 CPL_KERNEL_DEFAULT, 01499 hawki_sci_jitter_config.rej_low, 01500 hawki_sci_jitter_config.rej_high, 01501 hawki_sci_jitter_config.comb_meth, 01502 pos_x, pos_y)) == NULL) { 01503 cpl_msg_error(cpl_func, "Cannot apply the shift and add") ; 01504 cpl_bivector_delete(offs_used) ; 01505 cpl_msg_indent_less() ; 01506 return NULL ; 01507 } 01508 cpl_msg_indent_less() ; 01509 *pos_x -= hawki_sci_jitter_config.borders ; 01510 *pos_y -= hawki_sci_jitter_config.borders ; 01511 01512 /* Free and return */ 01513 cpl_bivector_delete(offs_used) ; 01514 return combined ; 01515 } 01516 01517 /*----------------------------------------------------------------------------*/ 01524 /*----------------------------------------------------------------------------*/ 01525 static int hawki_sci_jitter_qc 01526 (cpl_frameset * science_frames, 01527 cpl_image ** combined_images, 01528 cpl_table ** obj_charac) 01529 { 01530 cpl_vector * thresh_vec ; 01531 cpl_apertures * aperts ; 01532 int nb_objs ; 01533 double angle ; 01534 double * fwhms_x ; 01535 double * fwhms_y ; 01536 cpl_bivector * iqe ; 01537 int nb_good ; 01538 cpl_vector * fwhms_good ; 01539 double * fwhms_good_data ; 01540 double f_min, f_max, fr, fx, fy ; 01541 int chip; 01542 int iobj; 01543 int j; 01544 01545 /* Initialise */ 01546 double seeing_min_arcsec = 0.1 ; 01547 double seeing_max_arcsec = 5.0 ; 01548 double seeing_fwhm_var = 0.2 ; 01549 01550 /* Check entries */ 01551 if (combined_images == NULL) return -1 ; 01552 if (obj_charac == NULL) return -1 ; 01553 01554 /* Create the vector for the detection thresholds */ 01555 thresh_vec = cpl_vector_new(11) ; 01556 cpl_vector_set(thresh_vec, 0, 100.0) ; 01557 cpl_vector_set(thresh_vec, 0, 90.0) ; 01558 cpl_vector_set(thresh_vec, 0, 80.0) ; 01559 cpl_vector_set(thresh_vec, 0, 70.0) ; 01560 cpl_vector_set(thresh_vec, 0, 60.0) ; 01561 cpl_vector_set(thresh_vec, 0, 50.0) ; 01562 cpl_vector_set(thresh_vec, 1, 40.0) ; 01563 cpl_vector_set(thresh_vec, 1, 30.0) ; 01564 cpl_vector_set(thresh_vec, 1, 20.0) ; 01565 cpl_vector_set(thresh_vec, 1, 10.0) ; 01566 cpl_vector_set(thresh_vec, 2, 5.0) ; 01567 01568 /* Get the mean airmass */ 01569 hawki_sci_jitter_output.mean_airmass = 01570 hawki_get_mean_airmass(science_frames);; 01571 01572 /* Loop on the HAWK-I detectors */ 01573 for (chip=0 ; chip<HAWKI_NB_DETECTORS ; chip++) 01574 { 01575 /* Check entries */ 01576 if (combined_images[chip] == NULL) return -1 ; 01577 if (obj_charac[chip] == NULL) return -1 ; 01578 01579 /* Detect apertures */ 01580 if ((aperts = cpl_apertures_extract 01581 (combined_images[chip], thresh_vec, NULL)) == NULL) { 01582 cpl_msg_warning(cpl_func, "Cannot detect any aperture on chip %d", 01583 chip+1) ; 01584 continue; 01585 } 01586 01587 /* Number of detected objects */ 01588 nb_objs = cpl_apertures_get_size(aperts); 01589 cpl_msg_info(cpl_func, "%d objects detected on chip %d",nb_objs,chip+1); 01590 hawki_sci_jitter_output.nbobjs[chip] = nb_objs ; 01591 fwhms_x = cpl_malloc(nb_objs * sizeof(double)) ; 01592 fwhms_y = cpl_malloc(nb_objs * sizeof(double)) ; 01593 01594 /* Initialize the output table */ 01595 cpl_table_set_size(obj_charac[chip], nb_objs); 01596 cpl_table_new_column 01597 (obj_charac[chip], HAWKI_COL_OBJ_POSX, CPL_TYPE_DOUBLE); 01598 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_POSX,"pix"); 01599 cpl_table_new_column 01600 (obj_charac[chip], HAWKI_COL_OBJ_POSY, CPL_TYPE_DOUBLE); 01601 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_POSY,"pix"); 01602 cpl_table_new_column 01603 (obj_charac[chip], HAWKI_COL_OBJ_ANGLE, CPL_TYPE_DOUBLE); 01604 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_ANGLE,"grad"); 01605 cpl_table_new_column 01606 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MAJAX, CPL_TYPE_DOUBLE); 01607 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_FWHM_MAJAX,"pix"); 01608 cpl_table_new_column 01609 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MINAX, CPL_TYPE_DOUBLE); 01610 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_FWHM_MINAX,"pix"); 01611 cpl_table_new_column 01612 (obj_charac[chip], HAWKI_COL_OBJ_ELLIP, CPL_TYPE_DOUBLE); 01613 cpl_table_new_column 01614 (obj_charac[chip], HAWKI_COL_OBJ_FLUX, CPL_TYPE_DOUBLE); 01615 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_FLUX,"ADU"); 01616 for (iobj=0 ; iobj<nb_objs ; iobj++) 01617 { 01618 /* Fill with the already known information */ 01619 cpl_table_set_double(obj_charac[chip], HAWKI_COL_OBJ_POSX, iobj, 01620 cpl_apertures_get_centroid_x(aperts, iobj+1)); 01621 cpl_table_set_double(obj_charac[chip], HAWKI_COL_OBJ_POSY, iobj, 01622 cpl_apertures_get_centroid_y(aperts, iobj+1)); 01623 cpl_table_set_double(obj_charac[chip], HAWKI_COL_OBJ_FLUX, iobj, 01624 cpl_apertures_get_flux(aperts, iobj+1)) ; 01625 /* Compute the FWHM informations */ 01626 if ((iqe = cpl_image_iqe(combined_images[chip], 01627 (int)cpl_apertures_get_centroid_x(aperts, iobj+1) - 10, 01628 (int)cpl_apertures_get_centroid_y(aperts, iobj+1) - 10, 01629 (int)cpl_apertures_get_centroid_x(aperts, iobj+1) + 10, 01630 (int)cpl_apertures_get_centroid_y(aperts, iobj+1) + 10))==NULL) 01631 { 01632 cpl_error_reset() ; 01633 cpl_msg_debug(cpl_func, "Cannot get FWHM for obj at pos %g %g", 01634 cpl_apertures_get_centroid_x(aperts, iobj+1), 01635 cpl_apertures_get_centroid_y(aperts, iobj+1)) ; 01636 fwhms_x[iobj] = -1.0 ; 01637 fwhms_y[iobj] = -1.0 ; 01638 angle = 0.0 ; 01639 } 01640 else 01641 { 01642 fwhms_x[iobj] = cpl_vector_get(cpl_bivector_get_x(iqe), 2) ; 01643 fwhms_y[iobj] = cpl_vector_get(cpl_bivector_get_x(iqe), 3) ; 01644 angle = cpl_vector_get(cpl_bivector_get_x(iqe), 4) ; 01645 cpl_bivector_delete(iqe) ; 01646 cpl_msg_debug(cpl_func, 01647 "FWHM for obj at pos %g %g: %g x %g (%g)", 01648 cpl_apertures_get_centroid_x(aperts, iobj+1), 01649 cpl_apertures_get_centroid_y(aperts, iobj+1), 01650 fwhms_x[iobj], fwhms_y[iobj], angle) ; 01651 } 01652 cpl_table_set_double 01653 (obj_charac[chip], HAWKI_COL_OBJ_ANGLE, iobj, angle) ; 01654 cpl_table_set_double 01655 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MAJAX, iobj, 01656 fwhms_x[iobj]); 01657 cpl_table_set_double 01658 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MINAX, iobj, 01659 fwhms_y[iobj]); 01660 cpl_table_set_double 01661 (obj_charac[chip], HAWKI_COL_OBJ_ELLIP, iobj, 01662 1 - fwhms_y[iobj] / fwhms_x[iobj]); 01663 } 01664 cpl_apertures_delete(aperts) ; 01665 01666 /* Get the number of good values */ 01667 nb_good = 0 ; 01668 for (iobj=0 ; iobj<nb_objs ; iobj++) 01669 { 01670 if ((fwhms_x[iobj] > 0.0) && (fwhms_y[iobj] > 0.0)) nb_good++ ; 01671 } 01672 if (nb_good == 0) 01673 { 01674 cpl_msg_warning(cpl_func, "No objects to compute FWHM on chip %d", 01675 chip+1); 01676 cpl_free(fwhms_x) ; 01677 cpl_free(fwhms_y) ; 01678 continue; 01679 } 01680 01681 /* Get the good values */ 01682 fwhms_good = cpl_vector_new(nb_good) ; 01683 fwhms_good_data = cpl_vector_get_data(fwhms_good) ; 01684 j=0 ; 01685 for (iobj=0 ; iobj<nb_objs ; iobj++) 01686 { 01687 if ((fwhms_x[iobj] > 0.0) && (fwhms_y[iobj] > 0.0)) 01688 { 01689 fwhms_good_data[j] = (fwhms_x[iobj]+fwhms_y[iobj])/2.0 ; 01690 j++ ; 01691 } 01692 } 01693 01694 /* Compute the fwhm */ 01695 if (nb_good < 3) 01696 { 01697 /* Too few values to compute the median */ 01698 hawki_sci_jitter_output.fwhm_pix[chip] = fwhms_good_data[0] ; 01699 } 01700 else 01701 { 01702 /* Compute the median */ 01703 hawki_sci_jitter_output.fwhm_pix[chip] = 01704 cpl_vector_get_median_const(fwhms_good) ; 01705 } 01706 hawki_sci_jitter_output.fwhm_arcsec[chip] = 01707 hawki_sci_jitter_output.fwhm_pix[chip] * 01708 hawki_sci_jitter_output.pixscale ; 01709 01710 /* Compute the mode of the FWHMs */ 01711 if (nb_good > 5) 01712 { 01713 hawki_sci_jitter_output.fwhm_mode[chip] = 01714 hawki_vector_get_mode(fwhms_good); 01715 hawki_sci_jitter_output.fwhm_mode[chip] *= 01716 hawki_sci_jitter_output.pixscale ; 01717 } 01718 cpl_vector_delete(fwhms_good) ; 01719 01720 /* IQ is the median of the (fwhm_x+fwhm_y/2) of the good stars */ 01721 /* Compute f_min and f_max */ 01722 f_min = seeing_min_arcsec / hawki_sci_jitter_output.pixscale ; 01723 f_max = seeing_max_arcsec / hawki_sci_jitter_output.pixscale ; 01724 01725 /* Get the number of good values */ 01726 nb_good = 0 ; 01727 for (iobj=0 ; iobj<nb_objs ; iobj++) 01728 { 01729 fx = fwhms_x[iobj] ; 01730 fy = fwhms_y[iobj] ; 01731 fr = 2.0 * fabs(fx-fy) / (fx+fy) ; 01732 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) && 01733 (fr < seeing_fwhm_var)) nb_good++ ; 01734 } 01735 if (nb_good == 0) 01736 { 01737 cpl_msg_warning(cpl_func, "No objects to compute IQ on chip %d", 01738 chip+1); 01739 cpl_free(fwhms_x) ; 01740 cpl_free(fwhms_y) ; 01741 continue; 01742 } 01743 01744 /* Get the good values */ 01745 fwhms_good = cpl_vector_new(nb_good) ; 01746 fwhms_good_data = cpl_vector_get_data(fwhms_good) ; 01747 j=0 ; 01748 for (iobj=0 ; iobj<nb_objs ; iobj++) 01749 { 01750 fx = fwhms_x[iobj] ; 01751 fy = fwhms_y[iobj] ; 01752 fr = 2.0 * fabs(fx-fy) / (fx+fy) ; 01753 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) && 01754 (fr < seeing_fwhm_var)) 01755 { 01756 fwhms_good_data[j] = (fx + fy)/2.0 ; 01757 j++ ; 01758 } 01759 } 01760 cpl_free(fwhms_x) ; 01761 cpl_free(fwhms_y) ; 01762 01763 /* Compute the fwhm */ 01764 if (nb_good < 3) 01765 { 01766 /* Too few values to compute the median */ 01767 hawki_sci_jitter_output.iq[chip] = fwhms_good_data[0] ; 01768 } 01769 else 01770 { 01771 /* Compute the median */ 01772 hawki_sci_jitter_output.iq[chip] = 01773 cpl_vector_get_median_const(fwhms_good) ; 01774 } 01775 cpl_vector_delete(fwhms_good) ; 01776 hawki_sci_jitter_output.iq[chip] *= hawki_sci_jitter_output.pixscale ; 01777 } 01778 01779 /* Cleanup */ 01780 cpl_vector_delete(thresh_vec) ; 01781 01782 return 0; 01783 } 01784 01785 /*----------------------------------------------------------------------------*/ 01797 /*----------------------------------------------------------------------------*/ 01798 static int hawki_sci_jitter_read_calib 01799 (const char * flat, 01800 const char * dark, 01801 const char * bpm, 01802 cpl_image ** flat_image, 01803 cpl_image ** dark_image, 01804 cpl_image ** bpm_image, 01805 int idet) 01806 { 01807 const char * reffile; 01808 int ext_nb; 01809 01810 if(flat == NULL && dark == NULL && bpm == NULL) 01811 return 0; 01812 if(*flat_image != NULL || *dark_image != NULL || *bpm_image != NULL) 01813 return 0; 01814 01815 /* Get the extension number for this detector */ 01816 if(flat != NULL) 01817 reffile = flat; 01818 else if(dark != NULL) 01819 reffile = dark; 01820 else 01821 reffile = bpm; 01822 01823 /* Guess which is the extension to read */ 01824 if ((ext_nb = hawki_get_ext_from_detector(reffile, idet + 1)) == -1) { 01825 cpl_msg_error(cpl_func, "Cannot get the extension with detector %d", 01826 idet + 1); 01827 return -1; 01828 } 01829 01830 /* Load the dark image */ 01831 if(dark != NULL) 01832 *dark_image = cpl_image_load(dark, CPL_TYPE_FLOAT, 0, ext_nb); 01833 /* Load the flat image */ 01834 if(flat != NULL) 01835 *flat_image = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, ext_nb); 01836 /* Load the bpm image */ 01837 if(bpm != NULL) 01838 *bpm_image = cpl_image_load(bpm, CPL_TYPE_FLOAT, 0, ext_nb); 01839 01840 /* Multiply the dark image by the science exposure time */ 01841 if(dark != NULL) 01842 cpl_image_multiply_scalar(*dark_image, hawki_sci_jitter_output.dit); 01843 01844 /* Return */ 01845 return 0; 01846 } 01847 01848 /*----------------------------------------------------------------------------*/ 01857 /*----------------------------------------------------------------------------*/ 01858 static int hawki_sci_jitter_save 01859 (cpl_image ** combined, 01860 cpl_image * stitched, 01861 cpl_table ** obj_charac, 01862 cpl_table ** raw_jitter_stats, 01863 cpl_table ** bkg_stats, 01864 const cpl_table * raw_obj_tel_info, 01865 cpl_frameset * science_frames, 01866 cpl_frameset * calib_frames, 01867 cpl_parameterlist * parlist, 01868 cpl_frameset * set) 01869 { 01870 cpl_propertylist * plist ; 01871 double pscale, dit, bg_mean, bg_stdev, bg_instmag ; 01872 cpl_propertylist ** qclists ; 01873 const cpl_frame * ref_frame ; 01874 cpl_frameset * used_frames; 01875 cpl_propertylist * wcslist ; 01876 cpl_propertylist * telstats; 01877 cpl_propertylist * inputlist ; 01878 double crpix1, crpix2 ; 01879 int ext_nb ; 01880 const char * recipe_name = "hawki_sci_jitter" ; 01881 int i; 01882 int ext_chip_1; 01883 cpl_errorstate error_prevstate = cpl_errorstate_get(); 01884 01885 /* Initialise */ 01886 pscale = hawki_sci_jitter_output.pixscale; 01887 dit = hawki_sci_jitter_output.dit; 01888 01889 /* Get reference frame */ 01890 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW); 01891 01892 /* Get the used frames */ 01893 used_frames = cpl_frameset_duplicate(science_frames); 01894 for(i = 0; i< cpl_frameset_get_size(calib_frames); ++i) 01895 cpl_frameset_insert(used_frames, 01896 cpl_frame_duplicate(cpl_frameset_get_frame(calib_frames, i))); 01897 01898 /* Create the telescope data statistics */ 01899 telstats = cpl_propertylist_new(); 01900 hawki_compute_prop_tel_qc_stats(raw_obj_tel_info, telstats); 01901 01902 /* Create the QC lists */ 01903 qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 01904 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 01905 01906 /* Get the extension number */ 01907 ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), i+1); 01908 01909 /* Handle WCS keys */ 01910 wcslist = cpl_propertylist_load_regexp( 01911 cpl_frame_get_filename(ref_frame), ext_nb, HAWKI_HEADER_WCS, 0); 01912 qclists[i] = cpl_propertylist_new() ; 01913 01914 /* Compute bg_instmag */ 01915 bg_mean = cpl_table_get_column_mean(bkg_stats[i], HAWKI_COL_STAT_MEAN); 01916 if (cpl_table_get_nrow(bkg_stats[i]) < 2) bg_stdev = 0 ; 01917 else bg_stdev = cpl_table_get_column_stdev 01918 (bkg_stats[i], HAWKI_COL_STAT_MEAN); 01919 if(bg_mean >= 0) 01920 bg_instmag = -2.5 * log10(bg_mean/(pscale*pscale*dit)); 01921 else 01922 bg_instmag = 0; 01923 01924 /* Fill the QC */ 01925 cpl_propertylist_append_double 01926 (qclists[i], "ESO QC BACKGD MEAN", bg_mean); 01927 cpl_propertylist_set_comment(qclists[i], "ESO QC BACKGD MEAN", 01928 "Mean of all the image mean backgrounds"); 01929 cpl_propertylist_append_double 01930 (qclists[i], "ESO QC BACKGD STDEV", bg_stdev); 01931 cpl_propertylist_set_comment(qclists[i], "ESO QC BACKGD STDEV", 01932 "The standard deviation of all the image mean backgrounds"); 01933 cpl_propertylist_append_double 01934 (qclists[i], "ESO QC BACKGD INSTMAG", bg_instmag) ; 01935 cpl_propertylist_set_comment(qclists[i], "ESO QC BACKGD INSTMAG", 01936 "Mean of all the image mean backgrounds in instrumental magnitudes"); 01937 cpl_propertylist_append_int 01938 (qclists[i], "ESO QC NBOBJS", hawki_sci_jitter_output.nbobjs[i]); 01939 cpl_propertylist_set_comment(qclists[i], "ESO QC NBOBJS", 01940 "Number of detected objects in the combined image"); 01941 cpl_propertylist_append_double 01942 (qclists[i], "ESO QC IQ", hawki_sci_jitter_output.iq[i]); 01943 cpl_propertylist_set_comment(qclists[i], "ESO QC IQ", 01944 "Estimated image quality [arcsec]"); 01945 cpl_propertylist_append_double 01946 (qclists[i], "ESO QC IQ DIFF AMBI", 01947 hawki_sci_jitter_output.iq[i] - cpl_propertylist_get_double 01948 (telstats, "ESO QC TEL AMBI FWHM MEAN")); 01949 cpl_propertylist_set_comment(qclists[i], "ESO QC IQ DIFF AMBI", 01950 "Mean Observatory seeing measured by AS"); 01951 cpl_propertylist_append_double 01952 (qclists[i], "ESO QC IQ DIFF TEL", 01953 hawki_sci_jitter_output.iq[i] - cpl_propertylist_get_double 01954 (telstats, "ESO QC TEL IA FWHM MEAN")); 01955 cpl_propertylist_set_comment(qclists[i], "ESO QC IQ DIFF TEL", 01956 "Mean Observatory seeing measured by AS corrected by airmass"); 01957 cpl_propertylist_append_double 01958 (qclists[i], "ESO QC FWHM PIX", 01959 hawki_sci_jitter_output.fwhm_pix[i]); 01960 cpl_propertylist_set_comment(qclists[i], "ESO QC FWHM PIX", 01961 "The median FWHM in the image [pixels]"); 01962 cpl_propertylist_append_double 01963 (qclists[i], "ESO QC FWHM ARCSEC", 01964 hawki_sci_jitter_output.fwhm_arcsec[i]); 01965 cpl_propertylist_set_comment(qclists[i], "ESO QC FWHM ARCSEC", 01966 "The median FWHM in the image [arcsec]"); 01967 cpl_propertylist_append_double 01968 (qclists[i], "ESO QC FWHM MODE", 01969 hawki_sci_jitter_output.fwhm_mode[i]); 01970 cpl_propertylist_set_comment(qclists[i], "ESO QC FWHM MODE", 01971 "The mode FWHM in the image [pixels]"); 01972 cpl_propertylist_append_double 01973 (qclists[i], "ESO QC COMBINED POSX", 01974 hawki_sci_jitter_output.combined_pos_x[i]); 01975 cpl_propertylist_set_comment(qclists[i], "ESO QC COMBINED POSX", 01976 "Position in X of the first image"); 01977 cpl_propertylist_append_double 01978 (qclists[i], "ESO QC COMBINED POSY", 01979 hawki_sci_jitter_output.combined_pos_y[i]); 01980 cpl_propertylist_set_comment(qclists[i], "ESO QC COMBINED POSY", 01981 "Position in Y of the first image"); 01982 cpl_propertylist_append_double 01983 (qclists[i], "ESO QC COMBINED CUMOFFSETX", 01984 hawki_sci_jitter_output.combined_cumoffset_x[i]); 01985 cpl_propertylist_append_double 01986 (qclists[i], "ESO QC COMBINED CUMOFFSETY", 01987 hawki_sci_jitter_output.combined_cumoffset_y[i]); 01988 cpl_propertylist_append_int 01989 (qclists[i], "ESO QC DATANCOM",hawki_sci_jitter_output.ncomb[i]); 01990 cpl_propertylist_set_comment(qclists[i], "ESO QC DATANCOM", 01991 "Number of files used for the reduction"); 01992 cpl_propertylist_append_double 01993 (qclists[i], "ESO QC AIRMASS MEAN", 01994 hawki_sci_jitter_output.mean_airmass); 01995 cpl_propertylist_set_comment(qclists[i], "ESO QC AIRMASS MEAN", 01996 "Average airmass"); 01997 01998 /* Update WCS and write them */ 01999 crpix1 = cpl_propertylist_get_double(wcslist, "CRPIX1"); 02000 crpix1 += hawki_sci_jitter_output.combined_pos_x[i]; 02001 cpl_propertylist_update_double(wcslist, "CRPIX1", crpix1) ; 02002 crpix2 = cpl_propertylist_get_double(wcslist, "CRPIX2"); 02003 crpix2 += hawki_sci_jitter_output.combined_pos_y[i] ; 02004 cpl_propertylist_update_double(wcslist, "CRPIX2", crpix2) ; 02005 cpl_propertylist_copy_property_regexp 02006 (qclists[i], wcslist, HAWKI_HEADER_WCS, 0) ; 02007 cpl_propertylist_delete(wcslist); 02008 02009 /* Propagate some keywords from input raw frame extensions */ 02010 inputlist = cpl_propertylist_load_regexp( 02011 cpl_frame_get_filename(ref_frame), ext_nb, 02012 HAWKI_HEADER_EXT_FORWARD, 0) ; 02013 cpl_propertylist_append(qclists[i], inputlist); 02014 cpl_propertylist_delete(inputlist) ; 02015 } 02016 02017 /* Statistics of the raw images in the QC */ 02018 hawki_image_stats_stats(raw_jitter_stats, qclists); 02019 02020 /* Statistics of the detected objects in the QC */ 02021 hawki_obj_prop_stats(obj_charac, qclists); 02022 02023 /* Write the combined image */ 02024 hawki_images_save(set, 02025 parlist, 02026 used_frames, 02027 (const cpl_image **)combined, 02028 recipe_name, 02029 HAWKI_CALPRO_COMBINED, 02030 HAWKI_PROTYPE_COMBINED, 02031 NULL, 02032 (const cpl_propertylist**)qclists, 02033 "hawki_sci_jitter.fits"); 02034 02035 /* Erase the WCS */ 02036 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 02037 cpl_propertylist_erase_regexp(qclists[i], HAWKI_HEADER_WCS, 0) ; 02038 } 02039 02040 /* Create a propertylist for PRO.x */ 02041 plist = cpl_propertylist_new(); 02042 cpl_propertylist_append_string(plist, CPL_DFS_PRO_TYPE, 02043 HAWKI_PROTYPE_STITCHED) ; 02044 cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG, 02045 HAWKI_CALPRO_STITCHED) ; 02046 /* Handle WCS keys */ 02047 ext_chip_1 = 1; 02048 wcslist = cpl_propertylist_load_regexp( 02049 cpl_frame_get_filename(ref_frame), ext_chip_1, HAWKI_HEADER_WCS, 0); 02050 /* Update WCS and write them */ 02051 crpix1 = cpl_propertylist_get_double(wcslist, "CRPIX1"); 02052 crpix1 += hawki_sci_jitter_output.combined_pos_x[0]; 02053 cpl_propertylist_update_double(wcslist, "CRPIX1", crpix1) ; 02054 crpix2 = cpl_propertylist_get_double(wcslist, "CRPIX2"); 02055 crpix2 += hawki_sci_jitter_output.combined_pos_y[0] ; 02056 cpl_propertylist_update_double(wcslist, "CRPIX2", crpix2) ; 02057 cpl_propertylist_append(plist, wcslist); 02058 cpl_propertylist_delete(wcslist) ; 02059 /* Write the stitched image */ 02060 cpl_dfs_save_image(set, 02061 NULL, 02062 parlist, 02063 used_frames, 02064 NULL, 02065 stitched, 02066 CPL_BPP_IEEE_FLOAT, 02067 recipe_name, 02068 plist, 02069 NULL, 02070 PACKAGE "/" PACKAGE_VERSION, 02071 "hawki_sci_jitter_stitched.fits"); 02072 cpl_propertylist_delete(plist); 02073 02074 /* Write the FITS table with the objects statistics */ 02075 if (obj_charac) 02076 { 02077 hawki_tables_save(set, 02078 parlist, 02079 used_frames, 02080 (const cpl_table **)obj_charac, 02081 recipe_name, 02082 HAWKI_CALPRO_OBJ_PARAM, 02083 HAWKI_PROTYPE_OBJ_PARAM, 02084 NULL, 02085 (const cpl_propertylist**)qclists, 02086 "hawki_sci_jitter_stars.fits"); 02087 } 02088 02089 /* Write the table with the background statistics */ 02090 hawki_tables_save(set, 02091 parlist, 02092 used_frames, 02093 (const cpl_table **)bkg_stats, 02094 recipe_name, 02095 HAWKI_CALPRO_JITTER_BKG_STATS, 02096 HAWKI_PROTYPE_JITTER_BKG_STATS, 02097 NULL, 02098 (const cpl_propertylist **)qclists, 02099 "hawki_sci_jitter_bkg_stats.fits"); 02100 02101 /* Free and return */ 02102 cpl_frameset_delete(used_frames); 02103 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 02104 cpl_propertylist_delete(qclists[i]) ; 02105 } 02106 cpl_propertylist_delete(telstats) ; 02107 cpl_free(qclists) ; 02108 if(!cpl_errorstate_is_equal(error_prevstate)) 02109 { 02110 cpl_errorstate_set(CPL_ERROR_NONE); 02111 return -1; 02112 } 02113 return 0; 02114 } 02115 02116 int hawki_sci_jitter_whole_image_algo 02117 (cpl_frameset * obj, 02118 cpl_table ** raw_jitter_stats, 02119 cpl_table * raw_obj_tel_info, 02120 cpl_parameterlist * parlist, 02121 cpl_frameset * recipe_set) 02122 { 02123 int nframes; 02124 int iframe; 02125 02126 02127 nframes = cpl_frameset_get_size(obj); 02128 for( iframe = 0 ; iframe < nframes ; ++iframe) 02129 { 02130 /* Local storage variables */ 02131 cpl_frame * this_target_frame; 02132 cpl_propertylist * this_properties; 02133 02134 /* Computing statistics for this frame */ 02135 cpl_msg_info(cpl_func, "Getting statistics for image %d", iframe + 1); 02136 this_target_frame = cpl_frameset_get_frame(obj, iframe); 02137 hawki_image_stats_fill_from_frame 02138 (raw_jitter_stats, this_target_frame, iframe); 02139 02140 /* Compute the telescope pcs statistics */ 02141 this_properties = cpl_propertylist_load 02142 (cpl_frame_get_filename(this_target_frame), 0); 02143 if(this_properties == NULL) 02144 { 02145 cpl_msg_error(cpl_func,"Could not read the header of object frame"); 02146 return -1; 02147 } 02148 if(hawki_extract_prop_tel_qc(this_properties, raw_obj_tel_info, iframe)) 02149 { 02150 cpl_msg_warning(cpl_func,"Some telescope properties could not be " 02151 "read for image %d", iframe+1); 02152 cpl_errorstate_set(CPL_ERROR_NONE); 02153 } 02154 cpl_propertylist_delete(this_properties); 02155 } 02156 02157 /* Saving the already computed products */ 02158 cpl_msg_info(cpl_func, "Saving image statistics"); 02159 if(hawki_sci_jitter_save_stats(raw_jitter_stats, raw_obj_tel_info, 02160 obj, 02161 parlist, recipe_set) != 0) 02162 cpl_msg_warning(cpl_func,"Some data could not be saved. " 02163 "Check permisions or disk space"); 02164 02165 02166 /* Free and return */ 02167 return 0; 02168 } 02169 02170 int hawki_sci_jitter_save_stats 02171 (cpl_table ** raw_jitter_stats, 02172 cpl_table * raw_obj_tel_info, 02173 cpl_frameset * jitter_frames, 02174 cpl_parameterlist * parlist, 02175 cpl_frameset * recipe_set) 02176 { 02177 int idet; 02178 const cpl_frame * ref_frame; 02179 cpl_propertylist ** qcstats; 02180 cpl_propertylist * telstats; 02181 const char * recipe_name = "hawki_sci_jitter" ; 02182 cpl_errorstate error_prevstate = cpl_errorstate_get(); 02183 02184 /* Statistics of the raw images in the QC */ 02185 qcstats = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)); 02186 /* Create the QC lists */ 02187 ref_frame = irplib_frameset_get_first_from_group 02188 (recipe_set, CPL_FRAME_GROUP_RAW); 02189 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 02190 { 02191 int ext_nb; 02192 cpl_propertylist * reflist; 02193 02194 qcstats[idet] = cpl_propertylist_new(); 02195 /* Propagate some keywords from input raw frame extensions */ 02196 ext_nb = 02197 hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), idet+1); 02198 reflist = cpl_propertylist_load_regexp 02199 (cpl_frame_get_filename(ref_frame), ext_nb, 02200 HAWKI_HEADER_EXT_FORWARD, 0) ; 02201 cpl_propertylist_append(qcstats[idet], reflist); 02202 cpl_propertylist_delete(reflist); 02203 } 02204 hawki_image_stats_stats(raw_jitter_stats, qcstats); 02205 /* Write the table with the raw jitter objects statistics */ 02206 hawki_tables_save(recipe_set, 02207 parlist, 02208 jitter_frames, 02209 (const cpl_table **)raw_jitter_stats, 02210 recipe_name, 02211 HAWKI_CALPRO_JITTER_STATS, 02212 HAWKI_PROTYPE_JITTER_STATS, 02213 NULL, 02214 (const cpl_propertylist**)qcstats, 02215 "hawki_sci_jitter_stats.fits"); 02216 /* Free qcstats */ 02217 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 02218 cpl_propertylist_delete(qcstats[idet]); 02219 02220 /* Write the FITS table with the raw telescope data */ 02221 telstats = cpl_propertylist_new(); 02222 cpl_propertylist_append_string(telstats, CPL_DFS_PRO_TYPE, 02223 HAWKI_PROTYPE_SCIENCE_PCS); 02224 cpl_propertylist_append_string(telstats, CPL_DFS_PRO_CATG, 02225 HAWKI_CALPRO_SCIENCE_PCS); 02226 hawki_compute_prop_tel_qc_stats(raw_obj_tel_info, telstats); 02227 if(cpl_dfs_save_table(recipe_set, 02228 NULL, 02229 parlist, 02230 jitter_frames, 02231 NULL, 02232 raw_obj_tel_info, 02233 NULL, 02234 recipe_name, 02235 telstats, 02236 NULL, 02237 PACKAGE "/" PACKAGE_VERSION, 02238 "hawki_sci_jitter_pcs.fits") != CPL_ERROR_NONE) 02239 cpl_msg_error(cpl_func,"Cannot save PCS table"); 02240 02241 /* Free and return */ 02242 cpl_propertylist_delete(telstats); 02243 cpl_free(qcstats); 02244 if(!cpl_errorstate_is_equal(error_prevstate)) 02245 { 02246 cpl_errorstate_set(CPL_ERROR_NONE); 02247 return -1; 02248 } 02249 02250 return 0; 02251 }