HAWKI Pipeline Reference Manual 1.8.12
|
00001 /* $Id: hawki_cal_illum.c,v 1.8 2010/06/04 09:45:43 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: 2010/06/04 09:45:43 $ 00024 * $Revision: 1.8 $ 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 00039 #include "irplib_utils.h" 00040 #include "irplib_strehl.h" 00041 00042 #include "hawki_utils.h" 00043 #include "hawki_calib.h" 00044 #include "hawki_pfits.h" 00045 #include "hawki_dfs.h" 00046 #include "hawki_load.h" 00047 #include "hawki_save.h" 00048 00049 /*----------------------------------------------------------------------------- 00050 Functions prototypes 00051 -----------------------------------------------------------------------------*/ 00052 00053 static int hawki_cal_illum_create(cpl_plugin *) ; 00054 static int hawki_cal_illum_exec(cpl_plugin *) ; 00055 static int hawki_cal_illum_destroy(cpl_plugin *) ; 00056 static int hawki_cal_illum(cpl_parameterlist *, cpl_frameset *) ; 00057 static int hawki_cal_illum_save(const cpl_image **, const cpl_table **, 00058 cpl_parameterlist *, cpl_frameset *) ; 00059 static cpl_image * hawki_cal_illum_compute(cpl_frameset *, int, 00060 const char *, const char *, cpl_table **) ; 00061 static cpl_vector * hawki_cal_illum_phot(cpl_imagelist *, cpl_bivector *, 00062 int *) ; 00063 static cpl_bivector * hawki_cal_illum_find_pos(cpl_imagelist *, 00064 cpl_bivector *, int) ; 00065 00066 /*----------------------------------------------------------------------------- 00067 Static variables 00068 -----------------------------------------------------------------------------*/ 00069 00070 static struct { 00071 /* Inputs */ 00072 int subtract ; 00073 int degree ; 00074 int s_hx ; 00075 int s_hy ; 00076 double star_r ; 00077 double bg_r1 ; 00078 double bg_r2 ; 00079 } hawki_cal_illum_config ; 00080 00081 static char hawki_cal_illum_description[] = 00082 "hawki_cal_illum -- Illumination recipe\n" 00083 "The files listed in the Set Of Frames (sof-file) must be tagged:\n" 00084 "raw-file.fits "HAWKI_CAL_ILLUM_RAW" or\n" 00085 "flat-file.fits "HAWKI_CALPRO_FLAT" or\n" 00086 "bpm-file.fits "HAWKI_CALPRO_BPM"\n" ; 00087 00088 /*----------------------------------------------------------------------------- 00089 Functions code 00090 -----------------------------------------------------------------------------*/ 00091 00092 /*----------------------------------------------------------------------------*/ 00101 /*----------------------------------------------------------------------------*/ 00102 int cpl_plugin_get_info(cpl_pluginlist * list) 00103 { 00104 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe ) ; 00105 cpl_plugin * plugin = &recipe->interface ; 00106 00107 cpl_plugin_init(plugin, 00108 CPL_PLUGIN_API, 00109 HAWKI_BINARY_VERSION, 00110 CPL_PLUGIN_TYPE_RECIPE, 00111 "hawki_cal_illum", 00112 "Illumination recipe", 00113 hawki_cal_illum_description, 00114 "Yves Jung", 00115 PACKAGE_BUGREPORT, 00116 hawki_get_license(), 00117 hawki_cal_illum_create, 00118 hawki_cal_illum_exec, 00119 hawki_cal_illum_destroy) ; 00120 00121 cpl_pluginlist_append(list, plugin) ; 00122 00123 return 0; 00124 } 00125 00126 /*----------------------------------------------------------------------------*/ 00134 /*----------------------------------------------------------------------------*/ 00135 static int hawki_cal_illum_create(cpl_plugin * plugin) 00136 { 00137 cpl_recipe * recipe ; 00138 cpl_parameter * p ; 00139 00140 /* Check that the plugin is part of a valid recipe */ 00141 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00142 recipe = (cpl_recipe *)plugin ; 00143 else return -1 ; 00144 00145 /* Create the parameters list in the cpl_recipe object */ 00146 recipe->parameters = cpl_parameterlist_new() ; 00147 00148 /* Fill the parameters list */ 00149 /* --subtract */ 00150 p = cpl_parameter_new_value("hawki.hawki_cal_illum.subtract", 00151 CPL_TYPE_BOOL, "Flag to subtract the next images", 00152 "hawki.hawki_cal_illum", TRUE) ; 00153 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "subtract") ; 00154 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00155 cpl_parameterlist_append(recipe->parameters, p) ; 00156 /* --degree */ 00157 p = cpl_parameter_new_value("hawki.hawki_cal_illum.degree", 00158 CPL_TYPE_INT, "Polynomial degree for the fit", 00159 "hawki.hawki_cal_illum", 3) ; 00160 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "degree") ; 00161 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00162 cpl_parameterlist_append(recipe->parameters, p) ; 00163 /* --star_r */ 00164 p = cpl_parameter_new_value("hawki.hawki_cal_illum.star_r", CPL_TYPE_DOUBLE, 00165 "the star radius", "hawki.hawki_cal_illum", -1.0) ; 00166 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "star_r") ; 00167 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00168 cpl_parameterlist_append(recipe->parameters, p) ; 00169 /* --bg_r1 */ 00170 p = cpl_parameter_new_value("hawki.hawki_cal_illum.bg_r1", CPL_TYPE_DOUBLE, 00171 "the internal background radius", "hawki.hawki_cal_illum", -1.0) ; 00172 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bg_r1") ; 00173 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00174 cpl_parameterlist_append(recipe->parameters, p) ; 00175 /* --bg_r2 */ 00176 p = cpl_parameter_new_value("hawki.hawki_cal_illum.bg_r2", CPL_TYPE_DOUBLE, 00177 "the external background radius", "hawki.hawki_cal_illum", -1.0) ; 00178 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bg_r2") ; 00179 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00180 cpl_parameterlist_append(recipe->parameters, p) ; 00181 /* --s_hx */ 00182 p = cpl_parameter_new_value("hawki.hawki_cal_illum.s_hx", CPL_TYPE_INT, 00183 "Half size of the seach box in x", "hawki.hawki_cal_illum", 50) ; 00184 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "s_hx") ; 00185 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00186 cpl_parameterlist_append(recipe->parameters, p) ; 00187 /* --s_hy */ 00188 p = cpl_parameter_new_value("hawki.hawki_cal_illum.s_hy", CPL_TYPE_INT, 00189 "Half size of the seach box in y", "hawki.hawki_cal_illum", 50) ; 00190 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "s_hy") ; 00191 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00192 cpl_parameterlist_append(recipe->parameters, p) ; 00193 00194 /* Return */ 00195 return 0; 00196 } 00197 00198 /*----------------------------------------------------------------------------*/ 00204 /*----------------------------------------------------------------------------*/ 00205 static int hawki_cal_illum_exec(cpl_plugin * plugin) 00206 { 00207 cpl_recipe * recipe ; 00208 00209 /* Get the recipe out of the plugin */ 00210 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00211 recipe = (cpl_recipe *)plugin ; 00212 else return -1 ; 00213 00214 /* Issue a banner */ 00215 hawki_print_banner(); 00216 00217 return hawki_cal_illum(recipe->parameters, recipe->frames) ; 00218 } 00219 00220 /*----------------------------------------------------------------------------*/ 00226 /*----------------------------------------------------------------------------*/ 00227 static int hawki_cal_illum_destroy(cpl_plugin * plugin) 00228 { 00229 cpl_recipe * recipe ; 00230 00231 /* Get the recipe out of the plugin */ 00232 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00233 recipe = (cpl_recipe *)plugin ; 00234 else return -1 ; 00235 00236 cpl_parameterlist_delete(recipe->parameters) ; 00237 return 0 ; 00238 } 00239 00240 /*----------------------------------------------------------------------------*/ 00247 /*----------------------------------------------------------------------------*/ 00248 static int hawki_cal_illum( 00249 cpl_parameterlist * parlist, 00250 cpl_frameset * frameset) 00251 { 00252 cpl_parameter * par ; 00253 const char * flat ; 00254 const char * bpm ; 00255 cpl_frameset * rawframes ; 00256 cpl_frameset * cur_frames ; 00257 int * labels ; 00258 cpl_image * illum[HAWKI_NB_DETECTORS] ; 00259 cpl_table * flux[HAWKI_NB_DETECTORS] ; 00260 int i ; 00261 00262 /* Initialise */ 00263 rawframes = NULL ; 00264 00265 /* Retrieve input parameters */ 00266 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.subtract") ; 00267 hawki_cal_illum_config.subtract = cpl_parameter_get_bool(par) ; 00268 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.degree") ; 00269 hawki_cal_illum_config.degree = cpl_parameter_get_int(par) ; 00270 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.s_hx") ; 00271 hawki_cal_illum_config.s_hx = cpl_parameter_get_int(par) ; 00272 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.s_hy") ; 00273 hawki_cal_illum_config.s_hy = cpl_parameter_get_int(par) ; 00274 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.star_r") ; 00275 hawki_cal_illum_config.star_r = cpl_parameter_get_double(par) ; 00276 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.bg_r1") ; 00277 hawki_cal_illum_config.bg_r1 = cpl_parameter_get_double(par) ; 00278 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.bg_r2") ; 00279 hawki_cal_illum_config.bg_r2 = cpl_parameter_get_double(par) ; 00280 00281 /* Identify the RAW and CALIB frames in the input frameset */ 00282 if (hawki_dfs_set_groups(frameset)) { 00283 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00284 return -1 ; 00285 } 00286 00287 /* Retrieve calibration data */ 00288 flat = hawki_extract_first_filename(frameset, HAWKI_CALPRO_FLAT) ; 00289 bpm = hawki_extract_first_filename(frameset, HAWKI_CALPRO_BPM) ; 00290 00291 /* Retrieve raw frames */ 00292 if ((rawframes = hawki_extract_frameset(frameset, 00293 HAWKI_CAL_ILLUM_RAW)) == NULL) { 00294 cpl_msg_error(__func__, "No raw frame in input") ; 00295 return -1 ; 00296 } 00297 00298 /* Labelise frames */ 00299 cpl_msg_info(__func__, "Labelise the frames") ; 00300 if ((labels = hawki_detectors_labelise(rawframes)) == NULL) { 00301 cpl_msg_error(__func__, "Cannot labelise") ; 00302 cpl_frameset_delete(rawframes) ; 00303 return -1 ; 00304 } 00305 00306 /* Loop on the chips */ 00307 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 00308 cpl_msg_info(__func__, "Reduce chip nb %d", i+1) ; 00309 00310 /* Initialise */ 00311 illum[i] = NULL ; 00312 00313 /* Get the frames for which the star is in chip number i+1 */ 00314 if ((cur_frames = cpl_frameset_extract(rawframes, labels, 00315 i+1)) == NULL) { 00316 cpl_msg_warning(__func__, "No frames for chip nb %d", i+1) ; 00317 /* Create the flux table */ 00318 flux[i] = cpl_table_new(1) ; 00319 cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_POSX, CPL_TYPE_DOUBLE); 00320 cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_POSY, CPL_TYPE_DOUBLE); 00321 cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_FLUX, CPL_TYPE_DOUBLE); 00322 } else { 00323 /* Create the flux table */ 00324 flux[i] = cpl_table_new(cpl_frameset_get_size(cur_frames)) ; 00325 cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_POSX, CPL_TYPE_DOUBLE); 00326 cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_POSY, CPL_TYPE_DOUBLE); 00327 cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_FLUX, CPL_TYPE_DOUBLE); 00328 00329 /* Get the illumination */ 00330 if ((illum[i] = hawki_cal_illum_compute(cur_frames, i+1, 00331 bpm, flat, &(flux[i]))) == NULL) { 00332 cpl_msg_warning(__func__, "Cannot compute for chip %d", i+1) ; 00333 cpl_error_reset() ; 00334 } 00335 cpl_frameset_delete(cur_frames) ; 00336 } 00337 } 00338 cpl_frameset_delete(rawframes) ; 00339 cpl_free(labels) ; 00340 00341 /* Save the product */ 00342 cpl_msg_info(__func__, "Save the product") ; 00343 cpl_msg_indent_more() ; 00344 if (hawki_cal_illum_save((const cpl_image **)illum, 00345 (const cpl_table **)flux, parlist, frameset)) { 00346 cpl_msg_error(__func__, "Cannot save the product") ; 00347 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) cpl_table_delete(flux[i]) ; 00348 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) cpl_image_delete(illum[i]) ; 00349 cpl_msg_indent_less() ; 00350 return -1 ; 00351 } 00352 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) cpl_table_delete(flux[i]) ; 00353 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) cpl_image_delete(illum[i]) ; 00354 cpl_msg_indent_less() ; 00355 00356 /* Return */ 00357 if (cpl_error_get_code()) return -1 ; 00358 else return 0 ; 00359 } 00360 00361 /*----------------------------------------------------------------------------*/ 00371 /*----------------------------------------------------------------------------*/ 00372 static cpl_image * hawki_cal_illum_compute( 00373 cpl_frameset * raw, 00374 int chip, 00375 const char * bpm, 00376 const char * flat, 00377 cpl_table ** fl) 00378 { 00379 cpl_bivector * offsets ; 00380 cpl_imagelist * in ; 00381 cpl_image * ima1 ; 00382 cpl_image * ima2 ; 00383 cpl_bivector * positions ; 00384 cpl_bivector * purged_pos ; 00385 double * positions_x, 00386 * positions_y, 00387 * purged_pos_x, 00388 * purged_pos_y ; 00389 cpl_vector * flux ; 00390 cpl_vector * purged_flux ; 00391 cpl_polynomial * poly ; 00392 cpl_image * poly_ima ; 00393 int nval, nx, ny ; 00394 double val ; 00395 int ival ; 00396 int i, j ; 00397 00398 /* Check entries */ 00399 if (chip < 1 || chip > HAWKI_NB_DETECTORS) return NULL ; 00400 if (raw == NULL) return NULL ; 00401 if (fl == NULL) return NULL ; 00402 00403 /* Get the offsets from the raw frames */ 00404 cpl_msg_info(__func__, "Get the offsets from the files headers") ; 00405 cpl_msg_indent_more() ; 00406 if ((offsets = hawki_get_header_tel_offsets(raw)) == NULL) { 00407 cpl_msg_error(__func__, "Cannot get the offsets") ; 00408 cpl_msg_indent_less() ; 00409 return NULL ; 00410 } 00411 cpl_msg_indent_less() ; 00412 00413 /* Load the input data */ 00414 cpl_msg_info(__func__, "Load the input data") ; 00415 cpl_msg_indent_more() ; 00416 if ((in = hawki_load_detector(raw, chip, CPL_TYPE_FLOAT)) == NULL) { 00417 cpl_msg_error(__func__, "Cannot load input data") ; 00418 cpl_bivector_delete(offsets) ; 00419 cpl_msg_indent_less() ; 00420 return NULL ; 00421 } 00422 cpl_msg_indent_less() ; 00423 00424 /* Apply the calibrations */ 00425 if (flat || bpm) { 00426 cpl_msg_indent_more() ; 00427 if (hawki_flat_bpm_detector_calib(in, flat, bpm) == -1) { 00428 cpl_msg_error(__func__, "Cannot apply calibrations") ; 00429 cpl_bivector_delete(offsets) ; 00430 cpl_imagelist_delete(in) ; 00431 cpl_msg_indent_less() ; 00432 return NULL ; 00433 } 00434 cpl_msg_indent_less() ; 00435 } 00436 00437 /* Subtract the consecutive frames */ 00438 if (hawki_cal_illum_config.subtract) { 00439 cpl_msg_info(__func__, "Subtract the next images") ; 00440 ima1 = cpl_image_duplicate(cpl_imagelist_get(in, 0)) ; 00441 for (i=0 ; i<cpl_imagelist_get_size(in) ; i++) { 00442 if (i==cpl_imagelist_get_size(in)-1) { 00443 ima2 = ima1 ; 00444 } else { 00445 ima2 = cpl_imagelist_get(in, i+1) ; 00446 } 00447 cpl_image_subtract(cpl_imagelist_get(in, i), ima2) ; 00448 } 00449 cpl_image_delete(ima1) ; 00450 } 00451 00452 /* Find the positions */ 00453 cpl_msg_info(__func__, "Find the positions") ; 00454 cpl_msg_indent_more() ; 00455 if ((positions=hawki_cal_illum_find_pos(in, offsets, chip)) == NULL) { 00456 cpl_msg_error(__func__, "Cannot find the positions") ; 00457 cpl_imagelist_delete(in) ; 00458 cpl_bivector_delete(offsets) ; 00459 cpl_msg_indent_less() ; 00460 return NULL ; 00461 } 00462 cpl_bivector_delete(offsets) ; 00463 cpl_msg_indent_less() ; 00464 00465 /* Compute the photometry */ 00466 cpl_msg_info(__func__, "Compute the photometry") ; 00467 cpl_msg_indent_more() ; 00468 if ((flux=hawki_cal_illum_phot(in, positions, &nval)) == NULL) { 00469 cpl_msg_error(__func__, "Cannot find the positions") ; 00470 cpl_imagelist_delete(in) ; 00471 cpl_bivector_delete(positions) ; 00472 cpl_msg_indent_less() ; 00473 return NULL ; 00474 } 00475 nx = cpl_image_get_size_x(cpl_imagelist_get(in, 0)) ; 00476 ny = cpl_image_get_size_y(cpl_imagelist_get(in, 0)) ; 00477 cpl_imagelist_delete(in) ; 00478 cpl_msg_indent_less() ; 00479 if (nval < 1) { 00480 cpl_msg_error(__func__, "No flux computed") ; 00481 cpl_bivector_delete(positions) ; 00482 cpl_vector_delete(flux) ; 00483 return NULL ; 00484 } 00485 00486 /* Purge positions */ 00487 purged_pos = cpl_bivector_new(nval) ; 00488 purged_pos_x = cpl_bivector_get_x_data(purged_pos) ; 00489 purged_pos_y = cpl_bivector_get_y_data(purged_pos) ; 00490 positions_x = cpl_bivector_get_x_data(positions) ; 00491 positions_y = cpl_bivector_get_y_data(positions) ; 00492 purged_flux = cpl_vector_new(nval) ; 00493 j = 0 ; 00494 for (i=0 ; i<cpl_vector_get_size(flux) ; i++) { 00495 if (fabs(cpl_vector_get(flux, i)) > 0) { 00496 purged_pos_x[j] = positions_x[i] ; 00497 purged_pos_y[j] = positions_y[i] ; 00498 cpl_vector_set(purged_flux, j, cpl_vector_get(flux, i)) ; 00499 j++ ; 00500 } 00501 } 00502 00503 /* Fill the flux table */ 00504 for (i=0 ; i<cpl_vector_get_size(flux) ; i++) { 00505 cpl_table_set_double(*fl, HAWKI_COL_ILLUM_POSX, i, positions_x[i]) ; 00506 cpl_table_set_double(*fl, HAWKI_COL_ILLUM_POSY, i, positions_y[i]) ; 00507 cpl_table_set_double(*fl, HAWKI_COL_ILLUM_FLUX, i, 00508 cpl_vector_get(flux, i)) ; 00509 } 00510 cpl_bivector_delete(positions) ; 00511 cpl_vector_delete(flux) ; 00512 00513 /* Fit the polynomial */ 00514 cpl_msg_info(__func__, "Compute the polynomial") ; 00515 if ((poly = cpl_polynomial_fit_2d_create(purged_pos, purged_flux, 00516 hawki_cal_illum_config.degree, NULL)) == NULL) { 00517 cpl_msg_error(__func__, "Cannot fit the polynomial") ; 00518 cpl_bivector_delete(purged_pos) ; 00519 cpl_vector_delete(purged_flux) ; 00520 return NULL ; 00521 } 00522 cpl_bivector_delete(purged_pos) ; 00523 cpl_vector_delete(purged_flux) ; 00524 00525 /* Create the polynomial image */ 00526 poly_ima = cpl_image_new(nx, ny, CPL_TYPE_FLOAT) ; 00527 cpl_image_fill_polynomial(poly_ima, poly, 1.0, 1.0, 1.0, 1.0) ; 00528 cpl_polynomial_delete(poly) ; 00529 00530 /* Normalise the image */ 00531 val = cpl_image_get(poly_ima, 1024, 1024, &ival) ; 00532 cpl_image_divide_scalar(poly_ima, val) ; 00533 00534 return poly_ima ; 00535 } 00536 00537 /*----------------------------------------------------------------------------*/ 00545 /*----------------------------------------------------------------------------*/ 00546 static cpl_vector * hawki_cal_illum_phot( 00547 cpl_imagelist * ilist, 00548 cpl_bivector * positions, 00549 int * nvalid) 00550 { 00551 cpl_vector * flux ; 00552 cpl_image * cur_ima ; 00553 double * pos_x ; 00554 double * pos_y ; 00555 int ni ; 00556 int nok ; 00557 double bg, fl ; 00558 cpl_bivector * iqe_res ; 00559 double fwhm_x, fwhm_y, r, r1, r2 ; 00560 int i ; 00561 00562 /* Test entries */ 00563 if (ilist == NULL || positions == NULL || nvalid == NULL) return NULL ; 00564 ni = cpl_imagelist_get_size(ilist) ; 00565 pos_x = cpl_bivector_get_x_data(positions) ; 00566 pos_y = cpl_bivector_get_y_data(positions) ; 00567 nok = 0 ; 00568 00569 /* Create the flux vector */ 00570 flux = cpl_vector_new(ni) ; 00571 00572 /* Loop on the frames */ 00573 for (i=0 ; i<ni ; i++) { 00574 cur_ima = cpl_imagelist_get(ilist, i) ; 00575 00576 /* FWHM_X / FWHM_Y */ 00577 if ((iqe_res = cpl_image_iqe(cur_ima, 00578 (int)(pos_x[i]-10.0), (int)(pos_y[i]-10.0), 00579 (int)(pos_x[i]+10.0), (int)(pos_y[i]+10.0))) == NULL) { 00580 cpl_msg_debug(__func__,"Cannot get FWHM for image %d", i+1); 00581 fwhm_x = fwhm_y = -1.0 ; 00582 cpl_error_reset() ; 00583 } else { 00584 fwhm_x = cpl_vector_get(cpl_bivector_get_x(iqe_res), 2) ; 00585 fwhm_y = cpl_vector_get(cpl_bivector_get_x(iqe_res), 3) ; 00586 cpl_bivector_delete(iqe_res) ; 00587 } 00588 00589 /* Determine the radii */ 00590 r = hawki_cal_illum_config.star_r ; 00591 if (r < 0) { 00592 if (fwhm_x>0 && fwhm_y>0) r = 5*(fwhm_x+fwhm_y)/2.0 ; 00593 else r = HAWKI_PHOT_STAR_RADIUS ; 00594 } 00595 r1 = hawki_cal_illum_config.bg_r1 ; 00596 r2 = hawki_cal_illum_config.bg_r2 ; 00597 if (r1 < 0) r1 = r + 10.0 ; 00598 if (r2 < 0) r2 = r1 + 20.0 ; 00599 00600 bg = irplib_strehl_ring_background(cur_ima, (int)pos_x[i], 00601 (int)pos_y[i], r1, r2, IRPLIB_BG_METHOD_MEDIAN) ; 00602 fl = irplib_strehl_disk_flux(cur_ima, (int)pos_x[i], (int)pos_y[i], 00603 r, bg) ; 00604 cpl_vector_set(flux, i, fl); 00605 if (fabs(fl)>1e-3) nok++ ; 00606 cpl_msg_info(__func__, "Flux for image %d: %g (r=%g, r1=%g, r2=%g)", 00607 i+1, fl, r, r1, r2) ; 00608 } 00609 *nvalid = nok ; 00610 return flux ; 00611 } 00612 00613 /*----------------------------------------------------------------------------*/ 00621 /*----------------------------------------------------------------------------*/ 00622 static cpl_bivector * hawki_cal_illum_find_pos( 00623 cpl_imagelist * ilist, 00624 cpl_bivector * offsets, 00625 int chip) 00626 { 00627 cpl_bivector * positions ; 00628 double * positions_x ; 00629 double * positions_y ; 00630 double * offsets_x ; 00631 double * offsets_y ; 00632 cpl_image * tmp_ima ; 00633 cpl_image * cur_ima ; 00634 cpl_image * filtered_ima ; 00635 cpl_matrix * kernel ; 00636 int nx, ny, ni ; 00637 int llx, lly, urx, ury, posx, posy, gap ; 00638 int i ; 00639 00640 /* Test entries */ 00641 if (ilist == NULL || offsets == NULL) return NULL ; 00642 if (chip < 1 || chip > HAWKI_NB_DETECTORS) return NULL ; 00643 ni = cpl_imagelist_get_size(ilist) ; 00644 gap = 147 ; 00645 00646 /* Create the positions bivector */ 00647 positions = cpl_bivector_new(ni) ; 00648 positions_x = cpl_bivector_get_x_data(positions) ; 00649 positions_y = cpl_bivector_get_y_data(positions) ; 00650 offsets_x = cpl_bivector_get_x_data(offsets) ; 00651 offsets_y = cpl_bivector_get_y_data(offsets) ; 00652 00653 /* Create the kernel */ 00654 kernel = cpl_matrix_new(3, 3) ; 00655 cpl_matrix_fill(kernel, 1.0) ; 00656 00657 /* Loop on all the images */ 00658 for (i=0 ; i<ni ; i++) { 00659 cur_ima = cpl_imagelist_get(ilist, i) ; 00660 nx = cpl_image_get_size_x(cur_ima) ; 00661 ny = cpl_image_get_size_y(cur_ima) ; 00662 00663 /* Define zone */ 00664 if (chip == 1) { 00665 llx = nx + gap/2.0 + offsets_x[i] - hawki_cal_illum_config.s_hx ; 00666 urx = nx + gap/2.0 + offsets_x[i] + hawki_cal_illum_config.s_hx ; 00667 lly = ny + gap/2.0 + offsets_y[i] - hawki_cal_illum_config.s_hy ; 00668 ury = ny + gap/2.0 + offsets_y[i] + hawki_cal_illum_config.s_hy ; 00669 } else if (chip == 2) { 00670 llx = offsets_x[i] - gap/2.0 - hawki_cal_illum_config.s_hx ; 00671 urx = offsets_x[i] - gap/2.0 + hawki_cal_illum_config.s_hx ; 00672 lly = ny + gap/2.0 + offsets_y[i] - hawki_cal_illum_config.s_hy ; 00673 ury = ny + gap/2.0 + offsets_y[i] + hawki_cal_illum_config.s_hy ; 00674 } else if (chip == 3) { 00675 llx = offsets_x[i] - gap/2.0 - hawki_cal_illum_config.s_hx ; 00676 urx = offsets_x[i] - gap/2.0 + hawki_cal_illum_config.s_hx ; 00677 lly = offsets_y[i] - gap/2.0 - hawki_cal_illum_config.s_hy ; 00678 ury = offsets_y[i] - gap/2.0 + hawki_cal_illum_config.s_hy ; 00679 } else if (chip == 4) { 00680 llx = nx + gap/2.0 + offsets_x[i] - hawki_cal_illum_config.s_hx ; 00681 urx = nx + gap/2.0 + offsets_x[i] + hawki_cal_illum_config.s_hx ; 00682 lly = offsets_y[i] - gap/2.0 - hawki_cal_illum_config.s_hy ; 00683 ury = offsets_y[i] - gap/2.0 + hawki_cal_illum_config.s_hy ; 00684 } 00685 00686 /* Test zone */ 00687 if (llx>urx || lly>ury || llx<1 || urx>nx || lly<1 || ury>ny) { 00688 cpl_msg_error(__func__, "Bad specified zone") ; 00689 cpl_bivector_delete(positions) ; 00690 cpl_matrix_delete(kernel) ; 00691 return NULL ; 00692 } 00693 00694 /* Extract */ 00695 tmp_ima = cpl_image_extract(cur_ima, llx, lly, urx, ury) ; 00696 filtered_ima =cpl_image_filter_median(tmp_ima, kernel) ; 00697 cpl_image_delete(tmp_ima) ; 00698 00699 /* Find the max */ 00700 cpl_image_get_maxpos(filtered_ima, &posx, &posy) ; 00701 positions_x[i] = llx + posx ; 00702 positions_y[i] = lly + posy ; 00703 cpl_image_delete(filtered_ima) ; 00704 cpl_msg_info(__func__, "Star found at pos %g, %g in image %d", 00705 positions_x[i], positions_y[i], i+1) ; 00706 } 00707 cpl_matrix_delete(kernel) ; 00708 00709 return positions ; 00710 } 00711 00712 /*----------------------------------------------------------------------------*/ 00721 /*----------------------------------------------------------------------------*/ 00722 static int hawki_cal_illum_save( 00723 const cpl_image ** illum, 00724 const cpl_table ** flux, 00725 cpl_parameterlist * parlist, 00726 cpl_frameset * set) 00727 { 00728 cpl_propertylist ** qclists ; 00729 cpl_propertylist * paflist ; 00730 cpl_propertylist * paflist_cur ; 00731 const cpl_frame * ref_frame ; 00732 cpl_propertylist * inputlist ; 00733 int ext_nb ; 00734 char * filename ; 00735 char sval[16] ; 00736 const char * recipe_name = "hawki_cal_illum" ; 00737 int i; 00738 00739 /* Get the reference frame */ 00740 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ; 00741 00742 /* Create the QC lists */ 00743 qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 00744 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 00745 qclists[i] = cpl_propertylist_new() ; 00746 cpl_propertylist_append_double(qclists[i], "ESO QC DATANCOM", 00747 cpl_frameset_get_size(set)) ; 00748 00749 /* Propagate some keywords from input raw frame extensions */ 00750 ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), i+1); 00751 inputlist = cpl_propertylist_load_regexp( 00752 cpl_frame_get_filename(ref_frame), ext_nb, 00753 HAWKI_HEADER_EXT_FORWARD, 0) ; 00754 cpl_propertylist_copy_property_regexp(qclists[i], inputlist, "", 0) ; 00755 cpl_propertylist_delete(inputlist) ; 00756 } 00757 00758 /* Write the image */ 00759 hawki_images_save(set, 00760 parlist, 00761 set, 00762 (const cpl_image **)illum, 00763 recipe_name, 00764 HAWKI_CALPRO_ILLUM, 00765 HAWKI_PROTYPE_ILLUM, 00766 NULL, 00767 (const cpl_propertylist**)qclists, 00768 "hawki_cal_illum.fits") ; 00769 /* To handle cases where a chip is missing */ 00770 if (cpl_error_get_code() == CPL_ERROR_NULL_INPUT) cpl_error_reset() ; 00771 00772 /* Write the flux table */ 00773 hawki_tables_save(set, 00774 parlist, 00775 set, 00776 (const cpl_table **)flux, 00777 recipe_name, 00778 HAWKI_CALPRO_ILLUM_PHOTOM, 00779 HAWKI_PROTYPE_ILLUM_PHOTOM, 00780 NULL, 00781 (const cpl_propertylist**)qclists, 00782 "hawki_cal_illum_photom.fits") ; 00783 /* To handle cases where a chip is missing */ 00784 if (cpl_error_get_code() == CPL_ERROR_NULL_INPUT) cpl_error_reset() ; 00785 00786 /* Remove the keywords for the FITS extensions */ 00787 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 00788 cpl_propertylist_erase_regexp(qclists[i], HAWKI_HEADER_EXT_FORWARD, 0) ; 00789 } 00790 00791 /* Get FITS header from reference file */ 00792 paflist = cpl_propertylist_load_regexp(cpl_frame_get_filename(ref_frame), 00793 0, HAWKI_HEADER_PRI_TOPAF, 0) ; 00794 00795 /* Add the PRO REC1 ID in the paf files */ 00796 cpl_propertylist_prepend_string(paflist, "PRO REC1 ID", recipe_name) ; 00797 00798 /* Add the PRO CATG keyword. This is a workaround, since the current 00799 * implemented behaviour is not to have PAF files associated to products. 00800 * All this will be removed with the FITS2PAF utility in esorex 00801 */ 00802 cpl_propertylist_prepend_string(paflist, "PRO CATG", HAWKI_CALPRO_ILLUM); 00803 00804 /* Write the extension PAF files */ 00805 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 00806 /* Duplicate paflist */ 00807 paflist_cur = cpl_propertylist_duplicate(paflist) ; 00808 00809 /* Add the EXTNAME keyword in the PAF */ 00810 sprintf(sval, "CHIP%d.INT1", i+1) ; 00811 cpl_propertylist_prepend_string(paflist_cur, "EXTNAME", sval) ; 00812 00813 /* Get FITS header from reference file extension */ 00814 ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), i+1); 00815 inputlist = cpl_propertylist_load_regexp( 00816 cpl_frame_get_filename(ref_frame), ext_nb, 00817 HAWKI_HEADER_EXT_TOPAF, 0) ; 00818 cpl_propertylist_copy_property_regexp(paflist_cur, inputlist, "", 0) ; 00819 cpl_propertylist_delete(inputlist) ; 00820 00821 /* End of Workaround */ 00822 00823 /* Copy the QC in paflist */ 00824 cpl_propertylist_copy_property_regexp(paflist_cur, qclists[i], "", 0) ; 00825 00826 /* Paf file name */ 00827 filename = cpl_sprintf("%s_%02d.paf", recipe_name, i+1) ; 00828 00829 /* Save the PAF file */ 00830 cpl_dfs_save_paf("HAWKI", 00831 recipe_name, 00832 paflist_cur, 00833 filename) ; 00834 cpl_free(filename) ; 00835 cpl_propertylist_delete(paflist_cur) ; 00836 } 00837 00838 /* Free and return */ 00839 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 00840 cpl_propertylist_delete(qclists[i]) ; 00841 } 00842 cpl_free(qclists) ; 00843 cpl_propertylist_delete(paflist) ; 00844 return 0; 00845 } 00846