|
HAWKI Pipeline Reference Manual 1.8.11
|
00001 /* $Id: hawki_sci_jitter.c,v 1.31 2012/12/04 09:41:34 cgarcia Exp $ 00002 * 00003 * This file is part of the HAWKI Pipeline 00004 * Copyright (C) 2002,2003 European Southern Observatory 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 */ 00020 00021 /* 00022 * $Author: cgarcia $ 00023 * $Date: 2012/12/04 09:41:34 $ 00024 * $Revision: 1.31 $ 00025 * $Name: hawki-1_8_11 $ 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 /* Get the offsets */ 00825 if ((offsets = hawki_get_header_tel_offsets(jitters)) == NULL) { 00826 cpl_msg_error(cpl_func, "Cannot load the offsets") ; 00827 return NULL ; 00828 } 00829 offs_est_x = cpl_bivector_get_x_data(offsets) ; 00830 offs_est_y = cpl_bivector_get_y_data(offsets) ; 00831 00832 /* Print the header offsets */ 00833 for (ioff=0 ; ioff<cpl_bivector_get_size(offsets) ; ioff++) { 00834 cpl_msg_info(cpl_func, "Telescope offsets (Frame %d): %g %g", ioff+1, 00835 offs_est_x[ioff], offs_est_y[ioff]) ; 00836 } 00837 00838 /* Subtract the first offset to all offsets */ 00839 off_0_x = -offs_est_x[0]; // This is to get the cpl convention 00840 off_0_y = -offs_est_y[0]; 00841 for (ioff=1 ; ioff<cpl_bivector_get_size(offsets) ; ioff++) 00842 { 00843 offs_est_x[ioff] -= offs_est_x[0] ; 00844 offs_est_y[ioff] -= offs_est_y[0] ; 00845 } 00846 offs_est_x[0] = offs_est_y[0] = 0.00 ; 00847 00848 /* Check if the max offset is not too big */ 00849 /* The criteria is that for a given frame, the closest frame cannot be 00850 * further than hawki_sci_jitter_config.offset_max (in both dimensions) */ 00851 offset_x_sort = cpl_vector_duplicate(cpl_bivector_get_x(offsets)); 00852 offset_y_sort = cpl_vector_duplicate(cpl_bivector_get_y(offsets)); 00853 cpl_vector_sort(offset_x_sort, +1); 00854 cpl_vector_sort(offset_y_sort, +1); 00855 for (ioff=0 ; ioff<cpl_bivector_get_size(offsets) - 1 ; ioff++) 00856 { 00857 double diff_x, diff_y; 00858 diff_x = cpl_vector_get(offset_x_sort,ioff+1)-cpl_vector_get(offset_x_sort,ioff); 00859 cpl_vector_set(offset_x_sort, ioff, diff_x); 00860 diff_y = cpl_vector_get(offset_y_sort,ioff+1)-cpl_vector_get(offset_y_sort,ioff); 00861 cpl_vector_set(offset_y_sort, ioff, diff_y); 00862 } 00863 cpl_vector_set(offset_x_sort, cpl_bivector_get_size(offsets)-1, 0.); 00864 cpl_vector_set(offset_y_sort, cpl_bivector_get_size(offsets)-1, 0.); 00865 max_x = cpl_vector_get_max(offset_x_sort); 00866 max_y = cpl_vector_get_max(offset_y_sort); 00867 cpl_vector_delete(offset_x_sort); 00868 cpl_vector_delete(offset_y_sort); 00869 00870 if (max_x > hawki_sci_jitter_config.offset_max || 00871 max_y > hawki_sci_jitter_config.offset_max) 00872 { 00873 cpl_msg_error(cpl_func, "Sorry, no support for frames further than %d from its closest neighbour", 00874 hawki_sci_jitter_config.offset_max) ; 00875 cpl_bivector_delete(offsets); 00876 return NULL ; 00877 } 00878 00879 /* Create output object */ 00880 combined = cpl_malloc(HAWKI_NB_DETECTORS*sizeof(cpl_image*)) ; 00881 00882 /* Loop on the detectors */ 00883 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00884 { 00885 cpl_frameset * selected_jitter; 00886 cpl_bivector * selected_offsets; 00887 cpl_image * flat_ima = NULL; 00888 cpl_image * dark_ima = NULL; 00889 cpl_image * bpm_ima = NULL; 00890 cpl_imagelist * in = NULL; 00891 cpl_imagelist * in_sky = NULL; 00892 int nrejected; 00893 00894 cpl_msg_info(cpl_func, "Combine chip number %d", idet+1) ; 00895 cpl_msg_indent_more() ; 00896 00897 /* Apply frame selection based on offset values */ 00898 selected_jitter = cpl_frameset_duplicate(jitters); 00899 selected_offsets = cpl_bivector_duplicate(offsets); 00900 if(hawki_sci_jitter_config.max_njitter != -1) 00901 { 00902 if(hawki_sci_jitter_config.max_njitter < 00903 cpl_frameset_get_size(selected_jitter)) 00904 { 00905 while(cpl_frameset_get_size(selected_jitter) > 00906 hawki_sci_jitter_config.max_njitter) 00907 { 00908 int irm = cpl_frameset_get_size(selected_jitter) - 1; 00909 cpl_frameset_erase_frame 00910 (selected_jitter, 00911 cpl_frameset_get_frame(selected_jitter,irm)); 00912 } 00913 cpl_vector_set_size(cpl_bivector_get_x(selected_offsets), 00914 hawki_sci_jitter_config.max_njitter); 00915 cpl_vector_set_size(cpl_bivector_get_y(selected_offsets), 00916 hawki_sci_jitter_config.max_njitter); 00917 } 00918 } 00919 hawki_sci_jitter_output.ncomb[idet] = 00920 cpl_frameset_get_size(selected_jitter); 00921 nrejected = cpl_frameset_get_size(selected_jitter) - 00922 cpl_frameset_get_size(jitters); 00923 if(nrejected != 0) 00924 cpl_msg_info(cpl_func,"%d frames reject due to large offsets", 00925 nrejected); 00926 00927 00928 /* Load the input data */ 00929 cpl_msg_info(cpl_func, "Load the input data") ; 00930 cpl_msg_indent_more() ; 00931 if ((in = hawki_load_detector(selected_jitter, 00932 idet+1, CPL_TYPE_FLOAT)) == NULL) { 00933 cpl_msg_error(cpl_func, "Cannot load chip %d", idet+1) ; 00934 cpl_free(combined) ; 00935 cpl_bivector_delete(offsets) ; 00936 cpl_msg_indent_less() ; 00937 cpl_msg_indent_less() ; 00938 return NULL ; 00939 } 00940 if (sky) { 00941 if ((in_sky = hawki_load_detector(sky, idet+1, CPL_TYPE_FLOAT)) == NULL) 00942 { 00943 cpl_msg_warning(cpl_func, "Cannot load sky for chip %d",idet+1); 00944 } 00945 } else in_sky = NULL ; 00946 cpl_msg_indent_less() ; 00947 00948 /* Read the calibrations */ 00949 cpl_msg_info(cpl_func, "Load the calibration data") ; 00950 if(hawki_sci_jitter_read_calib(flat, dark, bpm, 00951 &flat_ima, &dark_ima, &bpm_ima, 00952 idet) != 0) 00953 { 00954 cpl_msg_error(cpl_func, "Cannot read some of the calibrations"); 00955 cpl_imagelist_delete(in); 00956 cpl_free(combined); 00957 if (in_sky) cpl_imagelist_delete(in_sky); 00958 cpl_bivector_delete(offsets); 00959 cpl_msg_indent_less(); 00960 cpl_msg_indent_less(); 00961 return NULL ; 00962 } 00963 00964 /* Apply the calibrations */ 00965 if (flat || dark || bpm ) 00966 { 00967 cpl_msg_info(cpl_func, "Apply the calibrations") ; 00968 cpl_msg_indent_more() ; 00969 /* Basic calibration of the OBJECTS */ 00970 if (hawki_flat_dark_bpm_detector_calib 00971 (in, flat_ima, dark_ima, bpm_ima) == -1) 00972 { 00973 cpl_msg_error(cpl_func, "Cannot calibrate the objects") ; 00974 cpl_imagelist_delete(in) ; 00975 cpl_free(combined) ; 00976 if (in_sky) cpl_imagelist_delete(in_sky) ; 00977 cpl_bivector_delete(offsets) ; 00978 cpl_image_delete(flat_ima); 00979 cpl_image_delete(dark_ima); 00980 cpl_image_delete(bpm_ima); 00981 cpl_msg_indent_less() ; 00982 cpl_msg_indent_less() ; 00983 return NULL ; 00984 } 00985 /* Basic calibration of the SKY */ 00986 if (in_sky) { 00987 if (hawki_flat_dark_bpm_detector_calib 00988 (in_sky, flat_ima, dark_ima, bpm_ima) == -1) 00989 { 00990 cpl_msg_warning(cpl_func, "Cannot calibrate the sky") ; 00991 cpl_imagelist_delete(in_sky) ; 00992 in_sky = NULL ; 00993 } 00994 } 00995 cpl_msg_indent_less() ; 00996 } 00997 cpl_image_delete(flat_ima); 00998 cpl_image_delete(dark_ima); 00999 cpl_image_delete(bpm_ima); 01000 01001 /* Apply the sky correction */ 01002 cpl_msg_info(cpl_func, "Sky estimation and correction") ; 01003 cpl_msg_indent_more() ; 01004 if (hawki_sci_jitter_sky(in, in_sky, bkg_stats, idet) == -1) 01005 { 01006 cpl_msg_error(cpl_func, "Cannot estimate the sky") ; 01007 cpl_imagelist_delete(in) ; 01008 if (in_sky) cpl_imagelist_delete(in_sky) ; 01009 cpl_free(combined) ; 01010 cpl_bivector_delete(offsets) ; 01011 cpl_msg_indent_less() ; 01012 cpl_msg_indent_less() ; 01013 return NULL ; 01014 } 01015 if (in_sky) cpl_imagelist_delete(in_sky) ; 01016 cpl_msg_indent_less() ; 01017 01018 /* Apply the shift and add */ 01019 cpl_msg_info(cpl_func, "Shift and stacking") ; 01020 cpl_msg_indent_more() ; 01021 comb_chip = hawki_sci_jitter_saa(&in, selected_offsets, 01022 &(hawki_sci_jitter_output.combined_pos_x[idet]), 01023 &(hawki_sci_jitter_output.combined_pos_y[idet])) ; 01024 hawki_sci_jitter_output.combined_cumoffset_x[idet] = 01025 hawki_sci_jitter_output.combined_pos_x[idet] - off_0_x; 01026 hawki_sci_jitter_output.combined_cumoffset_y[idet] = 01027 hawki_sci_jitter_output.combined_pos_y[idet] - off_0_y; 01028 if (comb_chip == NULL) { 01029 cpl_msg_error(cpl_func, "Cannot apply the shift and add") ; 01030 cpl_imagelist_delete(in) ; 01031 cpl_free(combined) ; 01032 cpl_bivector_delete(offsets) ; 01033 cpl_msg_indent_less() ; 01034 cpl_msg_indent_less() ; 01035 return NULL ; 01036 } 01037 cpl_imagelist_delete(in) ; 01038 cpl_msg_indent_less() ; 01039 01040 /* Put the results in the image list */ 01041 combined[idet] = comb_chip[0] ; 01042 cpl_image_delete(comb_chip[1]) ; 01043 cpl_free(comb_chip) ; 01044 cpl_msg_indent_less() ; 01045 01046 /* Free */ 01047 cpl_frameset_delete(selected_jitter); 01048 cpl_bivector_delete(selected_offsets); 01049 } 01050 cpl_bivector_delete(offsets) ; 01051 01052 return combined ; 01053 } 01054 01055 /*----------------------------------------------------------------------------*/ 01062 /*----------------------------------------------------------------------------*/ 01063 static int hawki_sci_jitter_sky 01064 (cpl_imagelist * objs, 01065 cpl_imagelist * skys, 01066 cpl_table ** bkg_stats, 01067 int idet) 01068 { 01069 cpl_image * sky ; 01070 int nframes; 01071 double median ; 01072 cpl_image * cur_ima ; 01073 int i ; 01074 01075 /* Initialise */ 01076 nframes = cpl_imagelist_get_size(objs) ; 01077 01078 /* Compute the sky frame */ 01079 if (skys != NULL) { 01080 cpl_msg_info(cpl_func, "Median of sky images") ; 01081 /* Use sky images */ 01082 if ((sky = cpl_imagelist_collapse_median_create(skys)) == NULL) { 01083 cpl_msg_error(cpl_func, "Cannot compute the median of sky images") ; 01084 return -1; 01085 } 01086 01087 /* Statistics on the background */ 01088 if(bkg_stats != NULL) 01089 { 01090 cpl_table_set_size(bkg_stats[idet], 1); 01091 hawki_image_stats_fill_from_image 01092 (bkg_stats, sky, 01093 1, 01094 1, 01095 cpl_image_get_size_x(sky), 01096 cpl_image_get_size_y(sky), 01097 idet, 0); 01098 } 01099 01100 /* Correct the objects images */ 01101 if (cpl_imagelist_subtract_image(objs, sky) != CPL_ERROR_NONE) { 01102 cpl_msg_error(cpl_func, "Cannot corr. the obj images from the sky"); 01103 cpl_image_delete(sky) ; 01104 return -1; 01105 } 01106 cpl_image_delete(sky) ; 01107 /* Normalise the object planes */ 01108 for (i=0 ; i<nframes ; i++) { 01109 cur_ima = cpl_imagelist_get(objs, i) ; 01110 median = cpl_image_get_median(cur_ima) ; 01111 cpl_image_subtract_scalar(cur_ima, median) ; 01112 } 01113 } else if (hawki_sci_jitter_config.sky_minnb > nframes) { 01114 cpl_msg_info(cpl_func, "Median of object images") ; 01115 /* Use objs images */ 01116 if ((sky = cpl_imagelist_collapse_median_create(objs)) == NULL) { 01117 cpl_msg_error(cpl_func, "Cannot compute the median of obj images") ; 01118 return -1; 01119 } 01120 01121 /* Statistics on the background */ 01122 if(bkg_stats != NULL) 01123 { 01124 cpl_table_set_size(bkg_stats[idet], 1); 01125 hawki_image_stats_fill_from_image 01126 (bkg_stats, sky, 01127 1, 01128 1, 01129 cpl_image_get_size_x(sky), 01130 cpl_image_get_size_y(sky), 01131 idet, 0); 01132 } 01133 01134 /* Correct the objects images */ 01135 if (cpl_imagelist_subtract_image(objs, sky) != CPL_ERROR_NONE) { 01136 cpl_msg_error(cpl_func, "Cannot corr. the obj images from the sky"); 01137 cpl_image_delete(sky) ; 01138 return -1; 01139 } 01140 /* Normalise the object planes */ 01141 for (i=0 ; i<nframes ; i++) { 01142 cur_ima = cpl_imagelist_get(objs, i) ; 01143 median = cpl_image_get_median(cur_ima) ; 01144 cpl_image_subtract_scalar(cur_ima, median) ; 01145 } 01146 /* Delete sky image */ 01147 cpl_image_delete(sky) ; 01148 } else { 01149 cpl_msg_info(cpl_func, "Computing running median on jitter images") ; 01150 /* Use objects images */ 01151 if (hawki_sci_jitter_sky_running(objs, bkg_stats, idet) == -1) 01152 { 01153 cpl_msg_error(cpl_func, 01154 "Cannot apply the running median"); 01155 return -1; 01156 } 01157 } 01158 return 0; 01159 } 01160 01161 /*----------------------------------------------------------------------------*/ 01180 /*----------------------------------------------------------------------------*/ 01181 static int hawki_sci_jitter_sky_running 01182 (cpl_imagelist * in, 01183 cpl_table ** bkg_stats, 01184 int idet) 01185 { 01186 int rejmin, rejmax, halfw; 01187 cpl_imagelist * result_buffer; 01188 int ni, nx, ny; 01189 cpl_vector * medians; 01190 cpl_image * cur_ima; 01191 cpl_image * tmp_ima; 01192 double one_med; 01193 int i, k; 01194 int first_buffered = 0; 01195 int next_not_to_be_used; 01196 01197 /* Test entries */ 01198 if (in==NULL) return -1; 01199 01200 /* Initialise */ 01201 rejmin = hawki_sci_jitter_config.sky_rejmin ; 01202 rejmax = hawki_sci_jitter_config.sky_rejmax ; 01203 halfw = hawki_sci_jitter_config.sky_halfw ; 01204 ni = cpl_imagelist_get_size(in) ; 01205 cur_ima = cpl_imagelist_get(in, 0) ; 01206 nx = cpl_image_get_size_x(cur_ima) ; 01207 ny = cpl_image_get_size_y(cur_ima) ; 01208 01209 /* Tests on validity of rejection parameters */ 01210 if (((rejmin+rejmax)>=halfw) || (halfw<1) || (rejmin<0) || (rejmax<0)) { 01211 cpl_msg_error(cpl_func, "cannot compute running median with " 01212 "rejection parameters %d (%d-%d)", 01213 halfw, rejmin, rejmax); 01214 return -1; 01215 } 01216 /* Pre-compute median value in each plane */ 01217 medians = cpl_vector_new(ni) ; 01218 for (i=0 ; i<ni ; i++) { 01219 cur_ima = cpl_imagelist_get(in, i) ; 01220 cpl_vector_set(medians, i, cpl_image_get_median(cur_ima)) ; 01221 } 01222 /* Allocate output cube */ 01223 result_buffer = cpl_imagelist_new() ; 01224 01225 /* Allocate output bg stats */ 01226 cpl_table_set_size(bkg_stats[idet], ni); 01227 01228 /* Main loop over input planes */ 01229 for (k=0 ; k<ni ; k++) 01230 { 01231 cpl_image * bkg; 01232 01233 /* Create the background image, to later compute stats */ 01234 bkg = cpl_image_new(nx, ny, CPL_TYPE_FLOAT); 01235 01236 hawki_bkg_from_running_mean 01237 (in, medians, k, halfw, rejmin, rejmax, bkg); 01238 01239 /* Subtract the background from the current image */ 01240 tmp_ima = cpl_image_subtract_create(cpl_imagelist_get(in, k), bkg); 01241 01242 /* Statistics on the background */ 01243 if(bkg_stats != NULL) 01244 { 01245 hawki_image_stats_fill_from_image 01246 (bkg_stats, bkg, 01247 1, 1, nx, ny, 01248 idet, k); 01249 } 01250 cpl_image_delete(bkg); 01251 01252 /* Place the new image in a result buffer */ 01253 cpl_imagelist_set(result_buffer, tmp_ima, 01254 cpl_imagelist_get_size(result_buffer)); 01255 01256 /* Empty the buffer as much as possible */ 01257 next_not_to_be_used = k - halfw; 01258 while(next_not_to_be_used >= first_buffered) 01259 { 01260 cpl_imagelist_set(in, cpl_imagelist_unset(result_buffer, 0), 01261 first_buffered); 01262 first_buffered++; 01263 } 01264 } 01265 /* Empty the buffer finally */ 01266 next_not_to_be_used = ni - 1; 01267 while(next_not_to_be_used >= first_buffered) 01268 { 01269 cpl_imagelist_set(in, cpl_imagelist_unset(result_buffer, 0), 01270 first_buffered); 01271 first_buffered++; 01272 } 01273 cpl_imagelist_delete(result_buffer); 01274 cpl_vector_delete(medians); 01275 01276 /* Subtract median from each frame */ 01277 for (i=0 ; i<ni ; i++) { 01278 cur_ima = cpl_imagelist_get(in, i); 01279 one_med = cpl_image_get_median(cur_ima) ; 01280 cpl_image_subtract_scalar(cur_ima, one_med) ; 01281 } 01282 return 0; 01283 } 01284 01285 /*----------------------------------------------------------------------------*/ 01294 /*----------------------------------------------------------------------------*/ 01295 static cpl_image ** hawki_sci_jitter_saa( 01296 cpl_imagelist ** in, 01297 cpl_bivector * offsets, 01298 double * pos_x, 01299 double * pos_y) 01300 { 01301 cpl_bivector * offs_est; 01302 cpl_bivector * offs_used; 01303 cpl_bivector * objs ; 01304 cpl_image ** combined ; 01305 int nfiles, ngood, nima, nx, ny ; 01306 int i; 01307 01308 /* Check entries */ 01309 if (pos_x == NULL || pos_y == NULL) return NULL ; 01310 if (offsets == NULL) return NULL ; 01311 01312 /* Get the number of images */ 01313 nfiles = cpl_imagelist_get_size(*in) ; 01314 if (cpl_bivector_get_size(offsets) != nfiles) { 01315 cpl_msg_error(cpl_func, "Invalid input objects sizes") ; 01316 return NULL ; 01317 } 01318 01319 /* Get the offsets estimation of each input file pair */ 01320 cpl_msg_info(cpl_func, "Get the offsets estimation") ; 01321 offs_est = NULL ; 01322 if (hawki_sci_jitter_config.offsets && 01323 hawki_sci_jitter_config.offsets[0] != (char)0) { 01324 /* A file has been provided on the command line */ 01325 offs_est = cpl_bivector_read((char*)hawki_sci_jitter_config.offsets); 01326 if ((offs_est==NULL)||(cpl_bivector_get_size(offs_est)!=nfiles)) { 01327 cpl_msg_error(cpl_func, "Cannot get offsets from %s", 01328 hawki_sci_jitter_config.offsets) ; 01329 return NULL ; 01330 } 01331 } else { 01332 /* Use the offsets from the header */ 01333 offs_est = cpl_bivector_duplicate(offsets) ; 01334 cpl_vector_multiply_scalar(cpl_bivector_get_x(offs_est), -1.0) ; 01335 cpl_vector_multiply_scalar(cpl_bivector_get_y(offs_est), -1.0) ; 01336 } 01337 01338 /* Read the provided objects file if provided */ 01339 objs = NULL ; 01340 if (hawki_sci_jitter_config.refine && 01341 hawki_sci_jitter_config.objects && 01342 hawki_sci_jitter_config.objects[0] != (char)0) { 01343 cpl_msg_info(cpl_func, "Get the user provided correlation objects") ; 01344 /* A file has been provided on the command line */ 01345 objs = cpl_bivector_read((char*)hawki_sci_jitter_config.objects) ; 01346 if (objs==NULL) { 01347 cpl_msg_error(cpl_func, "Cannot get objects from %s", 01348 hawki_sci_jitter_config.objects) ; 01349 cpl_bivector_delete(offs_est) ; 01350 return NULL ; 01351 } 01352 } 01353 01354 /* Get a correlation point from the difference of the first images */ 01355 if (hawki_sci_jitter_config.refine && objs == NULL) { 01356 cpl_apertures * aperts; 01357 cpl_image * detect_image; 01358 cpl_vector * thresh_vect; 01359 double * objs_x ; 01360 double * objs_y ; 01361 cpl_msg_info(cpl_func, "Get a cross-correlation point") ; 01362 thresh_vect = cpl_vector_new(4) ; 01363 cpl_vector_set(thresh_vect, 0, 5.0) ; 01364 cpl_vector_set(thresh_vect, 1, 2.0) ; 01365 cpl_vector_set(thresh_vect, 2, 1.0) ; 01366 cpl_vector_set(thresh_vect, 3, 0.5) ; 01367 detect_image = cpl_imagelist_get(*in, 0); 01368 if ((aperts = cpl_apertures_extract_window(detect_image, thresh_vect, 01369 400, 400, 1600, 1600, NULL)) == NULL) { 01370 cpl_msg_error(cpl_func, "Cannot find any cross-correlation point") ; 01371 cpl_bivector_delete(offs_est) ; 01372 cpl_vector_delete(thresh_vect) ; 01373 return NULL ; 01374 } 01375 cpl_vector_delete(thresh_vect) ; 01376 cpl_apertures_sort_by_npix(aperts) ; 01377 objs = cpl_bivector_new(1) ; 01378 objs_x = cpl_bivector_get_x_data(objs) ; 01379 objs_y = cpl_bivector_get_y_data(objs) ; 01380 objs_x[0] = cpl_apertures_get_pos_x(aperts, 1) ; 01381 objs_y[0] = cpl_apertures_get_pos_y(aperts, 1) ; 01382 cpl_apertures_delete(aperts) ; 01383 if (objs == NULL) { 01384 cpl_msg_error(cpl_func, "Cannot find any cross-correlation point") ; 01385 cpl_bivector_delete(offs_est) ; 01386 return NULL ; 01387 } 01388 cpl_msg_info(cpl_func, 01389 "Correlation point: %g %g\n", objs_x[0], objs_y[0]); 01390 } 01391 01392 /* Refine the offsets */ 01393 if (hawki_sci_jitter_config.refine) { 01394 cpl_bivector * offs_refined; 01395 double * offs_refined_x; 01396 double * offs_refined_y; 01397 double * offs_est_x; 01398 double * offs_est_y; 01399 cpl_vector * correl ; 01400 double * correl_data ; 01401 cpl_msg_info(cpl_func, "Refine the offsets"); 01402 cpl_msg_indent_more() ; 01403 nima = cpl_imagelist_get_size(*in) ; 01404 correl = cpl_vector_new(nima) ; 01405 if ((offs_refined = cpl_geom_img_offset_fine(*in, offs_est, objs, 01406 hawki_sci_jitter_config.sx, 01407 hawki_sci_jitter_config.sy, 01408 hawki_sci_jitter_config.mx, 01409 hawki_sci_jitter_config.my, 01410 correl)) == NULL) { 01411 cpl_msg_error(cpl_func, "Cannot refine the offsets"); 01412 cpl_bivector_delete(offs_est) ; 01413 if (objs != NULL) cpl_bivector_delete(objs) ; 01414 cpl_vector_delete(correl) ; 01415 return NULL ; 01416 } 01417 if (objs != NULL) cpl_bivector_delete(objs) ; 01418 01419 /* Display the results */ 01420 offs_est_x = cpl_bivector_get_x_data(offs_est); 01421 offs_est_y = cpl_bivector_get_y_data(offs_est); 01422 offs_refined_x = cpl_bivector_get_x_data(offs_refined); 01423 offs_refined_y = cpl_bivector_get_y_data(offs_refined) ; 01424 correl_data = cpl_vector_get_data(correl) ; 01425 cpl_msg_info(cpl_func, "Refined offsets [correlation factor]") ; 01426 ngood = 0 ; 01427 for (i=0 ; i<nima ; i++) { 01428 cpl_msg_info(cpl_func, "#%02d: %8.2f %8.2f [%12.2f]", 01429 i+1, offs_refined_x[i], offs_refined_y[i], correl_data[i]); 01430 if (correl_data[i] > -0.5) ngood++ ; 01431 } 01432 if (ngood == 0) { 01433 cpl_msg_error(cpl_func, "No frame correctly correlated") ; 01434 cpl_bivector_delete(offs_est); 01435 cpl_bivector_delete(offs_refined); 01436 cpl_vector_delete(correl); 01437 return NULL ; 01438 } 01439 cpl_msg_indent_less(); 01440 01441 /* Replace bad correlated images with the nominal offsets */ 01442 cpl_msg_info(cpl_func, "Using nominal offsets for badly " 01443 "correlated images (%d out of %d)", nima-ngood, nima); 01444 for (i=0 ; i<nima ; i++) { 01445 if (correl_data[i] < -0.5) { 01446 offs_refined_x[i] = offs_est_x[i]; 01447 offs_refined_y[i] = offs_est_y[i]; 01448 } 01449 } 01450 offs_used = cpl_bivector_duplicate(offs_refined); 01451 cpl_bivector_delete(offs_est); 01452 cpl_bivector_delete(offs_refined); 01453 cpl_vector_delete(correl); 01454 } 01455 else 01456 { 01457 offs_used = cpl_bivector_duplicate(offs_est); 01458 cpl_bivector_delete(offs_est); 01459 } 01460 01461 /* Discard the pixels on the sides */ 01462 if (hawki_sci_jitter_config.borders > 0) { 01463 cpl_imagelist * in_ext ; 01464 cpl_image * tmp1 ; 01465 cpl_image * tmp2 ; 01466 nx = cpl_image_get_size_x(cpl_imagelist_get(*in, 0)) ; 01467 ny = cpl_image_get_size_y(cpl_imagelist_get(*in, 0)) ; 01468 in_ext = cpl_imagelist_new() ; 01469 while(cpl_imagelist_get_size(*in) > 0) 01470 { 01471 tmp1 = cpl_imagelist_unset(*in, 0); 01472 tmp2 = cpl_image_extract(tmp1, 01473 hawki_sci_jitter_config.borders+1, 01474 hawki_sci_jitter_config.borders+1, 01475 nx-hawki_sci_jitter_config.borders, 01476 ny-hawki_sci_jitter_config.borders) ; 01477 cpl_image_delete(tmp1); 01478 cpl_imagelist_set(in_ext, tmp2, cpl_imagelist_get_size(in_ext)) ; 01479 } 01480 cpl_imagelist_delete(*in) ; 01481 *in = in_ext ; 01482 } 01483 01484 /* Apply the shift & add */ 01485 cpl_msg_info(cpl_func, "Recombine the images set") ; 01486 cpl_msg_indent_more() ; 01487 if ((combined=cpl_geom_img_offset_saa(*in, offs_used, 01488 CPL_KERNEL_DEFAULT, 01489 hawki_sci_jitter_config.rej_low, 01490 hawki_sci_jitter_config.rej_high, 01491 hawki_sci_jitter_config.comb_meth, 01492 pos_x, pos_y)) == NULL) { 01493 cpl_msg_error(cpl_func, "Cannot apply the shift and add") ; 01494 cpl_bivector_delete(offs_used) ; 01495 cpl_msg_indent_less() ; 01496 return NULL ; 01497 } 01498 cpl_msg_indent_less() ; 01499 *pos_x -= hawki_sci_jitter_config.borders ; 01500 *pos_y -= hawki_sci_jitter_config.borders ; 01501 01502 /* Free and return */ 01503 cpl_bivector_delete(offs_used) ; 01504 return combined ; 01505 } 01506 01507 /*----------------------------------------------------------------------------*/ 01514 /*----------------------------------------------------------------------------*/ 01515 static int hawki_sci_jitter_qc 01516 (cpl_frameset * science_frames, 01517 cpl_image ** combined_images, 01518 cpl_table ** obj_charac) 01519 { 01520 cpl_vector * thresh_vec ; 01521 cpl_apertures * aperts ; 01522 int nb_objs ; 01523 double angle ; 01524 double * fwhms_x ; 01525 double * fwhms_y ; 01526 cpl_bivector * iqe ; 01527 int nb_good ; 01528 cpl_vector * fwhms_good ; 01529 double * fwhms_good_data ; 01530 double f_min, f_max, fr, fx, fy ; 01531 int chip; 01532 int iobj; 01533 int j; 01534 01535 /* Initialise */ 01536 double seeing_min_arcsec = 0.1 ; 01537 double seeing_max_arcsec = 5.0 ; 01538 double seeing_fwhm_var = 0.2 ; 01539 01540 /* Check entries */ 01541 if (combined_images == NULL) return -1 ; 01542 if (obj_charac == NULL) return -1 ; 01543 01544 /* Create the vector for the detection thresholds */ 01545 thresh_vec = cpl_vector_new(11) ; 01546 cpl_vector_set(thresh_vec, 0, 100.0) ; 01547 cpl_vector_set(thresh_vec, 0, 90.0) ; 01548 cpl_vector_set(thresh_vec, 0, 80.0) ; 01549 cpl_vector_set(thresh_vec, 0, 70.0) ; 01550 cpl_vector_set(thresh_vec, 0, 60.0) ; 01551 cpl_vector_set(thresh_vec, 0, 50.0) ; 01552 cpl_vector_set(thresh_vec, 1, 40.0) ; 01553 cpl_vector_set(thresh_vec, 1, 30.0) ; 01554 cpl_vector_set(thresh_vec, 1, 20.0) ; 01555 cpl_vector_set(thresh_vec, 1, 10.0) ; 01556 cpl_vector_set(thresh_vec, 2, 5.0) ; 01557 01558 /* Get the mean airmass */ 01559 hawki_sci_jitter_output.mean_airmass = 01560 hawki_get_mean_airmass(science_frames);; 01561 01562 /* Loop on the HAWK-I detectors */ 01563 for (chip=0 ; chip<HAWKI_NB_DETECTORS ; chip++) 01564 { 01565 /* Check entries */ 01566 if (combined_images[chip] == NULL) return -1 ; 01567 if (obj_charac[chip] == NULL) return -1 ; 01568 01569 /* Detect apertures */ 01570 if ((aperts = cpl_apertures_extract 01571 (combined_images[chip], thresh_vec, NULL)) == NULL) { 01572 cpl_msg_warning(cpl_func, "Cannot detect any aperture on chip %d", 01573 chip+1) ; 01574 continue; 01575 } 01576 01577 /* Number of detected objects */ 01578 nb_objs = cpl_apertures_get_size(aperts); 01579 cpl_msg_info(cpl_func, "%d objects detected on chip %d",nb_objs,chip+1); 01580 hawki_sci_jitter_output.nbobjs[chip] = nb_objs ; 01581 fwhms_x = cpl_malloc(nb_objs * sizeof(double)) ; 01582 fwhms_y = cpl_malloc(nb_objs * sizeof(double)) ; 01583 01584 /* Initialize the output table */ 01585 cpl_table_set_size(obj_charac[chip], nb_objs); 01586 cpl_table_new_column 01587 (obj_charac[chip], HAWKI_COL_OBJ_POSX, CPL_TYPE_DOUBLE); 01588 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_POSX,"pix"); 01589 cpl_table_new_column 01590 (obj_charac[chip], HAWKI_COL_OBJ_POSY, CPL_TYPE_DOUBLE); 01591 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_POSY,"pix"); 01592 cpl_table_new_column 01593 (obj_charac[chip], HAWKI_COL_OBJ_ANGLE, CPL_TYPE_DOUBLE); 01594 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_ANGLE,"grad"); 01595 cpl_table_new_column 01596 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MAJAX, CPL_TYPE_DOUBLE); 01597 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_FWHM_MAJAX,"pix"); 01598 cpl_table_new_column 01599 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MINAX, CPL_TYPE_DOUBLE); 01600 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_FWHM_MINAX,"pix"); 01601 cpl_table_new_column 01602 (obj_charac[chip], HAWKI_COL_OBJ_ELLIP, CPL_TYPE_DOUBLE); 01603 cpl_table_new_column 01604 (obj_charac[chip], HAWKI_COL_OBJ_FLUX, CPL_TYPE_DOUBLE); 01605 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_FLUX,"ADU"); 01606 for (iobj=0 ; iobj<nb_objs ; iobj++) 01607 { 01608 /* Fill with the already known information */ 01609 cpl_table_set_double(obj_charac[chip], HAWKI_COL_OBJ_POSX, iobj, 01610 cpl_apertures_get_centroid_x(aperts, iobj+1)); 01611 cpl_table_set_double(obj_charac[chip], HAWKI_COL_OBJ_POSY, iobj, 01612 cpl_apertures_get_centroid_y(aperts, iobj+1)); 01613 cpl_table_set_double(obj_charac[chip], HAWKI_COL_OBJ_FLUX, iobj, 01614 cpl_apertures_get_flux(aperts, iobj+1)) ; 01615 /* Compute the FWHM informations */ 01616 if ((iqe = cpl_image_iqe(combined_images[chip], 01617 (int)cpl_apertures_get_centroid_x(aperts, iobj+1) - 10, 01618 (int)cpl_apertures_get_centroid_y(aperts, iobj+1) - 10, 01619 (int)cpl_apertures_get_centroid_x(aperts, iobj+1) + 10, 01620 (int)cpl_apertures_get_centroid_y(aperts, iobj+1) + 10))==NULL) 01621 { 01622 cpl_error_reset() ; 01623 cpl_msg_debug(cpl_func, "Cannot get FWHM for obj at pos %g %g", 01624 cpl_apertures_get_centroid_x(aperts, iobj+1), 01625 cpl_apertures_get_centroid_y(aperts, iobj+1)) ; 01626 fwhms_x[iobj] = -1.0 ; 01627 fwhms_y[iobj] = -1.0 ; 01628 angle = 0.0 ; 01629 } 01630 else 01631 { 01632 fwhms_x[iobj] = cpl_vector_get(cpl_bivector_get_x(iqe), 2) ; 01633 fwhms_y[iobj] = cpl_vector_get(cpl_bivector_get_x(iqe), 3) ; 01634 angle = cpl_vector_get(cpl_bivector_get_x(iqe), 4) ; 01635 cpl_bivector_delete(iqe) ; 01636 cpl_msg_debug(cpl_func, 01637 "FWHM for obj at pos %g %g: %g x %g (%g)", 01638 cpl_apertures_get_centroid_x(aperts, iobj+1), 01639 cpl_apertures_get_centroid_y(aperts, iobj+1), 01640 fwhms_x[iobj], fwhms_y[iobj], angle) ; 01641 } 01642 cpl_table_set_double 01643 (obj_charac[chip], HAWKI_COL_OBJ_ANGLE, iobj, angle) ; 01644 cpl_table_set_double 01645 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MAJAX, iobj, 01646 fwhms_x[iobj]); 01647 cpl_table_set_double 01648 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MINAX, iobj, 01649 fwhms_y[iobj]); 01650 cpl_table_set_double 01651 (obj_charac[chip], HAWKI_COL_OBJ_ELLIP, iobj, 01652 1 - fwhms_y[iobj] / fwhms_x[iobj]); 01653 } 01654 cpl_apertures_delete(aperts) ; 01655 01656 /* Get the number of good values */ 01657 nb_good = 0 ; 01658 for (iobj=0 ; iobj<nb_objs ; iobj++) 01659 { 01660 if ((fwhms_x[iobj] > 0.0) && (fwhms_y[iobj] > 0.0)) nb_good++ ; 01661 } 01662 if (nb_good == 0) 01663 { 01664 cpl_msg_warning(cpl_func, "No objects to compute FWHM on chip %d", 01665 chip+1); 01666 cpl_free(fwhms_x) ; 01667 cpl_free(fwhms_y) ; 01668 continue; 01669 } 01670 01671 /* Get the good values */ 01672 fwhms_good = cpl_vector_new(nb_good) ; 01673 fwhms_good_data = cpl_vector_get_data(fwhms_good) ; 01674 j=0 ; 01675 for (iobj=0 ; iobj<nb_objs ; iobj++) 01676 { 01677 if ((fwhms_x[iobj] > 0.0) && (fwhms_y[iobj] > 0.0)) 01678 { 01679 fwhms_good_data[j] = (fwhms_x[iobj]+fwhms_y[iobj])/2.0 ; 01680 j++ ; 01681 } 01682 } 01683 01684 /* Compute the fwhm */ 01685 if (nb_good < 3) 01686 { 01687 /* Too few values to compute the median */ 01688 hawki_sci_jitter_output.fwhm_pix[chip] = fwhms_good_data[0] ; 01689 } 01690 else 01691 { 01692 /* Compute the median */ 01693 hawki_sci_jitter_output.fwhm_pix[chip] = 01694 cpl_vector_get_median_const(fwhms_good) ; 01695 } 01696 hawki_sci_jitter_output.fwhm_arcsec[chip] = 01697 hawki_sci_jitter_output.fwhm_pix[chip] * 01698 hawki_sci_jitter_output.pixscale ; 01699 01700 /* Compute the mode of the FWHMs */ 01701 if (nb_good > 5) 01702 { 01703 hawki_sci_jitter_output.fwhm_mode[chip] = 01704 hawki_vector_get_mode(fwhms_good); 01705 hawki_sci_jitter_output.fwhm_mode[chip] *= 01706 hawki_sci_jitter_output.pixscale ; 01707 } 01708 cpl_vector_delete(fwhms_good) ; 01709 01710 /* IQ is the median of the (fwhm_x+fwhm_y/2) of the good stars */ 01711 /* Compute f_min and f_max */ 01712 f_min = seeing_min_arcsec / hawki_sci_jitter_output.pixscale ; 01713 f_max = seeing_max_arcsec / hawki_sci_jitter_output.pixscale ; 01714 01715 /* Get the number of good values */ 01716 nb_good = 0 ; 01717 for (iobj=0 ; iobj<nb_objs ; iobj++) 01718 { 01719 fx = fwhms_x[iobj] ; 01720 fy = fwhms_y[iobj] ; 01721 fr = 2.0 * fabs(fx-fy) / (fx+fy) ; 01722 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) && 01723 (fr < seeing_fwhm_var)) nb_good++ ; 01724 } 01725 if (nb_good == 0) 01726 { 01727 cpl_msg_warning(cpl_func, "No objects to compute IQ on chip %d", 01728 chip+1); 01729 cpl_free(fwhms_x) ; 01730 cpl_free(fwhms_y) ; 01731 continue; 01732 } 01733 01734 /* Get the good values */ 01735 fwhms_good = cpl_vector_new(nb_good) ; 01736 fwhms_good_data = cpl_vector_get_data(fwhms_good) ; 01737 j=0 ; 01738 for (iobj=0 ; iobj<nb_objs ; iobj++) 01739 { 01740 fx = fwhms_x[iobj] ; 01741 fy = fwhms_y[iobj] ; 01742 fr = 2.0 * fabs(fx-fy) / (fx+fy) ; 01743 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) && 01744 (fr < seeing_fwhm_var)) 01745 { 01746 fwhms_good_data[j] = (fx + fy)/2.0 ; 01747 j++ ; 01748 } 01749 } 01750 cpl_free(fwhms_x) ; 01751 cpl_free(fwhms_y) ; 01752 01753 /* Compute the fwhm */ 01754 if (nb_good < 3) 01755 { 01756 /* Too few values to compute the median */ 01757 hawki_sci_jitter_output.iq[chip] = fwhms_good_data[0] ; 01758 } 01759 else 01760 { 01761 /* Compute the median */ 01762 hawki_sci_jitter_output.iq[chip] = 01763 cpl_vector_get_median_const(fwhms_good) ; 01764 } 01765 cpl_vector_delete(fwhms_good) ; 01766 hawki_sci_jitter_output.iq[chip] *= hawki_sci_jitter_output.pixscale ; 01767 } 01768 01769 /* Cleanup */ 01770 cpl_vector_delete(thresh_vec) ; 01771 01772 return 0; 01773 } 01774 01775 /*----------------------------------------------------------------------------*/ 01787 /*----------------------------------------------------------------------------*/ 01788 static int hawki_sci_jitter_read_calib 01789 (const char * flat, 01790 const char * dark, 01791 const char * bpm, 01792 cpl_image ** flat_image, 01793 cpl_image ** dark_image, 01794 cpl_image ** bpm_image, 01795 int idet) 01796 { 01797 const char * reffile; 01798 int ext_nb; 01799 01800 if(flat == NULL && dark == NULL && bpm == NULL) 01801 return 0; 01802 if(*flat_image != NULL || *dark_image != NULL || *bpm_image != NULL) 01803 return 0; 01804 01805 /* Get the extension number for this detector */ 01806 if(flat != NULL) 01807 reffile = flat; 01808 else if(dark != NULL) 01809 reffile = dark; 01810 else 01811 reffile = bpm; 01812 01813 /* Guess which is the extension to read */ 01814 if ((ext_nb = hawki_get_ext_from_detector(reffile, idet + 1)) == -1) { 01815 cpl_msg_error(cpl_func, "Cannot get the extension with detector %d", 01816 idet + 1); 01817 return -1; 01818 } 01819 01820 /* Load the dark image */ 01821 if(dark != NULL) 01822 *dark_image = cpl_image_load(dark, CPL_TYPE_FLOAT, 0, ext_nb); 01823 /* Load the flat image */ 01824 if(flat != NULL) 01825 *flat_image = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, ext_nb); 01826 /* Load the bpm image */ 01827 if(bpm != NULL) 01828 *bpm_image = cpl_image_load(bpm, CPL_TYPE_FLOAT, 0, ext_nb); 01829 01830 /* Multiply the dark image by the science exposure time */ 01831 if(dark != NULL) 01832 cpl_image_multiply_scalar(*dark_image, hawki_sci_jitter_output.dit); 01833 01834 /* Return */ 01835 return 0; 01836 } 01837 01838 /*----------------------------------------------------------------------------*/ 01847 /*----------------------------------------------------------------------------*/ 01848 static int hawki_sci_jitter_save 01849 (cpl_image ** combined, 01850 cpl_image * stitched, 01851 cpl_table ** obj_charac, 01852 cpl_table ** raw_jitter_stats, 01853 cpl_table ** bkg_stats, 01854 const cpl_table * raw_obj_tel_info, 01855 cpl_frameset * science_frames, 01856 cpl_frameset * calib_frames, 01857 cpl_parameterlist * parlist, 01858 cpl_frameset * set) 01859 { 01860 cpl_propertylist * plist ; 01861 double pscale, dit, bg_mean, bg_stdev, bg_instmag ; 01862 cpl_propertylist ** qclists ; 01863 const cpl_frame * ref_frame ; 01864 cpl_frameset * used_frames; 01865 cpl_propertylist * wcslist ; 01866 cpl_propertylist * telstats; 01867 cpl_propertylist * inputlist ; 01868 double crpix1, crpix2 ; 01869 int ext_nb ; 01870 const char * recipe_name = "hawki_sci_jitter" ; 01871 int i; 01872 int ext_chip_1; 01873 cpl_errorstate error_prevstate = cpl_errorstate_get(); 01874 01875 /* Initialise */ 01876 pscale = hawki_sci_jitter_output.pixscale; 01877 dit = hawki_sci_jitter_output.dit; 01878 01879 /* Get reference frame */ 01880 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW); 01881 01882 /* Get the used frames */ 01883 used_frames = cpl_frameset_duplicate(science_frames); 01884 for(i = 0; i< cpl_frameset_get_size(calib_frames); ++i) 01885 cpl_frameset_insert(used_frames, 01886 cpl_frame_duplicate(cpl_frameset_get_frame(calib_frames, i))); 01887 01888 /* Create the telescope data statistics */ 01889 telstats = cpl_propertylist_new(); 01890 hawki_compute_prop_tel_qc_stats(raw_obj_tel_info, telstats); 01891 01892 /* Create the QC lists */ 01893 qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 01894 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 01895 01896 /* Get the extension number */ 01897 ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), i+1); 01898 01899 /* Handle WCS keys */ 01900 wcslist = cpl_propertylist_load_regexp( 01901 cpl_frame_get_filename(ref_frame), ext_nb, HAWKI_HEADER_WCS, 0); 01902 qclists[i] = cpl_propertylist_new() ; 01903 01904 /* Compute bg_instmag */ 01905 bg_mean = cpl_table_get_column_mean(bkg_stats[i], HAWKI_COL_STAT_MEAN); 01906 if (cpl_table_get_nrow(bkg_stats[i]) < 2) bg_stdev = 0 ; 01907 else bg_stdev = cpl_table_get_column_stdev 01908 (bkg_stats[i], HAWKI_COL_STAT_MEAN); 01909 if(bg_mean >= 0) 01910 bg_instmag = -2.5 * log10(bg_mean/(pscale*pscale*dit)); 01911 else 01912 bg_instmag = 0; 01913 01914 /* Fill the QC */ 01915 cpl_propertylist_append_double 01916 (qclists[i], "ESO QC BACKGD MEAN", bg_mean); 01917 cpl_propertylist_set_comment(qclists[i], "ESO QC BACKGD MEAN", 01918 "Mean of all the image mean backgrounds"); 01919 cpl_propertylist_append_double 01920 (qclists[i], "ESO QC BACKGD STDEV", bg_stdev); 01921 cpl_propertylist_set_comment(qclists[i], "ESO QC BACKGD STDEV", 01922 "The standard deviation of all the image mean backgrounds"); 01923 cpl_propertylist_append_double 01924 (qclists[i], "ESO QC BACKGD INSTMAG", bg_instmag) ; 01925 cpl_propertylist_set_comment(qclists[i], "ESO QC BACKGD INSTMAG", 01926 "Mean of all the image mean backgrounds in instrumental magnitudes"); 01927 cpl_propertylist_append_int 01928 (qclists[i], "ESO QC NBOBJS", hawki_sci_jitter_output.nbobjs[i]); 01929 cpl_propertylist_set_comment(qclists[i], "ESO QC NBOBJS", 01930 "Number of detected objects in the combined image"); 01931 cpl_propertylist_append_double 01932 (qclists[i], "ESO QC IQ", hawki_sci_jitter_output.iq[i]); 01933 cpl_propertylist_set_comment(qclists[i], "ESO QC IQ", 01934 "Estimated image quality [arcsec]"); 01935 cpl_propertylist_append_double 01936 (qclists[i], "ESO QC IQ DIFF AMBI", 01937 hawki_sci_jitter_output.iq[i] - cpl_propertylist_get_double 01938 (telstats, "ESO QC TEL AMBI FWHM MEAN")); 01939 cpl_propertylist_append_double 01940 (qclists[i], "ESO QC IQ DIFF TEL", 01941 hawki_sci_jitter_output.iq[i] - cpl_propertylist_get_double 01942 (telstats, "ESO QC TEL IA FWHM MEAN")); 01943 cpl_propertylist_append_double 01944 (qclists[i], "ESO QC FWHM PIX", 01945 hawki_sci_jitter_output.fwhm_pix[i]); 01946 cpl_propertylist_set_comment(qclists[i], "ESO QC FWHM PIX", 01947 "The median FWHM in the image [pixels]"); 01948 cpl_propertylist_append_double 01949 (qclists[i], "ESO QC FWHM ARCSEC", 01950 hawki_sci_jitter_output.fwhm_arcsec[i]); 01951 cpl_propertylist_set_comment(qclists[i], "ESO QC FWHM ARCSEC", 01952 "The median FWHM in the image [arcsec]"); 01953 cpl_propertylist_append_double 01954 (qclists[i], "ESO QC FWHM MODE", 01955 hawki_sci_jitter_output.fwhm_mode[i]); 01956 cpl_propertylist_set_comment(qclists[i], "ESO QC FWHM MODE", 01957 "The mode FWHM in the image [pixels]"); 01958 cpl_propertylist_append_double 01959 (qclists[i], "ESO QC COMBINED POSX", 01960 hawki_sci_jitter_output.combined_pos_x[i]); 01961 cpl_propertylist_set_comment(qclists[i], "ESO QC COMBINED POSX", 01962 "Position in X of the first image"); 01963 cpl_propertylist_append_double 01964 (qclists[i], "ESO QC COMBINED POSY", 01965 hawki_sci_jitter_output.combined_pos_y[i]); 01966 cpl_propertylist_set_comment(qclists[i], "ESO QC COMBINED POSY", 01967 "Position in Y of the first image"); 01968 cpl_propertylist_append_double 01969 (qclists[i], "ESO QC COMBINED CUMOFFSETX", 01970 hawki_sci_jitter_output.combined_cumoffset_x[i]); 01971 cpl_propertylist_append_double 01972 (qclists[i], "ESO QC COMBINED CUMOFFSETY", 01973 hawki_sci_jitter_output.combined_cumoffset_y[i]); 01974 cpl_propertylist_append_int 01975 (qclists[i], "ESO QC DATANCOM",hawki_sci_jitter_output.ncomb[i]); 01976 cpl_propertylist_set_comment(qclists[i], "ESO QC DATANCOM", 01977 "Number of files used for the reduction"); 01978 cpl_propertylist_append_double 01979 (qclists[i], "ESO QC AIRMASS MEAN", 01980 hawki_sci_jitter_output.mean_airmass); 01981 cpl_propertylist_set_comment(qclists[i], "ESO QC AIRMASS MEAN", 01982 "Average airmass"); 01983 01984 /* Update WCS and write them */ 01985 crpix1 = cpl_propertylist_get_double(wcslist, "CRPIX1"); 01986 crpix1 += hawki_sci_jitter_output.combined_pos_x[i]; 01987 cpl_propertylist_update_double(wcslist, "CRPIX1", crpix1) ; 01988 crpix2 = cpl_propertylist_get_double(wcslist, "CRPIX2"); 01989 crpix2 += hawki_sci_jitter_output.combined_pos_y[i] ; 01990 cpl_propertylist_update_double(wcslist, "CRPIX2", crpix2) ; 01991 cpl_propertylist_copy_property_regexp 01992 (qclists[i], wcslist, HAWKI_HEADER_WCS, 0) ; 01993 cpl_propertylist_delete(wcslist); 01994 01995 /* Propagate some keywords from input raw frame extensions */ 01996 inputlist = cpl_propertylist_load_regexp( 01997 cpl_frame_get_filename(ref_frame), ext_nb, 01998 HAWKI_HEADER_EXT_FORWARD, 0) ; 01999 cpl_propertylist_append(qclists[i], inputlist); 02000 cpl_propertylist_delete(inputlist) ; 02001 } 02002 02003 /* Statistics of the raw images in the QC */ 02004 hawki_image_stats_stats(raw_jitter_stats, qclists); 02005 02006 /* Statistics of the detected objects in the QC */ 02007 hawki_obj_prop_stats(obj_charac, qclists); 02008 02009 /* Write the combined image */ 02010 hawki_images_save(set, 02011 parlist, 02012 used_frames, 02013 (const cpl_image **)combined, 02014 recipe_name, 02015 HAWKI_CALPRO_COMBINED, 02016 HAWKI_PROTYPE_COMBINED, 02017 NULL, 02018 (const cpl_propertylist**)qclists, 02019 "hawki_sci_jitter.fits"); 02020 02021 /* Erase the WCS */ 02022 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 02023 cpl_propertylist_erase_regexp(qclists[i], HAWKI_HEADER_WCS, 0) ; 02024 } 02025 02026 /* Create a propertylist for PRO.x */ 02027 plist = cpl_propertylist_new(); 02028 cpl_propertylist_append_string(plist, CPL_DFS_PRO_TYPE, 02029 HAWKI_PROTYPE_STITCHED) ; 02030 cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG, 02031 HAWKI_CALPRO_STITCHED) ; 02032 /* Handle WCS keys */ 02033 ext_chip_1 = 1; 02034 wcslist = cpl_propertylist_load_regexp( 02035 cpl_frame_get_filename(ref_frame), ext_chip_1, HAWKI_HEADER_WCS, 0); 02036 /* Update WCS and write them */ 02037 crpix1 = cpl_propertylist_get_double(wcslist, "CRPIX1"); 02038 crpix1 += hawki_sci_jitter_output.combined_pos_x[0]; 02039 cpl_propertylist_update_double(wcslist, "CRPIX1", crpix1) ; 02040 crpix2 = cpl_propertylist_get_double(wcslist, "CRPIX2"); 02041 crpix2 += hawki_sci_jitter_output.combined_pos_y[0] ; 02042 cpl_propertylist_update_double(wcslist, "CRPIX2", crpix2) ; 02043 cpl_propertylist_append(plist, wcslist); 02044 cpl_propertylist_delete(wcslist) ; 02045 /* Write the stitched image */ 02046 cpl_dfs_save_image(set, 02047 NULL, 02048 parlist, 02049 used_frames, 02050 NULL, 02051 stitched, 02052 CPL_BPP_IEEE_FLOAT, 02053 recipe_name, 02054 plist, 02055 NULL, 02056 PACKAGE "/" PACKAGE_VERSION, 02057 "hawki_sci_jitter_stitched.fits"); 02058 cpl_propertylist_delete(plist); 02059 02060 /* Write the FITS table with the objects statistics */ 02061 if (obj_charac) 02062 { 02063 hawki_tables_save(set, 02064 parlist, 02065 used_frames, 02066 (const cpl_table **)obj_charac, 02067 recipe_name, 02068 HAWKI_CALPRO_OBJ_PARAM, 02069 HAWKI_PROTYPE_OBJ_PARAM, 02070 NULL, 02071 (const cpl_propertylist**)qclists, 02072 "hawki_sci_jitter_stars.fits"); 02073 } 02074 02075 /* Write the table with the background statistics */ 02076 hawki_tables_save(set, 02077 parlist, 02078 used_frames, 02079 (const cpl_table **)bkg_stats, 02080 recipe_name, 02081 HAWKI_CALPRO_JITTER_BKG_STATS, 02082 HAWKI_PROTYPE_JITTER_BKG_STATS, 02083 NULL, 02084 (const cpl_propertylist **)qclists, 02085 "hawki_sci_jitter_bkg_stats.fits"); 02086 02087 /* Free and return */ 02088 cpl_frameset_delete(used_frames); 02089 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 02090 cpl_propertylist_delete(qclists[i]) ; 02091 } 02092 cpl_propertylist_delete(telstats) ; 02093 cpl_free(qclists) ; 02094 if(!cpl_errorstate_is_equal(error_prevstate)) 02095 { 02096 cpl_errorstate_set(CPL_ERROR_NONE); 02097 return -1; 02098 } 02099 return 0; 02100 } 02101 02102 int hawki_sci_jitter_whole_image_algo 02103 (cpl_frameset * obj, 02104 cpl_table ** raw_jitter_stats, 02105 cpl_table * raw_obj_tel_info, 02106 cpl_parameterlist * parlist, 02107 cpl_frameset * recipe_set) 02108 { 02109 int nframes; 02110 int iframe; 02111 02112 02113 nframes = cpl_frameset_get_size(obj); 02114 for( iframe = 0 ; iframe < nframes ; ++iframe) 02115 { 02116 /* Local storage variables */ 02117 cpl_frame * this_target_frame; 02118 cpl_propertylist * this_properties; 02119 02120 /* Computing statistics for this frame */ 02121 cpl_msg_info(cpl_func, "Getting statistics for image %d", iframe + 1); 02122 this_target_frame = cpl_frameset_get_frame(obj, iframe); 02123 hawki_image_stats_fill_from_frame 02124 (raw_jitter_stats, this_target_frame, iframe); 02125 02126 /* Compute the telescope pcs statistics */ 02127 this_properties = cpl_propertylist_load 02128 (cpl_frame_get_filename(this_target_frame), 0); 02129 if(this_properties == NULL) 02130 { 02131 cpl_msg_error(cpl_func,"Could not read the header of object frame"); 02132 return -1; 02133 } 02134 if(hawki_extract_prop_tel_qc(this_properties, raw_obj_tel_info, iframe)) 02135 { 02136 cpl_msg_warning(cpl_func,"Some telescope properties could not be " 02137 "read for image %d", iframe+1); 02138 cpl_errorstate_set(CPL_ERROR_NONE); 02139 } 02140 cpl_propertylist_delete(this_properties); 02141 } 02142 02143 /* Saving the already computed products */ 02144 cpl_msg_info(cpl_func, "Saving image statistics"); 02145 if(hawki_sci_jitter_save_stats(raw_jitter_stats, raw_obj_tel_info, 02146 obj, 02147 parlist, recipe_set) != 0) 02148 cpl_msg_warning(cpl_func,"Some data could not be saved. " 02149 "Check permisions or disk space"); 02150 02151 02152 /* Free and return */ 02153 return 0; 02154 } 02155 02156 int hawki_sci_jitter_save_stats 02157 (cpl_table ** raw_jitter_stats, 02158 cpl_table * raw_obj_tel_info, 02159 cpl_frameset * jitter_frames, 02160 cpl_parameterlist * parlist, 02161 cpl_frameset * recipe_set) 02162 { 02163 int idet; 02164 const cpl_frame * ref_frame; 02165 cpl_propertylist ** qcstats; 02166 cpl_propertylist * telstats; 02167 const char * recipe_name = "hawki_sci_jitter" ; 02168 cpl_errorstate error_prevstate = cpl_errorstate_get(); 02169 02170 /* Statistics of the raw images in the QC */ 02171 qcstats = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)); 02172 /* Create the QC lists */ 02173 ref_frame = irplib_frameset_get_first_from_group 02174 (recipe_set, CPL_FRAME_GROUP_RAW); 02175 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 02176 { 02177 int ext_nb; 02178 cpl_propertylist * reflist; 02179 02180 qcstats[idet] = cpl_propertylist_new(); 02181 /* Propagate some keywords from input raw frame extensions */ 02182 ext_nb = 02183 hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), idet+1); 02184 reflist = cpl_propertylist_load_regexp 02185 (cpl_frame_get_filename(ref_frame), ext_nb, 02186 HAWKI_HEADER_EXT_FORWARD, 0) ; 02187 cpl_propertylist_append(qcstats[idet], reflist); 02188 cpl_propertylist_delete(reflist); 02189 } 02190 hawki_image_stats_stats(raw_jitter_stats, qcstats); 02191 /* Write the table with the raw jitter objects statistics */ 02192 hawki_tables_save(recipe_set, 02193 parlist, 02194 jitter_frames, 02195 (const cpl_table **)raw_jitter_stats, 02196 recipe_name, 02197 HAWKI_CALPRO_JITTER_STATS, 02198 HAWKI_PROTYPE_JITTER_STATS, 02199 NULL, 02200 (const cpl_propertylist**)qcstats, 02201 "hawki_sci_jitter_stats.fits"); 02202 /* Free qcstats */ 02203 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 02204 cpl_propertylist_delete(qcstats[idet]); 02205 02206 /* Write the FITS table with the raw telescope data */ 02207 telstats = cpl_propertylist_new(); 02208 cpl_propertylist_append_string(telstats, CPL_DFS_PRO_TYPE, 02209 HAWKI_PROTYPE_SCIENCE_PCS); 02210 cpl_propertylist_append_string(telstats, CPL_DFS_PRO_CATG, 02211 HAWKI_CALPRO_SCIENCE_PCS); 02212 hawki_compute_prop_tel_qc_stats(raw_obj_tel_info, telstats); 02213 if(cpl_dfs_save_table(recipe_set, 02214 NULL, 02215 parlist, 02216 jitter_frames, 02217 NULL, 02218 raw_obj_tel_info, 02219 NULL, 02220 recipe_name, 02221 telstats, 02222 NULL, 02223 PACKAGE "/" PACKAGE_VERSION, 02224 "hawki_sci_jitter_pcs.fits") != CPL_ERROR_NONE) 02225 cpl_msg_error(cpl_func,"Cannot save PCS table"); 02226 02227 /* Free and return */ 02228 cpl_propertylist_delete(telstats); 02229 cpl_free(qcstats); 02230 if(!cpl_errorstate_is_equal(error_prevstate)) 02231 { 02232 cpl_errorstate_set(CPL_ERROR_NONE); 02233 return -1; 02234 } 02235 02236 return 0; 02237 }
1.7.4