40 #include "irplib_plugin.h"
41 #include "irplib_utils.h"
42 #include "irplib_calib.h"
44 #include "isaac_utils.h"
45 #include "isaac_pfits.h"
46 #include "isaac_dfs.h"
52 #define RECIPE_STRING "isaac_img_jitter"
54 #ifndef NEGLIG_OFF_DIFF
55 #define NEGLIG_OFF_DIFF 0.1
58 #define SQR(x) ((x)*(x))
60 #ifdef ISAAC_IMG_ERR_ESTIMATE
61 #ifndef ISAAC_IMG_GAIN
63 #define ISAAC_IMG_GAIN 4.5
66 #ifndef ISAAC_IMG_SATURATION_LEVEL
68 #define ISAAC_IMG_SATURATION_LEVEL 40000.0
77 static cpl_image ** isaac_img_jitter_reduce(cpl_frameset *,
78 const cpl_parameterlist *,
81 const char *,
const char *,
82 const char *, cpl_vector **);
83 static cpl_imagelist ** isaac_img_jitter_load(
const cpl_frameset *,
84 const cpl_frameset *);
85 static cpl_vector * isaac_img_jitter_sky(cpl_imagelist **, cpl_imagelist *);
86 static cpl_vector * isaac_img_jitter_sky_running(cpl_imagelist **);
87 static cpl_image ** isaac_img_jitter_saa_nochop(cpl_imagelist *,
88 const cpl_frameset *);
89 static cpl_image ** isaac_img_jitter_saa_chop(cpl_imagelist *,
90 const cpl_frameset *);
91 static int isaac_img_jitter_chopping_classif(cpl_bivector *,
int **,
int **);
92 static cpl_error_code isaac_img_jitter_sub_row_median(cpl_image *);
93 static cpl_table * isaac_img_jitter_qc(cpl_image *);
94 static double isaac_img_jitter_get_mode(cpl_vector *);
95 static cpl_error_code isaac_img_jitter_save(cpl_frameset *,
const cpl_image *,
99 const cpl_parameterlist *);
101 cpl_recipe_define(isaac_img_jitter, ISAAC_BINARY_VERSION,
102 "Lars Lundin", PACKAGE_BUGREPORT,
"2008",
103 "ISAAC imaging jitter recipe",
104 RECIPE_STRING
" -- ISAAC imaging jitter recipe.\n"
105 "The files listed in the Set Of Frames (sof-file) "
107 "raw-file.fits " ISAAC_IMG_JITTER_OBJ_RAW
" or\n"
108 "raw-file.fits " ISAAC_IMG_JITTER_SKY_RAW
" or\n"
109 "raw-file.fits " ISAAC_IMG_JITTER_CHOP_RAW
" or\n"
110 "flat-file.fits " ISAAC_CALIB_FLAT
" or\n"
111 "bpm-file.fits " ISAAC_CALIB_BPM
" or\n"
112 "dark-file.fits " ISAAC_CALIB_DARK
"\n");
120 const char * offsets;
121 const char * objects;
131 cpl_geom_combine comb_meth;
150 } isaac_img_jitter_config;
166 cpl_error_code isaac_img_jitter_fill_parameterlist(cpl_parameterlist *
self)
168 const char * context = PACKAGE
"." RECIPE_STRING;
171 cpl_ensure_code(
self, CPL_ERROR_NULL_INPUT);
176 err = irplib_parameterlist_set_string(
self, PACKAGE, RECIPE_STRING,
177 "offsets", NULL,
"off", context,
178 "An optional ASCII specification of the offsets "
179 "in case those in FITS-headers are missing or wrong. "
180 "The file must consist of one line per object FITS-"
181 "file and each line must consist of two "
182 "numbers which represent the shift in pixels of that "
183 "image relative to the first image. The first line "
184 "should thus comprise two zeros. Correct FITS-header "
185 "offsets mean that the i'th X offset can be gotten "
186 "from Xoffset_0 - Xoffset_i, where Xoffset_i is the "
187 "value of ESO SEQ CUMOFFSETX and likewise for Y.");
188 cpl_ensure_code(!err, err);
191 err = irplib_parameterlist_set_string(
self, PACKAGE, RECIPE_STRING,
192 "objects", NULL,
"objs", context,
194 cpl_ensure_code(!err, err);
197 err = irplib_parameterlist_set_bool(
self, PACKAGE, RECIPE_STRING,
"oddeven",
198 CPL_FALSE, NULL, context,
"Flag to "
199 "correct the oddeven column effect");
200 cpl_ensure_code(!err, err);
203 err = irplib_parameterlist_set_string(
self, PACKAGE, RECIPE_STRING,
204 "sky_par",
"10,7,3,3", NULL, context,
205 "Rejection parameters for sky "
207 cpl_ensure_code(!err, err);
210 err = irplib_parameterlist_set_string(
self, PACKAGE, RECIPE_STRING,
"xcorr",
211 "40,40,65,65", NULL, context,
"Cross "
212 "correlation search and measure "
214 cpl_ensure_code(!err, err);
217 err = irplib_parameterlist_set_string(
self, PACKAGE, RECIPE_STRING,
218 "comb_meth",
"union", NULL, context,
219 "union / inter / first");
220 cpl_ensure_code(!err, err);
223 err = irplib_parameterlist_set_bool(
self, PACKAGE, RECIPE_STRING,
224 "saa_refine", CPL_TRUE, NULL, context,
225 "Flag to refine the offsets");
226 cpl_ensure_code(!err, err);
229 err = irplib_parameterlist_set_string(
self, PACKAGE, RECIPE_STRING,
"rej",
230 "2,2", NULL, context,
"Low and high "
231 "number of rejected values");
232 cpl_ensure_code(!err, err);
235 err = irplib_parameterlist_set_bool(
self, PACKAGE, RECIPE_STRING,
236 "row_med", CPL_TRUE, NULL, context,
237 "Flag to subtract the median of each "
239 cpl_ensure_code(!err, err);
241 return CPL_ERROR_NONE;
255 static int isaac_img_jitter(cpl_frameset * framelist,
256 const cpl_parameterlist * parlist)
262 cpl_frameset * objframes = NULL;
263 cpl_frameset * skyframes = NULL;
264 cpl_image ** combined = NULL;
265 cpl_table * objs_stats = NULL;
266 cpl_vector * sky_bg = NULL;
271 isaac_img_jitter_config.pixscale = -1.0;
272 isaac_img_jitter_config.dit = -1.0;
273 isaac_img_jitter_config.iq = -1.0;
274 isaac_img_jitter_config.nbobjs = -1;
275 isaac_img_jitter_config.fwhm_pix = -1.0;
276 isaac_img_jitter_config.fwhm_arcsec = -1.0;
277 isaac_img_jitter_config.fwhm_mode = -1.0;
278 isaac_img_jitter_config.offsets = NULL;
279 isaac_img_jitter_config.objects = NULL;
280 isaac_img_jitter_config.nb_obj_frames = 0;
281 isaac_img_jitter_config.nb_rej_frames = 0;
282 isaac_img_jitter_config.nb_sky_frames = 0;
286 isaac_img_jitter_config.offsets
287 = irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
291 isaac_img_jitter_config.objects
292 = irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
296 isaac_img_jitter_config.oddeven
297 = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
301 sval = irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
304 bug_if(sval == NULL);
306 skip_if (sscanf(sval,
"%d,%d,%d,%d",
307 &isaac_img_jitter_config.sky_minnb,
308 &isaac_img_jitter_config.sky_halfw,
309 &isaac_img_jitter_config.sky_rejmin,
310 &isaac_img_jitter_config.sky_rejmax) != 4);
313 sval = irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
315 bug_if(sval == NULL);
317 skip_if (sscanf(sval,
"%d,%d,%d,%d",
318 &isaac_img_jitter_config.sx,
319 &isaac_img_jitter_config.sy,
320 &isaac_img_jitter_config.mx,
321 &isaac_img_jitter_config.my) != 4);
324 sval = irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
326 bug_if(sval == NULL);
327 if (!strcmp(sval,
"union"))
328 isaac_img_jitter_config.comb_meth = CPL_GEOM_UNION;
329 else if (!strcmp(sval,
"inter"))
330 isaac_img_jitter_config.comb_meth = CPL_GEOM_INTERSECT;
331 else if (!strcmp(sval,
"first"))
332 isaac_img_jitter_config.comb_meth = CPL_GEOM_FIRST;
334 cpl_msg_error(cpl_func,
"Invalid combine method specified");
339 isaac_img_jitter_config.saa_refine
340 = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
344 sval = irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
346 bug_if(sval == NULL);
347 skip_if (sscanf(sval,
"%d,%d",
348 &isaac_img_jitter_config.rej_low,
349 &isaac_img_jitter_config.rej_high) != 2);
352 isaac_img_jitter_config.row_med
353 = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
366 ISAAC_IMG_JITTER_OBJ_RAW)) != NULL) {
367 isaac_img_jitter_config.chopping = 0;
369 ISAAC_IMG_JITTER_CHOP_RAW)) != NULL) {
370 isaac_img_jitter_config.chopping = 1;
372 cpl_msg_error(cpl_func,
"Cannot find objs frames in the input list");
378 cpl_msg_info(cpl_func,
"Apply the data recombination");
379 cpl_msg_indent_more();
380 if ((combined = isaac_img_jitter_reduce(framelist, parlist, objframes,
382 dark, badpix, &sky_bg)) == NULL) {
383 cpl_msg_error(cpl_func,
"Cannot recombine the data");
384 cpl_msg_indent_less();
387 cpl_msg_indent_less();
390 cpl_msg_info(cpl_func,
"Compute QC parameters from the combined image");
391 cpl_msg_indent_more();
392 if ((objs_stats = isaac_img_jitter_qc(combined[0])) == NULL) {
393 cpl_msg_warning(cpl_func,
"Cannot compute all parameters");
395 cpl_msg_indent_less();
398 cpl_msg_info(cpl_func,
"Save the products");
399 skip_if (isaac_img_jitter_save(framelist, combined[0], combined[1],
400 objs_stats, sky_bg, parlist));
404 cpl_frameset_delete(objframes);
405 cpl_frameset_delete(skyframes);
406 if (combined != NULL) {
407 cpl_image_delete(combined[0]);
408 cpl_image_delete(combined[1]);
411 cpl_table_delete(objs_stats);
412 cpl_vector_delete(sky_bg);
414 return cpl_error_get_code();
430 cpl_image ** isaac_img_jitter_reduce(cpl_frameset * frameset,
431 const cpl_parameterlist * parlist,
432 const cpl_frameset * obj,
433 const cpl_frameset * sky,
439 #ifdef ISAAC_IMG_ERR_ESTIMATE
440 cpl_propertylist * qclist;
444 cpl_image ** combined;
445 cpl_imagelist * corrected;
449 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, NULL);
450 cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
457 cpl_msg_info(cpl_func,
"Load the input data");
458 cpl_msg_indent_more();
459 if ((in = isaac_img_jitter_load(obj, sky)) == NULL) {
460 cpl_msg_error(cpl_func,
"Cannot load input data");
461 cpl_msg_indent_less();
464 cpl_msg_indent_less();
467 if (isaac_img_jitter_config.oddeven) {
468 cpl_msg_info(cpl_func,
"Apply the odd-even effect correction");
469 cpl_msg_indent_more();
470 corrected = cpl_imagelist_new();
471 for (i=0; i<cpl_imagelist_get_size(in[0]); i++) {
472 cpl_msg_info(cpl_func,
"Correct object frame nb %d", i+1);
474 cpl_imagelist_get(in[0], i))) == NULL) {
475 cpl_msg_warning(cpl_func,
"Problem in odd-even corr. %d",i+1);
476 cpl_imagelist_delete(corrected);
480 cpl_imagelist_set(corrected, cur_im, i);
483 if (corrected != NULL) {
484 cpl_imagelist_delete(in[0]);
487 cpl_msg_indent_less();
490 #ifdef ISAAC_IMG_ERR_ESTIMATE
494 err = cpl_imagelist_duplicate(in[0]);
498 cpl_image * dark_image;
500 cpl_msg_info(cpl_func,
"Error propagation: Subtract the dark to the images");
502 if ((dark_image = cpl_image_load(dark, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
503 cpl_msg_error(cpl_func,
"Cannot load the dark %s", dark);
507 if (cpl_imagelist_subtract_image(err, dark_image)!=CPL_ERROR_NONE) {
508 cpl_msg_error(cpl_func,
"Cannot apply the dark to the images");
509 cpl_image_delete(dark_image);
512 cpl_image_delete(dark_image);
519 cpl_msg_info(cpl_func,
"Error propagation: Correct the bad pixels in the images");
521 if ((bpm_im = cpl_image_load(bpm, CPL_TYPE_DOUBLE, 0, 0)) == NULL) {
522 cpl_msg_error(cpl_func,
"Cannot load the bad pixel map %s", bpm);
526 cpl_image_threshold(bpm_im, 0.4, 0.6, 1, 0);
528 cpl_imagelist_multiply_image(err, bpm_im);
531 cpl_image_delete(bpm_im);
534 cpl_imagelist_threshold(err, 1, ISAAC_IMG_SATURATION_LEVEL,
536 cpl_imagelist_divide_scalar(err, ISAAC_IMG_GAIN);
537 cpl_imagelist_power(err, 0.5);
541 cpl_image * flat_image;
542 cpl_msg_info(cpl_func,
"Error propagation: Divide the images by the flatfield");
544 if ((flat_image = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
545 cpl_msg_error(cpl_func,
"Cannot load the flat field %s", flat);
549 if (cpl_imagelist_divide_image(err, flat_image)!=CPL_ERROR_NONE) {
550 cpl_msg_error(cpl_func,
"Cannot apply the flatfield to the images");
551 cpl_image_delete(flat_image);
554 cpl_image_delete(flat_image);
556 cpl_imagelist_threshold(err, 1, ISAAC_IMG_SATURATION_LEVEL,
563 if (flat || dark || bpm) {
564 cpl_msg_info(cpl_func,
"Apply the calibrations");
565 cpl_msg_indent_more();
566 if (irplib_flat_dark_bpm_calib(in[0], flat, dark, bpm) == -1) {
568 cpl_msg_error(cpl_func,
"Cannot calibrate the objects");
569 cpl_imagelist_delete(in[0]);
570 if (in[1]) cpl_imagelist_delete(in[1]);
572 cpl_msg_indent_less();
576 if (irplib_flat_dark_bpm_calib(in[1], flat, dark, bpm) == -1) {
578 cpl_msg_error(cpl_func,
"Cannot calibrate the sky");
579 cpl_imagelist_delete(in[0]);
580 if (in[1]) cpl_imagelist_delete(in[1]);
582 cpl_msg_indent_less();
586 cpl_msg_indent_less();
590 #ifdef ISAAC_IMG_ERR_ESTIMATE
593 qclist = cpl_propertylist_new();
595 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG,
"ISAAC_IMAGELIST");
596 if(cpl_dfs_save_imagelist(frameset,
606 PACKAGE
"/" PACKAGE_VERSION,
607 "isaac_img_imagelist.fits")) {
609 (void)cpl_error_set_where(cpl_func);
612 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG,
"ISAAC_IMAGELISTERR");
613 if(cpl_dfs_save_imagelist(frameset,
623 PACKAGE
"/" PACKAGE_VERSION,
624 "isaac_img_imagelist_error.fits")) {
626 (void)cpl_error_set_where(cpl_func);
629 cpl_propertylist_delete(qclist);
630 cpl_imagelist_delete(err);
634 if (isaac_img_jitter_config.chopping == 0) {
635 cpl_msg_info(cpl_func,
"Sky estimation and correction");
636 cpl_msg_indent_more();
637 if ((*skybg = isaac_img_jitter_sky(&(in[0]), in[1])) == NULL) {
638 cpl_msg_error(cpl_func,
"Cannot estimate the sky");
639 cpl_imagelist_delete(in[0]);
640 if (in[1]) cpl_imagelist_delete(in[1]);
642 cpl_msg_indent_less();
645 cpl_msg_indent_less();
647 isaac_img_jitter_config.nb_obj_frames = cpl_imagelist_get_size(in[0]);
649 isaac_img_jitter_config.nb_sky_frames = cpl_imagelist_get_size(in[1]);
650 if (in[1]) cpl_imagelist_delete(in[1]);
654 cpl_msg_info(cpl_func,
"Shift and add");
655 cpl_msg_indent_more();
656 if (isaac_img_jitter_config.chopping == 0) {
657 combined = isaac_img_jitter_saa_nochop(in[0], obj);
658 }
else if (isaac_img_jitter_config.chopping == 1) {
659 combined = isaac_img_jitter_saa_chop(in[0], obj);
661 if (combined == NULL) {
662 cpl_msg_error(cpl_func,
"Cannot apply the shift and add");
663 cpl_imagelist_delete(in[0]);
665 if (*skybg != NULL) cpl_vector_delete(*skybg);
667 cpl_msg_indent_less();
670 cpl_imagelist_delete(in[0]);
672 cpl_msg_indent_less();
675 if (isaac_img_jitter_config.row_med) {
676 cpl_msg_info(cpl_func,
"Subtract the median from each row");
677 skip_if(isaac_img_jitter_sub_row_median(combined[0]));
693 static cpl_imagelist ** isaac_img_jitter_load(
694 const cpl_frameset * obj,
695 const cpl_frameset * sky)
697 cpl_imagelist ** isets;
698 cpl_imagelist * chop_b;
699 const cpl_frame * frame;
700 cpl_propertylist * plist;
704 if (obj == NULL)
return NULL;
707 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
710 frame = cpl_frameset_get_position_const(obj, 0);
711 cpl_ensure(frame != NULL, cpl_error_get_code(), NULL);
713 plist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
714 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
720 cpl_msg_error(cpl_func,
"Could not get frame type for jitter");
721 cpl_propertylist_delete(plist);
723 }
else if ((isaac_img_jitter_config.chopping==0) && strcmp(sval,
"INT")) {
724 cpl_msg_error(cpl_func,
"Wrong type for jitter: %s - Should be INT",
726 cpl_propertylist_delete(plist);
728 }
else if ((isaac_img_jitter_config.chopping==1) && strcmp(sval,
"CUBE1")) {
729 cpl_msg_error(cpl_func,
"Wrong type for chopping: %s - Should be CUBE1",
731 cpl_propertylist_delete(plist);
734 cpl_propertylist_delete(plist);
735 if (cpl_error_get_code()) {
736 cpl_msg_error(cpl_func,
"Missing keyword in FITS header");
741 isets = cpl_malloc(2 *
sizeof(cpl_imagelist *));
744 if (isaac_img_jitter_config.chopping == 0) {
745 isets[0] = cpl_imagelist_load_frameset(obj, CPL_TYPE_FLOAT, 1, 0);
747 isets[1] = cpl_imagelist_load_frameset(sky, CPL_TYPE_FLOAT, 1, 0);
748 else isets[1] = NULL;
749 }
else if (isaac_img_jitter_config.chopping == 1) {
751 isets[0] = cpl_imagelist_load_frameset(obj, CPL_TYPE_FLOAT, 1, 0);
752 chop_b = cpl_imagelist_load_frameset(obj, CPL_TYPE_FLOAT, 2, 0);
753 cpl_imagelist_subtract(isets[0], chop_b);
754 cpl_imagelist_delete(chop_b);
758 if (isets[0] == NULL) {
759 cpl_msg_error(cpl_func,
"The objects frames could not be loaded");
760 if (isets[1] != NULL) cpl_imagelist_delete(isets[1]);
776 static cpl_vector * isaac_img_jitter_sky(
777 cpl_imagelist ** objs,
778 cpl_imagelist * skys)
790 nframes = cpl_imagelist_get_size(*objs);
793 if (isaac_img_jitter_config.sky_minnb > nframes) sky_method = 1;
798 cpl_msg_info(cpl_func,
"Median of sky images");
800 nskys = cpl_imagelist_get_size(skys);
801 bg = cpl_vector_new(nskys);
802 for (i=0; i<nskys; i++) {
803 median = cpl_image_get_median(cpl_imagelist_get(skys, i));
804 cpl_vector_set(bg, i, median);
807 if ((sky = cpl_imagelist_collapse_median_create(skys)) == NULL) {
808 cpl_msg_error(cpl_func,
"Cannot compute the median of sky images");
809 cpl_vector_delete(bg);
813 if (cpl_imagelist_subtract_image(*objs, sky) != CPL_ERROR_NONE) {
814 cpl_msg_error(cpl_func,
"Cannot corr. the obj images from the sky");
815 cpl_image_delete(sky);
816 cpl_vector_delete(bg);
819 cpl_image_delete(sky);
821 for (i=0; i<nframes; i++) {
822 cur_ima = cpl_imagelist_get(*objs, i);
823 median = cpl_image_get_median(cur_ima);
824 cpl_image_subtract_scalar(cur_ima, median);
826 }
else if (sky_method == 1) {
827 cpl_msg_info(cpl_func,
"Median of object images");
829 if ((sky = cpl_imagelist_collapse_median_create(*objs)) == NULL) {
830 cpl_msg_error(cpl_func,
"Cannot compute the median of obj images");
834 if (cpl_imagelist_subtract_image(*objs, sky) != CPL_ERROR_NONE) {
835 cpl_msg_error(cpl_func,
"Cannot corr. the obj images from the sky");
836 cpl_image_delete(sky);
840 bg = cpl_vector_new(1);
841 cpl_vector_set(bg, 0, cpl_image_get_median(sky));
842 cpl_image_delete(sky);
844 for (i=0; i<nframes; i++) {
845 cur_ima = cpl_imagelist_get(*objs, i);
846 median = cpl_image_get_median(cur_ima);
847 cpl_image_subtract_scalar(cur_ima, median);
849 }
else if (sky_method == 2) {
850 cpl_msg_info(cpl_func,
"Running filter on object images");
852 if ((bg = isaac_img_jitter_sky_running(objs)) == NULL) {
853 cpl_msg_error(cpl_func,
854 "Cannot apply the running filter for the sky");
882 static cpl_vector * isaac_img_jitter_sky_running(cpl_imagelist ** in)
884 int rejmin, rejmax, halfw;
885 cpl_imagelist * filtres;
887 cpl_vector * medians;
892 cpl_vector * localwin;
893 int fr_p, to_p, n_curp;
900 if (in==NULL || *in == NULL)
return NULL;
903 rejmin = isaac_img_jitter_config.sky_rejmin;
904 rejmax = isaac_img_jitter_config.sky_rejmax;
905 halfw = isaac_img_jitter_config.sky_halfw;
906 ni = cpl_imagelist_get_size(*in);
907 cur_ima = cpl_imagelist_get(*in, 0);
908 nx = cpl_image_get_size_x(cur_ima);
909 ny = cpl_image_get_size_y(cur_ima);
912 if (((rejmin+rejmax)>=halfw) || (halfw<1) || (rejmin<0) || (rejmax<0)) {
913 cpl_msg_error(cpl_func,
"cannot run filter with rej parms %d (%d-%d)",
914 halfw, rejmin, rejmax);
918 medians = cpl_vector_new(ni);
919 for (i=0; i<ni; i++) {
920 cur_ima = cpl_imagelist_get(*in, i);
921 cpl_vector_set(medians, i, cpl_image_get_median(cur_ima));
924 filtres = cpl_imagelist_new();
927 bg = cpl_vector_new(ni);
930 for (k=0; k<ni; k++) {
932 tmp_ima = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
933 ptmp_ima = cpl_image_get_data_float(tmp_ima);
938 if (to_p>(ni-1)) to_p=ni-1;
941 n_curp = to_p - fr_p;
944 localwin = cpl_vector_new(n_curp);
948 for (pos=0; pos<nx*ny; pos++) {
951 for (i=fr_p; i<=to_p; i++) {
953 cur_ima = cpl_imagelist_get(*in, i);
954 pcur_ima = cpl_image_get_data_float(cur_ima);
955 cpl_vector_set(localwin, j,
956 (
double)pcur_ima[pos]-cpl_vector_get(medians, i));
961 cpl_vector_sort(localwin, 1);
964 for (i=rejmin; i<(n_curp-rejmax); i++) {
965 out += cpl_vector_get(localwin, i);
968 out /= (double)(n_curp - rejmin - rejmax);
970 cur_ima = cpl_imagelist_get(*in, k);
971 pcur_ima = cpl_image_get_data_float(cur_ima);
972 ptmp_ima[pos] = pcur_ima[pos] -
973 (float)(out + cpl_vector_get(medians, k));
975 bg_val += (out+cpl_vector_get(medians, k));
977 cpl_vector_delete(localwin);
978 cpl_vector_set(bg, k, bg_val/(nx*ny));
979 cpl_imagelist_set(filtres, tmp_ima, k);
981 cpl_imagelist_delete(*in);
982 cpl_vector_delete(medians);
985 for (i=0; i<ni; i++) {
986 cur_ima = cpl_imagelist_get(filtres, i);
987 one_med = cpl_image_get_median(cur_ima);
988 cpl_image_subtract_scalar(cur_ima, one_med);
1002 static cpl_image ** isaac_img_jitter_saa_nochop(
1004 const cpl_frameset * objframes)
1006 const cpl_frame * frame;
1007 cpl_propertylist * plist;
1008 cpl_bivector * offsets_est;
1009 double * offsets_est_x;
1010 double * offsets_est_y;
1011 cpl_bivector * objs;
1014 cpl_apertures * aperts;
1015 cpl_image ** combined;
1016 cpl_vector * thresh_vect;
1021 isaac_img_jitter_config.saa_refine ? 1 : 0;
1025 nfiles = cpl_imagelist_get_size(in);
1026 if (cpl_frameset_get_size(objframes) != nfiles) {
1027 cpl_msg_error(cpl_func,
"Invalid input objects sizes");
1032 cpl_msg_info(cpl_func,
"Get the offsets estimation");
1034 if (isaac_img_jitter_config.offsets &&
1035 isaac_img_jitter_config.offsets[0] != (
char)0) {
1037 offsets_est = cpl_bivector_read(isaac_img_jitter_config.offsets);
1038 if ((offsets_est==NULL)||(cpl_bivector_get_size(offsets_est)!=nfiles)) {
1039 cpl_msg_error(cpl_func,
"Cannot get offsets from %s",
1040 isaac_img_jitter_config.offsets);
1045 offsets_est = cpl_bivector_new(nfiles);
1046 offsets_est_x = cpl_bivector_get_x_data(offsets_est);
1047 offsets_est_y = cpl_bivector_get_y_data(offsets_est);
1048 for (i=0; i<nfiles; i++) {
1049 if (cpl_error_get_code()) {
1050 cpl_bivector_delete(offsets_est);
1055 frame = cpl_frameset_get_position_const(objframes, i);
1056 plist=cpl_propertylist_load(cpl_frame_get_filename(frame),0);
1059 cpl_propertylist_delete(plist);
1060 if (cpl_error_get_code()) {
1061 cpl_msg_warning(cpl_func,
"Cannot get offsets from header");
1062 cpl_bivector_delete(offsets_est);
1068 offsets_est_x[i] -= offsets_est_x[0];
1069 offsets_est_y[i] -= offsets_est_y[0];
1073 offsets_est_x[0] = offsets_est_y[0] = 0.0;
1079 if (isaac_img_jitter_config.objects &&
1080 isaac_img_jitter_config.objects[0] != (
char)0) {
1081 cpl_msg_info(cpl_func,
"Get the user provided correlation objects");
1083 objs = cpl_bivector_read(isaac_img_jitter_config.objects);
1085 cpl_msg_error(cpl_func,
"Cannot get objects from %s",
1086 isaac_img_jitter_config.objects);
1087 if (offsets_est) cpl_bivector_delete(offsets_est);
1094 cpl_msg_info(cpl_func,
"Get a cross-correlation point");
1095 thresh_vect = cpl_vector_new(4);
1096 cpl_vector_set(thresh_vect, 0, 5.0);
1097 cpl_vector_set(thresh_vect, 1, 2.0);
1098 cpl_vector_set(thresh_vect, 2, 1.0);
1099 cpl_vector_set(thresh_vect, 3, 0.5);
1100 diff = cpl_image_subtract_create(cpl_imagelist_get(in, 0),
1101 cpl_imagelist_get(in, 1));
1102 if ((aperts = cpl_apertures_extract_window(diff, thresh_vect,
1103 200, 200, 800, 800, NULL)) == NULL) {
1104 cpl_msg_error(cpl_func,
"Cannot find any cross-correlation point");
1105 if (offsets_est) cpl_bivector_delete(offsets_est);
1106 cpl_vector_delete(thresh_vect);
1107 cpl_image_delete(diff);
1110 cpl_image_delete(diff);
1111 cpl_vector_delete(thresh_vect);
1112 cpl_apertures_sort_by_npix(aperts);
1113 objs = cpl_bivector_new(1);
1114 objs_x = cpl_bivector_get_x_data(objs);
1115 objs_y = cpl_bivector_get_y_data(objs);
1116 objs_x[0] = cpl_apertures_get_pos_x(aperts, 1);
1117 objs_y[0] = cpl_apertures_get_pos_y(aperts, 1);
1118 cpl_apertures_delete(aperts);
1120 cpl_msg_error(cpl_func,
"Cannot find any cross-correlation point");
1121 if (offsets_est) cpl_bivector_delete(offsets_est);
1124 cpl_msg_info(cpl_func,
1125 "Correlation point: %g %g\n", objs_x[0], objs_y[0]);
1129 cpl_msg_info(cpl_func,
"Recombine the images set");
1130 cpl_msg_indent_more();
1131 if ((combined = cpl_geom_img_offset_combine(in, offsets_est, refine, objs,
1133 isaac_img_jitter_config.sx,
1134 isaac_img_jitter_config.sy,
1135 isaac_img_jitter_config.mx,
1136 isaac_img_jitter_config.my,
1137 isaac_img_jitter_config.rej_low,
1138 isaac_img_jitter_config.rej_high,
1139 isaac_img_jitter_config.comb_meth)) == NULL) {
1140 cpl_msg_error(cpl_func,
"Cannot recombine the images");
1141 if (offsets_est) cpl_bivector_delete(offsets_est);
1142 cpl_bivector_delete(objs);
1143 cpl_msg_indent_less();
1147 i = (int)(cpl_image_get_max(combined[1]));
1148 nima = cpl_imagelist_get_size(in);
1149 if ((nima > 3) && (nima>2*
1150 (isaac_img_jitter_config.rej_low+isaac_img_jitter_config.rej_high)))
1151 i += isaac_img_jitter_config.rej_low+isaac_img_jitter_config.rej_high;
1152 isaac_img_jitter_config.nb_rej_frames =
1153 isaac_img_jitter_config.nb_obj_frames - i;
1154 isaac_img_jitter_config.nb_obj_frames = i;
1155 cpl_msg_indent_less();
1158 if (offsets_est) cpl_bivector_delete(offsets_est);
1159 cpl_bivector_delete(objs);
1172 static cpl_image ** isaac_img_jitter_saa_chop(
1174 const cpl_frameset * objframes)
1176 const cpl_frame * frame;
1177 cpl_propertylist * plist;
1178 cpl_bivector * offsets_est;
1179 cpl_bivector * offsets_est_nod;
1180 double * offsets_est_x;
1181 double * offsets_est_y;
1182 double * offsets_est_nod_x;
1183 double * offsets_est_nod_y;
1184 cpl_bivector * objs;
1185 cpl_image ** combined;
1186 cpl_vector * thresh_vect;
1187 int nfiles, nb_chop;
1190 cpl_imagelist * nodded;
1191 cpl_image * tmp_ima;
1193 isaac_img_jitter_config.saa_refine ? 1 : 0;
1197 nfiles = cpl_imagelist_get_size(in);
1198 if (cpl_frameset_get_size(objframes) != nfiles) {
1199 cpl_msg_error(cpl_func,
"Invalid input objects sizes");
1204 cpl_msg_info(cpl_func,
"Get the offsets estimation");
1206 if (isaac_img_jitter_config.offsets &&
1207 isaac_img_jitter_config.offsets[0] != (
char)0) {
1209 offsets_est = cpl_bivector_read(isaac_img_jitter_config.offsets);
1210 if ((offsets_est==NULL) ||
1211 (cpl_bivector_get_size(offsets_est) != nfiles)) {
1212 cpl_msg_error(cpl_func,
"Cannot get offsets from %s",
1213 isaac_img_jitter_config.offsets);
1216 offsets_est_x = cpl_bivector_get_x_data(offsets_est);
1217 offsets_est_y = cpl_bivector_get_y_data(offsets_est);
1220 offsets_est = cpl_bivector_new(nfiles);
1221 offsets_est_x = cpl_bivector_get_x_data(offsets_est);
1222 offsets_est_y = cpl_bivector_get_y_data(offsets_est);
1223 for (i=0; i<nfiles; i++) {
1224 if (cpl_error_get_code()) {
1225 cpl_bivector_delete(offsets_est);
1229 frame = cpl_frameset_get_position_const(objframes, i);
1230 plist=cpl_propertylist_load(cpl_frame_get_filename(frame),0);
1233 cpl_propertylist_delete(plist);
1234 if (cpl_error_get_code()) {
1235 cpl_msg_warning(cpl_func,
"Cannot get offsets from header");
1236 cpl_bivector_delete(offsets_est);
1241 for (i=1; i<nfiles; i++) {
1242 offsets_est_x[i] -= offsets_est_x[0];
1243 offsets_est_y[i] -= offsets_est_y[0];
1245 offsets_est_x[0] = offsets_est_y[0] = 0.00;
1249 if ((nb_chop=isaac_img_jitter_chopping_classif(offsets_est,
1250 &chop_a, &chop_b)) == -1) {
1251 cpl_msg_error(cpl_func,
"cannot classify chopped frames");
1252 cpl_bivector_delete(offsets_est);
1257 nodded = cpl_imagelist_new();
1258 for (i=0; i<nb_chop; i++) {
1259 tmp_ima = cpl_image_subtract_create(
1260 cpl_imagelist_get(in, chop_a[i]),
1261 cpl_imagelist_get(in, chop_b[i]));
1262 cpl_imagelist_set(nodded, tmp_ima, i);
1266 offsets_est_nod = cpl_bivector_new(nb_chop);
1267 offsets_est_nod_x = cpl_bivector_get_x_data(offsets_est_nod);
1268 offsets_est_nod_y = cpl_bivector_get_y_data(offsets_est_nod);
1269 for (i=0; i<nb_chop; i++) {
1270 offsets_est_nod_x[i] = offsets_est_x[chop_a[i]];
1271 offsets_est_nod_y[i] = offsets_est_y[chop_a[i]];
1273 cpl_bivector_delete(offsets_est);
1279 if (isaac_img_jitter_config.objects &&
1280 isaac_img_jitter_config.objects[0] != (
char)0) {
1281 cpl_msg_info(cpl_func,
"Get the user provided correlation objects");
1283 objs = cpl_bivector_read(isaac_img_jitter_config.objects);
1285 cpl_msg_error(cpl_func,
"Cannot get objects from %s",
1286 isaac_img_jitter_config.objects);
1287 cpl_bivector_delete(offsets_est_nod);
1288 cpl_imagelist_delete(nodded);
1294 thresh_vect = cpl_vector_new(4);
1295 cpl_vector_set(thresh_vect, 0, 5.0);
1296 cpl_vector_set(thresh_vect, 1, 2.0);
1297 cpl_vector_set(thresh_vect, 2, 1.0);
1298 cpl_vector_set(thresh_vect, 3, 0.5);
1301 cpl_msg_info(cpl_func,
"Recombine the images set");
1302 cpl_msg_indent_more();
1303 if ((combined = cpl_geom_img_offset_combine(nodded, offsets_est_nod,
1304 refine, objs, thresh_vect, NULL,
1305 isaac_img_jitter_config.sx,
1306 isaac_img_jitter_config.sy,
1307 isaac_img_jitter_config.mx,
1308 isaac_img_jitter_config.my,
1309 isaac_img_jitter_config.rej_low,
1310 isaac_img_jitter_config.rej_high,
1311 isaac_img_jitter_config.comb_meth)) == NULL) {
1312 cpl_msg_error(cpl_func,
"Cannot recombine the images");
1313 cpl_bivector_delete(offsets_est_nod);
1314 cpl_imagelist_delete(nodded);
1315 if (objs) cpl_bivector_delete(objs);
1316 cpl_vector_delete(thresh_vect);
1317 cpl_msg_indent_less();
1321 i = (int)(cpl_image_get_max(combined[1]));
1322 isaac_img_jitter_config.nb_rej_frames =
1323 isaac_img_jitter_config.nb_obj_frames - i;
1324 isaac_img_jitter_config.nb_obj_frames = i;
1325 cpl_msg_indent_less();
1328 cpl_vector_delete(thresh_vect);
1329 cpl_bivector_delete(offsets_est_nod);
1330 cpl_imagelist_delete(nodded);
1331 if (objs) cpl_bivector_delete(objs);
1344 static int isaac_img_jitter_chopping_classif(
1345 cpl_bivector * offsets,
1362 if (offsets==NULL || chop_a==NULL || chop_b==NULL)
return CPL_ERROR_UNSPECIFIED;
1365 *chop_a = *chop_b = NULL;
1368 nb_obj = cpl_bivector_get_size(offsets);
1369 offsets_x = cpl_bivector_get_x_data(offsets);
1370 offsets_y = cpl_bivector_get_y_data(offsets);
1373 if (nb_obj == 0)
return CPL_ERROR_UNSPECIFIED;
1377 cpl_msg_error(cpl_func,
"odd number of frames in input [%d]", nb_obj);
1378 return CPL_ERROR_UNSPECIFIED;
1382 dist = cpl_calloc(nb_obj*nb_obj,
sizeof(
double));
1383 dcount = cpl_calloc(nb_obj*nb_obj,
sizeof(
int));
1384 for (i=0; i<nb_obj; i++) {
1385 for (j=0; j<nb_obj; j++) {
1386 dist[i+j*nb_obj] = sqrt(SQR(offsets_x[i] - offsets_x[j]) +
1387 SQR(offsets_y[i] - offsets_y[j]));
1391 for (i=0; i<nb_obj*nb_obj; i++) {
1392 for (j=0; j<nb_obj*nb_obj; j++)
1393 if (fabs(dist[i]-dist[j]) <= NEGLIG_OFF_DIFF) dcount[i] ++;
1400 for (i=0; i<nb_obj; i++){
1401 for (j=0; j<nb_obj; j++) {
1402 if ((dcount[i+j*nb_obj]>max_count)&&(dist[i+j*nb_obj]>0.5)){
1403 max_count = dcount[i+j*nb_obj];
1411 throw_x = offsets_x[j_max] - offsets_x[i_max];
1412 throw_y = offsets_y[j_max] - offsets_y[i_max];
1414 cpl_msg_info(cpl_func,
"Typical (%d) non-zero throw is (%g, %g) from %d "
1415 "(%g, %g) to %d (%g, %g)", max_count, throw_x, throw_y,
1416 i_max, offsets_x[i_max], offsets_y[i_max],
1417 j_max, offsets_x[j_max], offsets_y[j_max]);
1424 if ((throw_x == 0) && (throw_y == 0)) {
1425 cpl_msg_error(cpl_func,
"Throw is equal to 0 - cannot classify");
1426 return CPL_ERROR_UNSPECIFIED;
1430 *chop_a = cpl_calloc(nb_obj/2,
sizeof(
int));
1431 *chop_b = cpl_calloc(nb_obj/2,
sizeof(
int));
1434 for (i=0; i<nb_obj-1; i++) {
1437 if ((fabs(offsets_x[i]-offsets_x[i+1]+throw_x) < NEGLIG_OFF_DIFF) &&
1438 (fabs(offsets_y[i]-offsets_y[i+1]+throw_y) < NEGLIG_OFF_DIFF)) {
1440 (*chop_b)[l++] = i+1;
1442 }
else if ((fabs(offsets_x[i]-offsets_x[i+1]-throw_x) <
1444 (fabs(offsets_y[i]-offsets_y[i+1]-throw_y) <
1447 (*chop_a)[k++] = i+1;
1452 cpl_msg_info(cpl_func,
"Found %d A- and %d B-frames (out of %d)", k, l,
1456 for (i=0; i<nb_obj; i++) {
1459 for (j=0; j < nb_obj/2; j++) {
1460 if ((*chop_a)[j] == i || (*chop_b)[j] == i) classified = 1;
1462 if (classified == 0) {
1463 cpl_msg_error(cpl_func,
"Frame %d cannot be classified", i+1);
1466 *chop_a = *chop_b = NULL;
1467 return CPL_ERROR_UNSPECIFIED;
1475 *chop_a = *chop_b = NULL;
1476 return CPL_ERROR_UNSPECIFIED;
1489 static cpl_error_code isaac_img_jitter_sub_row_median(cpl_image *
self)
1491 const int nx = cpl_image_get_size_x(
self);
1492 const int ny = cpl_image_get_size_y(
self);
1493 float * pself = cpl_image_get_data_float(
self);
1496 bug_if(
self == NULL);
1497 bug_if(cpl_image_get_type(
self) != CPL_TYPE_FLOAT);
1500 for (j = 0; j < ny; j++, pself += nx) {
1501 cpl_errorstate prestate = cpl_errorstate_get();
1502 const double median = cpl_image_get_median_window(
self, 1, j+1, nx, j+1);
1504 if (cpl_errorstate_is_equal(prestate)) {
1505 for (i = 0; i < nx; i++) {
1506 pself[i] -= (float)median;
1509 cpl_msg_warning(cpl_func,
"Could not subtract median from %d "
1510 "pixel(s) in row %d/%d (%d bad pixel(s))", nx, 1+j,
1511 ny, (
int)cpl_image_count_rejected(
self));
1512 cpl_errorstate_set(prestate);
1518 return cpl_error_get_code();
1528 static cpl_table * isaac_img_jitter_qc(cpl_image * combined)
1530 cpl_vector * thresh_vec;
1531 cpl_apertures * aperts;
1536 cpl_table * out_tab;
1539 cpl_vector * fwhms_good;
1540 double * fwhms_good_data;
1541 double f_min, f_max, fr, fx, fy;
1545 double seeing_min_arcsec = 0.1;
1546 double seeing_max_arcsec = 5.0;
1547 double seeing_fwhm_var = 0.2;
1550 if (combined == NULL)
return NULL;
1553 thresh_vec = cpl_vector_new(4);
1554 cpl_vector_set(thresh_vec, 0, 5.0);
1555 cpl_vector_set(thresh_vec, 1, 2.0);
1556 cpl_vector_set(thresh_vec, 2, 1.0);
1557 cpl_vector_set(thresh_vec, 3, 0.5);
1560 if ((aperts = cpl_apertures_extract(combined, thresh_vec, NULL)) == NULL) {
1561 cpl_msg_error(cpl_func,
"Cannot detect any aperture");
1562 cpl_vector_delete(thresh_vec);
1565 cpl_vector_delete(thresh_vec);
1568 nb_objs = cpl_apertures_get_size(aperts);
1569 isaac_img_jitter_config.nbobjs = nb_objs;
1570 fwhms_x = cpl_malloc(nb_objs *
sizeof(
double));
1571 fwhms_y = cpl_malloc(nb_objs *
sizeof(
double));
1574 out_tab = cpl_table_new(nb_objs);
1575 cpl_table_new_column(out_tab,
"POS_X", CPL_TYPE_DOUBLE);
1576 cpl_table_new_column(out_tab,
"POS_Y", CPL_TYPE_DOUBLE);
1577 cpl_table_new_column(out_tab,
"ANGLE", CPL_TYPE_DOUBLE);
1578 cpl_table_new_column(out_tab,
"FWHM_X", CPL_TYPE_DOUBLE);
1579 cpl_table_new_column(out_tab,
"FWHM_Y", CPL_TYPE_DOUBLE);
1580 cpl_table_new_column(out_tab,
"ELLIP", CPL_TYPE_DOUBLE);
1581 cpl_table_new_column(out_tab,
"FLUX", CPL_TYPE_DOUBLE);
1582 for (i=0; i<nb_objs; i++) {
1584 cpl_table_set_double(out_tab,
"POS_X", i,
1585 cpl_apertures_get_centroid_x(aperts, i+1));
1586 cpl_table_set_double(out_tab,
"POS_Y", i,
1587 cpl_apertures_get_centroid_y(aperts, i+1));
1588 cpl_table_set_double(out_tab,
"FLUX", i,
1589 cpl_apertures_get_flux(aperts, i+1));
1591 if ((iqe = cpl_image_iqe(combined,
1592 (
int)cpl_apertures_get_centroid_x(aperts, i+1) - 10,
1593 (
int)cpl_apertures_get_centroid_y(aperts, i+1) - 10,
1594 (
int)cpl_apertures_get_centroid_x(aperts, i+1) + 10,
1595 (
int)cpl_apertures_get_centroid_y(aperts, i+1) + 10))==NULL){
1597 cpl_msg_warning(cpl_func,
"Cannot get FWHM for obj at pos %g %g",
1598 cpl_apertures_get_centroid_x(aperts, i+1),
1599 cpl_apertures_get_centroid_y(aperts, i+1));
1604 fwhms_x[i] = cpl_vector_get(cpl_bivector_get_x(iqe), 2);
1605 fwhms_y[i] = cpl_vector_get(cpl_bivector_get_x(iqe), 3);
1606 angle = cpl_vector_get(cpl_bivector_get_x(iqe), 4);
1607 cpl_bivector_delete(iqe);
1609 cpl_table_set_double(out_tab,
"ANGLE", i, angle);
1610 cpl_table_set_double(out_tab,
"FWHM_X", i, fwhms_x[i]);
1611 cpl_table_set_double(out_tab,
"FWHM_Y", i, fwhms_y[i]);
1612 if (fwhms_x[i] == 0.0) {
1613 cpl_msg_warning(cpl_func,
"Infinite ELLIP for obj at pos %g %g",
1614 cpl_apertures_get_centroid_x(aperts, i+1),
1615 cpl_apertures_get_centroid_y(aperts, i+1));
1616 cpl_table_set_double(out_tab,
"ELLIP", i, DBL_MAX);
1618 cpl_table_set_double(out_tab,
"ELLIP", i,
1619 fwhms_y[i] / fwhms_x[i]);
1622 cpl_apertures_delete(aperts);
1626 for (i=0; i<nb_objs; i++) {
1627 if ((fwhms_x[i] > 0.0) && (fwhms_y[i] > 0.0)) nb_good++;
1630 cpl_table_delete(out_tab);
1637 fwhms_good = cpl_vector_new(nb_good);
1638 fwhms_good_data = cpl_vector_get_data(fwhms_good);
1640 for (i=0; i<nb_objs; i++) {
1641 if ((fwhms_x[i] > 0.0) && (fwhms_y[i] > 0.0)) {
1642 fwhms_good_data[j] = (fwhms_x[i]+fwhms_y[i])/2.0;
1650 isaac_img_jitter_config.fwhm_pix = fwhms_good_data[0];
1653 isaac_img_jitter_config.fwhm_pix = cpl_vector_get_median_const(fwhms_good);
1655 isaac_img_jitter_config.fwhm_arcsec =
1656 isaac_img_jitter_config.fwhm_pix * isaac_img_jitter_config.pixscale;
1660 isaac_img_jitter_config.fwhm_mode=isaac_img_jitter_get_mode(fwhms_good);
1661 isaac_img_jitter_config.fwhm_mode *= isaac_img_jitter_config.pixscale;
1663 cpl_vector_delete(fwhms_good);
1667 f_min = seeing_min_arcsec / isaac_img_jitter_config.pixscale;
1668 f_max = seeing_max_arcsec / isaac_img_jitter_config.pixscale;
1672 for (i=0; i<nb_objs; i++) {
1675 fr = 2.0 * fabs(fx-fy) / (fx+fy);
1676 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) &&
1677 (fr < seeing_fwhm_var)) nb_good++;
1680 cpl_table_delete(out_tab);
1687 fwhms_good = cpl_vector_new(nb_good);
1688 fwhms_good_data = cpl_vector_get_data(fwhms_good);
1690 for (i=0; i<nb_objs; i++) {
1693 fr = 2.0 * fabs(fx-fy) / (fx+fy);
1694 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) &&
1695 (fr < seeing_fwhm_var)) {
1696 fwhms_good_data[j] = (fx + fy)/2.0;
1706 isaac_img_jitter_config.iq = fwhms_good_data[0];
1709 isaac_img_jitter_config.iq = cpl_vector_get_median_const(fwhms_good);
1711 cpl_vector_delete(fwhms_good);
1712 isaac_img_jitter_config.iq *= isaac_img_jitter_config.pixscale;
1714 isaac_img_jitter_config.angle_med = cpl_table_get_column_median(out_tab,
1716 isaac_img_jitter_config.ellip_med = cpl_table_get_column_median(out_tab,
1728 static double isaac_img_jitter_get_mode(cpl_vector * vec)
1734 cpl_bivector * hist;
1735 cpl_vector * hist_x;
1736 cpl_vector * hist_y;
1745 if (vec == NULL)
return -1.0;
1748 nb = cpl_vector_get_size(vec);
1752 min = cpl_vector_get_min(vec);
1753 max = cpl_vector_get_max(vec);
1754 bin_size = (max-min)/nbins;
1755 hist = cpl_bivector_new(nbins);
1756 hist_x = cpl_bivector_get_x(hist);
1757 hist_y = cpl_bivector_get_y(hist);
1758 cpl_vector_fill(hist_x, 0.0);
1759 cpl_vector_fill(hist_y, 0.0);
1760 for (i=0; i<nbins; i++) {
1761 cpl_vector_set(hist_x, i, min + i * bin_size);
1763 for (i=0; i<nb; i++) {
1764 cur_val = cpl_vector_get(vec, i);
1765 cur_bin = (int)((cur_val - min) / bin_size);
1766 if (cur_bin >= nbins) cur_bin -= 1.0;
1767 cur_val = cpl_vector_get(hist_y, cur_bin);
1769 cpl_vector_set(hist_y, cur_bin, cur_val);
1773 max_val = cpl_vector_get(hist_y, 0);
1775 for (i=0; i<nbins; i++) {
1776 cur_val = cpl_vector_get(hist_y, i);
1777 if (cur_val > max_val) {
1782 mode = cpl_vector_get(hist_x, max_bin);
1783 cpl_bivector_delete(hist);
1801 cpl_error_code isaac_img_jitter_save(cpl_frameset * set,
1802 const cpl_image * combined,
1803 const cpl_image * contrib,
1804 const cpl_table * objs_stats,
1805 const cpl_vector * sky_bg,
1806 const cpl_parameterlist * parlist)
1808 const cpl_frame * ref_frame
1809 = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
1810 const char * filename = cpl_frame_get_filename(ref_frame);
1811 const int sz_skybg = sky_bg ? cpl_vector_get_size(sky_bg) : 0;
1812 cpl_propertylist * plist = NULL;
1813 cpl_propertylist * qclist = cpl_propertylist_new();
1814 const char * wcs_reg =
"(CRVAL|CRPIX|CTYPE)[0-9]+|(CD)[0-9]+_[0-9]+";
1815 cpl_table * sky_bg_tab = NULL;
1819 bug_if(combined == NULL);
1820 bug_if(contrib == NULL);
1821 bug_if(parlist == NULL);
1824 if (isaac_img_jitter_config.chopping == 0) {
1825 const char * key =
"ESO QC BACKGD INSTMAG";
1826 const double pscale = isaac_img_jitter_config.pixscale;
1827 const double dit = isaac_img_jitter_config.dit;
1828 const double bg_mean = cpl_vector_get_mean(sky_bg);
1829 const double bg_stdev = sz_skybg < 2 ? 0.0
1830 : cpl_vector_get_stdev(sky_bg);
1833 bug_if(cpl_propertylist_append_double(qclist,
"ESO QC BACKGD MEAN",
1835 bug_if(cpl_propertylist_append_double(qclist,
"ESO QC BACKGD STDEV",
1838 if (pscale * dit != 0.0 && bg_mean / (pscale * pscale * dit) > 0.0) {
1839 const double bg_instmag = -2.5 * log10(bg_mean/(pscale*pscale*dit));
1841 bug_if(cpl_propertylist_append_double(qclist, key, bg_instmag));
1843 cpl_msg_warning(cpl_func,
"Could not compute %s: dit=%g, pscale=%g, "
1844 "bg_mean=%g", key, dit, pscale, bg_mean);
1848 cpl_propertylist_append_int(qclist,
"ESO QC NBOBJS",
1849 isaac_img_jitter_config.nbobjs);
1850 cpl_propertylist_append_double(qclist,
"ESO QC IQ",
1851 isaac_img_jitter_config.iq);
1852 cpl_propertylist_append_double(qclist,
"ESO QC FWHM PIX",
1853 isaac_img_jitter_config.fwhm_pix);
1854 cpl_propertylist_append_double(qclist,
"ESO QC FWHM ARCSEC",
1855 isaac_img_jitter_config.fwhm_arcsec);
1856 cpl_propertylist_append_double(qclist,
"ESO QC FWHM MODE",
1857 isaac_img_jitter_config.fwhm_mode);
1858 cpl_propertylist_append_int(qclist,
"ESO QC NB_OBJ_F",
1859 isaac_img_jitter_config.nb_obj_frames);
1860 cpl_propertylist_append_int(qclist,
"ESO QC NB_SKY_F",
1861 isaac_img_jitter_config.nb_sky_frames);
1862 cpl_propertylist_append_int(qclist,
"ESO QC NB_REJ_F",
1863 isaac_img_jitter_config.nb_rej_frames);
1864 cpl_propertylist_append_double(qclist,
"ESO QC ANGLE MED",
1865 isaac_img_jitter_config.angle_med);
1866 cpl_propertylist_append_double(qclist,
"ESO QC ELLIP MED",
1867 isaac_img_jitter_config.ellip_med);
1871 plist = cpl_propertylist_load(filename, 0);
1872 skip_if(plist == NULL);
1875 bug_if(cpl_propertylist_copy_property_regexp(qclist, plist, wcs_reg, 0));
1878 (void)cpl_propertylist_erase_regexp(plist,
1879 "^(ARCFILE|MJD-OBS|INSTRUME"
1880 "|ESO TPL ID|ESO TPL NEXP"
1882 "|ESO DPR TECH|ESO DPR TYPE"
1883 "|DATE-OBS|ESO OBS ID"
1884 "|ESO INS PIXSCALE)$", 1);
1887 skip_if(irplib_dfs_save_image(set, parlist, set, combined,
1888 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
1889 ISAAC_IMG_JITTER_COMB, qclist, NULL,
1890 PACKAGE
"/" PACKAGE_VERSION,
1891 RECIPE_STRING CPL_DFS_FITS));
1892 (void)cpl_propertylist_erase_regexp(qclist, wcs_reg, 0);
1895 skip_if (cpl_image_save(contrib, RECIPE_STRING CPL_DFS_FITS,
1896 CPL_BPP_16_UNSIGNED, NULL, CPL_IO_EXTEND));
1898 if (sky_bg != NULL) {
1902 sky_bg_tab = cpl_table_new(sz_skybg);
1904 cpl_table_new_column(sky_bg_tab,
"SKY_BG", CPL_TYPE_DOUBLE);
1906 for (i = 0; i < sz_skybg; i++) {
1907 cpl_table_set_double(sky_bg_tab,
"SKY_BG", i,
1908 cpl_vector_get(sky_bg, i));
1911 skip_if(irplib_dfs_save_table(set, parlist, set, sky_bg_tab, NULL,
1912 RECIPE_STRING, ISAAC_IMG_JITTER_BG,
1913 qclist, NULL, PACKAGE
"/" PACKAGE_VERSION,
1914 RECIPE_STRING
"_bg" CPL_DFS_FITS));
1915 cpl_table_delete(sky_bg_tab);
1921 skip_if(irplib_dfs_save_table(set, parlist, set, objs_stats, NULL,
1922 RECIPE_STRING, ISAAC_IMG_JITTER_STARS,
1923 qclist, NULL, PACKAGE
"/" PACKAGE_VERSION,
1924 RECIPE_STRING
"_stars" CPL_DFS_FITS));
1927 bug_if(cpl_propertylist_append(plist, qclist));
1928 cpl_propertylist_empty(qclist);
1931 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG,
1932 ISAAC_IMG_JITTER_COMB);
1935 skip_if (cpl_dfs_save_paf(
"ISAAC", RECIPE_STRING, plist,
1936 RECIPE_STRING CPL_DFS_PAF));
1940 cpl_propertylist_delete(plist);
1941 cpl_propertylist_delete(qclist);
1942 cpl_table_delete(sky_bg_tab);
1944 return cpl_error_get_code();
int isaac_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
const char * isaac_pfits_get_frame_type(const cpl_propertylist *plist)
find out the frame type
double isaac_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
double isaac_pfits_get_pixscale(const cpl_propertylist *plist)
find out the pixel scale
double isaac_pfits_get_cumoffsety(const cpl_propertylist *plist)
find out the cumulative offset in Y
double isaac_pfits_get_cumoffsetx(const cpl_propertylist *plist)
find out the cumulative offset in X
const char * isaac_extract_filename(const cpl_frameset *self, const char *tag)
Extract the filename of the first frame of the given tag.
cpl_image * isaac_oddeven_correct(const cpl_image *in)
Correct the odd/even in an image.
cpl_frameset * isaac_extract_frameset(const cpl_frameset *self, const char *tag)
Extract the frames with the given tag from a frameset.