HAWKI Pipeline Reference Manual 1.8.12
|
00001 /* $Id: hawki_step_detect_obj.c,v 1.27 2012/11/30 14:50:51 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/11/30 14:50:51 $ 00024 * $Revision: 1.27 $ 00025 * $Name: hawki-1_8_12 $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 Includes 00034 -----------------------------------------------------------------------------*/ 00035 00036 #include <math.h> 00037 #include <cpl.h> 00038 #include <string.h> 00039 00040 #include "irplib_utils.h" 00041 #include "irplib_calib.h" 00042 00043 #include "hawki_utils.h" 00044 #include "hawki_obj_det.h" 00045 #include "hawki_mask.h" 00046 #include "hawki_image_stats.h" 00047 #include "hawki_calib.h" 00048 #include "hawki_load.h" 00049 #include "hawki_save.h" 00050 #include "hawki_pfits.h" 00051 #include "hawki_dfs.h" 00052 00053 /*----------------------------------------------------------------------------- 00054 Functions prototypes 00055 -----------------------------------------------------------------------------*/ 00056 00057 #ifdef __cplusplus 00058 extern "C" 00059 #endif 00060 int cpl_plugin_get_info(cpl_pluginlist * list); 00061 00062 static int hawki_step_detect_obj_create(cpl_plugin *) ; 00063 static int hawki_step_detect_obj_exec(cpl_plugin *) ; 00064 static int hawki_step_detect_obj_destroy(cpl_plugin *) ; 00065 static int hawki_step_detect_obj(cpl_parameterlist *, cpl_frameset *) ; 00066 00067 static void hawki_step_detect_obj_init_output(void); 00068 static void hawki_step_detect_obj_get_pscale 00069 (cpl_frameset * combframes); 00070 static int hawki_step_detect_obj_retrieve_input_param 00071 (cpl_parameterlist * parlist); 00072 static cpl_apertures ** hawki_step_detect_obj_mask_and_apertures 00073 (cpl_frameset * combframes, 00074 cpl_image ** mask_image, 00075 cpl_image ** comb_image); 00076 static int hawki_step_detect_obj_aper_params 00077 (cpl_image ** combined_images, 00078 cpl_apertures ** apertures, 00079 cpl_table ** obj_charac); 00080 static int hawki_step_detect_obj_save 00081 (cpl_image ** mask_images, 00082 cpl_table ** obj_charac, 00083 cpl_propertylist ** obj_stats, 00084 cpl_parameterlist * parlist, 00085 cpl_frameset * framelist); 00086 00087 /*----------------------------------------------------------------------------- 00088 Static variables 00089 -----------------------------------------------------------------------------*/ 00090 00091 static struct 00092 { 00093 /* Inputs */ 00094 double sigma_det; 00095 int growing_radius; 00096 } hawki_step_detect_obj_config; 00097 00098 static struct 00099 { 00100 /* Outputs */ 00101 double pixscale; 00102 double iq[HAWKI_NB_DETECTORS] ; 00103 int nbobjs[HAWKI_NB_DETECTORS] ; 00104 double fwhm_pix[HAWKI_NB_DETECTORS] ; 00105 double fwhm_arcsec[HAWKI_NB_DETECTORS] ; 00106 double fwhm_mode[HAWKI_NB_DETECTORS] ; 00107 double pos_x[HAWKI_NB_DETECTORS] ; 00108 double pos_y[HAWKI_NB_DETECTORS] ; 00109 } hawki_step_detect_obj_output; 00110 00111 static char hawki_step_detect_obj_description[] = 00112 "hawki_step_detect_obj -- hawki detect objects recipe.\n" 00113 "This recipe detects objects from the combined image creating a mask\n" 00114 "and a list of object properties\n" 00115 "The input of the recipe files listed in the Set Of Frames (sof-file)\n" 00116 "must be tagged as:\n" 00117 "combined.fits "HAWKI_CALPRO_COMBINED"\n" 00118 "The recipe creates as an output:\n" 00119 "hawki_step_detect_obj_mask.fits ("HAWKI_CALPRO_OBJ_MASK"): A mask with 1 where the objects are present and 0 elsewhere\n" 00120 "hawki_step_detect_obj_stars.fits ("HAWKI_CALPRO_OBJ_PARAM"): A table with the detected objects characteristics\n" 00121 "Return code:\n" 00122 "esorex exits with an error code of 0 if the recipe completes successfully\n" 00123 "or 1 otherwise"; 00124 00125 00126 00127 /*----------------------------------------------------------------------------- 00128 Functions code 00129 -----------------------------------------------------------------------------*/ 00130 00131 /*----------------------------------------------------------------------------*/ 00139 /*----------------------------------------------------------------------------*/ 00140 int cpl_plugin_get_info(cpl_pluginlist * list) 00141 { 00142 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ; 00143 cpl_plugin * plugin = &recipe->interface ; 00144 00145 cpl_plugin_init(plugin, 00146 CPL_PLUGIN_API, 00147 HAWKI_BINARY_VERSION, 00148 CPL_PLUGIN_TYPE_RECIPE, 00149 "hawki_step_detect_obj", 00150 "Object detection recipe", 00151 hawki_step_detect_obj_description, 00152 "Cesar Enrique Garcia Dabo", 00153 PACKAGE_BUGREPORT, 00154 hawki_get_license(), 00155 hawki_step_detect_obj_create, 00156 hawki_step_detect_obj_exec, 00157 hawki_step_detect_obj_destroy) ; 00158 00159 cpl_pluginlist_append(list, plugin) ; 00160 00161 return 0; 00162 } 00163 00164 /*----------------------------------------------------------------------------*/ 00173 /*----------------------------------------------------------------------------*/ 00174 static int hawki_step_detect_obj_create(cpl_plugin * plugin) 00175 { 00176 cpl_recipe * recipe ; 00177 cpl_parameter * p ; 00178 00179 /* Get the recipe out of the plugin */ 00180 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00181 recipe = (cpl_recipe *)plugin ; 00182 else return -1 ; 00183 00184 /* Create the parameters list in the cpl_recipe object */ 00185 recipe->parameters = cpl_parameterlist_new() ; 00186 if (recipe->parameters == NULL) 00187 return 1; 00188 00189 /* Fill the parameters list */ 00190 /* --sigma_det */ 00191 p = cpl_parameter_new_value("hawki.hawki_step_detect_obj.sigma_det", 00192 CPL_TYPE_DOUBLE, "detection level", 00193 "hawki.hawki_step_detect_obj", 6.); 00194 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sigma_det"); 00195 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00196 cpl_parameterlist_append(recipe->parameters, p); 00197 00198 /* --growing_radius */ 00199 p = cpl_parameter_new_value("hawki.hawki_step_detect_obj.growing_radius", 00200 CPL_TYPE_INT, 00201 "radius of convolution kernel to apply to objects", 00202 "hawki.hawki_step_detect_obj", 5); 00203 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "growing_radius"); 00204 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00205 cpl_parameterlist_append(recipe->parameters, p); 00206 00207 /* Return */ 00208 return 0; 00209 } 00210 00211 /*----------------------------------------------------------------------------*/ 00217 /*----------------------------------------------------------------------------*/ 00218 static int hawki_step_detect_obj_exec(cpl_plugin * plugin) 00219 { 00220 cpl_recipe * recipe ; 00221 00222 /* Get the recipe out of the plugin */ 00223 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00224 recipe = (cpl_recipe *)plugin ; 00225 else return -1 ; 00226 00227 /* Issue a banner */ 00228 hawki_print_banner(); 00229 00230 return hawki_step_detect_obj(recipe->parameters, recipe->frames) ; 00231 } 00232 00233 /*----------------------------------------------------------------------------*/ 00239 /*----------------------------------------------------------------------------*/ 00240 static int hawki_step_detect_obj_destroy(cpl_plugin * plugin) 00241 { 00242 cpl_recipe * recipe ; 00243 00244 /* Get the recipe out of the plugin */ 00245 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00246 recipe = (cpl_recipe *)plugin ; 00247 else return -1 ; 00248 00249 cpl_parameterlist_delete(recipe->parameters) ; 00250 return 0 ; 00251 } 00252 00253 /*----------------------------------------------------------------------------*/ 00260 /*----------------------------------------------------------------------------*/ 00261 static int hawki_step_detect_obj( 00262 cpl_parameterlist * parlist, 00263 cpl_frameset * framelist) 00264 { 00265 cpl_frameset * combframes; 00266 cpl_image ** mask_image; 00267 cpl_image ** comb_image; 00268 cpl_apertures ** apertures; 00269 cpl_table ** obj_charac; 00270 cpl_propertylist ** obj_stats; 00271 int idet; 00272 00273 /* Initialise */ 00274 hawki_step_detect_obj_init_output(); 00275 00276 /* Retrieve input parameters */ 00277 if(hawki_step_detect_obj_retrieve_input_param(parlist)) 00278 { 00279 cpl_msg_error(__func__, "Wrong parameters"); 00280 return -1; 00281 } 00282 00283 /* Identify the RAW and CALIB frames in the input frameset */ 00284 if (hawki_dfs_set_groups(framelist)) { 00285 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00286 return -1 ; 00287 } 00288 00289 /* Retrieve raw frames */ 00290 combframes = hawki_extract_frameset(framelist, HAWKI_CALPRO_COMBINED) ; 00291 if (combframes == NULL) 00292 { 00293 cpl_msg_error(__func__, "Cannot find combined images in the input (%s)", 00294 HAWKI_CALPRO_COMBINED); 00295 return -1 ; 00296 } 00297 if (cpl_frameset_get_size(combframes) != 1) 00298 { 00299 cpl_msg_error(__func__, "Only one combined image must be provided"); 00300 return -1 ; 00301 } 00302 00303 /* Get info from the headers */ 00304 hawki_step_detect_obj_get_pscale(combframes); 00305 00306 /* Get the mask with the points above the background 00307 * and the associated apertures*/ 00308 cpl_msg_info(__func__, "Getting the object masks") ; 00309 mask_image = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_image *)); 00310 comb_image = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_image *)); 00311 apertures = hawki_step_detect_obj_mask_and_apertures 00312 (combframes, mask_image, comb_image); 00313 if(apertures == NULL) 00314 { 00315 cpl_msg_error(__func__,"Could not detect objects in image"); 00316 cpl_frameset_delete(combframes); 00317 cpl_free(mask_image); 00318 cpl_free(comb_image); 00319 return -1; 00320 } 00321 00322 /* Get object characterizations and statistics */ 00323 cpl_msg_info(__func__, "Getting object parameters") ; 00324 obj_charac = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table *)) ; 00325 obj_stats = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist *)); 00326 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00327 { 00328 obj_charac[idet] = cpl_table_new 00329 (cpl_apertures_get_size(apertures[idet])); 00330 obj_stats[idet] = cpl_propertylist_new(); 00331 } 00332 hawki_step_detect_obj_aper_params(comb_image, apertures, obj_charac); 00333 00334 /* Statistics of the detected objects in the QC */ 00335 hawki_obj_prop_stats(obj_charac, obj_stats); 00336 00337 /* Save the products */ 00338 cpl_msg_info(__func__, "Save the products") ; 00339 if (hawki_step_detect_obj_save(mask_image, obj_charac, obj_stats, 00340 parlist, framelist) == -1) 00341 { 00342 cpl_msg_warning(__func__, "Some data could not be saved. " 00343 "Check permisions or disk space") ; 00344 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00345 { 00346 cpl_table_delete(obj_charac[idet]); 00347 cpl_propertylist_delete(obj_stats[idet]); 00348 cpl_apertures_delete(apertures[idet]); 00349 } 00350 cpl_free(apertures); 00351 cpl_free(obj_charac); 00352 cpl_free(obj_stats); 00353 cpl_frameset_delete(combframes); 00354 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00355 { 00356 cpl_image_delete(mask_image[idet]); 00357 cpl_image_delete(comb_image[idet]); 00358 } 00359 cpl_free(mask_image); 00360 cpl_free(comb_image); 00361 return -1 ; 00362 } 00363 00364 /* Return */ 00365 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00366 { 00367 cpl_table_delete(obj_charac[idet]); 00368 cpl_propertylist_delete(obj_stats[idet]); 00369 cpl_apertures_delete(apertures[idet]); 00370 cpl_image_delete(mask_image[idet]); 00371 cpl_image_delete(comb_image[idet]); 00372 } 00373 cpl_free(apertures); 00374 cpl_free(obj_charac); 00375 cpl_free(obj_stats); 00376 cpl_frameset_delete(combframes); 00377 cpl_free(mask_image); 00378 cpl_free(comb_image); 00379 00380 /* Return */ 00381 if (cpl_error_get_code()) 00382 { 00383 cpl_msg_error(__func__, 00384 "HAWK-I pipeline could not recover from previous errors"); 00385 return -1 ; 00386 } 00387 else return 0 ; 00388 } 00389 00390 int hawki_step_detect_obj_retrieve_input_param 00391 (cpl_parameterlist * parlist) 00392 { 00393 cpl_parameter * par ; 00394 00395 par = NULL ; 00396 par = cpl_parameterlist_find 00397 (parlist, "hawki.hawki_step_detect_obj.sigma_det"); 00398 hawki_step_detect_obj_config.sigma_det = cpl_parameter_get_double(par); 00399 par = cpl_parameterlist_find 00400 (parlist, "hawki.hawki_step_detect_obj.growing_radius"); 00401 hawki_step_detect_obj_config.growing_radius = cpl_parameter_get_int(par); 00402 if(hawki_step_detect_obj_config.growing_radius > 100) 00403 { 00404 cpl_msg_error(__func__,"The maximum radius allowed is 100"); 00405 return -1; 00406 } 00407 if(hawki_step_detect_obj_config.sigma_det <= 0 ) 00408 { 00409 cpl_msg_error(__func__,"Detection sigma has to be greater than 0"); 00410 return -1; 00411 } 00412 00413 return 0; 00414 } 00415 00416 00417 00418 /*----------------------------------------------------------------------------*/ 00428 /*----------------------------------------------------------------------------*/ 00429 static cpl_apertures ** hawki_step_detect_obj_mask_and_apertures 00430 (cpl_frameset * combframes, 00431 cpl_image ** mask_image, 00432 cpl_image ** comb_image) 00433 { 00434 cpl_apertures ** apertures; 00435 int idet; 00436 00437 /* Create output object */ 00438 apertures = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_apertures *)); 00439 00440 /* Loop on the detectors */ 00441 cpl_msg_indent_more(); 00442 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00443 { 00444 cpl_image * chip_image; 00445 cpl_image * chip_image_sort; 00446 cpl_mask * object_mask; 00447 cpl_mask * kernel_op; 00448 cpl_matrix * kernel; 00449 cpl_image * labels; 00450 cpl_size nobj; 00451 double bkg_level; 00452 double bkg_noise; 00453 double threshold; 00454 int kernel_size; 00455 int ix; 00456 int iy; 00457 00458 cpl_msg_info(__func__, "Detecting objects on chip number %d", idet+1) ; 00459 cpl_msg_indent_more(); 00460 00461 /* Load the input data */ 00462 cpl_msg_info(__func__, "Load the input data") ; 00463 chip_image = hawki_load_image(combframes, 0, idet+1, CPL_TYPE_FLOAT); 00464 if (chip_image == NULL) 00465 { 00466 cpl_msg_error(__func__, "Cannot load chip %d", idet+1) ; 00467 cpl_msg_indent_less() ; 00468 cpl_free(apertures); 00469 return NULL ; 00470 } 00471 00472 /* Subtract the median of the frame first */ 00473 chip_image_sort = cpl_image_duplicate(chip_image); 00474 bkg_level = cpl_image_get_median(chip_image); 00475 bkg_noise = hawki_image_float_get_sigma_from_quartile(chip_image_sort); 00476 cpl_image_delete(chip_image_sort); 00477 threshold = bkg_level + hawki_step_detect_obj_config.sigma_det * bkg_noise; 00478 cpl_msg_info(__func__, "Background: %f",bkg_level); 00479 cpl_msg_info(__func__, "Background noise: %f",bkg_noise); 00480 00481 /* Create the mask */ 00482 cpl_msg_info(__func__, "Mask creation with threshold: %f",threshold); 00483 object_mask = cpl_mask_threshold_image_create 00484 (chip_image, threshold, DBL_MAX); 00485 00486 /* Apply a morphological opening to remove single pixel detections */ 00487 cpl_msg_info(__func__, "Removing single pixel detections"); 00488 kernel_op = cpl_mask_new(3, 3); 00489 cpl_mask_not(kernel_op); 00490 if (cpl_mask_filter(object_mask, object_mask, kernel_op, 00491 CPL_FILTER_OPENING, 00492 CPL_BORDER_ZERO) != CPL_ERROR_NONE) 00493 { 00494 cpl_mask_delete(object_mask); 00495 cpl_mask_delete(kernel_op); 00496 return NULL; 00497 } 00498 cpl_mask_delete(kernel_op); 00499 00500 /* Apply dilation to the mask */ 00501 if(hawki_step_detect_obj_config.growing_radius>0) 00502 { 00503 cpl_msg_info(__func__, "Growing the mask with radius %d", 00504 hawki_step_detect_obj_config.growing_radius); 00505 kernel_size = hawki_step_detect_obj_config.growing_radius*2+1; 00506 kernel = cpl_matrix_new(kernel_size, kernel_size); 00507 for(ix=0;ix<kernel_size;++ix) 00508 for(iy=0;iy<kernel_size;++iy) 00509 { 00510 double xpos = ix+0.5-kernel_size/2.; 00511 double ypos = iy+0.5-kernel_size/2.; 00512 double kernel_func = 1-sqrt(xpos*xpos+ypos*ypos)/ 00513 hawki_step_detect_obj_config.growing_radius; 00514 if(kernel_func<0) 00515 kernel_func = 0; 00516 cpl_matrix_set(kernel, ix, iy, kernel_func); 00517 } 00518 if (hawki_mask_convolve(object_mask, kernel) != CPL_ERROR_NONE) { 00519 cpl_mask_delete(object_mask) ; 00520 cpl_matrix_delete(kernel) ; 00521 return NULL; 00522 } 00523 cpl_matrix_delete(kernel); 00524 } 00525 00526 /* Put the mask and the chip image in the imagelist */ 00527 mask_image[idet] = cpl_image_new_from_mask(object_mask); 00528 comb_image[idet] = chip_image; 00529 00530 /* Labelise the different detected apertures */ 00531 cpl_msg_info(__func__, "Labelise mask") ; 00532 labels = cpl_image_labelise_mask_create(object_mask, &nobj); 00533 if (labels == NULL) 00534 { 00535 int jdet; 00536 cpl_free(apertures); 00537 cpl_mask_delete(object_mask); 00538 for (jdet=0 ; jdet<idet + 1 ; jdet++) 00539 { 00540 cpl_image_delete(mask_image[jdet]); 00541 cpl_image_delete(comb_image[jdet]); 00542 } 00543 } 00544 cpl_msg_info(__func__, "Number of objects detected: %"CPL_SIZE_FORMAT, 00545 nobj) ; 00546 00547 /* Create the detected apertures list */ 00548 cpl_msg_info(__func__, "Create apertures") ; 00549 apertures[idet] = cpl_apertures_new_from_image(chip_image, labels); 00550 if (apertures[idet] == NULL) 00551 { 00552 int jdet; 00553 cpl_free(apertures); 00554 cpl_mask_delete(object_mask); 00555 for (jdet=0 ; jdet<idet + 1 ; jdet++) 00556 { 00557 cpl_image_delete(mask_image[jdet]); 00558 cpl_image_delete(comb_image[jdet]); 00559 } 00560 return NULL; 00561 } 00562 00563 /* Free */ 00564 cpl_mask_delete(object_mask); 00565 cpl_image_delete(labels); 00566 cpl_msg_indent_less(); 00567 } 00568 00569 /* Free and return */ 00570 cpl_msg_indent_less(); 00571 return apertures; 00572 } 00573 00574 /*----------------------------------------------------------------------------*/ 00581 /*----------------------------------------------------------------------------*/ 00582 static int hawki_step_detect_obj_aper_params 00583 (cpl_image ** combined_images, 00584 cpl_apertures ** apertures, 00585 cpl_table ** obj_charac) 00586 { 00587 int nb_objs ; 00588 double angle ; 00589 double * fwhms_x ; 00590 double * fwhms_y ; 00591 cpl_bivector * iqe ; 00592 int nb_good ; 00593 cpl_vector * fwhms_good ; 00594 double * fwhms_good_data ; 00595 double f_min, f_max, fr, fx, fy ; 00596 int chip; 00597 int iobj; 00598 int j; 00599 00600 /* Initialise */ 00601 double seeing_min_arcsec = 0.1 ; 00602 double seeing_max_arcsec = 5.0 ; 00603 double seeing_fwhm_var = 0.2 ; 00604 00605 /* Check entries */ 00606 if (combined_images == NULL) return -1 ; 00607 if (obj_charac == NULL) return -1 ; 00608 00609 /* Loop on the HAWK-I detectors */ 00610 cpl_msg_indent_more(); 00611 for (chip=0 ; chip<HAWKI_NB_DETECTORS ; chip++) 00612 { 00613 00614 /* Number of detected objects */ 00615 nb_objs = cpl_apertures_get_size(apertures[chip]); 00616 cpl_msg_info(__func__, "%d objects detected on chip %d",nb_objs,chip+1); 00617 hawki_step_detect_obj_output.nbobjs[chip] = nb_objs ; 00618 fwhms_x = cpl_malloc(nb_objs * sizeof(double)) ; 00619 fwhms_y = cpl_malloc(nb_objs * sizeof(double)) ; 00620 00621 /* Initialize the output table */ 00622 cpl_table_set_size(obj_charac[chip], nb_objs); 00623 cpl_table_new_column 00624 (obj_charac[chip], HAWKI_COL_OBJ_POSX, CPL_TYPE_DOUBLE); 00625 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_POSX,"pix"); 00626 cpl_table_new_column 00627 (obj_charac[chip], HAWKI_COL_OBJ_POSY, CPL_TYPE_DOUBLE); 00628 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_POSY,"pix"); 00629 cpl_table_new_column 00630 (obj_charac[chip], HAWKI_COL_OBJ_ANGLE, CPL_TYPE_DOUBLE); 00631 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_ANGLE,"grad"); 00632 cpl_table_new_column 00633 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MAJAX, CPL_TYPE_DOUBLE); 00634 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_FWHM_MAJAX,"pix"); 00635 cpl_table_new_column 00636 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MINAX, CPL_TYPE_DOUBLE); 00637 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_FWHM_MINAX,"pix"); 00638 cpl_table_new_column 00639 (obj_charac[chip], HAWKI_COL_OBJ_ELLIP, CPL_TYPE_DOUBLE); 00640 cpl_table_new_column 00641 (obj_charac[chip], HAWKI_COL_OBJ_FLUX, CPL_TYPE_DOUBLE); 00642 cpl_table_set_column_unit(obj_charac[chip],HAWKI_COL_OBJ_FLUX,"ADU"); 00643 for (iobj=0 ; iobj<nb_objs ; iobj++) 00644 { 00645 /* Fill with the already known information */ 00646 cpl_table_set_double(obj_charac[chip], HAWKI_COL_OBJ_POSX, iobj, 00647 cpl_apertures_get_centroid_x(apertures[chip], 00648 iobj+1)); 00649 cpl_table_set_double(obj_charac[chip], HAWKI_COL_OBJ_POSY, iobj, 00650 cpl_apertures_get_centroid_y(apertures[chip], 00651 iobj+1)); 00652 cpl_table_set_double(obj_charac[chip], HAWKI_COL_OBJ_FLUX, iobj, 00653 cpl_apertures_get_flux(apertures[chip], 00654 iobj+1)); 00655 /* Compute the FWHM informations */ 00656 iqe = cpl_image_iqe(combined_images[chip], 00657 (int)cpl_apertures_get_centroid_x(apertures[chip], iobj+1)- 10, 00658 (int)cpl_apertures_get_centroid_y(apertures[chip], iobj+1)- 10, 00659 (int)cpl_apertures_get_centroid_x(apertures[chip], iobj+1)+ 10, 00660 (int)cpl_apertures_get_centroid_y(apertures[chip], iobj+1)+ 10); 00661 if (iqe == NULL) 00662 { 00663 cpl_error_reset() ; 00664 cpl_msg_debug(__func__, "Cannot get FWHM for obj at pos %g %g", 00665 cpl_apertures_get_centroid_x(apertures[chip], 00666 iobj+1), 00667 cpl_apertures_get_centroid_y(apertures[chip], 00668 iobj+1)) ; 00669 fwhms_x[iobj] = -1.0 ; 00670 fwhms_y[iobj] = -1.0 ; 00671 angle = 0.0 ; 00672 } 00673 else 00674 { 00675 fwhms_x[iobj] = cpl_vector_get(cpl_bivector_get_x(iqe), 2) ; 00676 fwhms_y[iobj] = cpl_vector_get(cpl_bivector_get_x(iqe), 3) ; 00677 angle = cpl_vector_get(cpl_bivector_get_x(iqe), 4) ; 00678 cpl_bivector_delete(iqe) ; 00679 cpl_msg_debug(__func__, 00680 "FWHM for obj at pos %g %g: %g x %g (%g)", 00681 cpl_apertures_get_centroid_x(apertures[chip], 00682 iobj+1), 00683 cpl_apertures_get_centroid_y(apertures[chip], 00684 iobj+1), 00685 fwhms_x[iobj], fwhms_y[iobj], angle) ; 00686 } 00687 cpl_table_set_double 00688 (obj_charac[chip], HAWKI_COL_OBJ_ANGLE, iobj, angle) ; 00689 cpl_table_set_double 00690 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MAJAX, iobj, 00691 fwhms_x[iobj]); 00692 cpl_table_set_double 00693 (obj_charac[chip], HAWKI_COL_OBJ_FWHM_MINAX, iobj, 00694 fwhms_y[iobj]); 00695 cpl_table_set_double 00696 (obj_charac[chip], HAWKI_COL_OBJ_ELLIP, iobj, 00697 1 - fwhms_y[iobj] / fwhms_x[iobj]); 00698 } 00699 00700 /* Get the number of good values */ 00701 nb_good = 0 ; 00702 for (iobj=0 ; iobj<nb_objs ; iobj++) 00703 { 00704 if ((fwhms_x[iobj] > 0.0) && (fwhms_y[iobj] > 0.0)) nb_good++ ; 00705 } 00706 if (nb_good == 0) 00707 { 00708 cpl_msg_warning 00709 (__func__, "No objects to compute mean FWHM on chip %d",chip+1); 00710 cpl_free(fwhms_x) ; 00711 cpl_free(fwhms_y) ; 00712 continue; 00713 } 00714 00715 /* Get the good values */ 00716 fwhms_good = cpl_vector_new(nb_good) ; 00717 fwhms_good_data = cpl_vector_get_data(fwhms_good) ; 00718 j=0 ; 00719 for (iobj=0 ; iobj<nb_objs ; iobj++) 00720 { 00721 if ((fwhms_x[iobj] > 0.0) && (fwhms_y[iobj] > 0.0)) 00722 { 00723 fwhms_good_data[j] = (fwhms_x[iobj]+fwhms_y[iobj])/2.0 ; 00724 j++ ; 00725 } 00726 } 00727 00728 /* Compute the fwhm */ 00729 if (nb_good < 3) 00730 { 00731 /* Too few values to compute the median */ 00732 hawki_step_detect_obj_output.fwhm_pix[chip] = fwhms_good_data[0] ; 00733 cpl_msg_warning 00734 (__func__, "Fewer than 3 objects, using the first object FWHM"); 00735 } 00736 else 00737 { 00738 /* Compute the median */ 00739 hawki_step_detect_obj_output.fwhm_pix[chip] = 00740 cpl_vector_get_median_const(fwhms_good); 00741 } 00742 hawki_step_detect_obj_output.fwhm_arcsec[chip] = 00743 hawki_step_detect_obj_output.fwhm_pix[chip] * 00744 hawki_step_detect_obj_output.pixscale ; 00745 00746 /* Compute the mode of the FWHMs */ 00747 if (nb_good > 5) 00748 { 00749 hawki_step_detect_obj_output.fwhm_mode[chip] = 00750 hawki_vector_get_mode(fwhms_good); 00751 hawki_step_detect_obj_output.fwhm_mode[chip] *= 00752 hawki_step_detect_obj_output.pixscale; 00753 } 00754 cpl_vector_delete(fwhms_good); 00755 00756 /* IQ is the median of the (fwhm_x+fwhm_y/2) of the good stars */ 00757 /* Compute f_min and f_max */ 00758 f_min = seeing_min_arcsec / hawki_step_detect_obj_output.pixscale; 00759 f_max = seeing_max_arcsec / hawki_step_detect_obj_output.pixscale; 00760 00761 /* Get the number of good values */ 00762 nb_good = 0 ; 00763 for (iobj=0 ; iobj<nb_objs ; iobj++) 00764 { 00765 fx = fwhms_x[iobj] ; 00766 fy = fwhms_y[iobj] ; 00767 fr = 2.0 * fabs(fx-fy) / (fx+fy) ; 00768 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) && 00769 (fr < seeing_fwhm_var)) nb_good++ ; 00770 } 00771 if (nb_good == 0) 00772 { 00773 cpl_msg_warning(__func__, "No objects to compute IQ on chip %d", 00774 chip+1); 00775 cpl_free(fwhms_x) ; 00776 cpl_free(fwhms_y) ; 00777 continue; 00778 } 00779 00780 /* Get the good values */ 00781 fwhms_good = cpl_vector_new(nb_good) ; 00782 fwhms_good_data = cpl_vector_get_data(fwhms_good) ; 00783 j=0 ; 00784 for (iobj=0 ; iobj<nb_objs ; iobj++) 00785 { 00786 fx = fwhms_x[iobj] ; 00787 fy = fwhms_y[iobj] ; 00788 fr = 2.0 * fabs(fx-fy) / (fx+fy) ; 00789 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) && 00790 (fr < seeing_fwhm_var)) 00791 { 00792 fwhms_good_data[j] = (fx + fy)/2.0 ; 00793 j++ ; 00794 } 00795 } 00796 cpl_free(fwhms_x) ; 00797 cpl_free(fwhms_y) ; 00798 00799 /* Compute the fwhm */ 00800 if (nb_good < 3) 00801 { 00802 /* Too few values to compute the median */ 00803 hawki_step_detect_obj_output.iq[chip] = fwhms_good_data[0] ; 00804 } 00805 else 00806 { 00807 /* Compute the median */ 00808 hawki_step_detect_obj_output.iq[chip] = 00809 cpl_vector_get_median_const(fwhms_good) ; 00810 } 00811 cpl_vector_delete(fwhms_good); 00812 hawki_step_detect_obj_output.iq[chip] *= 00813 hawki_step_detect_obj_output.pixscale; 00814 } 00815 cpl_msg_indent_less(); 00816 00817 return 0; 00818 } 00819 00820 00821 /*----------------------------------------------------------------------------*/ 00830 /*----------------------------------------------------------------------------*/ 00831 static int hawki_step_detect_obj_save 00832 (cpl_image ** mask_images, 00833 cpl_table ** obj_charac, 00834 cpl_propertylist ** obj_stats, 00835 cpl_parameterlist * parlist, 00836 cpl_frameset * framelist) 00837 { 00838 const cpl_frame * ref_frame ; 00839 cpl_propertylist ** qclists; 00840 int ext_nb ; 00841 const char * recipe_name = "hawki_step_detect_obj" ; 00842 int i; 00843 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00844 00845 00846 00847 /* Load the WCS keys */ 00848 ref_frame = irplib_frameset_get_first_from_group 00849 (framelist, CPL_FRAME_GROUP_RAW); 00850 00851 /* Create the QC lists */ 00852 qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 00853 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) 00854 { 00855 cpl_propertylist * inputlist; 00856 cpl_propertylist * offsetlist; 00857 cpl_propertylist * wcslist; 00858 00859 /* Get the extension number */ 00860 ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), i+1); 00861 qclists[i] = cpl_propertylist_new() ; 00862 00863 /* Fill the QC */ 00864 cpl_propertylist_append_int 00865 (qclists[i], "ESO QC NBOBJS", 00866 hawki_step_detect_obj_output.nbobjs[i]); 00867 cpl_propertylist_append_double 00868 (qclists[i], "ESO QC IQ", hawki_step_detect_obj_output.iq[i]); 00869 cpl_propertylist_append_double 00870 (qclists[i], "ESO QC FWHM PIX", 00871 hawki_step_detect_obj_output.fwhm_pix[i]); 00872 cpl_propertylist_append_double 00873 (qclists[i], "ESO QC FWHM ARCSEC", 00874 hawki_step_detect_obj_output.fwhm_arcsec[i]); 00875 cpl_propertylist_append_double 00876 (qclists[i], "ESO QC FWHM MODE", 00877 hawki_step_detect_obj_output.fwhm_mode[i]); 00878 00879 /* Propagate some keywords from input raw frame extensions */ 00880 inputlist = cpl_propertylist_load_regexp( 00881 cpl_frame_get_filename(ref_frame), ext_nb, 00882 HAWKI_HEADER_EXT_FORWARD, 0); 00883 offsetlist = cpl_propertylist_load_regexp( 00884 cpl_frame_get_filename(ref_frame), ext_nb, 00885 HAWKI_HEADER_COMB_OFFSETS, 0); 00886 wcslist = cpl_propertylist_load_regexp( 00887 cpl_frame_get_filename(ref_frame), ext_nb, 00888 HAWKI_HEADER_WCS, 0); 00889 cpl_propertylist_append(qclists[i], inputlist); 00890 cpl_propertylist_append(qclists[i], offsetlist); 00891 cpl_propertylist_append(qclists[i], wcslist); 00892 cpl_propertylist_delete(inputlist); 00893 cpl_propertylist_delete(offsetlist); 00894 cpl_propertylist_delete(wcslist); 00895 00896 /* Add the object statistics keywords */ 00897 cpl_propertylist_append(qclists[i], obj_stats[i]); 00898 } 00899 00900 00901 /* Write the object mask */ 00902 hawki_images_save(framelist, 00903 parlist, 00904 framelist, 00905 (const cpl_image**)mask_images, 00906 recipe_name, 00907 HAWKI_CALPRO_OBJ_MASK, 00908 HAWKI_PROTYPE_OBJ_MASK, 00909 NULL, 00910 (const cpl_propertylist**)qclists, 00911 "hawki_step_detect_obj_mask.fits") ; 00912 00913 /* Write the FITS table with the objects statistics */ 00914 hawki_tables_save(framelist, 00915 parlist, 00916 framelist, 00917 (const cpl_table **)obj_charac, 00918 recipe_name, 00919 HAWKI_CALPRO_OBJ_PARAM, 00920 HAWKI_PROTYPE_OBJ_PARAM, 00921 NULL, 00922 (const cpl_propertylist**)qclists, 00923 "hawki_step_detect_obj_stars.fits") ; 00924 00925 00926 /* Free and return */ 00927 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 00928 cpl_propertylist_delete(qclists[i]) ; 00929 } 00930 cpl_free(qclists) ; 00931 if(!cpl_errorstate_is_equal(error_prevstate)) 00932 { 00933 cpl_errorstate_set(CPL_ERROR_NONE); 00934 return -1; 00935 } 00936 return 0; 00937 } 00938 00939 static void hawki_step_detect_obj_init_output(void) 00940 { 00941 int idet; 00942 00943 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00944 { 00945 hawki_step_detect_obj_output.iq[idet] = -1.0 ; 00946 hawki_step_detect_obj_output.nbobjs[idet] = -1 ; 00947 hawki_step_detect_obj_output.fwhm_pix[idet] = -1.0 ; 00948 hawki_step_detect_obj_output.fwhm_arcsec[idet] = -1.0 ; 00949 hawki_step_detect_obj_output.fwhm_mode[idet] = -1.0 ; 00950 hawki_step_detect_obj_output.pos_x[idet] = -1.0 ; 00951 hawki_step_detect_obj_output.pos_y[idet] = -1.0 ; 00952 } 00953 hawki_step_detect_obj_output.pixscale = -1.0; 00954 } 00955 00956 static void hawki_step_detect_obj_get_pscale 00957 (cpl_frameset * combframes) 00958 { 00959 cpl_propertylist * plist; 00960 cpl_frame * firstframe; 00961 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00962 00963 /* Get the header infos */ 00964 firstframe = cpl_frameset_get_frame(combframes, 0) ; 00965 plist=cpl_propertylist_load(cpl_frame_get_filename(firstframe), 0) ; 00966 hawki_step_detect_obj_output.pixscale = hawki_pfits_get_pixscale(plist); 00967 cpl_propertylist_delete(plist) ; 00968 if(!cpl_errorstate_is_equal(error_prevstate)) 00969 { 00970 cpl_msg_error(__func__, "Missing PIXSCALE keyword in FITS header") ; 00971 cpl_errorstate_set(CPL_ERROR_NONE); 00972 return; 00973 } 00974 } 00975