40 #include "irplib_utils.h"
41 #include "irplib_calib.h"
43 #include "hawki_utils.h"
44 #include "hawki_calib.h"
45 #include "hawki_load.h"
46 #include "hawki_save.h"
47 #include "hawki_pfits.h"
48 #include "hawki_dfs.h"
49 #include "hawki_saa.h"
50 #include "hawki_bkg.h"
51 #include "hawki_distortion.h"
52 #include "hawki_properties_tel.h"
53 #include "hawki_image_stats.h"
59 #define NEGLIG_OFF_DIFF 0.1
60 #define SQR(x) ((x)*(x))
66 static int hawki_step_refine_offsets_create(cpl_plugin *) ;
67 static int hawki_step_refine_offsets_exec(cpl_plugin *) ;
68 static int hawki_step_refine_offsets_destroy(cpl_plugin *) ;
69 static int hawki_step_refine_offsets(cpl_parameterlist *, cpl_frameset *) ;
71 static int hawki_step_refine_offsets_retrieve_input_param
72 (cpl_parameterlist * parlist);
73 static int hawki_step_refine_offsets_fine
74 (
const cpl_frameset * science_objects_frames,
75 const cpl_frameset * reference_objects_frames,
76 cpl_bivector ** refined_offsets,
77 cpl_vector ** correl);
79 static int hawki_step_refine_offsets_save
80 (cpl_bivector ** refined_offsets,
81 cpl_vector ** correlations,
82 cpl_parameterlist * recipe_parlist,
83 cpl_frameset * recipe_frameset);
85 static cpl_bivector ** hawki_step_refine_offsets_read_select_objects
86 (
const cpl_frameset * reference_obj_frames,
87 double first_image_off_x,
88 double first_image_off_y,
104 } hawki_step_refine_offsets_config;
106 static char hawki_step_refine_offsets_description[] =
107 "hawki_step_refine_offsets -- utility to refine the nominal offsets.\n"
108 "This utility will take the offsets in the header as a first approach\n"
109 "and tries to refine them correlating the input images at the points\n"
110 "given by the detected objects.\n"
111 "The input of the recipe files listed in the Set Of Frames (sof-file)\n"
112 "must be tagged as:\n"
113 "images.fits "HAWKI_CALPRO_DIST_CORRECTED
" or\n"
114 "images.fits "HAWKI_CALPRO_BKG_SUBTRACTED
" and\n"
115 "det_obj_stats.fits "HAWKI_CALPRO_OBJ_PARAM
"\n"
116 "The recipe creates as an output:\n"
117 "hawki_step_refine_offsets.fits ("HAWKI_CALPRO_OFFSETS
"): Table with refined offsets\n"
119 "esorex exits with an error code of 0 if the recipe completes successfully\n"
136 int cpl_plugin_get_info(cpl_pluginlist * list)
138 cpl_recipe * recipe = cpl_calloc(1,
sizeof(*recipe)) ;
139 cpl_plugin * plugin = &recipe->interface ;
141 cpl_plugin_init(plugin,
143 HAWKI_BINARY_VERSION,
144 CPL_PLUGIN_TYPE_RECIPE,
145 "hawki_step_refine_offsets",
147 hawki_step_refine_offsets_description,
148 "Cesar Enrique Garcia Dabo",
151 hawki_step_refine_offsets_create,
152 hawki_step_refine_offsets_exec,
153 hawki_step_refine_offsets_destroy) ;
155 cpl_pluginlist_append(list, plugin) ;
170 static int hawki_step_refine_offsets_create(cpl_plugin * plugin)
172 cpl_recipe * recipe ;
176 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
177 recipe = (cpl_recipe *)plugin ;
181 recipe->parameters = cpl_parameterlist_new() ;
182 if (recipe->parameters == NULL)
187 p = cpl_parameter_new_value(
"hawki.hawki_step_refine_offsets.xcorr",
189 "Cross correlation search and measure sizes",
190 "hawki.hawki_step_refine_offsets",
192 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"xcorr") ;
193 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
194 cpl_parameterlist_append(recipe->parameters, p) ;
197 p = cpl_parameter_new_value(
"hawki.hawki_step_refine_offsets.nbrightest",
199 "Number of brightest objects to use",
200 "hawki.hawki_step_refine_offsets",
202 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nbrightest") ;
203 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
204 cpl_parameterlist_append(recipe->parameters, p) ;
217 static int hawki_step_refine_offsets_exec(cpl_plugin * plugin)
219 cpl_recipe * recipe ;
222 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
223 recipe = (cpl_recipe *)plugin ;
229 return hawki_step_refine_offsets(recipe->parameters, recipe->frames) ;
239 static int hawki_step_refine_offsets_destroy(cpl_plugin * plugin)
241 cpl_recipe * recipe ;
244 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
245 recipe = (cpl_recipe *)plugin ;
248 cpl_parameterlist_delete(recipe->parameters) ;
260 static int hawki_step_refine_offsets(
261 cpl_parameterlist * parlist,
262 cpl_frameset * framelist)
264 cpl_frameset * science_obj_frames ;
265 cpl_frameset * reference_obj_frames ;
266 cpl_bivector ** refined_offsets;
267 cpl_vector ** correl;
271 if(hawki_step_refine_offsets_retrieve_input_param(parlist))
273 cpl_msg_error(__func__,
"Wrong parameters");
279 cpl_msg_error(__func__,
"Cannot identify RAW and CALIB frames") ;
284 cpl_msg_info(__func__,
"Identifying input frames");
287 if (science_obj_frames == NULL)
291 if (science_obj_frames == NULL)
293 cpl_msg_error(__func__,
"No science object frames provided (%s)",
294 HAWKI_CALPRO_DIST_CORRECTED);
300 reference_obj_frames =
302 if(cpl_frameset_get_size(reference_obj_frames) != 1)
304 cpl_msg_error(__func__,
"One object parameters frame must be provided (%s)",
305 HAWKI_CALPRO_OBJ_PARAM);
306 cpl_frameset_delete(science_obj_frames) ;
307 if(reference_obj_frames != NULL)
308 cpl_frameset_delete(reference_obj_frames);
313 refined_offsets = cpl_malloc(HAWKI_NB_DETECTORS *
sizeof(cpl_bivector *));
314 correl = cpl_malloc(HAWKI_NB_DETECTORS *
sizeof(cpl_vector *));
315 for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
317 refined_offsets[idet] = cpl_bivector_new
318 (cpl_frameset_get_size(science_obj_frames));
319 correl[idet] = cpl_vector_new
320 (cpl_frameset_get_size(science_obj_frames));
322 if (hawki_step_refine_offsets_fine
323 (science_obj_frames, reference_obj_frames,
324 refined_offsets, correl) == -1)
326 cpl_msg_error(__func__,
"Cannot refine the objects") ;
327 cpl_frameset_delete(reference_obj_frames) ;
328 cpl_frameset_delete(science_obj_frames) ;
329 for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
331 cpl_bivector_delete(refined_offsets[idet]);
332 cpl_vector_delete(correl[idet]);
334 cpl_free(refined_offsets);
340 cpl_msg_info(__func__,
"Save the products") ;
341 if (hawki_step_refine_offsets_save
342 (refined_offsets, correl, parlist, framelist) == -1)
344 cpl_msg_warning(__func__,
"Some data could not be saved. "
345 "Check permisions or disk space");
346 cpl_frameset_delete(science_obj_frames);
347 cpl_frameset_delete(reference_obj_frames);
348 for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
350 cpl_bivector_delete(refined_offsets[idet]);
351 cpl_vector_delete(correl[idet]);
353 cpl_free(refined_offsets);
359 cpl_frameset_delete(science_obj_frames);
360 cpl_frameset_delete(reference_obj_frames);
361 for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
363 cpl_bivector_delete(refined_offsets[idet]);
364 cpl_vector_delete(correl[idet]);
366 cpl_free(refined_offsets);
370 if (cpl_error_get_code())
372 cpl_msg_error(__func__,
373 "HAWK-I pipeline could not recover from previous errors");
379 int hawki_step_refine_offsets_retrieve_input_param
380 (cpl_parameterlist * parlist)
382 cpl_parameter * par ;
385 par = cpl_parameterlist_find
386 (parlist,
"hawki.hawki_step_refine_offsets.nbrightest");
387 hawki_step_refine_offsets_config.nbrightest =
388 cpl_parameter_get_int(par);
389 par = cpl_parameterlist_find
390 (parlist,
"hawki.hawki_step_refine_offsets.xcorr");
391 sval = cpl_parameter_get_string(par);
392 if (sscanf(sval,
"%d,%d,%d,%d",
393 &hawki_step_refine_offsets_config.sx,
394 &hawki_step_refine_offsets_config.sy,
395 &hawki_step_refine_offsets_config.mx,
396 &hawki_step_refine_offsets_config.my)!=4)
411 static int hawki_step_refine_offsets_fine
412 (
const cpl_frameset * science_obj_frames,
413 const cpl_frameset * reference_obj_frames,
414 cpl_bivector ** refined_offsets,
415 cpl_vector ** correl)
418 cpl_bivector * nominal_offsets ;
419 cpl_bivector ** reference_objects;
420 double * offs_est_x ;
421 double * offs_est_y ;
424 double max_x, max_y ;
427 cpl_propertylist * header;
432 cpl_msg_info(__func__,
"Getting the nominal offsets");
434 if (nominal_offsets == NULL)
436 cpl_msg_error(__func__,
"Cannot load the header offsets") ;
439 offs_est_x = cpl_bivector_get_x_data(nominal_offsets);
440 offs_est_y = cpl_bivector_get_y_data(nominal_offsets);
443 cpl_msg_indent_more();
444 for (ioff=0 ; ioff<cpl_bivector_get_size(nominal_offsets) ; ioff++)
446 cpl_msg_info(__func__,
"Telescope offsets (Frame %d): %g %g", ioff+1,
447 offs_est_x[ioff], offs_est_y[ioff]) ;
449 cpl_msg_indent_less();
452 header = cpl_propertylist_load
453 (cpl_frame_get_filename
454 (cpl_frameset_get_first_const(science_obj_frames)), 1);
457 cpl_propertylist_delete(header);
460 off_0_x = offs_est_x[0];
461 off_0_y = offs_est_y[0];
466 hawki_step_refine_offsets_read_select_objects(reference_obj_frames,
471 if(reference_objects == NULL)
473 cpl_msg_error(__func__,
"Error reading the reference objects");
474 cpl_bivector_delete(nominal_offsets);
479 max_x = max_y = 0.0 ;
480 for (ioff=1 ; ioff<cpl_bivector_get_size(nominal_offsets) ; ioff++)
482 offs_est_x[ioff] -= off_0_x;
483 offs_est_y[ioff] -= off_0_y;
484 if (fabs(offs_est_x[ioff]) > max_x) max_x = fabs(offs_est_x[ioff]) ;
485 if (fabs(offs_est_y[ioff]) > max_y) max_y = fabs(offs_est_y[ioff]) ;
487 offs_est_x[0] = offs_est_y[0] = 0.00 ;
491 cpl_vector_multiply_scalar(cpl_bivector_get_x(nominal_offsets), -1.0);
492 cpl_vector_multiply_scalar(cpl_bivector_get_y(nominal_offsets), -1.0);
495 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
497 cpl_msg_info(__func__,
"Working on detector number %d", idet+1) ;
498 cpl_msg_indent_more();
501 cpl_msg_info(__func__,
"Loading the input data") ;
502 cpl_msg_indent_more() ;
504 idet+1, CPL_TYPE_FLOAT)) == NULL)
506 cpl_msg_error(__func__,
"Cannot load chip %d", idet+1) ;
507 cpl_bivector_delete(nominal_offsets) ;
508 for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
510 cpl_bivector_delete(reference_objects[idet]);
512 cpl_free(reference_objects);
513 cpl_msg_indent_less() ;
514 cpl_msg_indent_less() ;
519 cpl_msg_info(__func__,
"Getting the refinement");
520 cpl_msg_indent_more() ;
521 if (hawki_geom_refine_images_offsets
524 reference_objects[idet],
525 hawki_step_refine_offsets_config.sx,
526 hawki_step_refine_offsets_config.sy,
527 hawki_step_refine_offsets_config.mx,
528 hawki_step_refine_offsets_config.my,
529 refined_offsets[idet],
532 cpl_msg_error(__func__,
"Cannot apply the shift and add") ;
533 cpl_imagelist_delete(in) ;
534 cpl_bivector_delete(nominal_offsets) ;
535 for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
536 cpl_bivector_delete(reference_objects[idet]);
537 cpl_free(reference_objects);
538 cpl_msg_indent_less() ;
539 cpl_msg_indent_less() ;
545 cpl_vector_multiply_scalar
546 (cpl_bivector_get_x(refined_offsets[idet]), -1.0);
547 cpl_vector_multiply_scalar
548 (cpl_bivector_get_y(refined_offsets[idet]), -1.0);
549 cpl_vector_add_scalar
550 (cpl_bivector_get_x(refined_offsets[idet]), off_0_x);
551 cpl_vector_add_scalar
552 (cpl_bivector_get_y(refined_offsets[idet]), off_0_y);
555 for (ioff=0 ; ioff<cpl_bivector_get_size(refined_offsets[idet]); ioff++)
557 cpl_msg_info(__func__,
"Refined telescope offsets (Frame %d): %g %g",
559 cpl_vector_get(cpl_bivector_get_x
560 (refined_offsets[idet]), ioff),
561 cpl_vector_get(cpl_bivector_get_y
562 (refined_offsets[idet]), ioff));
564 cpl_imagelist_delete(in) ;
565 cpl_msg_indent_less() ;
566 cpl_msg_indent_less() ;
570 cpl_bivector_delete(nominal_offsets);
571 for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
572 cpl_bivector_delete(reference_objects[idet]);
573 cpl_free(reference_objects);
588 static int hawki_step_refine_offsets_save
589 (cpl_bivector ** refined_offsets,
590 cpl_vector ** correlations,
591 cpl_parameterlist * recipe_parlist,
592 cpl_frameset * recipe_frameset)
594 cpl_table ** offset_tables;
598 const char * recipe_name =
"hawki_step_refine_offsets";
599 cpl_errorstate error_prevstate = cpl_errorstate_get();
603 offset_tables = cpl_malloc(HAWKI_NB_DETECTORS *
sizeof(cpl_table *));
604 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
606 offset_tables[idet] = cpl_table_new
607 (cpl_bivector_get_size(refined_offsets[idet]));
608 cpl_table_new_column(offset_tables[idet],
609 HAWKI_COL_OFFSET_X, CPL_TYPE_FLOAT);
610 cpl_table_set_column_unit(offset_tables[idet],HAWKI_COL_OFFSET_X,
"pix");
611 cpl_table_new_column(offset_tables[idet],
612 HAWKI_COL_OFFSET_Y, CPL_TYPE_FLOAT);
613 cpl_table_set_column_unit(offset_tables[idet],HAWKI_COL_OFFSET_Y,
"pix");
614 cpl_table_new_column(offset_tables[idet],
615 HAWKI_COL_CORRELATION, CPL_TYPE_FLOAT);
616 noff = cpl_bivector_get_size(refined_offsets[idet]);
617 for(ioff = 0; ioff < noff; ++ioff)
619 double xoffset, yoffset, corr;
620 xoffset = cpl_vector_get
621 (cpl_bivector_get_x(refined_offsets[idet]), ioff);
622 yoffset = cpl_vector_get
623 (cpl_bivector_get_y(refined_offsets[idet]), ioff);
624 corr = cpl_vector_get(correlations[idet], ioff);
626 (offset_tables[idet], HAWKI_COL_OFFSET_X, ioff, xoffset);
628 (offset_tables[idet], HAWKI_COL_OFFSET_Y, ioff, yoffset);
630 (offset_tables[idet], HAWKI_COL_CORRELATION, ioff, corr);
638 (
const cpl_table **)offset_tables,
640 HAWKI_CALPRO_OFFSETS,
641 HAWKI_PROTYPE_OFFSETS,
644 "hawki_step_refine_offsets.fits") != CPL_ERROR_NONE)
646 cpl_msg_error(__func__,
"Cannot save the first extension table") ;
647 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
648 cpl_table_delete(offset_tables[idet]);
649 cpl_free(offset_tables);
654 for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
655 cpl_table_delete(offset_tables[idet]);
656 cpl_free(offset_tables);
657 if(!cpl_errorstate_is_equal(error_prevstate))
659 cpl_errorstate_set(CPL_ERROR_NONE);
681 static cpl_bivector ** hawki_step_refine_offsets_read_select_objects
682 (
const cpl_frameset * reference_obj_frames,
683 double first_image_off_x,
684 double first_image_off_y,
688 const cpl_frame * reference_obj_frame;
689 cpl_table ** obj_param;
690 cpl_propertylist * sort_column;
691 cpl_bivector ** reference_objects;
695 cpl_msg_info(__func__,
"Getting the reference object positions");
696 reference_obj_frame = cpl_frameset_get_first_const(reference_obj_frames);
698 if(obj_param == NULL)
700 cpl_msg_error(__func__,
"Could not read the reference objects parameters");
705 sort_column = cpl_propertylist_new();
706 cpl_propertylist_append_bool(sort_column, HAWKI_COL_OBJ_FLUX, CPL_TRUE);
709 reference_objects = cpl_malloc(HAWKI_NB_DETECTORS *
sizeof(cpl_bivector *));
712 cpl_msg_indent_more();
713 for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
715 cpl_propertylist * objects_plist;
722 double reference_offset_x;
723 double reference_offset_y;
729 (cpl_frame_get_filename(reference_obj_frame), idet + 1);
730 objects_plist = cpl_propertylist_load
731 (cpl_frame_get_filename(reference_obj_frame), ext_nb);
736 if(cpl_error_get_code() != CPL_ERROR_NONE)
738 cpl_msg_error(__func__,
"Could not find keywords "
739 "ESO QC COMBINED CUMOFFSETX,Y in reference objects frame");
740 cpl_propertylist_delete(objects_plist);
741 cpl_propertylist_delete(sort_column);
744 cpl_msg_info(__func__,
"Objects offsets wrt telescope: %f %f",
745 reference_offset_x, reference_offset_y);
746 cpl_propertylist_delete(objects_plist);
749 cpl_table_sort(obj_param[idet], sort_column);
750 nobj = cpl_table_get_nrow(obj_param[idet]);
753 reference_objects[idet] = cpl_bivector_new(nobj);
754 obj_x = cpl_bivector_get_x(reference_objects[idet]);
755 obj_y = cpl_bivector_get_y(reference_objects[idet]);
756 cpl_msg_info(__func__,
"Number of objects in chip %d: %d", idet+1,nobj);
759 cpl_table_unselect_all(obj_param[idet]);
760 for(iobj = 0 ; iobj < nobj; ++iobj)
762 double xpos_orig = cpl_table_get
763 (obj_param[idet], HAWKI_COL_OBJ_POSX, iobj, NULL);
764 double ypos_orig = cpl_table_get
765 (obj_param[idet], HAWKI_COL_OBJ_POSY, iobj, NULL);
766 double xpos_rel = xpos_orig - reference_offset_x + first_image_off_x;
767 double ypos_rel = ypos_orig - reference_offset_y + first_image_off_y;
768 if(xpos_rel < 0.0 || xpos_rel >= nx ||
769 ypos_rel < 0.0 || ypos_rel >= ny)
771 cpl_table_select_row(obj_param[idet], iobj);
774 cpl_table_erase_selected(obj_param[idet]);
775 nobj = cpl_table_get_nrow(obj_param[idet]);
776 cpl_msg_info(__func__,
"Number of objects within limits of detector "
777 "in chip %d: %d", idet+1,nobj);
780 nselect = hawki_step_refine_offsets_config.nbrightest;
781 if(nselect < 0 || nselect > nobj)
783 cpl_msg_info(__func__,
"Number of selected objects: %d", nselect);
784 for(iobj = 0 ; iobj < nselect; ++iobj)
786 double xpos_orig = cpl_table_get
787 (obj_param[idet], HAWKI_COL_OBJ_POSX, iobj, NULL);
788 double ypos_orig = cpl_table_get
789 (obj_param[idet], HAWKI_COL_OBJ_POSY, iobj, NULL);
792 (obj_x, iobj, xpos_orig - reference_offset_x + first_image_off_x);
794 (obj_y, iobj, ypos_orig - reference_offset_y + first_image_off_y);
795 cpl_msg_debug(__func__,
"Using anchor point at %f,%f",
796 cpl_vector_get(obj_x,iobj),
797 cpl_vector_get(obj_y,iobj));
800 cpl_vector_set_size(obj_x, nselect);
801 cpl_vector_set_size(obj_y, nselect);
804 cpl_msg_indent_less();
807 for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
808 cpl_table_delete(obj_param[idet]);
810 cpl_propertylist_delete(sort_column);
812 return reference_objects;