|
HAWKI Pipeline Reference Manual 1.8.2
|
00001 /* $Id: hawki_cal_distortion.c,v 1.12 2010/11/04 11:40:06 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/11/04 11:40:06 $ 00024 * $Revision: 1.12 $ 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 00042 #include "hawki_alloc.h" 00043 #include "hawki_utils.h" 00044 #include "hawki_calib.h" 00045 #include "hawki_distortion.h" 00046 #include "hawki_load.h" 00047 #include "hawki_save.h" 00048 #include "hawki_pfits.h" 00049 #include "hawki_dfs.h" 00050 #include "irplib_cat.h" 00051 #include "irplib_stdstar.h" 00052 #include "irplib_match_cats.h" 00053 #include "hawki_match_cats.h" 00054 00055 /*----------------------------------------------------------------------------- 00056 Functions prototypes 00057 -----------------------------------------------------------------------------*/ 00058 00059 static int hawki_cal_distortion_create(cpl_plugin *) ; 00060 static int hawki_cal_distortion_exec(cpl_plugin *) ; 00061 static int hawki_cal_distortion_destroy(cpl_plugin *) ; 00062 static int hawki_cal_distortion(cpl_parameterlist * parlist, 00063 cpl_frameset * frameset); 00064 00065 00066 static int hawki_cal_distortion_get_apertures_from_raw_distor 00067 (cpl_frameset * raw_target, 00068 const cpl_frame * flat, 00069 const cpl_frame * dark, 00070 const cpl_frame * bpm, 00071 cpl_image ** master_sky, 00072 double sigma_det, 00073 cpl_apertures *** apertures); 00074 00075 static int hawki_cal_distortion_load_master_calib 00076 (const cpl_frame * flat, 00077 const cpl_frame * dark, 00078 const cpl_frame * bpm, 00079 cpl_imagelist ** flat_images, 00080 cpl_imagelist ** dark_images, 00081 cpl_imagelist ** bpm_images); 00082 00083 static cpl_image ** hawki_cal_distortion_get_master_sky 00084 (cpl_frameset * raw_target, 00085 const cpl_frame * flat, 00086 const cpl_frame * dark, 00087 const cpl_frame * bpm); 00088 00089 static int hawki_cal_distortion_subtract_sky 00090 (cpl_imagelist * distor_corrected, 00091 cpl_image * master_sky); 00092 00093 static hawki_distortion ** hawki_cal_distortion_compute_dist_solution 00094 (cpl_apertures *** apertures, 00095 int nframes, 00096 cpl_bivector * offsets, 00097 int grid_points, 00098 int * nmatched_pairs, 00099 double * rms, 00100 hawki_distortion ** distortion_guess); 00101 00102 static cpl_apertures * hawki_cal_distortion_get_image_apertures 00103 (cpl_image * image, 00104 double sigma_det); 00105 00106 static int hawki_cal_distortion_fill_obj_pos 00107 (cpl_table * objects_positions, 00108 cpl_apertures * apertures); 00109 00110 static int hawki_cal_distortion_add_offset_to_positions 00111 (cpl_table ** objects_positions, 00112 cpl_bivector * offsets); 00113 00114 static int hawki_cal_distortion_fit_first_order_solution 00115 (hawki_distortion * distortion, 00116 cpl_polynomial * fit2d_x, 00117 cpl_polynomial * fit2d_y); 00118 00119 static cpl_propertylist ** hawki_cal_distortion_qc 00120 (hawki_distortion ** distortion, 00121 int * nmatched_pairs, 00122 double * rms); 00123 00124 static int hawki_cal_distortion_save 00125 (hawki_distortion ** distortion, 00126 cpl_parameterlist * parlist, 00127 cpl_propertylist ** qclists, 00128 cpl_frameset * recipe_set); 00129 00130 static int hawki_cal_distortion_retrieve_input_param 00131 (cpl_parameterlist * parlist); 00132 00133 00134 /*----------------------------------------------------------------------------- 00135 Static variables 00136 -----------------------------------------------------------------------------*/ 00137 00138 static struct 00139 { 00140 /* Inputs */ 00141 double sigma_det; 00142 int grid_points; 00143 int borders; 00144 int subtract_linear; 00145 } hawki_cal_distortion_config; 00146 00147 static char hawki_cal_distortion_description[] = 00148 "hawki_cal_distortion -- HAWK-I distortion and astrometry autocalibration.\n\n" 00149 "The input files must be tagged:\n" 00150 "distortion_field.fits "HAWKI_CAL_DISTOR_RAW"\n" 00151 "sky_distortion.fits "HAWKI_CAL_DISTOR_SKY_RAW"\n" 00152 "flat-file.fits "HAWKI_CALPRO_FLAT" (optional)\n" 00153 "dark-file.fits "HAWKI_CALPRO_DARK" (optional)\n" 00154 "bpm-file.fits "HAWKI_CALPRO_BPM" (optional)\n\n" 00155 "The recipe creates as an output:\n" 00156 "hawki_cal_distortion_distx.fits ("HAWKI_CALPRO_DISTORTION_X") \n" 00157 "hawki_cal_distortion_disty.fits ("HAWKI_CALPRO_DISTORTION_Y") \n\n" 00158 "The recipe performs the following steps:\n" 00159 "-Basic calibration of astrometry fields\n" 00160 "-Autocalibration of distortion, using method in A&A 454,1029 (2006)\n\n" 00161 "Return code:\n" 00162 "esorex exits with an error code of 0 if the recipe completes successfully\n" 00163 "or 1 otherwise"; 00164 00165 /*----------------------------------------------------------------------------- 00166 Functions code 00167 -----------------------------------------------------------------------------*/ 00168 00169 /*----------------------------------------------------------------------------*/ 00177 /*----------------------------------------------------------------------------*/ 00178 int cpl_plugin_get_info(cpl_pluginlist * list) 00179 { 00180 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ; 00181 cpl_plugin * plugin = &recipe->interface ; 00182 00183 cpl_plugin_init(plugin, 00184 CPL_PLUGIN_API, 00185 HAWKI_BINARY_VERSION, 00186 CPL_PLUGIN_TYPE_RECIPE, 00187 "hawki_cal_distortion", 00188 "Distortion autocalibration", 00189 hawki_cal_distortion_description, 00190 "Cesar Enrique Garcia Dabo", 00191 PACKAGE_BUGREPORT, 00192 hawki_get_license(), 00193 hawki_cal_distortion_create, 00194 hawki_cal_distortion_exec, 00195 hawki_cal_distortion_destroy); 00196 00197 cpl_pluginlist_append(list, plugin) ; 00198 00199 return 0; 00200 } 00201 00202 /*----------------------------------------------------------------------------*/ 00211 /*----------------------------------------------------------------------------*/ 00212 static int hawki_cal_distortion_create(cpl_plugin * plugin) 00213 { 00214 cpl_recipe * recipe ; 00215 cpl_parameter * p ; 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 /* Create the parameters list in the cpl_recipe object */ 00223 recipe->parameters = cpl_parameterlist_new() ; 00224 00225 /* Fill the parameters list */ 00226 /* --sigma_det */ 00227 p = cpl_parameter_new_value("hawki.hawki_cal_distortion.sigma_det", 00228 CPL_TYPE_DOUBLE, "detection level", 00229 "hawki.hawki_cal_distortion", 6.) ; 00230 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sigma_det") ; 00231 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00232 cpl_parameterlist_append(recipe->parameters, p) ; 00233 00234 /* --grid_points */ 00235 p = cpl_parameter_new_value("hawki.hawki_cal_distortion.grid_points", 00236 CPL_TYPE_INT, 00237 "number of points in distortion grid", 00238 "hawki.hawki_cal_distortion", 9) ; 00239 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "grid_points") ; 00240 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00241 cpl_parameterlist_append(recipe->parameters, p) ; 00242 00243 /* --borders */ 00244 p = cpl_parameter_new_value("hawki.hawki_cal_distortion.borders", 00245 CPL_TYPE_INT, 00246 "number of pixels to trim at the borders", 00247 "hawki.hawki_cal_distortion", 6) ; 00248 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "borders") ; 00249 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00250 cpl_parameterlist_append(recipe->parameters, p) ; 00251 00252 /* --subtract_linear */ 00253 p = cpl_parameter_new_value("hawki.hawki_cal_distortion.subtract_linear", 00254 CPL_TYPE_BOOL, 00255 "Subtract a linear term to the solution", 00256 "hawki.hawki_cal_distortion", TRUE) ; 00257 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "subtract_linear") ; 00258 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ; 00259 cpl_parameterlist_append(recipe->parameters, p) ; 00260 00261 /* Return */ 00262 return 0; 00263 } 00264 00265 /*----------------------------------------------------------------------------*/ 00271 /*----------------------------------------------------------------------------*/ 00272 static int hawki_cal_distortion_exec(cpl_plugin * plugin) 00273 { 00274 cpl_recipe * recipe ; 00275 00276 /* Get the recipe out of the plugin */ 00277 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00278 recipe = (cpl_recipe *)plugin ; 00279 else return -1 ; 00280 00281 /* Issue a banner */ 00282 hawki_print_banner(); 00283 00284 return hawki_cal_distortion(recipe->parameters, recipe->frames) ; 00285 } 00286 00287 /*----------------------------------------------------------------------------*/ 00293 /*----------------------------------------------------------------------------*/ 00294 static int hawki_cal_distortion_destroy(cpl_plugin * plugin) 00295 { 00296 cpl_recipe * recipe ; 00297 00298 /* Get the recipe out of the plugin */ 00299 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00300 recipe = (cpl_recipe *)plugin ; 00301 else return -1 ; 00302 00303 cpl_parameterlist_delete(recipe->parameters) ; 00304 return 0 ; 00305 } 00306 00307 /*----------------------------------------------------------------------------*/ 00313 /*----------------------------------------------------------------------------*/ 00314 static int hawki_cal_distortion(cpl_parameterlist * parlist, 00315 cpl_frameset * frameset) 00316 { 00317 const cpl_frame * flat = NULL; 00318 const cpl_frame * dark = NULL; 00319 const cpl_frame * bpm = NULL; 00320 cpl_frameset * distorframes = NULL; 00321 cpl_frameset * skyframes = NULL; 00322 const cpl_frame * distorxguess = NULL; 00323 const cpl_frame * distoryguess = NULL; 00324 hawki_distortion ** distortionguess = NULL; 00325 hawki_distortion ** distortion = NULL; 00326 cpl_propertylist ** qclists = NULL; 00327 cpl_image ** master_sky = NULL; 00328 cpl_bivector * nominal_offsets = NULL; 00329 cpl_apertures ** apertures[HAWKI_NB_DETECTORS]; 00330 int nmatched_pairs[HAWKI_NB_DETECTORS]; 00331 double rms[HAWKI_NB_DETECTORS]; 00332 int idet; 00333 int ioff; 00334 int iframe; 00335 int nframes; 00336 00337 00338 /* Retrieve input parameters */ 00339 if(hawki_cal_distortion_retrieve_input_param(parlist)) 00340 { 00341 cpl_msg_error(__func__, "Wrong parameters"); 00342 return -1; 00343 } 00344 00345 /* Identify the RAW and CALIB frames in the input frameset */ 00346 if (hawki_dfs_set_groups(frameset)) { 00347 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00348 return -1 ; 00349 } 00350 00351 /* Retrieve calibration data */ 00352 cpl_msg_info(__func__, "Identifying calibration data"); 00353 flat = cpl_frameset_find_const(frameset, HAWKI_CALPRO_FLAT); 00354 dark = cpl_frameset_find_const(frameset, HAWKI_CALPRO_DARK); 00355 bpm = cpl_frameset_find_const(frameset, HAWKI_CALPRO_BPM); 00356 00357 /* Retrieve raw frames */ 00358 cpl_msg_info(__func__, "Identifying distortion and sky data"); 00359 distorframes = hawki_extract_frameset(frameset, HAWKI_CAL_DISTOR_RAW) ; 00360 if (distorframes == NULL) 00361 { 00362 cpl_msg_error(__func__, "Distortion images have to be provided (%s)", 00363 HAWKI_CAL_DISTOR_RAW); 00364 return -1 ; 00365 } 00366 /* Retrieve sky frames */ 00367 skyframes = hawki_extract_frameset(frameset, HAWKI_CAL_DISTOR_SKY_RAW) ; 00368 if (skyframes == NULL) 00369 { 00370 cpl_msg_error(__func__, "Sky images have to be provided (%s)", 00371 HAWKI_CAL_DISTOR_SKY_RAW); 00372 cpl_frameset_delete(distorframes); 00373 return -1 ; 00374 } 00375 /* Retrieve the distortion first guess (if provided) */ 00376 distorxguess = cpl_frameset_find_const(frameset, HAWKI_CALPRO_DISTORTION_X); 00377 distoryguess = cpl_frameset_find_const(frameset, HAWKI_CALPRO_DISTORTION_Y); 00378 if(distorxguess != NULL && distoryguess != NULL) 00379 { 00380 //distortionguess = hawki_distortion_load(distorxtguess) 00381 } 00382 00383 /* Get the master sky frame */ 00384 cpl_msg_info(__func__, "Computing the master sky image"); 00385 master_sky = hawki_cal_distortion_get_master_sky(skyframes, flat, dark, bpm); 00386 if(master_sky == NULL) 00387 { 00388 cpl_msg_error(__func__, "Cannot get master sky image") ; 00389 cpl_frameset_delete(distorframes); 00390 cpl_frameset_delete(skyframes); 00391 return -1; 00392 } 00393 00394 /* Aperture detection, basic reduction and sky subtraction of distortion images */ 00395 cpl_msg_info(__func__, "Getting objects from distortion images"); 00396 if(hawki_cal_distortion_get_apertures_from_raw_distor 00397 (distorframes, flat, dark, bpm, master_sky, 00398 hawki_cal_distortion_config.sigma_det, apertures) == -1) 00399 { 00400 cpl_msg_error(__func__, 00401 "Cannot get objects from distortion images"); 00402 for(idet = 0; idet < HAWKI_NB_DETECTORS ; ++idet) 00403 cpl_image_delete(master_sky[idet]); 00404 cpl_free(master_sky); 00405 cpl_frameset_delete(distorframes); 00406 cpl_frameset_delete(skyframes); 00407 return -1 ; 00408 } 00409 for(idet = 0; idet < HAWKI_NB_DETECTORS ; ++idet) 00410 cpl_image_delete(master_sky[idet]); 00411 cpl_free(master_sky); 00412 00413 /* Get the nominal offsets from the header */ 00414 cpl_msg_info(__func__,"Getting the nominal offsets"); 00415 nominal_offsets = hawki_get_header_tel_offsets(distorframes); 00416 if (nominal_offsets == NULL) 00417 { 00418 cpl_msg_error(__func__, "Cannot load the header offsets") ; 00419 cpl_frameset_delete(distorframes); 00420 cpl_frameset_delete(skyframes); 00421 return -1; 00422 } 00423 00424 /* Get the oposite offsets. This is to change from 00425 * telescope convention to cpl convention */ 00426 cpl_vector_multiply_scalar(cpl_bivector_get_x(nominal_offsets), -1.0); 00427 cpl_vector_multiply_scalar(cpl_bivector_get_y(nominal_offsets), -1.0); 00428 00429 /* Print the header offsets */ 00430 cpl_msg_indent_more(); 00431 for (ioff=0 ; ioff<cpl_bivector_get_size(nominal_offsets) ; ioff++) 00432 { 00433 cpl_msg_info(__func__, "Telescope offsets (Frame %d): %g %g", ioff+1, 00434 cpl_bivector_get_x_data(nominal_offsets)[ioff], 00435 cpl_bivector_get_y_data(nominal_offsets)[ioff]); 00436 } 00437 cpl_msg_indent_less(); 00438 00439 /* Get the distortion solution, the real stuff */ 00440 cpl_msg_info(__func__, "Computing the distortion"); 00441 nframes = cpl_frameset_get_size(distorframes); 00442 distortion = hawki_cal_distortion_compute_dist_solution 00443 (apertures, nframes, nominal_offsets, 00444 hawki_cal_distortion_config.grid_points, 00445 nmatched_pairs, rms, 00446 distortionguess); 00447 cpl_bivector_delete(nominal_offsets); 00448 if(distortion == NULL) 00449 { 00450 cpl_frameset_delete(distorframes); 00451 cpl_frameset_delete(skyframes); 00452 return -1; 00453 } 00454 00455 /* Get some QC */ 00456 qclists = hawki_cal_distortion_qc(distortion, nmatched_pairs, rms); 00457 00458 /* Save the products */ 00459 cpl_msg_info(__func__,"Saving products"); 00460 if(hawki_cal_distortion_save(distortion, 00461 parlist, qclists, frameset) == -1) 00462 { 00463 cpl_msg_error(__func__,"Could not save products"); 00464 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00465 cpl_propertylist_delete(qclists[idet]); 00466 cpl_free(qclists); 00467 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00468 hawki_distortion_delete(distortion[idet]); 00469 cpl_free(distortion); 00470 cpl_frameset_delete(distorframes); 00471 cpl_frameset_delete(skyframes); 00472 return -1; 00473 } 00474 00475 /* Free and return */ 00476 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00477 cpl_propertylist_delete(qclists[idet]); 00478 cpl_free(qclists); 00479 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00480 hawki_distortion_delete(distortion[idet]); 00481 cpl_free(distortion); 00482 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00483 { 00484 for(iframe = 0 ; iframe < nframes; iframe++) 00485 cpl_apertures_delete(apertures[idet][iframe]); 00486 cpl_free(apertures[idet]); 00487 } 00488 cpl_frameset_delete(distorframes); 00489 cpl_frameset_delete(skyframes); 00490 00491 00492 /* Return */ 00493 if (cpl_error_get_code()) 00494 { 00495 cpl_msg_error(__func__, 00496 "HAWK-I pipeline could not recover from previous errors"); 00497 return -1 ; 00498 } 00499 else return 0 ; 00500 } 00501 00502 /*----------------------------------------------------------------------------*/ 00513 /*----------------------------------------------------------------------------*/ 00514 static int hawki_cal_distortion_load_master_calib 00515 (const cpl_frame * flat, 00516 const cpl_frame * dark, 00517 const cpl_frame * bpm, 00518 cpl_imagelist ** flat_images, 00519 cpl_imagelist ** dark_images, 00520 cpl_imagelist ** bpm_images) 00521 { 00522 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00523 00524 /* Initializing the pointers */ 00525 *flat_images = NULL; 00526 *dark_images = NULL; 00527 *bpm_images = NULL; 00528 00529 /* Loading the calibration files */ 00530 cpl_msg_info(__func__, "Loading the calibration data") ; 00531 if(flat != NULL) 00532 { 00533 *flat_images = hawki_load_frame(flat, CPL_TYPE_FLOAT); 00534 if(flat_images == NULL) 00535 { 00536 cpl_msg_error(__func__, "Error reading flat") ; 00537 return -1; 00538 } 00539 } 00540 if(dark != NULL) 00541 { 00542 *dark_images = hawki_load_frame(dark, CPL_TYPE_FLOAT); 00543 if(dark_images == NULL) 00544 { 00545 cpl_msg_error(__func__, "Error reading dark") ; 00546 cpl_imagelist_delete(*flat_images); 00547 return -1; 00548 } 00549 } 00550 if(bpm != NULL) 00551 { 00552 *bpm_images = hawki_load_frame(bpm, CPL_TYPE_INT); 00553 if(bpm_images == NULL) 00554 { 00555 cpl_msg_error(__func__, "Error reading bpm") ; 00556 cpl_imagelist_delete(*flat_images); 00557 cpl_imagelist_delete(*dark_images); 00558 return -1; 00559 } 00560 } 00561 00562 if(!cpl_errorstate_is_equal(error_prevstate )) 00563 { 00564 cpl_msg_error(__func__, "A problem happened loading calibration"); 00565 cpl_imagelist_delete(*flat_images); 00566 cpl_imagelist_delete(*dark_images); 00567 cpl_imagelist_delete(*bpm_images); 00568 return -1; 00569 } 00570 return 0; 00571 } 00572 00573 /*----------------------------------------------------------------------------*/ 00583 /*----------------------------------------------------------------------------*/ 00584 static int hawki_cal_distortion_get_apertures_from_raw_distor 00585 (cpl_frameset * raw_distor, 00586 const cpl_frame * flat, 00587 const cpl_frame * dark, 00588 const cpl_frame * bpm, 00589 cpl_image ** master_sky, 00590 double sigma_det, 00591 cpl_apertures *** apertures) 00592 { 00593 cpl_imagelist * flat_images; 00594 cpl_imagelist * dark_images; 00595 cpl_imagelist * bpm_images; 00596 cpl_propertylist * plist; 00597 00598 double science_dit; 00599 int iframe; 00600 int nframes; 00601 int idet; 00602 00603 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00604 00605 /* Indentation */ 00606 cpl_msg_indent_more(); 00607 00608 /* Loading calibrations */ 00609 hawki_cal_distortion_load_master_calib 00610 (flat, dark, bpm, &flat_images, &dark_images, &bpm_images); 00611 00612 /* Multiply the dark image by the science exposure time */ 00613 if(dark != NULL) 00614 { 00615 if ((plist=cpl_propertylist_load 00616 (cpl_frame_get_filename 00617 (cpl_frameset_get_first_const(raw_distor)), 0)) == NULL) 00618 { 00619 cpl_msg_error(__func__, "Cannot get header from frame"); 00620 cpl_imagelist_delete(flat_images); 00621 cpl_imagelist_delete(dark_images); 00622 return -1; 00623 } 00624 science_dit = hawki_pfits_get_dit(plist); 00625 cpl_imagelist_multiply_scalar(dark_images, science_dit); 00626 cpl_propertylist_delete(plist); 00627 } 00628 00629 /* Loop on detectors */ 00630 nframes = cpl_frameset_get_size(raw_distor); 00631 for(idet = 0; idet < HAWKI_NB_DETECTORS ; ++idet) 00632 { 00633 cpl_imagelist * distor_serie; 00634 cpl_imagelist * distor_serie_trimmed; 00635 00636 cpl_msg_info(__func__, "Working on detector %d", idet + 1); 00637 cpl_msg_indent_more(); 00638 00639 /* Loading the distortion images for one detector */ 00640 cpl_msg_info(__func__, "Loading distortion images"); 00641 distor_serie = hawki_load_detector(raw_distor, idet + 1, CPL_TYPE_FLOAT); 00642 if(distor_serie== NULL) 00643 { 00644 cpl_msg_error(__func__, "Error reading distortion images"); 00645 return -1; 00646 } 00647 00648 /* Applying the calibrations */ 00649 cpl_msg_info(__func__, "Applying basic calibration") ; 00650 cpl_msg_indent_more(); 00651 if (hawki_flat_dark_bpm_detector_calib 00652 (distor_serie, 00653 cpl_imagelist_get(flat_images, idet), 00654 cpl_imagelist_get(dark_images, idet), 00655 cpl_imagelist_get(bpm_images, idet)) == -1) 00656 { 00657 cpl_msg_error(__func__, "Cannot calibrate frame") ; 00658 cpl_imagelist_delete(flat_images); 00659 cpl_imagelist_delete(dark_images); 00660 cpl_imagelist_delete(bpm_images); 00661 cpl_imagelist_delete(distor_serie); 00662 cpl_msg_indent_less() ; 00663 return -1; 00664 } 00665 cpl_msg_indent_less(); 00666 00667 /* Discard the pixels on the sides */ 00668 if (hawki_cal_distortion_config.borders > 0) 00669 { 00670 distor_serie_trimmed = hawki_trim_detector_calib(distor_serie, 00671 hawki_cal_distortion_config.borders); 00672 cpl_imagelist_delete(distor_serie); 00673 } 00674 else 00675 distor_serie_trimmed = distor_serie; 00676 00677 /* Subtract sky */ 00678 cpl_msg_info(__func__, "Subtracting master sky") ; 00679 if(hawki_cal_distortion_subtract_sky(distor_serie_trimmed, master_sky[idet]) == -1) 00680 { 00681 cpl_msg_error(__func__, "Cannot subtract the sky") ; 00682 cpl_imagelist_delete(flat_images); 00683 cpl_imagelist_delete(dark_images); 00684 cpl_imagelist_delete(bpm_images); 00685 cpl_imagelist_delete(distor_serie_trimmed); 00686 return -1; 00687 } 00688 00689 /* Creating apertures */ 00690 apertures[idet] = cpl_malloc(sizeof(*(apertures[idet])) * nframes); 00691 for(iframe = 0 ; iframe < nframes; iframe++) 00692 { 00693 cpl_image * this_image = cpl_imagelist_get(distor_serie_trimmed, iframe); 00694 cpl_msg_info(__func__,"Working with distortion image %d", iframe+1); 00695 cpl_msg_indent_more(); 00696 apertures[idet][iframe] = 00697 hawki_cal_distortion_get_image_apertures(this_image, sigma_det); 00698 cpl_msg_indent_less(); 00699 } 00700 00701 /* Delete the list of images */ 00702 cpl_imagelist_delete(distor_serie_trimmed); 00703 cpl_msg_indent_less(); 00704 } 00705 cpl_imagelist_delete(flat_images); 00706 cpl_imagelist_delete(dark_images); 00707 cpl_imagelist_delete(bpm_images); 00708 00709 00710 if(!cpl_errorstate_is_equal(error_prevstate )) 00711 { 00712 cpl_msg_error(__func__, "A problem happened with basic calibration"); 00713 return -1 ; 00714 } 00715 return 0; 00716 } 00717 00718 static cpl_image ** hawki_cal_distortion_get_master_sky 00719 (cpl_frameset * raw_sky_frames, 00720 const cpl_frame * flat, 00721 const cpl_frame * dark, 00722 const cpl_frame * bpm) 00723 { 00724 cpl_propertylist * plist; 00725 double science_dit; 00726 int idet; 00727 int jdet; 00728 cpl_imagelist * flat_images; 00729 cpl_imagelist * dark_images; 00730 cpl_imagelist * bpm_images; 00731 cpl_image ** bkg_images = NULL; 00732 00733 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00734 00735 /* Indentation */ 00736 cpl_msg_indent_more(); 00737 00738 /* Reading calibrations */ 00739 hawki_cal_distortion_load_master_calib 00740 (flat, dark, bpm, &flat_images, &dark_images, &bpm_images); 00741 00742 /* Multiply the dark image by the science exposure time */ 00743 if(dark != NULL) 00744 { 00745 if ((plist=cpl_propertylist_load 00746 (cpl_frame_get_filename 00747 (cpl_frameset_get_first_const(raw_sky_frames)), 0)) == NULL) 00748 { 00749 cpl_msg_error(__func__, "Cannot get header from frame"); 00750 cpl_imagelist_delete(flat_images); 00751 cpl_imagelist_delete(dark_images); 00752 cpl_imagelist_delete(bpm_images); 00753 return NULL; 00754 } 00755 science_dit = hawki_pfits_get_dit(plist); 00756 cpl_imagelist_multiply_scalar(dark_images, science_dit); 00757 cpl_propertylist_delete(plist); 00758 } 00759 00760 /* Compute the sky median */ 00761 bkg_images = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(*bkg_images)); 00762 for(idet = 0; idet < HAWKI_NB_DETECTORS ; ++idet) 00763 { 00764 cpl_imagelist * sky_serie; 00765 cpl_imagelist * sky_serie_trimmed; 00766 00767 /* Loading the sky images for one detector */ 00768 sky_serie = hawki_load_detector(raw_sky_frames, idet + 1, CPL_TYPE_FLOAT); 00769 if(sky_serie== NULL) 00770 { 00771 cpl_msg_error(__func__, "Error reading object image") ; 00772 return NULL; 00773 } 00774 00775 /* Applying the calibrations */ 00776 cpl_msg_info(__func__, "Working on detector %d", idet + 1); 00777 cpl_msg_indent_more(); 00778 if (hawki_flat_dark_bpm_detector_calib 00779 (sky_serie, 00780 cpl_imagelist_get(flat_images, idet), 00781 cpl_imagelist_get(dark_images, idet), 00782 cpl_imagelist_get(bpm_images, idet)) == -1) 00783 { 00784 cpl_msg_error(__func__, "Cannot calibrate frame") ; 00785 cpl_imagelist_delete(flat_images); 00786 cpl_imagelist_delete(dark_images); 00787 cpl_imagelist_delete(bpm_images); 00788 cpl_imagelist_delete(sky_serie); 00789 for(jdet = 0; jdet < idet; ++jdet) 00790 cpl_image_delete(bkg_images[jdet]); 00791 cpl_free(bkg_images); 00792 cpl_msg_indent_less() ; 00793 return NULL; 00794 } 00795 00796 /* Discard the pixels on the sides */ 00797 if (hawki_cal_distortion_config.borders > 0) 00798 { 00799 sky_serie_trimmed = hawki_trim_detector_calib(sky_serie, 00800 hawki_cal_distortion_config.borders); 00801 cpl_imagelist_delete(sky_serie); 00802 } 00803 else 00804 sky_serie_trimmed = sky_serie; 00805 00806 /* Averaging */ 00807 if ((bkg_images[idet] = 00808 cpl_imagelist_collapse_median_create(sky_serie_trimmed)) == NULL) 00809 { 00810 cpl_msg_error(__func__, "Cannot compute the median of obj images"); 00811 cpl_imagelist_delete(flat_images); 00812 cpl_imagelist_delete(dark_images); 00813 cpl_imagelist_delete(bpm_images); 00814 cpl_imagelist_delete(sky_serie_trimmed); 00815 for(jdet = 0; jdet < idet; ++jdet) 00816 cpl_image_delete(bkg_images[jdet]); 00817 cpl_free(bkg_images); 00818 cpl_msg_indent_less(); 00819 return NULL; 00820 } 00821 cpl_imagelist_delete(sky_serie_trimmed); 00822 cpl_msg_indent_less(); 00823 } 00824 00825 /* Subtract the median of the frame */ 00826 for(idet = 0; idet < HAWKI_NB_DETECTORS ; ++idet) 00827 cpl_image_subtract_scalar(bkg_images[idet], 00828 cpl_image_get_median(bkg_images[idet])); 00829 00830 /* Cleaning up */ 00831 cpl_msg_indent_less(); 00832 cpl_imagelist_delete(flat_images); 00833 cpl_imagelist_delete(dark_images); 00834 cpl_imagelist_delete(bpm_images); 00835 00836 if(!cpl_errorstate_is_equal(error_prevstate )) 00837 { 00838 cpl_msg_error(__func__, "A problem happened with basic calibration"); 00839 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet) 00840 cpl_image_delete(bkg_images[idet]); 00841 cpl_free(bkg_images); 00842 return NULL ; 00843 } 00844 return bkg_images; 00845 } 00846 00847 static int hawki_cal_distortion_subtract_sky 00848 (cpl_imagelist * distor_corrected, 00849 cpl_image * master_sky) 00850 { 00851 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00852 00853 /* Subtract the background to each object frame */ 00854 int idist, ndistor; 00855 ndistor = cpl_imagelist_get_size(distor_corrected); 00856 for(idist = 0; idist < ndistor; ++idist) 00857 { 00858 cpl_image * target_image = 00859 cpl_imagelist_get(distor_corrected, idist); 00860 /* First subtract the median of the image */ 00861 cpl_image_subtract_scalar 00862 (target_image, cpl_image_get_median(target_image)); 00863 00864 if (cpl_image_subtract 00865 (target_image, master_sky)!=CPL_ERROR_NONE) 00866 { 00867 cpl_msg_error(cpl_func,"Cannot apply the bkg to the images"); 00868 return -1 ; 00869 } 00870 } 00871 00872 /* Free and return */ 00873 if(!cpl_errorstate_is_equal(error_prevstate )) 00874 { 00875 cpl_msg_error(__func__, "A problem happened with sky subtraction"); 00876 return -1; 00877 } 00878 return 0; 00879 } 00880 00881 00882 /*----------------------------------------------------------------------------*/ 00892 /*----------------------------------------------------------------------------*/ 00893 static hawki_distortion ** hawki_cal_distortion_compute_dist_solution 00894 (cpl_apertures *** apertures, 00895 int nframes, 00896 cpl_bivector * offsets, 00897 int grid_points, 00898 int * nmatched_pairs, 00899 double * rms, 00900 hawki_distortion ** distortion_guess) 00901 { 00902 int idet; 00903 hawki_distortion ** distortion = NULL; 00904 00905 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00906 00907 /* Allocate the distortion */ 00908 distortion = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(*distortion)); 00909 00910 /* Loop on the detectors */ 00911 cpl_msg_indent_more(); 00912 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00913 { 00914 cpl_table ** obj_pos; 00915 cpl_table ** obj_pos_offset; 00916 int iframe; 00917 cpl_table * matches; 00918 hawki_distortion * dist_guess; 00919 cpl_polynomial * fit2d_x = NULL; 00920 cpl_polynomial * fit2d_y = NULL; 00921 00922 00923 cpl_msg_info(__func__, "Working on detector %d", idet+1); 00924 cpl_msg_indent_more(); 00925 00926 /* Initialize the objects positions */ 00927 obj_pos = 00928 cpl_malloc(sizeof(*obj_pos) * nframes); 00929 obj_pos_offset = 00930 cpl_malloc(sizeof(*obj_pos_offset) * nframes); 00931 for(iframe = 0; iframe < nframes; ++iframe) 00932 { 00933 obj_pos[iframe] = cpl_table_new(0); 00934 cpl_table_new_column 00935 (obj_pos[iframe], HAWKI_COL_OBJ_POSX, CPL_TYPE_DOUBLE); 00936 cpl_table_new_column 00937 (obj_pos[iframe], HAWKI_COL_OBJ_POSY, CPL_TYPE_DOUBLE); 00938 } 00939 00940 /* Loop on images to fill object_positions */ 00941 for(iframe = 0 ; iframe < nframes ; ++iframe) 00942 { 00943 cpl_apertures * this_apertures; 00944 00945 /* Create the detected apertures list */ 00946 this_apertures = apertures[idet][iframe]; 00947 00948 /* Fill the objects position table */ 00949 hawki_cal_distortion_fill_obj_pos(obj_pos[iframe], 00950 this_apertures); 00951 obj_pos_offset[iframe] = cpl_table_duplicate(obj_pos[iframe]); 00952 } 00953 00954 /* Get the objects positions with offsets */ 00955 hawki_cal_distortion_add_offset_to_positions 00956 (obj_pos_offset, offsets); 00957 //for(iframe = 0; iframe < nframes; ++iframe) 00958 // cpl_table_dump(obj_pos_offset[iframe],0,cpl_table_get_nrow(obj_pos_offset[iframe]),stdout); 00959 00960 00961 /* Get the all the matching pairs */ 00962 cpl_msg_info(__func__, "Matching all catalogs (may take a while)"); 00963 matches = irplib_match_cat_pairs(obj_pos_offset, nframes, 00964 hawki_match_condition_5_pix); 00965 for(iframe = 0; iframe < nframes; ++iframe) 00966 cpl_table_delete(obj_pos_offset[iframe]); 00967 cpl_free(obj_pos_offset); 00968 if(matches == NULL) 00969 { 00970 cpl_msg_error(__func__, "Cannot match objects "); 00971 for(iframe = 0; iframe < nframes; ++iframe) 00972 cpl_table_delete(obj_pos[iframe]); 00973 cpl_free(obj_pos); 00974 return NULL; 00975 } 00976 cpl_msg_info(__func__,"Number of matching pairs %d", 00977 cpl_table_get_nrow(matches)); 00978 nmatched_pairs[idet] = cpl_table_get_nrow(matches); 00979 //cpl_table_save(matches, NULL, NULL, "matches.fits", CPL_IO_CREATE); 00980 00981 /* Compute the distortion */ 00982 cpl_msg_info(__func__, "Computing distortion with the matched objects"); 00983 cpl_msg_info(__func__, " (This step will take a long time to run)"); 00984 if(distortion_guess != NULL) 00985 dist_guess = distortion_guess[idet]; 00986 else 00987 dist_guess = NULL; 00988 distortion[idet] = hawki_distortion_compute_solution 00989 ((const cpl_table **)obj_pos, offsets, matches, 00990 nframes, HAWKI_DET_NPIX_X , HAWKI_DET_NPIX_Y, grid_points, 00991 dist_guess, rms + idet); 00992 if(distortion[idet] == NULL) 00993 { 00994 int jdet; 00995 cpl_msg_error(__func__,"Could not get the distortion"); 00996 for(iframe = 0; iframe < nframes; ++iframe) 00997 cpl_table_delete(obj_pos[iframe]); 00998 cpl_free(obj_pos); 00999 for(jdet = 0; jdet < idet; ++jdet) 01000 hawki_distortion_delete(distortion[idet]); 01001 cpl_table_delete(matches); 01002 return NULL; 01003 } 01004 01005 /* Removing the first order polinomial to the distortion */ 01006 if(hawki_cal_distortion_config.subtract_linear) 01007 { 01008 cpl_msg_info(__func__,"Subtracting first order polynomial"); 01009 fit2d_x = cpl_polynomial_new(2); 01010 fit2d_y = cpl_polynomial_new(2); 01011 hawki_cal_distortion_fit_first_order_solution 01012 (distortion[idet], fit2d_x, fit2d_y); 01013 } 01014 01015 /* Free */ 01016 for(iframe = 0; iframe < nframes; ++iframe) 01017 cpl_table_delete(obj_pos[iframe]); 01018 cpl_free(obj_pos); 01019 if(hawki_cal_distortion_config.subtract_linear) 01020 { 01021 cpl_polynomial_delete(fit2d_x); 01022 cpl_polynomial_delete(fit2d_y); 01023 } 01024 cpl_table_delete(matches); 01025 cpl_msg_indent_less(); 01026 } 01027 01028 if(!cpl_errorstate_is_equal(error_prevstate )) 01029 { 01030 cpl_msg_error(__func__, "A problem happened computing the distortion"); 01031 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 01032 hawki_distortion_delete(distortion[idet]); 01033 return NULL ; 01034 } 01035 /* Free and return */ 01036 return distortion; 01037 } 01038 01039 static cpl_apertures * hawki_cal_distortion_get_image_apertures 01040 (cpl_image * image, 01041 double sigma_det) 01042 { 01043 cpl_apertures * apertures = NULL; 01044 cpl_matrix * kernel = NULL; 01045 cpl_mask * object_mask = NULL; 01046 cpl_image * labels = NULL; 01047 int nobj; 01048 double median; 01049 double med_dist; 01050 double threshold; 01051 01052 /* Get the threshold */ 01053 median = cpl_image_get_median_dev(image, &med_dist); 01054 threshold = median + sigma_det * med_dist; 01055 cpl_msg_info(__func__,"Detection threshold: %f", threshold); 01056 01057 /* Create the mask */ 01058 object_mask = cpl_mask_threshold_image_create 01059 (image, threshold, DBL_MAX); 01060 if (object_mask == NULL) 01061 return NULL; 01062 01063 /* Apply morphological opening to remove single pixel detections */ 01064 kernel = cpl_matrix_new(3, 3); 01065 cpl_matrix_fill(kernel, 1.00) ; 01066 if (cpl_mask_opening(object_mask, kernel) != CPL_ERROR_NONE) { 01067 cpl_mask_delete(object_mask) ; 01068 cpl_matrix_delete(kernel) ; 01069 return NULL; 01070 } 01071 cpl_matrix_delete(kernel); 01072 01073 /* Labelise the different detected apertures */ 01074 labels = cpl_image_labelise_mask_create(object_mask, &nobj); 01075 if (labels == NULL) 01076 { 01077 cpl_mask_delete(object_mask); 01078 return NULL; 01079 } 01080 cpl_mask_delete(object_mask); 01081 cpl_msg_info(__func__, "Number of objects detected: %d", nobj) ; 01082 01083 /* Create the detected apertures list */ 01084 apertures = cpl_apertures_new_from_image(image, labels); 01085 if (apertures == NULL) 01086 { 01087 cpl_image_delete(labels); 01088 return NULL; 01089 } 01090 cpl_image_delete(labels); 01091 return apertures; 01092 } 01093 01094 static int hawki_cal_distortion_fill_obj_pos 01095 (cpl_table * objects_positions, 01096 cpl_apertures * apertures) 01097 { 01098 int nobjs; 01099 int iobj; 01100 double border_off = 0; 01101 01102 /* Take into account that the images have been trimmed */ 01103 if(hawki_cal_distortion_config.borders > 0) 01104 border_off = hawki_cal_distortion_config.borders; 01105 01106 nobjs = cpl_apertures_get_size(apertures); 01107 cpl_table_set_size(objects_positions, nobjs); 01108 01109 for (iobj=0 ; iobj<nobjs ; iobj++) 01110 { 01111 /* Fill with the already known information */ 01112 cpl_table_set_double(objects_positions, HAWKI_COL_OBJ_POSX, iobj, 01113 cpl_apertures_get_centroid_x(apertures, 01114 iobj+1) + border_off); 01115 cpl_table_set_double(objects_positions, HAWKI_COL_OBJ_POSY, iobj, 01116 cpl_apertures_get_centroid_y(apertures, 01117 iobj+1) + border_off); 01118 } 01119 01120 return 0; 01121 } 01122 01123 static int hawki_cal_distortion_add_offset_to_positions 01124 (cpl_table ** objects_positions, 01125 cpl_bivector * offsets) 01126 { 01127 int nframes; 01128 int iframe; 01129 int nobjs; 01130 int iobj; 01131 01132 nframes = cpl_bivector_get_size(offsets); 01133 01134 for(iframe = 0 ; iframe < nframes ; ++iframe) 01135 { 01136 double offset_x; 01137 double offset_y; 01138 int null; 01139 offset_x = cpl_bivector_get_x_data(offsets)[iframe]; 01140 offset_y = cpl_bivector_get_y_data(offsets)[iframe]; 01141 nobjs = cpl_table_get_nrow(objects_positions[iframe]); 01142 for (iobj=0 ; iobj<nobjs ; iobj++) 01143 { 01144 cpl_table_set_double(objects_positions[iframe], 01145 HAWKI_COL_OBJ_POSX, iobj, 01146 cpl_table_get_double(objects_positions[iframe], 01147 HAWKI_COL_OBJ_POSX, iobj, &null) + offset_x); 01148 cpl_table_set_double(objects_positions[iframe], 01149 HAWKI_COL_OBJ_POSY, iobj, 01150 cpl_table_get_double(objects_positions[iframe], 01151 HAWKI_COL_OBJ_POSY, iobj, &null) + offset_y); 01152 } 01153 } 01154 01155 return 0; 01156 } 01157 01158 static int hawki_cal_distortion_fit_first_order_solution 01159 (hawki_distortion * distortion, 01160 cpl_polynomial * fit2d_x, 01161 cpl_polynomial * fit2d_y) 01162 { 01163 cpl_matrix * pixel_pos; 01164 cpl_vector * dist_x_val; 01165 cpl_vector * dist_y_val; 01166 int nx; 01167 int ny; 01168 int i; 01169 int j; 01170 int null; 01171 const int mindeg2d[] = {0, 0}; 01172 const int maxdeg2d[] = {1, 1}; 01173 cpl_errorstate error_prevstate = cpl_errorstate_get(); 01174 cpl_vector * pix; 01175 cpl_image * dist_x_plane; 01176 cpl_image * dist_y_plane; 01177 double dist_x_mean; 01178 double dist_y_mean; 01179 01180 /* Fill the bivector with pixel positions in X,Y */ 01181 nx = hawki_distortion_get_size_x(distortion); 01182 ny = hawki_distortion_get_size_y(distortion); 01183 pixel_pos = cpl_matrix_new(2, nx * ny); 01184 dist_x_val = cpl_vector_new(nx*ny); 01185 dist_y_val = cpl_vector_new(nx*ny); 01186 for(i = 0; i < nx; ++i) 01187 for(j = 0; j < ny; ++j) 01188 { 01189 cpl_matrix_set(pixel_pos, 0, i + nx * j, (double)i); 01190 cpl_matrix_set(pixel_pos, 1, i + nx * j, (double)j); 01191 cpl_vector_set(dist_x_val, i + nx * j, 01192 cpl_image_get(distortion->dist_x, i+1, j+1, &null)); 01193 cpl_vector_set(dist_y_val, i + nx * j, 01194 cpl_image_get(distortion->dist_y, i+1, j+1, &null)); 01195 } 01196 01197 /* Fit the polynomial */ 01198 cpl_polynomial_fit(fit2d_x, pixel_pos, NULL, dist_x_val, 01199 NULL, CPL_FALSE, mindeg2d, maxdeg2d); 01200 cpl_polynomial_fit(fit2d_y, pixel_pos, NULL, dist_y_val, 01201 NULL, CPL_FALSE, mindeg2d, maxdeg2d); 01202 /* Removing the constant term */ 01203 cpl_polynomial_set_coeff(fit2d_x, mindeg2d, 0.); 01204 cpl_polynomial_set_coeff(fit2d_y, mindeg2d, 0.); 01205 01206 /* Subtract the linear term */ 01207 pix = cpl_vector_new(2); 01208 dist_x_plane = cpl_image_new(nx,ny,cpl_image_get_type(distortion->dist_x)); 01209 dist_y_plane = cpl_image_new(nx,ny,cpl_image_get_type(distortion->dist_y)); 01210 for(i = 0; i < nx; ++i) 01211 for(j = 0; j < ny; ++j) 01212 { 01213 double fit_value_x; 01214 double fit_value_y; 01215 cpl_vector_set(pix, 0, (double)i); 01216 cpl_vector_set(pix, 1, (double)j); 01217 fit_value_x = cpl_polynomial_eval(fit2d_x, pix); 01218 fit_value_y = cpl_polynomial_eval(fit2d_y, pix); 01219 cpl_image_set(dist_x_plane, i+1, j+1, fit_value_x); 01220 cpl_image_set(dist_y_plane, i+1, j+1, fit_value_y); 01221 } 01222 cpl_image_subtract(distortion->dist_x, dist_x_plane); 01223 cpl_image_subtract(distortion->dist_y, dist_y_plane); 01224 01225 /* Subtract the mean distortion, again */ 01226 dist_x_mean = cpl_image_get_mean(distortion->dist_x); 01227 dist_y_mean = cpl_image_get_mean(distortion->dist_y); 01228 cpl_msg_warning(__func__,"Subtracting mean distortion in X %f",dist_x_mean); 01229 cpl_msg_warning(__func__,"Subtracting mean distortion in Y %f",dist_y_mean); 01230 cpl_image_subtract_scalar(distortion->dist_x, dist_x_mean); 01231 cpl_image_subtract_scalar(distortion->dist_y, dist_y_mean); 01232 01233 /* Free and return */ 01234 cpl_matrix_delete(pixel_pos); 01235 cpl_vector_delete(dist_x_val); 01236 cpl_vector_delete(dist_y_val); 01237 cpl_vector_delete(pix); 01238 cpl_image_delete(dist_x_plane); 01239 cpl_image_delete(dist_y_plane); 01240 01241 if(!cpl_errorstate_is_equal(error_prevstate )) 01242 { 01243 cpl_msg_error(__func__, "A problem happened computing the linear term"); 01244 cpl_msg_error(__func__,"Error %s",cpl_error_get_message()); 01245 //cpl_msg_error(__func__,"Where %s",cpl_error_get_where()); 01246 return -1; 01247 } 01248 return 0; 01249 } 01250 01251 /*----------------------------------------------------------------------------*/ 01256 /*----------------------------------------------------------------------------*/ 01257 static cpl_propertylist ** hawki_cal_distortion_qc 01258 (hawki_distortion ** distortion, 01259 int * nmatched_pairs, 01260 double * rms) 01261 { 01262 int idet; 01263 cpl_propertylist ** qclists; 01264 01265 /* Allocate the qclists */ 01266 qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 01267 01268 /* Loop on the detectors to get the mean zpoint */ 01269 for(idet = 0 ; idet < HAWKI_NB_DETECTORS ; ++idet) 01270 { 01271 /* Allocate this qclist */ 01272 qclists[idet] = cpl_propertylist_new() ; 01273 01274 cpl_propertylist_append_double 01275 (qclists[idet], "ESO QC DIST NMATCHED", nmatched_pairs[idet]); 01276 01277 cpl_propertylist_append_double 01278 (qclists[idet], "ESO QC DIST TOTAL RMS", rms[idet]); 01279 01280 /* Getting the jacobian of the distortion map */ 01281 /* The jacobian has to be definitive positive in all the detector to 01282 * be have a biyective function invertible anywhere: 01283 * http://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant#Jacobian_determinant 01284 * http://en.wikipedia.org/wiki/Inverse_function#Inverses_and_derivatives 01285 * This should be a QC check. 01286 */ 01287 01288 01289 //cpl_propertylist_append_double 01290 //(qclists[idet], "ESO QC DIST JACOBIAN_1_1", jacobian[1][1]); 01291 } 01292 01293 return qclists; 01294 } 01295 01296 /*----------------------------------------------------------------------------*/ 01306 /*----------------------------------------------------------------------------*/ 01307 static int hawki_cal_distortion_save 01308 (hawki_distortion ** distortion, 01309 cpl_parameterlist * parlist, 01310 cpl_propertylist ** qclists, 01311 cpl_frameset * recipe_set) 01312 { 01313 const char * recipe_name = "hawki_cal_distortion"; 01314 01315 /* Write the distortion in both axes */ 01316 hawki_distortion_save(recipe_set, 01317 parlist, 01318 recipe_set, 01319 (const hawki_distortion **) distortion, 01320 recipe_name, 01321 NULL, 01322 (const cpl_propertylist **)qclists, 01323 "hawki_cal_distortion_x.fits", 01324 "hawki_cal_distortion_y.fits"); 01325 01326 /* Free and return */ 01327 return 0; 01328 } 01329 01330 static int hawki_cal_distortion_retrieve_input_param 01331 (cpl_parameterlist * parlist) 01332 { 01333 cpl_parameter * par ; 01334 01335 par = NULL ; 01336 par = cpl_parameterlist_find 01337 (parlist, "hawki.hawki_cal_distortion.sigma_det"); 01338 hawki_cal_distortion_config.sigma_det = cpl_parameter_get_double(par); 01339 par = cpl_parameterlist_find 01340 (parlist, "hawki.hawki_cal_distortion.grid_points"); 01341 hawki_cal_distortion_config.grid_points = cpl_parameter_get_int(par); 01342 par = cpl_parameterlist_find 01343 (parlist, "hawki.hawki_cal_distortion.borders"); 01344 hawki_cal_distortion_config.borders = cpl_parameter_get_int(par); 01345 par = cpl_parameterlist_find 01346 (parlist, "hawki.hawki_cal_distortion.subtract_linear"); 01347 hawki_cal_distortion_config.subtract_linear = cpl_parameter_get_bool(par); 01348 01349 01350 return 0; 01351 }
1.7.3