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