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