36 #include "naco_recipe.h"
37 #include "naco_strehl.h"
39 #include "irplib_strehl.h"
40 #include "irplib_wcs.h"
41 #include "irplib_stdstar.h"
49 #define RECIPE_STRING "naco_img_zpoint"
52 typedef enum _NACO_BAND_ {
76 static cpl_table * naco_img_zpoint_reduce(cpl_propertylist *,
77 const irplib_framelist *,
78 const cpl_parameterlist *,
79 const char *,
const char *,
82 static cpl_error_code naco_img_zpoint_qc(cpl_propertylist *,
84 const irplib_framelist *);
86 static cpl_error_code naco_img_zpoint_save(cpl_frameset *,
87 const cpl_parameterlist *,
88 const cpl_propertylist *,
89 const cpl_propertylist *,
93 static cpl_error_code naco_img_zpoint_reduce_one(cpl_table *, cpl_vector *,
int,
95 const cpl_parameterlist *,
96 const char *,
double,
double,
97 double,
double *,
double *,
98 double *,
double *,
double *);
100 static double naco_img_zpoint_find_mag(cpl_propertylist *,
double,
double,
101 const char *,
const char *);
103 static cpl_table * naco_img_zpoint_load_std_star(
const char *,
double,
double,
double);
105 static cpl_error_code naco_img_zpoint_find_std_star(cpl_table *,
112 static cpl_error_code naco_img_zpoint_qc_all(cpl_propertylist *,
114 const irplib_framelist *);
116 static cpl_error_code naco_img_zpoint_check_im(cpl_image **,
const cpl_image *,
117 int,
int,
double,
double,
118 double,
double,
double);
120 static naco_band naco_get_bbfilter(
const char *);
122 static const char * naco_std_band_name(naco_band);
125 NACO_RECIPE_DEFINE(naco_img_zpoint,
136 "Zero point computation recipe",
137 RECIPE_STRING
" -- Zero point recipe\n"
138 "The files listed in the Set Of Frames (sof-file) "
140 "NACO-raw-file.fits " NACO_IMG_ZPOINT_CHOP
" or\n"
141 "NACO-raw-file.fits " NACO_IMG_ZPOINT_JITTER
".\n"
142 "NACO-Imaging-Standard-Star-Catalog.fits "
143 NACO_IMG_STD_CAT
"\n"
144 "Optionally, a flat field frame may be inluded:\n"
145 "NACO-flat-file.fits " NACO_CALIB_FLAT
"\n");
158 double phot_star_radius;
164 } naco_img_zpoint_config;
186 static int naco_img_zpoint(cpl_frameset * framelist,
187 const cpl_parameterlist * parlist)
189 irplib_framelist* allframes = NULL;
190 irplib_framelist* rawframes = NULL;
191 cpl_propertylist* qclist = cpl_propertylist_new();
192 cpl_propertylist* paflist = cpl_propertylist_new();
194 const char * star_cat;
195 cpl_table * tab = NULL;
196 cpl_image * check_im = NULL;
200 naco_img_zpoint_config.ra
203 naco_img_zpoint_config.dec
206 naco_img_zpoint_config.pscale
209 naco_img_zpoint_config.magnitude
212 naco_img_zpoint_config.sx
215 skip_if_lt(naco_img_zpoint_config.sx, 1,
216 "for the size of the search window in X-direction [pixel]");
219 naco_img_zpoint_config.sy
222 skip_if_lt(naco_img_zpoint_config.sy, 1,
223 "for the size of the search window in Y-direction [pixel]");
226 naco_img_zpoint_config.phot_star_radius
230 naco_img_zpoint_config.phot_bg_r1
234 naco_img_zpoint_config.phot_bg_r2
238 naco_img_zpoint_config.check_im
244 allframes = irplib_framelist_cast(framelist);
245 skip_if(allframes == NULL);
247 rawframes = irplib_framelist_extract_regexp(allframes,
248 "^(" NACO_IMG_ZPOINT_JITTER
249 "|" NACO_IMG_ZPOINT_CHOP
")$",
251 skip_if(rawframes == NULL);
252 irplib_framelist_empty(allframes);
255 star_cat = irplib_frameset_find_file(framelist, NACO_IMG_STD_CAT);
256 error_if (star_cat == NULL, CPL_ERROR_DATA_NOT_FOUND,
"The input "
257 "file(s) have no star catalog tagged %s", NACO_IMG_STD_CAT);
260 flat = irplib_frameset_find_file(framelist, NACO_CALIB_FLAT);
263 skip_if( irplib_framelist_load_propertylist(rawframes, 0, 0,
"^("
264 IRPLIB_PFITS_REGEXP_RECAL
"|"
265 NACO_PFITS_REGEXP_ZPOINT
"|"
266 NACO_PFITS_REGEXP_ZPOINT_PAF
"|"
267 NACO_PFITS_REGEXP_ZPOINT_REF
270 skip_if(irplib_framelist_load_propertylist_all(rawframes, 0,
"^("
271 NACO_PFITS_REGEXP_ZPOINT
275 tab = naco_img_zpoint_reduce(qclist, rawframes, parlist, star_cat, flat,
277 skip_if (tab == NULL);
279 skip_if(naco_img_zpoint_qc(qclist, paflist, rawframes));
282 irplib_framelist_empty(rawframes);
285 bug_if (cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
286 NACO_IMG_ZPOINT_RES));
289 skip_if (naco_img_zpoint_save(framelist, parlist, qclist, paflist, tab,
294 cpl_table_delete(tab);
295 cpl_image_delete(check_im);
296 irplib_framelist_delete(allframes);
297 irplib_framelist_delete(rawframes);
298 cpl_propertylist_delete(qclist);
299 cpl_propertylist_delete(paflist);
301 return cpl_error_get_code();
317 static cpl_table * naco_img_zpoint_reduce(cpl_propertylist * qclist,
318 const irplib_framelist * rawframes,
319 const cpl_parameterlist * parlist,
320 const char * star_cat,
322 cpl_image ** pcheck_im)
324 cpl_errorstate prestate = cpl_errorstate_get();
325 const cpl_propertylist * plist
326 = irplib_framelist_get_propertylist_const(rawframes, 0);
327 cpl_image * flat_im = NULL;
328 cpl_image * rawimage = NULL;
329 cpl_image * imdiff = NULL;
331 const int ndiff = 2 * irplib_framelist_get_size(rawframes)-2;
332 double pos_x_cen = DBL_MAX;
333 double pos_y_cen = DBL_MAX;
334 cpl_apertures * aperts = NULL;
335 double psigmas[] = {20.0, 10.0, 8.0, 6.0, 5.0};
336 const int nsigmas = (int)(
sizeof(psigmas)/
sizeof(double));
338 cpl_vector * sigmas = NULL;
339 cpl_table * out_tab = NULL;
340 cpl_vector * zpoints = NULL;
341 cpl_stats * fstats = NULL;
343 double off_x0 = DBL_MAX;
344 double off_y0 = DBL_MAX;
345 double off_x = DBL_MAX;
346 double off_y = DBL_MAX;
347 double str_sum = 0.0;
348 double str_err_sum = 0.0;
351 double bg_no_sum = 0.0;
370 bug_if (pcheck_im == NULL);
371 bug_if (*pcheck_im != NULL);
373 skip_if_lt(ndiff/2+1, 3,
"raw frames");
378 skip_if (dit <= 0.0);
379 if (naco_img_zpoint_config.ra > 998.0)
381 if (naco_img_zpoint_config.dec > 998.0)
385 if (naco_img_zpoint_config.pscale <= 0.0) {
387 skip_if(naco_img_zpoint_config.pscale <= 0.0);
390 cpl_msg_info(cpl_func,
"Using star at position: RA = %g ; DEC = %g",
391 naco_img_zpoint_config.ra, naco_img_zpoint_config.dec);
397 if (naco_img_zpoint_config.magnitude > IRPLIB_STDSTAR_LIMIT) {
398 naco_img_zpoint_config.magnitude
399 = naco_img_zpoint_find_mag(qclist,
400 naco_img_zpoint_config.ra,
401 naco_img_zpoint_config.dec,
403 if (cpl_error_get_code()) {
404 const cpl_propertylist * reflist
405 = irplib_framelist_get_propertylist_const(rawframes, 0);
408 if (starname != NULL) {
409 error_if (0, cpl_error_get_code(),
"Star '%s' has "
410 "no magnitude for filter '%s' in catalogue '%s'",
411 starname, filter, star_cat);
415 cpl_msg_info(cpl_func,
"Star magnitude with filter %s : %g", filter,
416 naco_img_zpoint_config.magnitude);
417 bug_if(cpl_propertylist_append_double(qclist,
"ESO QC STARMAG",
418 naco_img_zpoint_config.magnitude));
420 zpoints = cpl_vector_new(ndiff);
421 out_tab = cpl_table_new(ndiff);
422 cpl_table_new_column(out_tab,
"POSX", CPL_TYPE_DOUBLE);
423 cpl_table_new_column(out_tab,
"POSY", CPL_TYPE_DOUBLE);
424 cpl_table_new_column(out_tab,
"ZPOINT", CPL_TYPE_DOUBLE);
425 cpl_table_new_column(out_tab,
"PEAK", CPL_TYPE_DOUBLE);
426 cpl_table_new_column(out_tab,
"FLUX", CPL_TYPE_DOUBLE);
427 cpl_table_new_column(out_tab,
"BGD_NOISE", CPL_TYPE_DOUBLE);
428 cpl_table_new_column(out_tab,
"STREHL", CPL_TYPE_DOUBLE);
429 cpl_table_new_column(out_tab,
"STREHL_ERR", CPL_TYPE_DOUBLE);
430 cpl_table_new_column(out_tab,
"BGD", CPL_TYPE_DOUBLE);
431 cpl_table_new_column(out_tab,
"FWHMX", CPL_TYPE_DOUBLE);
432 cpl_table_new_column(out_tab,
"FWHMY", CPL_TYPE_DOUBLE);
437 flat_im = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, 0);
439 if (flat_im == NULL) {
440 cpl_msg_error(cpl_func,
"Could not load flat field %s", flat);
443 fstats = cpl_stats_new_from_image(flat_im, CPL_STATS_ALL);
444 if (cpl_stats_get_min(fstats) <= 0.0) {
445 cpl_msg_warning(cpl_func,
"Setting non-positive (down to %g) "
446 "flat field pixels to 1",
447 cpl_stats_get_min(fstats));
448 bug_if(cpl_image_threshold(flat_im, 0.0, DBL_MAX, 1.0,
454 cpl_msg_info(cpl_func,
"Loading the image from raw frame %d",1);
455 rawimage = cpl_image_load(cpl_frame_get_filename(
456 irplib_framelist_get_const(rawframes, 0)),
457 CPL_TYPE_FLOAT, 0, 0);
458 if (rawimage == NULL) {
459 cpl_msg_error(cpl_func,
"Could not load image from first raw frame");
463 for (i=0; i < ndiff; i++) {
466 double str, str_err, pe, fl, bg_no;
471 if (i == 0 || i % 2 == 1) {
487 cpl_msg_info(cpl_func,
"Offsets for difference image %d: (%g,%g)",
492 plist = irplib_framelist_get_propertylist_const(rawframes,
497 const char * filename = cpl_frame_get_filename(
498 irplib_framelist_get_const(rawframes, 1+i/2));
502 cpl_image_delete(imdiff);
505 cpl_msg_info(cpl_func,
"Loading the image from raw frame %d",2+i/2);
506 rawimage = cpl_image_load(filename, CPL_TYPE_FLOAT, 0, 0);
507 if (rawimage == NULL) {
508 cpl_msg_error(cpl_func,
"Could not load image %d", 2+i/2);
511 bug_if(cpl_image_subtract(imdiff, rawimage));
512 if (flat_im != NULL) skip_if(cpl_image_divide(imdiff, flat_im));
514 bug_if(cpl_image_multiply_scalar(imdiff, -1.0));
518 double min_dist = DBL_MAX;
519 const int size_x = cpl_image_get_size_x(imdiff);
520 const int size_y = cpl_image_get_size_y(imdiff);
524 cpl_msg_info(cpl_func,
"Detecting a bright object in the first "
525 "difference image using %d sigma-levels ranging from "
526 "%g down to %g", nsigmas, psigmas[0],
528 sigmas = cpl_vector_wrap(nsigmas, psigmas);
530 aperts = cpl_apertures_extract(imdiff, sigmas, &isigma);
531 if (aperts == NULL || cpl_apertures_get_size(aperts) < 1) {
532 cpl_msg_error(cpl_func,
"Could not detect any bright object");
535 for (iap=0; iap < cpl_apertures_get_size(aperts); iap++) {
537 = cpl_apertures_get_centroid_x(aperts, iap+1) - size_x/2.0;
539 = cpl_apertures_get_centroid_y(aperts, iap+1) - size_y/2.0;
540 const double dist = d_x * d_x + d_y * d_y;
541 if (iap == 0 || dist < min_dist) {
547 cpl_apertures_delete(aperts);
550 pos_x_cen += size_x/2.0;
551 pos_y_cen += size_y/2.0;
552 cpl_msg_info(cpl_func,
"Detected a bright object at sigma=%g, at "
553 "position: %g %g", psigmas[isigma], pos_x_cen,
558 pos_x = pos_x_cen + off_x;
559 pos_y = pos_y_cen + off_y;
563 const double opos_x = pos_x;
564 const double opos_y = pos_y;
565 const int llx = (int)pos_x - naco_img_zpoint_config.sx;
566 const int urx = (
int)pos_x + naco_img_zpoint_config.sx;
567 const int lly = (int)pos_y - naco_img_zpoint_config.sy;
568 const int ury = (
int)pos_y + naco_img_zpoint_config.sy;
569 pos_x = cpl_image_get_centroid_x_window(imdiff, llx, lly, urx, ury);
570 pos_y = cpl_image_get_centroid_y_window(imdiff, llx, lly, urx, ury);
571 error_if (0, cpl_error_get_code(),
"Could not refine the positions "
572 "of difference image %d", i+1);
573 cpl_msg_info(cpl_func,
"For difference image %d refined object "
574 "position (x,y): (%g,%g) -> (%g,%g)", i,
575 opos_x, opos_y, pos_x, pos_y);
581 if (naco_img_zpoint_config.check_im) {
582 const double r1 = naco_img_zpoint_config.phot_star_radius
583 /naco_img_zpoint_config.pscale;
584 const double r2 = naco_img_zpoint_config.phot_bg_r1
585 /naco_img_zpoint_config.pscale;
586 const double r3 = naco_img_zpoint_config.phot_bg_r2
587 /naco_img_zpoint_config.pscale;
589 skip_if(naco_img_zpoint_check_im(pcheck_im, imdiff, i, ndiff,
590 pos_x, pos_y, r1, r2, r3));
594 code = naco_img_zpoint_reduce_one(out_tab, zpoints, i, imdiff,
597 &str, &str_err, &pe, &fl, &bg_no);
599 cpl_msg_warning(cpl_func,
"Strehl computation for difference image "
600 "%d at (x,y)=(%g,%g) failed:", i+1, pos_x, pos_y);
601 cpl_errorstate_dump(prestate, CPL_FALSE,
602 cpl_errorstate_dump_one_warning);
603 cpl_errorstate_set(prestate);
605 }
else if (str <= 0.0 || str >= 1.0) {
606 cpl_msg_info(cpl_func,
"Excluding from statistics non-physical "
607 "Strehl ratio for difference image %d at (x,y)=(%g,%g)"
608 ": %g", i+1, pos_x, pos_y, str);
616 str_err_sum += str_err;
622 skip_if_lt(nok_strehl, 1,
"valid strehl measurements");
624 strehl = str_sum / (double)nok_strehl;
625 strehl_err = str_err_sum / (double)nok_strehl;
626 strehl_rms = bg_no_sum / (double)nok_strehl;
627 star_peak = pe_sum / (double)nok_strehl;
628 star_flux = fl_sum / (double)nok_strehl;
631 cpl_vector_sort(zpoints, 1);
633 for (i=1; i < ndiff-1; i++) {
634 const double zp = cpl_vector_get(zpoints, i);
641 cpl_vector_delete(zpoints);
644 skip_if_lt(nok_zp, 1,
"valid zpoint measurements");
646 avg_zp /= (double)nok_zp;
647 sqsum /= (double)nok_zp;
648 zpointrms = sqsum - avg_zp * avg_zp;
649 zpointrms = zpointrms > 0.0 ? sqrt(zpointrms) : 0.0;
652 cpl_msg_info(cpl_func,
"***** FINAL RESULTS *****");
653 cpl_msg_info(cpl_func,
"Strehl : %g", strehl);
654 cpl_msg_info(cpl_func,
"Strehl error : %g", strehl_err);
655 cpl_msg_info(cpl_func,
"Peak : %g", star_peak);
656 cpl_msg_info(cpl_func,
"Flux : %g", star_flux);
657 cpl_msg_info(cpl_func,
"Strehl RMS %g", strehl_rms);
658 cpl_msg_info(cpl_func,
"Zero point : %g", avg_zp);
659 cpl_msg_info(cpl_func,
"Zero p. RMS: %g", zpointrms);
661 cpl_propertylist_append_double(qclist,
"ESO QC ZPOINT", avg_zp);
662 cpl_propertylist_append_double(qclist,
"ESO QC ZPOINTRMS", zpointrms);
663 cpl_propertylist_append_double(qclist,
"ESO QC STREHL", strehl);
664 cpl_propertylist_append_double(qclist,
"ESO QC STREHL ERROR", strehl_err);
665 cpl_propertylist_append_double(qclist,
"ESO QC STREHL RMS", strehl_rms);
666 cpl_propertylist_append_double(qclist,
"ESO QC STREHL PEAK", star_peak);
667 cpl_propertylist_append_double(qclist,
"ESO QC STREHL FLUX", star_flux);
668 cpl_propertylist_append_string(qclist,
"ESO QC FILTER OBS", filter);
674 cpl_stats_delete(fstats);
675 cpl_image_delete(rawimage);
676 cpl_image_delete(imdiff);
677 cpl_image_delete(flat_im);
678 cpl_apertures_delete(aperts);
679 cpl_vector_unwrap(sigmas);
680 cpl_vector_delete(zpoints);
682 if (cpl_error_get_code()) {
683 cpl_image_delete(*pcheck_im);
685 cpl_table_delete(out_tab);
713 static cpl_error_code naco_img_zpoint_check_im(cpl_image **
self,
714 const cpl_image * imdiff,
723 const float * pin_ima = cpl_image_get_data_float_const(imdiff);
725 const int in_nx = cpl_image_get_size_x(imdiff);
726 const int in_ny = cpl_image_get_size_y(imdiff);
727 const int box_sz = 2 * (int)r3 + 1;
728 const int nx = box_sz * nima;
729 const int ny = box_sz;
731 const int llx = (int)(pos_x - r3);
732 const int lly = (int)(pos_y - r3);
738 bug_if(
self == NULL);
744 bug_if(*
self != NULL);
746 cpl_msg_info(cpl_func,
"Creating %d X %d X %d check-image",
747 nima, box_sz, box_sz);
750 *
self = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
753 pout_ima = cpl_image_get_data_float(*
self);
757 for (j=0; j < box_sz; j++) {
758 if (j + lly < 0 || j + lly >= in_ny)
continue;
759 for (i=0; i < box_sz; i++) {
760 if (i + llx >= 0 && i + llx < in_nx) {
761 const int in_pos = llx + i + (lly+j) * in_nx;
762 const int out_pos = (box_sz * idiff) + i + j * nx;
764 bug_if ( in_pos < 0 || in_pos >= in_nx*in_ny);
765 bug_if (out_pos < 0 || out_pos >= nx* ny);
767 pout_ima[out_pos] = pin_ima[in_pos];
774 const double sqr1 = sqrt(r1*r1);
775 const double sqr2 = sqrt(r2*r2);
776 const double sqr3 = sqrt(r3*r3);
777 for (j=0; j < box_sz; j++) {
778 const int jdist = j - box_sz/2;
779 for (i=0; i < box_sz; i++) {
780 const int idist = i - box_sz/2;
782 = sqrt((
double)(idist * idist + jdist * jdist));
783 if (fabs(dist-sqr1) < 0.5 ||
784 fabs(dist-sqr2) < 0.5 ||
785 fabs(dist-sqr3) < 0.5) pout_ima[i + j * nx] = 10000;
792 return cpl_error_get_code();
818 cpl_error_code naco_img_zpoint_reduce_one(cpl_table * zptab,
819 cpl_vector * zpoints,
821 const cpl_image *
self,
822 const cpl_parameterlist * parlist,
828 double * pstrehl_err,
833 cpl_errorstate cleanstate = cpl_errorstate_get();
834 double zeropoint, background;
837 double star_bg, psf_peak, psf_flux;
838 double fwhm_x, fwhm_y;
841 bug_if(pstar_flux == NULL);
842 bug_if(filter == NULL);
845 r = naco_img_zpoint_config.phot_star_radius/naco_img_zpoint_config.pscale;
846 r1 = naco_img_zpoint_config.phot_bg_r1/naco_img_zpoint_config.pscale;
847 r2 = naco_img_zpoint_config.phot_bg_r2/naco_img_zpoint_config.pscale;
848 background = irplib_strehl_ring_background(
self, pos_x, pos_y, r1, r2,
849 IRPLIB_BG_METHOD_AVER_REJ);
851 *pstar_flux = irplib_strehl_disk_flux(
self, pos_x, pos_y, r, background);
856 "Cannot get filter infos [%s]", filter);
861 naco_img_zpoint_config.pscale,
862 pstrehl, pstrehl_err, &star_bg,
863 pstar_peak, pstar_flux,
864 &psf_peak, &psf_flux, pbg_noise),
865 "Could not compute the Strehl ratio. r=%g <= r1=%g < r2=%g",
869 if (cpl_image_get_fwhm(
self, (
int)pos_x, (
int)pos_y, &fwhm_x, &fwhm_y)) {
870 irplib_error_recover(cleanstate,
"Could not compute FWHM for image %d:",
872 fwhm_x = fwhm_y = 0.0;
875 cpl_msg_warning(cpl_func,
"Could not compute FWHM in x for image "
880 cpl_msg_warning(cpl_func,
"Could not compute FWHM in y for image "
886 zeropoint = naco_img_zpoint_config.magnitude + 2.5 * log10(*pstar_flux/dit);
888 cpl_msg_info(cpl_func,
"Strehl : %g", *pstrehl);
889 cpl_msg_info(cpl_func,
"Strehl error : %g", *pstrehl_err);
890 cpl_msg_info(cpl_func,
"Peak : %g", *pstar_peak);
891 cpl_msg_info(cpl_func,
"Flux : %g", *pstar_flux);
892 cpl_msg_info(cpl_func,
"Background : %g", background);
893 cpl_msg_info(cpl_func,
"Bg noise : %g", *pbg_noise);
894 cpl_msg_info(cpl_func,
"Zero point : %g", zeropoint);
895 cpl_msg_info(cpl_func,
"FWHM in x : %g", fwhm_x);
896 cpl_msg_info(cpl_func,
"FWHM in y : %g", fwhm_y);
899 cpl_vector_set(zpoints, idiff, zeropoint);
900 cpl_table_set_double(zptab,
"POSX", idiff, pos_x);
901 cpl_table_set_double(zptab,
"POSY", idiff, pos_y);
902 cpl_table_set_double(zptab,
"ZPOINT", idiff, zeropoint);
903 cpl_table_set_double(zptab,
"PEAK", idiff, *pstar_peak);
904 cpl_table_set_double(zptab,
"FLUX", idiff, *pstar_flux);
905 cpl_table_set_double(zptab,
"BGD_NOISE", idiff, *pbg_noise);
906 cpl_table_set_double(zptab,
"STREHL", idiff, *pstrehl);
907 cpl_table_set_double(zptab,
"STREHL_ERR", idiff, *pstrehl_err);
908 cpl_table_set_double(zptab,
"BGD", idiff, background);
909 cpl_table_set_double(zptab,
"FWHMX", idiff, fwhm_x);
910 cpl_table_set_double(zptab,
"FWHMY", idiff, fwhm_y);
916 if (cpl_error_get_code())
917 cpl_msg_error(cpl_func,
"Cannot reduce the image %d", idiff+1);
919 return cpl_error_get_code();
934 static double naco_img_zpoint_find_mag(cpl_propertylist * qclist,
937 const char * star_cat,
940 cpl_error_code error;
941 const char * star_name;
942 const char * star_type;
943 const char * cat_name;
945 double star_mag = 0.0;
947 const char * bandname = NULL;
948 cpl_table * stdstars = NULL;
949 const char * sw_cat[] = {
"LCO-Palomar",
"LCO-Palomar-NICMOS-Red-Stars",
950 "ESO-VanDerBliek",
"UKIRT-Extended",
951 "UKIRT-Fundamental",
"SAAO-Carter", NULL};
952 const char * lw_cat[] = {
"ESO-VanDerBliek",
"UKIRT-Standards",
955 bug_if (filter == NULL);
957 cpl_msg_info(cpl_func,
"Get the star magnitude with filter: %s", filter);
959 band = naco_get_bbfilter(filter);
964 stdstars = naco_img_zpoint_load_std_star(star_cat, ra, dec,
965 (IRPLIB_STDSTAR_MAXDIST)/60.0);
967 skip_if(stdstars == NULL);
968 skip_if(cpl_table_get_nrow(stdstars) == 0);
979 bandname = naco_std_band_name(band);
981 error = naco_img_zpoint_find_std_star(stdstars, sw_cat, ra, dec,
982 bandname, CPL_FALSE, &istar);
985 if (istar >= 0)
break;
989 if (band == BAND_K) {
990 bandname = naco_std_band_name(BAND_KS);
992 cpl_msg_info(cpl_func,
"Retrying with alternative band: %s",
995 error = naco_img_zpoint_find_std_star(stdstars, sw_cat, ra, dec,
996 bandname, CPL_TRUE, &istar);
998 }
else if (band == BAND_KS) {
999 bandname = naco_std_band_name(BAND_K);
1001 cpl_msg_info(cpl_func,
"Retrying with alternative band: %s",
1004 error = naco_img_zpoint_find_std_star(stdstars, sw_cat, ra, dec,
1005 bandname, CPL_TRUE, &istar);
1015 bandname = naco_std_band_name(band);
1017 error = naco_img_zpoint_find_std_star(stdstars, lw_cat, ra, dec,
1018 bandname, CPL_FALSE, &istar);
1022 naco_band other = BAND_UNKNOWN;
1041 bandname = naco_std_band_name(other);
1043 cpl_msg_info(cpl_func,
"Retrying with alternative band: %s",
1046 error = naco_img_zpoint_find_std_star(stdstars, lw_cat, ra, dec,
1047 bandname, CPL_TRUE, &istar);
1054 error_if (error || istar < 0, CPL_ERROR_DATA_NOT_FOUND,
"Star magnitude "
1055 "for filter '%s' not found in catalog(s) at (RA,DEC)=(%g,%g)"
1056 " with tolerance=%g (degrees)", filter, ra, dec,
1057 IRPLIB_STDSTAR_MAXDIST/60.0);
1059 star_mag = cpl_table_get_double(stdstars, bandname, istar, NULL);
1060 star_name = cpl_table_get_string(stdstars, IRPLIB_STDSTAR_STAR_COL, istar);
1061 star_type = cpl_table_get_string(stdstars, IRPLIB_STDSTAR_TYPE_COL, istar);
1062 cat_name = cpl_table_get_string(stdstars,
"CAT_NAME", istar);
1066 bug_if(cpl_propertylist_append_string(qclist,
"ESO QC STDNAME",
1068 bug_if(cpl_propertylist_append_string(qclist,
"ESO QC CATNAME",
1070 bug_if(cpl_propertylist_append_string(qclist,
"ESO QC SPECTYPE",
1073 cpl_msg_info(cpl_func,
"Found standard star '%s' of type '%s' with "
1074 "magnitude %g for filter %s from catalog '%s'",
1075 star_name, star_type, star_mag, bandname, cat_name);
1079 cpl_table_delete(stdstars);
1108 static cpl_error_code naco_img_zpoint_find_std_star(cpl_table *
self,
1110 double ra,
double dec,
1111 const char * bandname,
1116 double min_dist = IRPLIB_STDSTAR_MAXDIST / 60.0;
1119 bug_if (pistar == NULL);
1122 bug_if (
self == NULL);
1123 bug_if (bandname == NULL);
1126 ? cpl_table_or_selected_double
1127 : cpl_table_and_selected_double)(
self, bandname,
1129 IRPLIB_STDSTAR_LIMIT);
1132 cpl_msg_info(cpl_func,
"None of the standard star catalog(s) have "
1133 "a star with a known magnitude for band %s within a "
1134 "distance of tol=%g [degrees] from (RA,DEC)=(%g,%g)",
1135 bandname, min_dist, ra, dec);
1141 const int nrows = cpl_table_get_nrow(
self);
1147 bug_if (cat == NULL);
1149 for (icat = 0; cat[icat] != NULL; icat++) {
1151 char * regexp = cpl_sprintf(
"^%s$", cat[icat]);
1153 cpl_msg_info(cpl_func,
"Trying %s", cat[icat]);
1155 nsel = cpl_table_and_selected_string(
self,
"CAT_NAME",
1156 CPL_EQUAL_TO, regexp);
1159 if (nsel > 0)
break;
1162 nsel = cpl_table_or_selected_double(
self, bandname,
1164 IRPLIB_STDSTAR_LIMIT);
1172 for (i=0; i < nrows; i++) {
1173 if (cpl_table_is_selected(
self, i)) {
1175 const double distance
1176 = irplib_wcs_great_circle_dist(ra, dec,
1177 cpl_table_get_double(
self, IRPLIB_STDSTAR_RA_COL, i, NULL),
1178 cpl_table_get_double(
self, IRPLIB_STDSTAR_DEC_COL, i,NULL));
1180 if (distance < min_dist) {
1181 min_dist = distance;
1189 cpl_msg_info(cpl_func,
"Found %d star(s) with known magnitude in band "
1190 "%s - selected one with distance %g", nsel, bandname,
1198 return cpl_error_get_code();
1212 static cpl_error_code naco_img_zpoint_qc(cpl_propertylist * qclist,
1213 cpl_propertylist * paflist,
1214 const irplib_framelist * rawframes)
1217 cpl_errorstate cleanstate = cpl_errorstate_get();
1218 const cpl_propertylist * reflist
1219 = irplib_framelist_get_propertylist_const(rawframes, 0);
1227 bug_if(cpl_propertylist_copy_property_regexp(paflist, reflist,
"^("
1228 NACO_PFITS_REGEXP_ZPOINT_PAF
1235 naco_error_reset(
"Could not get FITS key:");
1237 bug_if(cpl_propertylist_append_string(qclist,
"ESO QC FILTER NDENS",
1241 naco_error_reset(
"Could not get FITS key:");
1243 bug_if(cpl_propertylist_append_string(qclist,
"ESO QC FILTER POL",
1246 skip_if (naco_img_zpoint_qc_all(qclist, paflist, rawframes));
1248 bug_if(cpl_propertylist_append(paflist, qclist));
1250 bug_if(cpl_propertylist_copy_property_regexp(qclist, reflist,
"^("
1251 IRPLIB_PFITS_REGEXP_RECAL
1255 bug_if(cpl_propertylist_append_double(qclist,
"ESO QC AIRMASS",
1256 irplib_pfits_get_double(qclist,
1261 return cpl_error_get_code();
1277 static cpl_error_code naco_img_zpoint_save(cpl_frameset * set,
1278 const cpl_parameterlist * parlist,
1279 const cpl_propertylist * qclist,
1280 const cpl_propertylist * paflist,
1281 const cpl_table * tab,
1282 const cpl_image * check_im)
1288 skip_if (irplib_dfs_save_table(set, parlist, set, tab, NULL, RECIPE_STRING,
1289 NACO_IMG_ZPOINT_RES, qclist, NULL, naco_pipe_id,
1290 RECIPE_STRING CPL_DFS_FITS));
1295 skip_if (irplib_dfs_save_image(set, parlist, set, check_im,
1296 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
1297 NACO_IMG_ZPOINT_CHECK, qclist, NULL,
1299 RECIPE_STRING
"_check" CPL_DFS_FITS));
1301 skip_if (cpl_dfs_save_paf(
"NACO", RECIPE_STRING, paflist,
1302 RECIPE_STRING CPL_DFS_PAF));
1306 return cpl_error_get_code();
1319 static cpl_error_code naco_img_zpoint_qc_all(cpl_propertylist * qclist,
1320 cpl_propertylist * paflist,
1321 const irplib_framelist * rawframes)
1323 const int nframes = irplib_framelist_get_size(rawframes);
1324 cpl_vector * ec_vec = cpl_vector_new(nframes);
1325 cpl_vector * flux_vec = cpl_vector_new(nframes);
1326 cpl_vector * l0_vec = cpl_vector_new(nframes);
1327 cpl_vector * t0_vec = cpl_vector_new(nframes);
1328 cpl_vector * r0_vec = cpl_vector_new(nframes);
1329 cpl_vector * hum_vec = cpl_vector_new(nframes);
1330 double ec, flux, l0, t0, r0, hum;
1336 bug_if(nframes <= 0);
1338 for (i = 0; i < nframes; i++) {
1339 const cpl_propertylist * plist
1340 = irplib_framelist_get_propertylist_const(rawframes, i);
1349 skip_if(cpl_vector_set(hum_vec, i,
1356 ec = cpl_vector_get_median(ec_vec);
1357 flux = cpl_vector_get_median(flux_vec);
1358 l0 = cpl_vector_get_median(l0_vec);
1359 t0 = cpl_vector_get_median(t0_vec);
1360 r0 = cpl_vector_get_median(r0_vec);
1361 hum = cpl_vector_get_mean(hum_vec);
1364 cpl_propertylist_append_double(qclist,
"ESO QC AMBI RHUM AVG", hum);
1365 cpl_propertylist_append_double(paflist,
1366 "ESO AOS RTC DET DST L0MEAN", l0);
1367 cpl_propertylist_append_double(paflist,
1368 "ESO AOS RTC DET DST T0MEAN", t0);
1369 cpl_propertylist_append_double(paflist,
1370 "ESO AOS RTC DET DST R0MEAN", r0);
1371 cpl_propertylist_append_double(paflist,
1372 "ESO AOS RTC DET DST ECMEAN", ec);
1373 cpl_propertylist_append_double(paflist,
1374 "ESO AOS RTC DET DST FLUXMEAN", flux);
1380 cpl_vector_delete(ec_vec);
1381 cpl_vector_delete(flux_vec);
1382 cpl_vector_delete(r0_vec);
1383 cpl_vector_delete(t0_vec);
1384 cpl_vector_delete(l0_vec);
1385 cpl_vector_delete(hum_vec);
1387 return cpl_error_get_code();
1399 static naco_band naco_get_bbfilter(
const char * filter)
1401 naco_band
self = BAND_UNKNOWN;
1404 bug_if (filter == NULL);
1406 if (!strcmp(filter,
"J"))
self = BAND_J;
1407 else if (!strcmp(filter,
"Jc"))
self = BAND_J;
1408 else if (!strcmp(filter,
"H"))
self = BAND_H;
1409 else if (!strcmp(filter,
"K"))
self = BAND_K;
1410 else if (!strcmp(filter,
"Ks"))
self = BAND_KS;
1411 else if (!strcmp(filter,
"L"))
self = BAND_L;
1412 else if (!strcmp(filter,
"L_prime"))
self = BAND_LP;
1413 else if (!strcmp(filter,
"M_prime"))
self = BAND_MP;
1414 else if (!strcmp(filter,
"NB_1.04"))
self = BAND_J;
1415 else if (!strcmp(filter,
"NB_1.08"))
self = BAND_J;
1416 else if (!strcmp(filter,
"NB_1.09"))
self = BAND_J;
1417 else if (!strcmp(filter,
"NB_1.24"))
self = BAND_J;
1418 else if (!strcmp(filter,
"NB_1.26"))
self = BAND_J;
1419 else if (!strcmp(filter,
"NB_1.28"))
self = BAND_J;
1420 else if (!strcmp(filter,
"NB_1.64"))
self = BAND_H;
1421 else if (!strcmp(filter,
"NB_1.75"))
self = BAND_H;
1422 else if (!strcmp(filter,
"NB_3.74"))
self = BAND_L;
1423 else if (!strcmp(filter,
"IB_2.00"))
self = BAND_K;
1424 else if (!strcmp(filter,
"IB_2.03"))
self = BAND_K;
1425 else if (!strcmp(filter,
"IB_2.06"))
self = BAND_K;
1426 else if (!strcmp(filter,
"IB_2.09"))
self = BAND_K;
1427 else if (!strcmp(filter,
"IB_2.12"))
self = BAND_K;
1428 else if (!strcmp(filter,
"NB_2.12"))
self = BAND_K;
1429 else if (!strcmp(filter,
"IB_2.15"))
self = BAND_K;
1430 else if (!strcmp(filter,
"NB_2.17"))
self = BAND_K;
1431 else if (!strcmp(filter,
"IB_2.18"))
self = BAND_K;
1432 else if (!strcmp(filter,
"IB_2.21"))
self = BAND_K;
1433 else if (!strcmp(filter,
"IB_2.24"))
self = BAND_K;
1434 else if (!strcmp(filter,
"IB_2.27"))
self = BAND_K;
1435 else if (!strcmp(filter,
"IB_2.30"))
self = BAND_K;
1436 else if (!strcmp(filter,
"IB_2.33"))
self = BAND_K;
1437 else if (!strcmp(filter,
"IB_2.36"))
self = BAND_K;
1438 else if (!strcmp(filter,
"IB_2.39"))
self = BAND_K;
1439 else if (!strcmp(filter,
"IB_2.42"))
self = BAND_K;
1440 else if (!strcmp(filter,
"IB_2.45"))
self = BAND_K;
1441 else if (!strcmp(filter,
"IB_2.48"))
self = BAND_K;
1442 else if (!strcmp(filter,
"NB_4.05"))
self = BAND_M;
1444 else if (!strcmp(filter,
"IB_4.05"))
self = BAND_M;
1445 else if (!strcmp(filter,
"SJ"))
self = BAND_UNKNOWN;
1446 else if (!strcmp(filter,
"SH"))
self = BAND_UNKNOWN;
1447 else if (!strcmp(filter,
"SK"))
self = BAND_UNKNOWN;
1449 error_if (
self == BAND_UNKNOWN, CPL_ERROR_UNSUPPORTED_MODE,
"No broad-"
1450 "band could be associated with the filter: %s", filter);
1470 static cpl_table * naco_img_zpoint_load_std_star(
const char * star_cat,
1471 double ra,
double dec,
1475 cpl_table *
self = cpl_table_load(star_cat, 1, 0);
1477 = cpl_table_get_data_double_const(
self, IRPLIB_STDSTAR_RA_COL);
1479 = cpl_table_get_data_double_const(
self, IRPLIB_STDSTAR_DEC_COL);
1480 const int nrow = cpl_table_get_nrow(
self);
1483 skip_if(
self == NULL);
1484 bug_if(star_cat == NULL);
1485 skip_if(pra == NULL);
1486 skip_if(pdec == NULL);
1489 bug_if(cpl_table_unselect_all(
self));
1491 for (i = 0; i < nrow; i++) {
1492 const double deci = pdec[i];
1494 if (deci > dec + tol ||
1496 irplib_wcs_great_circle_dist(ra, dec, pra[i], deci) > tol) {
1498 bug_if(cpl_table_select_row(
self, i));
1503 if (cpl_table_count_selected(
self) == nrow) {
1504 double mindist = DBL_MAX;
1507 for (i = 0; i < nrow; i++) {
1509 = irplib_wcs_great_circle_dist(ra, dec, pra[i], pdec[i]);
1511 if (i == 0 || dist < mindist) {
1517 (void)cpl_error_set_message_macro(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1518 __FILE__, __LINE__,
"Catalog '%s' "
1519 "star %d of %d at (RA,DEC)=(%g,%g) "
1520 "is closest to target at "
1521 "(RA,DEC)=(%g,%g) with a too large "
1522 "distance of %g [degrees] > %g",
1523 star_cat, 1+idist, nrow, pra[idist],
1524 pdec[idist], ra, dec, mindist, tol);
1527 bug_if(cpl_table_erase_selected(
self));
1529 cpl_msg_info(cpl_func,
"Loaded %d of %d stars from '%s' which are within "
1530 "%g degrees from (RA,DEC)=(%g,%g)",
1531 (
int)cpl_table_get_nrow(
self), nrow, star_cat, tol, ra, dec);
1532 if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
1533 cpl_table_dump(
self, 0, cpl_table_get_nrow(
self), stdout);
1550 static const char * naco_std_band_name(naco_band band)
1553 case BAND_J:
return "J";
1554 case BAND_JS:
return "Js";
1555 case BAND_JBLOCK:
return "J+Block";
1556 case BAND_H:
return "H";
1557 case BAND_K:
return "K";
1558 case BAND_KS:
return "Ks";
1559 case BAND_L:
return "L";
1560 case BAND_M:
return "M";
1561 case BAND_LP:
return "Lp";
1562 case BAND_MP:
return "Mp";
1563 case BAND_Z:
return "Z";
1564 case BAND_SZ:
return "SZ";
1565 case BAND_SH:
return "SH";
1566 case BAND_SK:
return "SK";
1567 case BAND_SL:
return "SL";
1568 default:
return "Unknown";