ERIS Pipeline Reference Manual 1.8.15
eris/eris_ifu_strehl.c
1/* $Id: eris_ifu_strehl.c,v 1.9 2013-03-26 17:00:44 jtaylor Exp $
2 *
3 * This file is part of the ERIS Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
26/*-----------------------------------------------------------------------------
27 Includes
28 -----------------------------------------------------------------------------*/
29
30#include <eris_ifu_strehl.h>
31#include <eris_ifu_jitter_interface.h>
32#include <eris_ifu_wavecal_static.h>
33#include <eris_utils.h>
34#include <eris_pfits.h>
35#include <eris_ifu_utils.h>
36#include <string.h>
37#include <cpl.h>
38#include <hdrl.h>
39
40#define M1_RADIUS 8.15
41#define M2_RADIUS 0.9
42#define ERIS_IFU_RAW_BPM "RAW_BPM"
43#define ERIS_IFU_RAW_ERROR "RAW_ERROR"
44/*----------------------------------------------------------------------------*/
106/*----------------------------------------------------------------------------*/
107
110#define HDRL_PARAMETER_HEAD void * base
112typedef struct {
113 HDRL_PARAMETER_HEAD;
114 cpl_size llx ;
115 cpl_size lly ;
116 cpl_size urx ;
117 cpl_size ury ;
118} hdrl_rect_region_parameter;
119
120/*----------------------------------------------------------------------------*/
136/*----------------------------------------------------------------------------*/
137static cpl_error_code eris_ifu_propertylist_save(
138 const char * procatg,
139 const char * filename,
140 const cpl_propertylist * header,
141 const cpl_parameterlist * parlist,
142 cpl_frameset * frameset)
143{
144 /* Add a QC parameter */
145 cpl_propertylist * applist = cpl_propertylist_new();
146
147 /* Add the product category and save image */
148 cpl_propertylist_update_string(applist, CPL_DFS_PRO_CATG, procatg);
149
150 cpl_dfs_save_propertylist(frameset, NULL, parlist, frameset, NULL,
151 "ERIS_IFU_STREHL", header, NULL, PACKAGE "/" PACKAGE_VERSION,
152 filename);
153 cpl_propertylist_delete(applist);
154 eris_check_error_code("eris_ifu_propertylist_save");
155 return cpl_error_get_code();
156}
157
158
159
160/*----------------------------------------------------------------------------*/
184/*----------------------------------------------------------------------------*/
185static cpl_error_code hdrl_rect_region_fix_negatives(
186 hdrl_parameter * rect_region,
187 const cpl_size nx,
188 const cpl_size ny)
189{
190 hdrl_rect_region_parameter * rr_loc =
191 (hdrl_rect_region_parameter *)rect_region ;
192
193 cpl_error_ensure(rect_region != 0, CPL_ERROR_NULL_INPUT,
194 return CPL_ERROR_NULL_INPUT, "region input must not be NULL");
195 cpl_error_ensure(hdrl_rect_region_parameter_check(rect_region),
196 CPL_ERROR_ILLEGAL_INPUT, return CPL_ERROR_ILLEGAL_INPUT,
197 "Expected Rect Region parameter") ;
198
199 if (nx > 0 && rr_loc->llx < 1) rr_loc->llx += nx;
200 if (ny > 0 && rr_loc->lly < 1) rr_loc->lly += ny;
201 if (nx > 0 && rr_loc->urx < 1) rr_loc->urx += nx;
202 if (ny > 0 && rr_loc->ury < 1) rr_loc->ury += ny;
203
204 return hdrl_rect_region_parameter_verify(rect_region, nx, ny);
205}
206
207/*----------------------------------------------------------------------------*/
239/*----------------------------------------------------------------------------*/
240static cpl_error_code
241eris_ifu_detector_shotnoise_model(const cpl_image* ima_data, const double gain,
242 const double ron, cpl_image ** ima_errs)
243{
244 cpl_ensure_code(ima_data, CPL_ERROR_NULL_INPUT);
245 cpl_ensure_code(ima_errs, CPL_ERROR_NULL_INPUT);
246 cpl_ensure_code(gain > 0., CPL_ERROR_ILLEGAL_INPUT);
247 cpl_ensure_code(ron > 0., CPL_ERROR_ILLEGAL_INPUT);
248
249 *ima_errs = cpl_image_duplicate(ima_data);
250 /* set negative values (= zero measurable electrons) to read out noise */
251 cpl_image_threshold(*ima_errs, 0., INFINITY, ron, ron);
252
253 /* err_ADU = sqrt(counts/gain + ron * ron)*/
254
255 cpl_image_divide_scalar(*ima_errs, gain);
256 cpl_image_add_scalar(*ima_errs, ron * ron);
257 cpl_image_power(*ima_errs, 0.5);
258 eris_check_error_code("eris_ifu_detector_shotnoise_model");
259 return cpl_error_get_code();
260}
261
262
263
264/* ---------------------------------------------------------------------------*/
279/* ---------------------------------------------------------------------------*/
280static cpl_error_code
281eris_ifu_fix_neg_region(const cpl_frame * frm, cpl_size extnum,
282 hdrl_parameter * par)
283{
284 cpl_propertylist * plist =
285 cpl_propertylist_load(cpl_frame_get_filename(frm), extnum);
286 if (!plist) {
287 return cpl_error_get_code();
288 }
289 cpl_size nx = eris_pfits_get_naxis1(plist);
290 cpl_size ny = eris_pfits_get_naxis2(plist);
292 cpl_propertylist_delete(plist);
293 eris_check_error_code("eris_ifu_fix_neg_region");
294 return cpl_error_get_code();
295}
296
297/* ---------------------------------------------------------------------------*/
313/* ---------------------------------------------------------------------------*/
314static cpl_image * eris_ifu_image_mef_load_region(
315 cpl_frame * frm,
316 cpl_size eidx,
317 hdrl_parameter * region_params)
318{
319 cpl_image * out = NULL ;
320
321 if (region_params == NULL) {
322 out = cpl_image_load(cpl_frame_get_filename(frm),
323 CPL_TYPE_DOUBLE, 0, eidx);
324 } else {
325 eris_ifu_fix_neg_region(frm, eidx, region_params);
326 out = cpl_image_load_window(cpl_frame_get_filename(frm),
327 CPL_TYPE_DOUBLE, 0, eidx,
328 hdrl_rect_region_get_llx(region_params),
329 hdrl_rect_region_get_lly(region_params),
330 hdrl_rect_region_get_urx(region_params),
331 hdrl_rect_region_get_ury(region_params)) ;
332 }
333 eris_check_error_code("eris_ifu_image_mef_load_region");
334 return out ;
335}
336
337
338/*----------------------------------------------------------------------------*/
373/*----------------------------------------------------------------------------*/
374static cpl_error_code eris_ifu_hdrl_image_load(
375 cpl_frame * in,
376 cpl_size ext_num,
377 cpl_frame * in_err,
378 cpl_size ext_num_err,
379 cpl_frame * in_bpm,
380 cpl_size ext_num_bpm,
381 hdrl_parameter * region_params,
382 double ron,
383 double gain,
384 hdrl_image ** out_hdrl_ima)
385{
386 cpl_image * img ;
387
388 /* Check Entries */
389 cpl_ensure_code(in, CPL_ERROR_NULL_INPUT);
390 cpl_ensure_code(out_hdrl_ima, CPL_ERROR_NULL_INPUT);
391
392 /* Load in image */
393 img = eris_ifu_image_mef_load_region(in, ext_num, region_params);
394 if (img == NULL) return CPL_ERROR_ILLEGAL_INPUT ;
395
396 /* Load BPM */
397 if (in_bpm != NULL) {
398 cpl_image * bpm = eris_ifu_image_mef_load_region(in_bpm, ext_num_bpm, region_params);
399 cpl_mask * bpm_mask = cpl_mask_threshold_image_create(bpm,
400 -0.5, 0.5) ;
401 cpl_image_delete(bpm) ;
402 cpl_mask_not(bpm_mask) ;
403 cpl_image_reject_from_mask(img, bpm_mask);
404 cpl_mask_delete(bpm_mask) ;
405 }
406
407 /* Load error */
408 cpl_image * err =NULL;
409 if (in_err != NULL) {
410 err = eris_ifu_image_mef_load_region(in_err, ext_num_err, region_params);
411 } else if (ron < 0. && gain < 0.) {
412 /* no error */
413 err = NULL;
414 } else {
415 /* No passed error -> Create uniform error */
416 eris_ifu_detector_shotnoise_model(img, gain, ron, &err);
417 }
418
419 /* Create out himage */
420 *out_hdrl_ima = hdrl_image_create(img, err);
421
422 /* Cleanup */
423 cpl_image_delete(img);
424 cpl_image_delete(err);
425 eris_check_error_code("eris_ifu_hdrl_image_load");
426 return cpl_error_get_code();
427}
428
429/*----------------------------------------------------------------------------*/
461/*----------------------------------------------------------------------------*/
462/*TODO: NOT USED
463static cpl_error_code
464eris_ifu_strehl_calculate(hdrl_image* hima,
465 const double wavelength,
466 const double m1_radius,
467 const double m2_radius,
468 const double pixel_scale_x,
469 const double pixel_scale_y,
470 const double flux_radius,
471 const double bkg_radius_low,
472 const double bkg_radius_high)
473{
474
475
476 hdrl_parameter * strehl_p = hdrl_strehl_parameter_create(wavelength, m1_radius,
477 m2_radius, pixel_scale_x, pixel_scale_y, flux_radius, bkg_radius_low,
478 bkg_radius_high);
479 return cpl_error_get_code();
480}
481*/
482/*----------------------------------------------------------------------------*/
500/*----------------------------------------------------------------------------*/
501
502cpl_error_code
503eris_ifu_strehl_compute(cpl_frameset * frameset, const cpl_parameterlist * parlist,
504 const char* recipe_name)
505{
506
507 int extnum_raw = 0;
508 int extnum_err = 1;
509 int extnum_bpm = 2;
510 hdrl_strehl_result res;
511
512 cpl_frame * in_frm ;
513 cpl_frame * err_frm ;
514 cpl_frame * bpm_frm ;
515 hdrl_image * hima ;
516 hdrl_parameter * region_params = NULL;
517
518 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
519 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
520 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
521 /* Check initial Entries */
522 if (eris_ifu_dfs_set_groups(frameset) != CPL_ERROR_NONE) {
523 return cpl_error_get_code();
524 }
525
526 /* Get parameters*/
527 /* those params are not needed
528 *
529 * char* param_name = NULL;
530 * const cpl_parameter * par = NULL;
531 param_name = cpl_sprintf("%s.ext-nb-raw", recipe_name);
532 par = cpl_parameterlist_find_const(parlist, param_name);
533 extnum_raw = cpl_parameter_get_int(par);
534 cpl_free(param_name);
535
536 param_name = cpl_sprintf("%s.ext-nb-raw-err", recipe_name);
537 par = cpl_parameterlist_find_const(parlist, param_name);
538 extnum_err = cpl_parameter_get_int(par);
539 cpl_free(param_name);
540
541 param_name = cpl_sprintf("%s.ext-nb-raw-bpm", recipe_name);
542 par = cpl_parameterlist_find_const(parlist, param_name);
543 extnum_bpm = cpl_parameter_get_int(par);
544 cpl_free(param_name);
545 */
546
547 /* Parse the Strehl Parameters */
548 hdrl_parameter * p = hdrl_strehl_parameter_parse_parlist(parlist,
549 recipe_name);
550 if (p == NULL) {
551 return cpl_error_set_message(cpl_func, CPL_ERROR_UNSPECIFIED,
552 "Parsing of the strehl parameters failed");
553 }
554
555 /* Parse the Region Parameters
556 region_params=hdrl_rect_region_parameter_parse_parlist(parlist,
557 recipe_name, "region-") ;
558 if (region_params == NULL) {
559 hdrl_parameter_delete(p);
560 return cpl_error_set_message(cpl_func, CPL_ERROR_UNSPECIFIED,
561 "Parsing of the region parameters failed");
562 }
563 */
564
565 /* Load INPUT Data */
566 /* Get the first Required frame */
567 if ((in_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_CUBE))==NULL) {
568 //if (region_params) hdrl_parameter_delete(region_params) ;
569 if (p) hdrl_parameter_delete(p) ;
570 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
571 "Missing RAW file");
572 }
573 //bpm_frm = cpl_frameset_find(frameset, ERIS_IFU_RAW_BPM) ;
574 //err_frm = cpl_frameset_find(frameset, ERIS_IFU_RAW_ERROR) ;
575 int sx = 0;
576 int sy = 0;
577 const char* fname = cpl_frame_get_filename(in_frm);
578 cpl_image* in_ima = cpl_image_load(fname,CPL_TYPE_FLOAT, 0, 0);
579 sx = cpl_image_get_size_x(in_ima);
580 sy = cpl_image_get_size_y(in_ima);
581 bpm_frm = in_frm;
582 err_frm = in_frm;
583 cpl_propertylist* plist = cpl_propertylist_load(fname,0);
584 double ron = cpl_propertylist_get_double(plist,"ESO DET CHIP RON");
585 double gain = cpl_propertylist_get_double(plist,"ESO DET CHIP GAIN");
586 cpl_propertylist_delete(plist);
587 cpl_image_delete(in_ima);
588 region_params = hdrl_rect_region_parameter_create(1, 1, sx, sy);
589 /* Load the image */
590 if (eris_ifu_hdrl_image_load(in_frm, extnum_raw, err_frm, extnum_err,
591 bpm_frm, extnum_bpm, region_params, ron, gain,
592 &hima) != CPL_ERROR_NONE) {
593 if (region_params) hdrl_parameter_delete(region_params) ;
594 if (p) hdrl_parameter_delete(p) ;
595 return cpl_error_set_message(cpl_func, CPL_ERROR_FILE_NOT_FOUND,
596 "Cannot load RAW image");
597 }
598 if (region_params) hdrl_parameter_delete(region_params) ;
599
600
601 /* This is not needed as ERRORS are provided by the input data
602 if(err_frm == NULL) {
603 // Replace the error image created by the ron/gain by the mad-scaled
604 // rms of the image
605 double dmad = 0.;
606 cpl_image * img = cpl_image_load(cpl_frame_get_filename(in_frm),
607 CPL_TYPE_DOUBLE, 0, extnum_raw);
608 cpl_image_get_mad(img, &dmad);
609 cpl_image_delete(img);
610
611 cpl_image_multiply_scalar(hdrl_image_get_error(hima), 0.);
612 cpl_image_add_scalar(hdrl_image_get_error(hima),
613 (dmad * CPL_MATH_STD_MAD));
614 }
615 */
616 cpl_msg_info(cpl_func,"Handles NANs");
618 /* Strehl COMPUTATION */
619 res = hdrl_strehl_compute(hima, p);
621 cpl_msg_info(cpl_func,"strehl=%g+-%g", res.strehl_value.data,
622 res.strehl_value.error);
623 /* expected difference sqrt(pi / 2) due to median */
624 cpl_msg_info(cpl_func, "star peak at %g/%g: %g +- %g", res.star_x,
625 res.star_y, res.star_peak.data, res.star_peak.error);
626 cpl_msg_info(cpl_func, "star flux %g+-%g", res.star_flux.data,
627 res.star_flux.error);
628 cpl_msg_info(cpl_func,"median estimated background=%g+-%g "
629 "(computed error %g)",
630 res.star_background.data, res.star_background.error,
631 res.computed_background_error);
632 cpl_propertylist* header=cpl_propertylist_new();
633 cpl_propertylist_update_double(header, "ESO QC STREHL",
634 res.strehl_value.data);
635 cpl_propertylist_update_double(header, "ESO QC STREHL ERROR",
636 res.strehl_value.error);
637 cpl_propertylist_update_string(header, CPL_DFS_PRO_CATG, "ERIS_IFU_STREHL");
638
639 eris_ifu_propertylist_save("ERIS_IFU_STREHL","eris_ifu_strehl.fits", header,
640 parlist,frameset);
641
642
643 /* Cleanup */
644 cpl_propertylist_delete(header);
645 hdrl_image_delete(hima);
646 /* In case of Poisson error model: */
647 eris_check_error_code("eris_ifu_strehl_compute");
648 return cpl_error_get_code();
649}
650
651/*----------------------------------------------------------------------------*/
734/*----------------------------------------------------------------------------*/
735
736cpl_error_code
737eris_ifu_stdstar_strehl_compute(cpl_frameset * frameset,
738 const cpl_parameterlist * parlist,
739 const char* context/*,
740 const char* recipe_name*/)
741{
742 //const cpl_parameter * par = NULL;
743 int extnum_raw = 1;
744 int extnum_err = 2;
745 int extnum_bpm = 3;
746 hdrl_strehl_result res;
747
748 cpl_frame * in_frm = NULL ;
749 cpl_frame * err_frm ;
750 cpl_frame * bpm_frm ;
751 hdrl_image * hima ;
752 hdrl_parameter * region_params = NULL;
753 char* param_name = NULL;
754
755 double wavelength = 0;
756 //ifsPreopticsScale = eris_ifu_get_spiffier_preoptics_scale(sof->band);
757 double pixel_scale_x = 0;
758 double pixel_scale_y = 0;
759 double flux_radius_pix = 1;
760 double bkg_radius_low = 1;
761 double bkg_radius_high = 1.5;
762
763 cpl_ensure_code(frameset,CPL_ERROR_NULL_INPUT);
764 cpl_ensure_code(parlist,CPL_ERROR_NULL_INPUT);
765 cpl_ensure_code(context,CPL_ERROR_NULL_INPUT);
766
767 param_name = cpl_sprintf("%s.strehl_flux_radius", context);
768 flux_radius_pix = cpl_parameter_get_double(
769 cpl_parameterlist_find_const(parlist, param_name));
770 cpl_free(param_name);
771
772
773 param_name = cpl_sprintf("%s.strehl_bkg-radius-low", context);
774 bkg_radius_low = cpl_parameter_get_double(
775 cpl_parameterlist_find_const(parlist, param_name));
776 cpl_free(param_name);
777
778
779 param_name = cpl_sprintf("%s.strehl_bkg-radius-high", context);
780 bkg_radius_high = cpl_parameter_get_double(
781 cpl_parameterlist_find_const(parlist, param_name));
782 cpl_free(param_name);
783
784
785 ifsBand band = UNDEFINED_BAND;
786 ifsPreopticsScale scale = UNDEFINED_SCALE;
787 ifsInstrument instrument = UNSET_INSTRUMENT;
788 eris_ifu_jitter_get_instrument_settings(frameset, &instrument, &band, &scale);
789
790 switch(scale) {
791 case S250MAS:
792 pixel_scale_x = 0.250;
793 break;
794
795 case S100MAS:
796 pixel_scale_x = 0.100;
797 break;
798
799 case S25MAS:
800 pixel_scale_x = 0.025;
801 break;
802
803 case UNDEFINED_SCALE:
804 pixel_scale_x = 0.025;
805 break;
806 //TODO: FOLLOWING TO BE VERIFIED
807 case PUPIL:
808 pixel_scale_x = 0.100;
809 break;
810 }
811 eris_ifu_get_central_lambda(band, &wavelength);
812 wavelength *= 1.e-6; /* convert to [m] */
813 pixel_scale_y = pixel_scale_x;
814 cpl_msg_info(cpl_func,"pixel_scale: %g [arcsec]",pixel_scale_x);
815 /* Determine flux_radius, bkg_radius_low, bkg_radius_high from QC.FWHM
816 * on cube collapsed median*/
817 cpl_frame* std_frm;
818 cpl_frame* std_flux_frm;
819 cpl_frame* psf_frm;
820 //cpl_frameset_dump(frameset,stdout);
821 std_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_MEDIAN);
822 std_flux_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_MEDIAN);
823 psf_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD_MEDIAN);
824 if ( (std_frm == NULL) && (psf_frm == NULL) && (std_flux_frm == NULL)) {
825 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
826 "Missing ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD_MEDIAN file, Cannot compute Strehl,");
827 } else {
828 if(std_frm != NULL) {
829 in_frm = std_frm;
830 } else if(psf_frm != NULL) {
831 in_frm = psf_frm;
832 } else if(std_flux_frm != NULL) {
833 in_frm = std_flux_frm;
834 }
835 }
836
837 cpl_propertylist* plist = cpl_propertylist_load(cpl_frame_get_filename(in_frm),0);
838 double fwhm_maj = 9;
839 double fwhm_min = 9;
840
841 if(cpl_propertylist_has(plist, "ESO QC FWHM MAJ")) {
842 fwhm_maj = cpl_propertylist_get_double(plist, "ESO QC FWHM MAJ");
843 if(fwhm_maj == 0) {
844 if(cpl_propertylist_has(plist, "ESO QC FWHMX")) {
845 fwhm_maj = cpl_propertylist_get_double(plist, "ESO QC FWHMX");
846 }
847 }
848 }
849
850 if(cpl_propertylist_has(plist, "ESO QC FWHM MIN")) {
851 fwhm_min = cpl_propertylist_get_double(plist, "ESO QC FWHM MIN");
852 if(fwhm_min == 0) {
853 if(cpl_propertylist_has(plist, "ESO QC FWHMY")) {
854 fwhm_min = cpl_propertylist_get_double(plist, "ESO QC FWHMY");
855 }
856 }
857 }
858
859 cpl_propertylist_delete(plist);
860 //cpl_msg_info(cpl_func,"flux_radius_pix: %g",flux_radius_pix);
861 //cpl_msg_info(cpl_func,"fwhm_min: %g fwhm_maj: %g",fwhm_min, fwhm_maj);
862 double fwhm_sup = (fwhm_maj > fwhm_min) ? fwhm_maj : fwhm_min;
863 if(flux_radius_pix == -1) {
864 cpl_msg_info(cpl_func,"pipeline setting flux_radius_pix: 3 * PSF sigmas");
865 flux_radius_pix = 3. * fwhm_sup / CPL_MATH_FWHM_SIG; // 3 sigmas
866 }
867 cpl_msg_info(cpl_func,"flux_radius_pix: %g",flux_radius_pix);
868 double flux_radius_arc = flux_radius_pix * pixel_scale_x;
869 //cpl_msg_info(cpl_func,"bkg_radius_low: %g",bkg_radius_low);
870 if(bkg_radius_low == -1) {
871 cpl_msg_info(cpl_func,"pipeline setting bkg_radius_low: 1.5 * flux_radius");
872 bkg_radius_low = 1.5 * flux_radius_arc;
873 } else {
874 bkg_radius_low *= pixel_scale_x;
875 }
876 //cpl_msg_info(cpl_func,"bkg_radius_high: %g",bkg_radius_high);
877 if(bkg_radius_high == -1) {
878 cpl_msg_info(cpl_func,"pipeline setting bkg_radius_high: 2.0 * flux_radius");
879 bkg_radius_high = 2.0 * flux_radius_arc;
880 } else {
881 bkg_radius_high *= pixel_scale_x;
882 }
883
884 cpl_msg_info(cpl_func,"flux_radius: %g [arcsec] bkg_radius_low: %g [arcsec] bkg_radius_high: %g [arcsec]",
885 flux_radius_arc, bkg_radius_low,bkg_radius_high);
886
887 cpl_msg_info(cpl_func,"flux_radius: %g [pix] bkg_radius_low: %g [pix] bkg_radius_high: %g [pix]",
888 flux_radius_arc / pixel_scale_x,bkg_radius_low / pixel_scale_x,bkg_radius_high / pixel_scale_x);
889
890
891 /* Load INPUT Data for Strehl Computation: we use the cube collapsed mean */
892 std_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_STD_CUBE_MEAN);
893 psf_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_PSF_CUBE_MEAN);
894 std_flux_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_MEAN);
895 if ( (std_frm == NULL) && (std_flux_frm == NULL) && (psf_frm == NULL) ) {
896
897 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
898 "Missing ERIS_IFU_PRO_JITTER_PSF_CUBE_MEAN file, Cannot compute Strehl,");
899 } else {
900 if(std_frm != NULL) {
901 in_frm = std_frm;
902 } else if(psf_frm != NULL) {
903 in_frm = psf_frm;
904 }
905 }
906
907 int sx = 0;
908 int sy = 0;
909 const char* fname = cpl_frame_get_filename(in_frm);
910 cpl_msg_info(cpl_func,"strehl computed on: %s",fname);
911 cpl_image* in_ima = cpl_image_load(fname,CPL_TYPE_FLOAT, 0, 1);
912
913 sx = cpl_image_get_size_x(in_ima);
914 sy = cpl_image_get_size_y(in_ima);
915 bpm_frm = in_frm;
916 err_frm = in_frm;
917
918 plist = cpl_propertylist_load(fname,0);
919 double ron = cpl_propertylist_get_double(plist,"ESO DET CHIP RON");
920 double gain = cpl_propertylist_get_double(plist,"ESO DET CHIP GAIN");
921
922 //cpl_propertylist_delete(plist);
923 cpl_image_delete(in_ima);
924 region_params = hdrl_rect_region_parameter_create(1, 1, sx, sy);
925
926 /* Load the image */
927 if (eris_ifu_hdrl_image_load(in_frm, extnum_raw, err_frm, extnum_err,
928 bpm_frm, extnum_bpm, region_params, ron, gain,
929 &hima) != CPL_ERROR_NONE) {
930 if (region_params) hdrl_parameter_delete(region_params) ;
931
932 return cpl_error_set_message(cpl_func, CPL_ERROR_FILE_NOT_FOUND,
933 "Cannot load RAW image");
934 }
935 if (region_params) hdrl_parameter_delete(region_params) ;
936
937
938 //cpl_msg_info(cpl_func,"Handles NANs");
940
941 cpl_size cx = 0;
942 cpl_size cy = 0;
943 cpl_size margin_x = 4;
944 cpl_size margin_y = 4;
945 cpl_size llx = margin_x;
946 cpl_size lly = margin_y;
947 cpl_size urx = sx - margin_x;
948 cpl_size ury = sy - margin_y;
949
950 cpl_image_get_maxpos_window(hdrl_image_get_image(hima), llx, lly, urx, ury, &cx, &cy);
951 cpl_msg_info(cpl_func,"Image max detected at cx: %lld, cy: %lld",cx, cy);
952 /*
953 cpl_image_save(hdrl_image_get_image(hima),"ima.fits", CPL_TYPE_DOUBLE, NULL,
954 CPL_IO_DEFAULT);
955 */
956 cpl_msg_info(cpl_func,"check Strehl parameters");
957 /*
958 cpl_msg_info(cpl_func,"flux_radius[pix]: %g bkg_radius_low[pix]: %g bkg_radius_high[pix]: %g",
959 flux_radius_pix ,bkg_radius_low / pixel_scale_x,bkg_radius_high / pixel_scale_x );
960 */
961 res.strehl_value.data = 0;
962 res.strehl_value.error = 0;
963 hdrl_parameter * p;
964 cpl_msg_info(cpl_func,"wavelength: %g M1: %g M2: %g",wavelength, M1_RADIUS,M2_RADIUS);
965 cpl_msg_info(cpl_func,"flux_radius_pix: %g cx: %lld cy: %lld sx: %d sy:%d",flux_radius_pix, cx, cy, sx, sy);
966
967 /* Adaptive parameter adjustment if PSF near edge */
968 if( (flux_radius_pix + cx) > (sx -2) ||
969 (flux_radius_pix + cy) > (sy -2) ||
970 (cx-flux_radius_pix) < 2 ||
971 (cy-flux_radius_pix) < 2){
972 //cpl_msg_info(cpl_func,"flux_radius_pix: %g",flux_radius_pix);
973 cpl_msg_info(cpl_func,"correct Strehl parameters");
974 flux_radius_pix = ( (flux_radius_pix + cx) > (sx -2) ) ? flux_radius_pix : sx -2;
975 flux_radius_pix = ( (flux_radius_pix + cy) > (sy -2) ) ? flux_radius_pix : sy -2;
976 flux_radius_pix = ( (cx - flux_radius_pix) < 2 ) ? cx -2 : flux_radius_pix;
977 flux_radius_pix = ( (cy - flux_radius_pix) < 2 ) ? cy -2 : flux_radius_pix;
978 //cpl_msg_info(cpl_func,"flux_radius_pix %g pixel_scale_x %g", flux_radius_pix, pixel_scale_x);
979 flux_radius_arc = flux_radius_pix * pixel_scale_x;
980 bkg_radius_low = flux_radius_arc;
981 bkg_radius_high = (flux_radius_pix + 1) * pixel_scale_x;
982 cpl_msg_info(cpl_func,"flux_radius: %g bkg_radius_low: %g bkg_radius_high: %g",
983 flux_radius_arc ,bkg_radius_low ,bkg_radius_high );
984
985 if(bkg_radius_low > 0) {
986 p = hdrl_strehl_parameter_create(wavelength,
987 M1_RADIUS, M2_RADIUS, pixel_scale_x, pixel_scale_y,
988 flux_radius_arc, bkg_radius_low, bkg_radius_high) ;
989 /* Strehl COMPUTATION */
990 res = hdrl_strehl_compute(hima, p);
992 } else {
993 cpl_msg_warning(cpl_func,"bkg_radius_low: %g. Skip Strehl computation.", bkg_radius_low);
994 }
995
996
997 } else {
998 //cpl_msg_info(cpl_func,"fwhm_sup: %g",fwhm_sup);
999 //for (flux_radius_pix=fwhm_sup; flux_radius_pix < 3 * fwhm_sup; flux_radius_pix += 0.2) {
1000 flux_radius_arc = flux_radius_pix * pixel_scale_x;
1001 cpl_msg_info(cpl_func,"flux_radius_pix: %g",flux_radius_pix);
1002 if(bkg_radius_low > 0) {
1003 p = hdrl_strehl_parameter_create(wavelength,
1004 M1_RADIUS, M2_RADIUS, pixel_scale_x, pixel_scale_y,
1005 flux_radius_arc, bkg_radius_low, bkg_radius_high) ;
1006
1007 res = hdrl_strehl_compute(hima, p);
1009 cpl_msg_info(cpl_func,"strehl=%g+-%g", res.strehl_value.data,
1010 res.strehl_value.error);
1011 } else {
1012 cpl_msg_warning(cpl_func,"bkg_radius_low: %g. Skip Strehl computation.", bkg_radius_low);
1013 }
1014
1015 //}
1016 }
1017
1018
1019
1020 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1021 cpl_msg_error(cpl_func,"Error computing Strehl. Temporarily suppress it.");
1022 cpl_error_set(cpl_func,CPL_ERROR_NONE);
1023 hdrl_image_delete(hima);
1024 return CPL_ERROR_NONE;
1025 } else {
1026 if (res.strehl_value.data > 0) {
1027
1028 cpl_msg_info(cpl_func,"strehl=%g+-%g", res.strehl_value.data,
1029 res.strehl_value.error);
1030 /* expected difference sqrt(pi / 2) due to median */
1031 cpl_msg_info(cpl_func, "star peak at %g/%g: %g +- %g", res.star_x,
1032 res.star_y, res.star_peak.data, res.star_peak.error);
1033 cpl_msg_info(cpl_func, "star flux %g+-%g", res.star_flux.data,
1034 res.star_flux.error);
1035 cpl_msg_info(cpl_func,"median estimated background=%g+-%g "
1036 "(computed error %g)",
1037 res.star_background.data, res.star_background.error,
1038 res.computed_background_error);
1039
1040 double qc_strehl = 0;
1041 double qc_strehl_err = 0;
1042 if(isnan(res.strehl_value.data)){
1043 qc_strehl=999.;
1044 qc_strehl_err=999.;
1045 } else {
1046 qc_strehl=res.strehl_value.data;
1047 qc_strehl_err=res.strehl_value.error;
1048 }
1049
1050 cpl_image* data = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, extnum_raw);
1051
1052 cpl_image* errs = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, extnum_err);
1053 cpl_propertylist* eheader = cpl_propertylist_load(fname, extnum_err);
1054
1055
1056 cpl_image* qual = cpl_image_load(fname, CPL_TYPE_INT, 0, extnum_bpm);
1057 cpl_propertylist* qheader = cpl_propertylist_load(fname, extnum_bpm);
1058
1059
1060
1061 cpl_propertylist_append_double(plist, "ESO QC STREHL", qc_strehl);
1062 cpl_propertylist_append_double(plist, "ESO QC STREHL ERROR", qc_strehl_err);
1063 cpl_image_save(data, fname, CPL_TYPE_DOUBLE, plist, CPL_IO_DEFAULT);
1064 //cpl_propertylist_dump(plist,stdout);
1065 /*
1066 const char* pcatg = cpl_propertylist_get_string(plist, FHDR_PRO_CATG);
1067 eris_ifu_save_image(frameset, plist, parlist, recipe_name, pcatg,
1068 fname, CPL_TYPE_DOUBLE, data);
1069 */
1070
1071 cpl_image_save(errs, fname, CPL_TYPE_DOUBLE, eheader, CPL_IO_EXTEND);
1072 cpl_image_save(qual, fname, CPL_TYPE_INT, qheader, CPL_IO_EXTEND);
1073 cpl_image_delete(data);
1074 cpl_image_delete(errs);
1075 cpl_image_delete(qual);
1076
1077 cpl_propertylist_delete(eheader);
1078 cpl_propertylist_delete(qheader);
1079 //cpl_msg_info(cpl_func,"ok5");
1080 }
1081 }
1082 cpl_propertylist_delete(plist);
1083 /* Cleanup */
1084
1085 hdrl_image_delete(hima);
1086 eris_check_error_code("eris_ifu_stdstar_strehl_compute");
1087
1088 return cpl_error_get_code();
1089}
1090
cpl_error_code eris_ifu_dfs_set_groups(cpl_frameset *self)
Set the frame group (RAW, CALIB, or PRODUCT) for all frames in a frameset.
Definition: eris_ifu_dfs.c:89
cpl_error_code eris_ifu_jitter_get_instrument_settings(cpl_frameset *frames, ifsInstrument *instrument, ifsBand *band, ifsPreopticsScale *scale)
Extract instrument configuration from frameset.
cpl_error_code eris_ifu_mask_nans_in_hdrlimage(hdrl_image **hima)
Flag NaNs in HDRL image.
int eris_pfits_get_naxis2(const cpl_propertylist *plist)
find out the character string associated to the NAXIS2 keyword
Definition: eris_pfits.c:168
int eris_pfits_get_naxis1(const cpl_propertylist *plist)
find out the character string associated to the NAXIS1 keyword
Definition: eris_pfits.c:155
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
Definition: eris_utils.c:56
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
Definition: hdrl_image.c:295
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:105
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter
hdrl_strehl_result hdrl_strehl_compute(const hdrl_image *himg, hdrl_parameter *params)
This function computes the Strehl ratio.
Definition: hdrl_strehl.c:1326
hdrl_parameter * hdrl_strehl_parameter_create(double wavelength, double m1_radius, double m2_radius, double pixel_scale_x, double pixel_scale_y, double flux_radius, double bkg_radius_low, double bkg_radius_high)
Creates Strehl Parameters object.
Definition: hdrl_strehl.c:188
hdrl_parameter * hdrl_strehl_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse parameter list to create input parameters for the Strehl.
Definition: hdrl_strehl.c:448
cpl_error_code hdrl_rect_region_parameter_verify(const hdrl_parameter *param, const cpl_size max_x, const cpl_size max_y)
Verify basic correctness of the parameters.
Definition: hdrl_utils.c:560
cpl_error_code hdrl_rect_region_fix_negatives(hdrl_parameter *rect_region, const cpl_size nx, const cpl_size ny)
wrap negative or zero coordinates around full image size
Definition: hdrl_utils.c:715
hdrl_parameter * hdrl_rect_region_parameter_create(cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury)
Creates Rect Region Parameters object.
Definition: hdrl_utils.c:459
cpl_size hdrl_rect_region_get_llx(const hdrl_parameter *p)
get lower left x coordinate of rectangual region
Definition: hdrl_utils.c:518
cpl_size hdrl_rect_region_get_urx(const hdrl_parameter *p)
get upper right x coordinate of rectangular region
Definition: hdrl_utils.c:536
cpl_size hdrl_rect_region_get_lly(const hdrl_parameter *p)
get lower left y coordinate of rectangual region
Definition: hdrl_utils.c:527
cpl_size hdrl_rect_region_get_ury(const hdrl_parameter *p)
get upper right y coordinate of rectangual region
Definition: hdrl_utils.c:545
cpl_boolean hdrl_rect_region_parameter_check(const hdrl_parameter *self)
Check that the parameter is hdrl_rect_region parameter.
Definition: hdrl_utils.c:506