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