ERIS Pipeline Reference Manual 1.8.10
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/*----------------------------------------------------------------------------*/
50/*----------------------------------------------------------------------------*/
51
54#define HDRL_PARAMETER_HEAD void * base
56typedef struct {
57 HDRL_PARAMETER_HEAD;
58 cpl_size llx ;
59 cpl_size lly ;
60 cpl_size urx ;
61 cpl_size ury ;
62} hdrl_rect_region_parameter;
63
64/*----------------------------------------------------------------------------*/
75/*----------------------------------------------------------------------------*/
76static cpl_error_code eris_ifu_propertylist_save(
77 const char * procatg,
78 const char * filename,
79 const cpl_propertylist * header,
80 const cpl_parameterlist * parlist,
81 cpl_frameset * frameset)
82{
83 /* Add a QC parameter */
84 cpl_propertylist * applist = cpl_propertylist_new();
85
86 /* Add the product category and save image */
87 cpl_propertylist_update_string(applist, CPL_DFS_PRO_CATG, procatg);
88
89 cpl_dfs_save_propertylist(frameset, NULL, parlist, frameset, NULL,
90 "ERIS_IFU_STREHL", header, NULL, PACKAGE "/" PACKAGE_VERSION,
91 filename);
92 cpl_propertylist_delete(applist);
93 eris_check_error_code("eris_ifu_propertylist_save");
94 return cpl_error_get_code();
95}
96
97
98
99/*----------------------------------------------------------------------------*/
110/*----------------------------------------------------------------------------*/
111static cpl_error_code hdrl_rect_region_fix_negatives(
112 hdrl_parameter * rect_region,
113 const cpl_size nx,
114 const cpl_size ny)
115{
116 hdrl_rect_region_parameter * rr_loc =
117 (hdrl_rect_region_parameter *)rect_region ;
118
119 cpl_error_ensure(rect_region != 0, CPL_ERROR_NULL_INPUT,
120 return CPL_ERROR_NULL_INPUT, "region input must not be NULL");
121 cpl_error_ensure(hdrl_rect_region_parameter_check(rect_region),
122 CPL_ERROR_ILLEGAL_INPUT, return CPL_ERROR_ILLEGAL_INPUT,
123 "Expected Rect Region parameter") ;
124
125 if (nx > 0 && rr_loc->llx < 1) rr_loc->llx += nx;
126 if (ny > 0 && rr_loc->lly < 1) rr_loc->lly += ny;
127 if (nx > 0 && rr_loc->urx < 1) rr_loc->urx += nx;
128 if (ny > 0 && rr_loc->ury < 1) rr_loc->ury += ny;
129
130 return hdrl_rect_region_parameter_verify(rect_region, nx, ny);
131}
132
133/*----------------------------------------------------------------------------*/
154/*----------------------------------------------------------------------------*/
155static cpl_error_code
156eris_ifu_detector_shotnoise_model(const cpl_image* ima_data, const double gain,
157 const double ron, cpl_image ** ima_errs)
158{
159 cpl_ensure_code(ima_data, CPL_ERROR_NULL_INPUT);
160 cpl_ensure_code(ima_errs, CPL_ERROR_NULL_INPUT);
161 cpl_ensure_code(gain > 0., CPL_ERROR_ILLEGAL_INPUT);
162 cpl_ensure_code(ron > 0., CPL_ERROR_ILLEGAL_INPUT);
163
164 *ima_errs = cpl_image_duplicate(ima_data);
165 /* set negative values (= zero measurable electrons) to read out noise */
166 cpl_image_threshold(*ima_errs, 0., INFINITY, ron, ron);
167
168 /* err_ADU = sqrt(counts/gain + ron * ron)*/
169
170 cpl_image_divide_scalar(*ima_errs, gain);
171 cpl_image_add_scalar(*ima_errs, ron * ron);
172 cpl_image_power(*ima_errs, 0.5);
173 eris_check_error_code("eris_ifu_detector_shotnoise_model");
174 return cpl_error_get_code();
175}
176
177
178
179/* ---------------------------------------------------------------------------*/
188/* ---------------------------------------------------------------------------*/
189static cpl_error_code
190eris_ifu_fix_neg_region(const cpl_frame * frm, cpl_size extnum,
191 hdrl_parameter * par)
192{
193 cpl_propertylist * plist =
194 cpl_propertylist_load(cpl_frame_get_filename(frm), extnum);
195 if (!plist) {
196 return cpl_error_get_code();
197 }
198 cpl_size nx = eris_pfits_get_naxis1(plist);
199 cpl_size ny = eris_pfits_get_naxis2(plist);
201 cpl_propertylist_delete(plist);
202 eris_check_error_code("eris_ifu_fix_neg_region");
203 return cpl_error_get_code();
204}
205
206/* ---------------------------------------------------------------------------*/
214/* ---------------------------------------------------------------------------*/
215static cpl_image * eris_ifu_image_mef_load_region(
216 cpl_frame * frm,
217 cpl_size eidx,
218 hdrl_parameter * region_params)
219{
220 cpl_image * out = NULL ;
221
222 if (region_params == NULL) {
223 out = cpl_image_load(cpl_frame_get_filename(frm),
224 CPL_TYPE_DOUBLE, 0, eidx);
225 } else {
226 eris_ifu_fix_neg_region(frm, eidx, region_params);
227 out = cpl_image_load_window(cpl_frame_get_filename(frm),
228 CPL_TYPE_DOUBLE, 0, eidx,
229 hdrl_rect_region_get_llx(region_params),
230 hdrl_rect_region_get_lly(region_params),
231 hdrl_rect_region_get_urx(region_params),
232 hdrl_rect_region_get_ury(region_params)) ;
233 }
234 eris_check_error_code("eris_ifu_image_mef_load_region");
235 return out ;
236}
237
238
239/*----------------------------------------------------------------------------*/
255/*----------------------------------------------------------------------------*/
256static cpl_error_code eris_ifu_hdrl_image_load(
257 cpl_frame * in,
258 cpl_size ext_num,
259 cpl_frame * in_err,
260 cpl_size ext_num_err,
261 cpl_frame * in_bpm,
262 cpl_size ext_num_bpm,
263 hdrl_parameter * region_params,
264 double ron,
265 double gain,
266 hdrl_image ** out_hdrl_ima)
267{
268 cpl_image * img ;
269
270 /* Check Entries */
271 cpl_ensure_code(in, CPL_ERROR_NULL_INPUT);
272 cpl_ensure_code(out_hdrl_ima, CPL_ERROR_NULL_INPUT);
273
274 /* Load in image */
275 img = eris_ifu_image_mef_load_region(in, ext_num, region_params);
276 if (img == NULL) return CPL_ERROR_ILLEGAL_INPUT ;
277
278 /* Load BPM */
279 if (in_bpm != NULL) {
280 cpl_image * bpm = eris_ifu_image_mef_load_region(in_bpm, ext_num_bpm, region_params);
281 cpl_mask * bpm_mask = cpl_mask_threshold_image_create(bpm,
282 -0.5, 0.5) ;
283 cpl_image_delete(bpm) ;
284 cpl_mask_not(bpm_mask) ;
285 cpl_image_reject_from_mask(img, bpm_mask);
286 cpl_mask_delete(bpm_mask) ;
287 }
288
289 /* Load error */
290 cpl_image * err =NULL;
291 if (in_err != NULL) {
292 err = eris_ifu_image_mef_load_region(in_err, ext_num_err, region_params);
293 } else if (ron < 0. && gain < 0.) {
294 /* no error */
295 err = NULL;
296 } else {
297 /* No passed error -> Create uniform error */
298 eris_ifu_detector_shotnoise_model(img, gain, ron, &err);
299 }
300
301 /* Create out himage */
302 *out_hdrl_ima = hdrl_image_create(img, err);
303
304 /* Cleanup */
305 cpl_image_delete(img);
306 cpl_image_delete(err);
307 eris_check_error_code("eris_ifu_hdrl_image_load");
308 return cpl_error_get_code();
309}
310
311/*----------------------------------------------------------------------------*/
326/*----------------------------------------------------------------------------*/
327/*TODO: NOT USED
328static cpl_error_code
329eris_ifu_strehl_calculate(hdrl_image* hima,
330 const double wavelength,
331 const double m1_radius,
332 const double m2_radius,
333 const double pixel_scale_x,
334 const double pixel_scale_y,
335 const double flux_radius,
336 const double bkg_radius_low,
337 const double bkg_radius_high)
338{
339
340
341 hdrl_parameter * strehl_p = hdrl_strehl_parameter_create(wavelength, m1_radius,
342 m2_radius, pixel_scale_x, pixel_scale_y, flux_radius, bkg_radius_low,
343 bkg_radius_high);
344 return cpl_error_get_code();
345}
346*/
347/*----------------------------------------------------------------------------*/
355/*----------------------------------------------------------------------------*/
356
357cpl_error_code
358eris_ifu_strehl_compute(cpl_frameset * frameset, const cpl_parameterlist * parlist,
359 const char* recipe_name)
360{
361
362 int extnum_raw = 0;
363 int extnum_err = 1;
364 int extnum_bpm = 2;
365 hdrl_strehl_result res;
366
367 cpl_frame * in_frm ;
368 cpl_frame * err_frm ;
369 cpl_frame * bpm_frm ;
370 hdrl_image * hima ;
371 hdrl_parameter * region_params = NULL;
372
373 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
374 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
375 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
376 /* Check initial Entries */
377 if (eris_ifu_dfs_set_groups(frameset) != CPL_ERROR_NONE) {
378 return cpl_error_get_code();
379 }
380
381 /* Get parameters*/
382 /* those params are not needed
383 *
384 * char* param_name = NULL;
385 * const cpl_parameter * par = NULL;
386 param_name = cpl_sprintf("%s.ext-nb-raw", recipe_name);
387 par = cpl_parameterlist_find_const(parlist, param_name);
388 extnum_raw = cpl_parameter_get_int(par);
389 cpl_free(param_name);
390
391 param_name = cpl_sprintf("%s.ext-nb-raw-err", recipe_name);
392 par = cpl_parameterlist_find_const(parlist, param_name);
393 extnum_err = cpl_parameter_get_int(par);
394 cpl_free(param_name);
395
396 param_name = cpl_sprintf("%s.ext-nb-raw-bpm", recipe_name);
397 par = cpl_parameterlist_find_const(parlist, param_name);
398 extnum_bpm = cpl_parameter_get_int(par);
399 cpl_free(param_name);
400 */
401
402 /* Parse the Strehl Parameters */
403 hdrl_parameter * p = hdrl_strehl_parameter_parse_parlist(parlist,
404 recipe_name);
405 if (p == NULL) {
406 return cpl_error_set_message(cpl_func, CPL_ERROR_UNSPECIFIED,
407 "Parsing of the strehl parameters failed");
408 }
409
410 /* Parse the Region Parameters
411 region_params=hdrl_rect_region_parameter_parse_parlist(parlist,
412 recipe_name, "region-") ;
413 if (region_params == NULL) {
414 hdrl_parameter_delete(p);
415 return cpl_error_set_message(cpl_func, CPL_ERROR_UNSPECIFIED,
416 "Parsing of the region parameters failed");
417 }
418 */
419
420 /* Load INPUT Data */
421 /* Get the first Required frame */
422 if ((in_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_CUBE))==NULL) {
423 //if (region_params) hdrl_parameter_delete(region_params) ;
424 if (p) hdrl_parameter_delete(p) ;
425 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
426 "Missing RAW file");
427 }
428 //bpm_frm = cpl_frameset_find(frameset, ERIS_IFU_RAW_BPM) ;
429 //err_frm = cpl_frameset_find(frameset, ERIS_IFU_RAW_ERROR) ;
430 int sx = 0;
431 int sy = 0;
432 const char* fname = cpl_frame_get_filename(in_frm);
433 cpl_image* in_ima = cpl_image_load(fname,CPL_TYPE_FLOAT, 0, 0);
434 sx = cpl_image_get_size_x(in_ima);
435 sy = cpl_image_get_size_y(in_ima);
436 bpm_frm = in_frm;
437 err_frm = in_frm;
438 cpl_propertylist* plist = cpl_propertylist_load(fname,0);
439 double ron = cpl_propertylist_get_double(plist,"ESO DET CHIP RON");
440 double gain = cpl_propertylist_get_double(plist,"ESO DET CHIP GAIN");
441 cpl_propertylist_delete(plist);
442 cpl_image_delete(in_ima);
443 region_params = hdrl_rect_region_parameter_create(1, 1, sx, sy);
444 /* Load the image */
445 if (eris_ifu_hdrl_image_load(in_frm, extnum_raw, err_frm, extnum_err,
446 bpm_frm, extnum_bpm, region_params, ron, gain,
447 &hima) != CPL_ERROR_NONE) {
448 if (region_params) hdrl_parameter_delete(region_params) ;
449 if (p) hdrl_parameter_delete(p) ;
450 return cpl_error_set_message(cpl_func, CPL_ERROR_FILE_NOT_FOUND,
451 "Cannot load RAW image");
452 }
453 if (region_params) hdrl_parameter_delete(region_params) ;
454
455
456 /* This is not needed as ERRORS are provided by the input data
457 if(err_frm == NULL) {
458 // Replace the error image created by the ron/gain by the mad-scaled
459 // rms of the image
460 double dmad = 0.;
461 cpl_image * img = cpl_image_load(cpl_frame_get_filename(in_frm),
462 CPL_TYPE_DOUBLE, 0, extnum_raw);
463 cpl_image_get_mad(img, &dmad);
464 cpl_image_delete(img);
465
466 cpl_image_multiply_scalar(hdrl_image_get_error(hima), 0.);
467 cpl_image_add_scalar(hdrl_image_get_error(hima),
468 (dmad * CPL_MATH_STD_MAD));
469 }
470 */
471 cpl_msg_info(cpl_func,"Handles NANs");
473 /* Strehl COMPUTATION */
474 res = hdrl_strehl_compute(hima, p);
476 cpl_msg_info(cpl_func,"strehl=%g+-%g", res.strehl_value.data,
477 res.strehl_value.error);
478 /* expected difference sqrt(pi / 2) due to median */
479 cpl_msg_info(cpl_func, "star peak at %g/%g: %g +- %g", res.star_x,
480 res.star_y, res.star_peak.data, res.star_peak.error);
481 cpl_msg_info(cpl_func, "star flux %g+-%g", res.star_flux.data,
482 res.star_flux.error);
483 cpl_msg_info(cpl_func,"median estimated background=%g+-%g "
484 "(computed error %g)",
485 res.star_background.data, res.star_background.error,
486 res.computed_background_error);
487 cpl_propertylist* header=cpl_propertylist_new();
488 cpl_propertylist_update_double(header, "ESO QC STREHL",
489 res.strehl_value.data);
490 cpl_propertylist_update_double(header, "ESO QC STREHL ERROR",
491 res.strehl_value.error);
492 cpl_propertylist_update_string(header, CPL_DFS_PRO_CATG, "ERIS_IFU_STREHL");
493
494 eris_ifu_propertylist_save("ERIS_IFU_STREHL","eris_ifu_strehl.fits", header,
495 parlist,frameset);
496
497
498 /* Cleanup */
499 cpl_propertylist_delete(header);
500 hdrl_image_delete(hima);
501 /* In case of Poisson error model: */
502 eris_check_error_code("eris_ifu_strehl_compute");
503 return cpl_error_get_code();
504}
505
506/*----------------------------------------------------------------------------*/
515/*----------------------------------------------------------------------------*/
516
517cpl_error_code
518eris_ifu_stdstar_strehl_compute(cpl_frameset * frameset,
519 const cpl_parameterlist * parlist,
520 const char* context/*,
521 const char* recipe_name*/)
522{
523 //const cpl_parameter * par = NULL;
524 int extnum_raw = 1;
525 int extnum_err = 2;
526 int extnum_bpm = 3;
527 hdrl_strehl_result res;
528
529 cpl_frame * in_frm = NULL ;
530 cpl_frame * err_frm ;
531 cpl_frame * bpm_frm ;
532 hdrl_image * hima ;
533 hdrl_parameter * region_params = NULL;
534 char* param_name = NULL;
535
536 double wavelength = 0;
537 //ifsPreopticsScale = eris_ifu_get_spiffier_preoptics_scale(sof->band);
538 double pixel_scale_x = 0;
539 double pixel_scale_y = 0;
540 double flux_radius_pix = 1;
541 double bkg_radius_low = 1;
542 double bkg_radius_high = 1.5;
543
544 cpl_ensure_code(frameset,CPL_ERROR_NULL_INPUT);
545 cpl_ensure_code(parlist,CPL_ERROR_NULL_INPUT);
546 cpl_ensure_code(context,CPL_ERROR_NULL_INPUT);
547
548 param_name = cpl_sprintf("%s.strehl_flux_radius", context);
549 flux_radius_pix = cpl_parameter_get_double(
550 cpl_parameterlist_find_const(parlist, param_name));
551 cpl_free(param_name);
552
553
554 param_name = cpl_sprintf("%s.strehl_bkg-radius-low", context);
555 bkg_radius_low = cpl_parameter_get_double(
556 cpl_parameterlist_find_const(parlist, param_name));
557 cpl_free(param_name);
558
559
560 param_name = cpl_sprintf("%s.strehl_bkg-radius-high", context);
561 bkg_radius_high = cpl_parameter_get_double(
562 cpl_parameterlist_find_const(parlist, param_name));
563 cpl_free(param_name);
564
565
566 ifsBand band = UNDEFINED_BAND;
567 ifsPreopticsScale scale = UNDEFINED_SCALE;
568 ifsInstrument instrument = UNSET_INSTRUMENT;
569 eris_ifu_jitter_get_instrument_settings(frameset, &instrument, &band, &scale);
570
571 switch(scale) {
572 case S250MAS:
573 pixel_scale_x = 0.250;
574 break;
575
576 case S100MAS:
577 pixel_scale_x = 0.100;
578 break;
579
580 case S25MAS:
581 pixel_scale_x = 0.025;
582 break;
583
584 case UNDEFINED_SCALE:
585 pixel_scale_x = 0.025;
586 break;
587 //TODO: FOLLOWING TO BE VERIFIED
588 case PUPIL:
589 pixel_scale_x = 0.100;
590 break;
591 }
592 eris_ifu_get_central_lambda(band, &wavelength);
593 wavelength *= 1.e-6; /* convert to [m] */
594 pixel_scale_y = pixel_scale_x;
595 cpl_msg_info(cpl_func,"pixel_scale: %g [arcsec]",pixel_scale_x);
596 /* Determine flux_radius, bkg_radius_low, bkg_radius_high from QC.FWHM
597 * on cube collapsed median*/
598 cpl_frame* std_frm;
599 cpl_frame* std_flux_frm;
600 cpl_frame* psf_frm;
601 //cpl_frameset_dump(frameset,stdout);
602 std_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_MEDIAN);
603 std_flux_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_MEDIAN);
604 psf_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD_MEDIAN);
605 if ( (std_frm == NULL) && (psf_frm == NULL) && (std_flux_frm == NULL)) {
606 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
607 "Missing ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD_MEDIAN file, Cannot compute Strehl,");
608 } else {
609 if(std_frm != NULL) {
610 in_frm = std_frm;
611 } else if(psf_frm != NULL) {
612 in_frm = psf_frm;
613 } else if(std_flux_frm != NULL) {
614 in_frm = std_flux_frm;
615 }
616 }
617
618 cpl_propertylist* plist = cpl_propertylist_load(cpl_frame_get_filename(in_frm),0);
619 double fwhm_maj = 9;
620 double fwhm_min = 9;
621
622 if(cpl_propertylist_has(plist, "ESO QC FWHM MAJ")) {
623 fwhm_maj = cpl_propertylist_get_double(plist, "ESO QC FWHM MAJ");
624 if(fwhm_maj == 0) {
625 if(cpl_propertylist_has(plist, "ESO QC FWHMX")) {
626 fwhm_maj = cpl_propertylist_get_double(plist, "ESO QC FWHMX");
627 }
628 }
629 }
630
631 if(cpl_propertylist_has(plist, "ESO QC FWHM MIN")) {
632 fwhm_min = cpl_propertylist_get_double(plist, "ESO QC FWHM MIN");
633 if(fwhm_min == 0) {
634 if(cpl_propertylist_has(plist, "ESO QC FWHMY")) {
635 fwhm_min = cpl_propertylist_get_double(plist, "ESO QC FWHMY");
636 }
637 }
638 }
639
640 cpl_propertylist_delete(plist);
641 //cpl_msg_info(cpl_func,"flux_radius_pix: %g",flux_radius_pix);
642 //cpl_msg_info(cpl_func,"fwhm_min: %g fwhm_maj: %g",fwhm_min, fwhm_maj);
643 double fwhm_sup = (fwhm_maj > fwhm_min) ? fwhm_maj : fwhm_min;
644 if(flux_radius_pix == -1) {
645 cpl_msg_info(cpl_func,"pipeline setting flux_radius_pix: 3 * PSF sigmas");
646 flux_radius_pix = 3. * fwhm_sup / CPL_MATH_FWHM_SIG; // 3 sigmas
647 }
648 cpl_msg_info(cpl_func,"flux_radius_pix: %g",flux_radius_pix);
649 double flux_radius_arc = flux_radius_pix * pixel_scale_x;
650 //cpl_msg_info(cpl_func,"bkg_radius_low: %g",bkg_radius_low);
651 if(bkg_radius_low == -1) {
652 cpl_msg_info(cpl_func,"pipeline setting bkg_radius_low: 1.5 * flux_radius");
653 bkg_radius_low = 1.5 * flux_radius_arc;
654 } else {
655 bkg_radius_low *= pixel_scale_x;
656 }
657 //cpl_msg_info(cpl_func,"bkg_radius_high: %g",bkg_radius_high);
658 if(bkg_radius_high == -1) {
659 cpl_msg_info(cpl_func,"pipeline setting bkg_radius_high: 2.0 * flux_radius");
660 bkg_radius_high = 2.0 * flux_radius_arc;
661 } else {
662 bkg_radius_high *= pixel_scale_x;
663 }
664
665 cpl_msg_info(cpl_func,"flux_radius: %g [arcsec] bkg_radius_low: %g [arcsec] bkg_radius_high: %g [arcsec]",
666 flux_radius_arc, bkg_radius_low,bkg_radius_high);
667
668 cpl_msg_info(cpl_func,"flux_radius: %g [pix] bkg_radius_low: %g [pix] bkg_radius_high: %g [pix]",
669 flux_radius_arc / pixel_scale_x,bkg_radius_low / pixel_scale_x,bkg_radius_high / pixel_scale_x);
670
671
672 /* Load INPUT Data for Strehl Computation: we use the cube collapsed mean */
673 std_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_STD_CUBE_MEAN);
674 psf_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_PSF_CUBE_MEAN);
675 std_flux_frm = cpl_frameset_find(frameset, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_MEAN);
676 if ( (std_frm == NULL) && (std_flux_frm == NULL) && (psf_frm == NULL) ) {
677
678 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
679 "Missing ERIS_IFU_PRO_JITTER_PSF_CUBE_MEAN file, Cannot compute Strehl,");
680 } else {
681 if(std_frm != NULL) {
682 in_frm = std_frm;
683 } else if(psf_frm != NULL) {
684 in_frm = psf_frm;
685 }
686 }
687
688 int sx = 0;
689 int sy = 0;
690 const char* fname = cpl_frame_get_filename(in_frm);
691 cpl_msg_info(cpl_func,"strehl computed on: %s",fname);
692 cpl_image* in_ima = cpl_image_load(fname,CPL_TYPE_FLOAT, 0, 1);
693
694 sx = cpl_image_get_size_x(in_ima);
695 sy = cpl_image_get_size_y(in_ima);
696 bpm_frm = in_frm;
697 err_frm = in_frm;
698
699 plist = cpl_propertylist_load(fname,0);
700 double ron = cpl_propertylist_get_double(plist,"ESO DET CHIP RON");
701 double gain = cpl_propertylist_get_double(plist,"ESO DET CHIP GAIN");
702
703 //cpl_propertylist_delete(plist);
704 cpl_image_delete(in_ima);
705 region_params = hdrl_rect_region_parameter_create(1, 1, sx, sy);
706
707 /* Load the image */
708 if (eris_ifu_hdrl_image_load(in_frm, extnum_raw, err_frm, extnum_err,
709 bpm_frm, extnum_bpm, region_params, ron, gain,
710 &hima) != CPL_ERROR_NONE) {
711 if (region_params) hdrl_parameter_delete(region_params) ;
712
713 return cpl_error_set_message(cpl_func, CPL_ERROR_FILE_NOT_FOUND,
714 "Cannot load RAW image");
715 }
716 if (region_params) hdrl_parameter_delete(region_params) ;
717
718
719 //cpl_msg_info(cpl_func,"Handles NANs");
721
722 cpl_size cx = 0;
723 cpl_size cy = 0;
724 cpl_size margin_x = 4;
725 cpl_size margin_y = 4;
726 cpl_size llx = margin_x;
727 cpl_size lly = margin_y;
728 cpl_size urx = sx - margin_x;
729 cpl_size ury = sy - margin_y;
730
731 cpl_image_get_maxpos_window(hdrl_image_get_image(hima), llx, lly, urx, ury, &cx, &cy);
732 cpl_msg_info(cpl_func,"Image max detected at cx: %lld, cy: %lld",cx, cy);
733 /*
734 cpl_image_save(hdrl_image_get_image(hima),"ima.fits", CPL_TYPE_DOUBLE, NULL,
735 CPL_IO_DEFAULT);
736 */
737 cpl_msg_info(cpl_func,"check Strehl parameters");
738 /*
739 cpl_msg_info(cpl_func,"flux_radius[pix]: %g bkg_radius_low[pix]: %g bkg_radius_high[pix]: %g",
740 flux_radius_pix ,bkg_radius_low / pixel_scale_x,bkg_radius_high / pixel_scale_x );
741 */
742 res.strehl_value.data = 0;
743 res.strehl_value.error = 0;
744 hdrl_parameter * p;
745 cpl_msg_info(cpl_func,"wavelength: %g M1: %g M2: %g",wavelength, M1_RADIUS,M2_RADIUS);
746 cpl_msg_info(cpl_func,"flux_radius_pix: %g cx: %lld cy: %lld sx: %d sy:%d",flux_radius_pix, cx, cy, sx, sy);
747 if( (flux_radius_pix + cx) > (sx -2) ||
748 (flux_radius_pix + cy) > (sy -2) ||
749 (cx-flux_radius_pix) < 2 ||
750 (cy-flux_radius_pix) < 2){
751 //cpl_msg_info(cpl_func,"flux_radius_pix: %g",flux_radius_pix);
752 cpl_msg_info(cpl_func,"correct Strehl parameters");
753 flux_radius_pix = ( (flux_radius_pix + cx) > (sx -2) ) ? flux_radius_pix : sx -2;
754 flux_radius_pix = ( (flux_radius_pix + cy) > (sy -2) ) ? flux_radius_pix : sy -2;
755 flux_radius_pix = ( (cx - flux_radius_pix) < 2 ) ? cx -2 : flux_radius_pix;
756 flux_radius_pix = ( (cy - flux_radius_pix) < 2 ) ? cy -2 : flux_radius_pix;
757 //cpl_msg_info(cpl_func,"flux_radius_pix %g pixel_scale_x %g", flux_radius_pix, pixel_scale_x);
758 flux_radius_arc = flux_radius_pix * pixel_scale_x;
759 bkg_radius_low = flux_radius_arc;
760 bkg_radius_high = (flux_radius_pix + 1) * pixel_scale_x;
761 cpl_msg_info(cpl_func,"flux_radius: %g bkg_radius_low: %g bkg_radius_high: %g",
762 flux_radius_arc ,bkg_radius_low ,bkg_radius_high );
763
764 if(bkg_radius_low > 0) {
765 p = hdrl_strehl_parameter_create(wavelength,
766 M1_RADIUS, M2_RADIUS, pixel_scale_x, pixel_scale_y,
767 flux_radius_arc, bkg_radius_low, bkg_radius_high) ;
768 /* Strehl COMPUTATION */
769 res = hdrl_strehl_compute(hima, p);
771 } else {
772 cpl_msg_warning(cpl_func,"bkg_radius_low: %g. Skip Strehl computation.", bkg_radius_low);
773 }
774
775
776 } else {
777 //cpl_msg_info(cpl_func,"fwhm_sup: %g",fwhm_sup);
778 //for (flux_radius_pix=fwhm_sup; flux_radius_pix < 3 * fwhm_sup; flux_radius_pix += 0.2) {
779 flux_radius_arc = flux_radius_pix * pixel_scale_x;
780 cpl_msg_info(cpl_func,"flux_radius_pix: %g",flux_radius_pix);
781 if(bkg_radius_low > 0) {
782 p = hdrl_strehl_parameter_create(wavelength,
783 M1_RADIUS, M2_RADIUS, pixel_scale_x, pixel_scale_y,
784 flux_radius_arc, bkg_radius_low, bkg_radius_high) ;
785
786 res = hdrl_strehl_compute(hima, p);
788 cpl_msg_info(cpl_func,"strehl=%g+-%g", res.strehl_value.data,
789 res.strehl_value.error);
790 } else {
791 cpl_msg_warning(cpl_func,"bkg_radius_low: %g. Skip Strehl computation.", bkg_radius_low);
792 }
793
794 //}
795 }
796
797
798
799 if(cpl_error_get_code() != CPL_ERROR_NONE) {
800 cpl_msg_error(cpl_func,"Error computing Strehl. Temporarily suppress it.");
801 cpl_error_set(cpl_func,CPL_ERROR_NONE);
802 hdrl_image_delete(hima);
803 return CPL_ERROR_NONE;
804 } else {
805 if (res.strehl_value.data > 0) {
806
807 cpl_msg_info(cpl_func,"strehl=%g+-%g", res.strehl_value.data,
808 res.strehl_value.error);
809 /* expected difference sqrt(pi / 2) due to median */
810 cpl_msg_info(cpl_func, "star peak at %g/%g: %g +- %g", res.star_x,
811 res.star_y, res.star_peak.data, res.star_peak.error);
812 cpl_msg_info(cpl_func, "star flux %g+-%g", res.star_flux.data,
813 res.star_flux.error);
814 cpl_msg_info(cpl_func,"median estimated background=%g+-%g "
815 "(computed error %g)",
816 res.star_background.data, res.star_background.error,
817 res.computed_background_error);
818
819 double qc_strehl = 0;
820 double qc_strehl_err = 0;
821 if(isnan(res.strehl_value.data)){
822 qc_strehl=999.;
823 qc_strehl_err=999.;
824 } else {
825 qc_strehl=res.strehl_value.data;
826 qc_strehl_err=res.strehl_value.error;
827 }
828
829 cpl_image* data = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, extnum_raw);
830
831 cpl_image* errs = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, extnum_err);
832 cpl_propertylist* eheader = cpl_propertylist_load(fname, extnum_err);
833
834
835 cpl_image* qual = cpl_image_load(fname, CPL_TYPE_INT, 0, extnum_bpm);
836 cpl_propertylist* qheader = cpl_propertylist_load(fname, extnum_bpm);
837
838
839
840 cpl_propertylist_append_double(plist, "ESO QC STREHL", qc_strehl);
841 cpl_propertylist_append_double(plist, "ESO QC STREHL ERROR", qc_strehl_err);
842 cpl_image_save(data, fname, CPL_TYPE_DOUBLE, plist, CPL_IO_DEFAULT);
843 //cpl_propertylist_dump(plist,stdout);
844 /*
845 const char* pcatg = cpl_propertylist_get_string(plist, FHDR_PRO_CATG);
846 eris_ifu_save_image(frameset, plist, parlist, recipe_name, pcatg,
847 fname, CPL_TYPE_DOUBLE, data);
848 */
849
850 cpl_image_save(errs, fname, CPL_TYPE_DOUBLE, eheader, CPL_IO_EXTEND);
851 cpl_image_save(qual, fname, CPL_TYPE_INT, qheader, CPL_IO_EXTEND);
852 cpl_image_delete(data);
853 cpl_image_delete(errs);
854 cpl_image_delete(qual);
855
856 cpl_propertylist_delete(eheader);
857 cpl_propertylist_delete(qheader);
858 //cpl_msg_info(cpl_func,"ok5");
859 }
860 }
861 cpl_propertylist_delete(plist);
862 /* Cleanup */
863
864 hdrl_image_delete(hima);
865 eris_check_error_code("eris_ifu_stdstar_strehl_compute");
866
867 return cpl_error_get_code();
868}
869
cpl_error_code eris_ifu_dfs_set_groups(cpl_frameset *self)
Set the group as RAW or CALIB in a frameset.
Definition: eris_ifu_dfs.c:63
cpl_error_code eris_ifu_mask_nans_in_hdrlimage(hdrl_image **hima)
Flag NANs in 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