sinfo_new_psf.c

00001 /*
00002  * This file is part of the ESO SINFONI Pipeline
00003  * Copyright (C) 2004,2005 European Southern Observatory
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00018  */
00019 /*----------------------------------------------------------------------------
00020 
00021      File name    :       sinfo_new_psf.c
00022    Author       :    A. Modigliani
00023    Created on   :    Sep 17, 2003
00024    Description  :
00025 
00026  sinfo_new_psf.py does the image reconstruction of a set of
00027  sky-subtracted, flatfielded,
00028  bad pixel corrected and slope of the spectra aligned exposures of a bright
00029  star with continuum spectrum. The resulting image can be used to determine
00030  the PSF
00031  ---------------------------------------------------------------------------*/
00032 #ifdef HAVE_CONFIG_H
00033 #  include <config.h>
00034 #endif
00035 
00036 /*----------------------------------------------------------------------------
00037                                 Includes
00038  ---------------------------------------------------------------------------*/
00039 #define _GNU_SOURCE
00040 #include <math.h>
00041 
00042 #include <sinfo_cpl_size.h>
00043 
00044 #include <irplib_utils.h>
00045 #include <irplib_strehl.h>
00046 #include "sinfo_new_psf.h"
00047 #include "sinfo_pro_save.h"
00048 #include "sinfo_hidden.h"
00049 #include "sinfo_key_names.h"
00050 #include "sinfo_psf_ini.h"
00051 #include "sinfo_psf_ini_by_cpl.h"
00052 #include "sinfo_utilities_scired.h"
00053 #include "sinfo_hidden.h"
00054 #include "sinfo_pfits.h"
00055 #include "sinfo_functions.h"
00056 #include "sinfo_error.h"
00057 #include "sinfo_utils_wrappers.h"
00058 #include "sinfo_globals.h"
00059 //Used only for sinfo_propertylist_has
00060 #include "sinfo_dfs.h"
00061 /*----------------------------------------------------------------------------
00062                                 Defines
00063  ---------------------------------------------------------------------------*/
00064                                                    //PSO
00065 #define SINFO_MATH_PI   3.1415926535897932384626433832795028841971693993751058
00066 #define SINFO_MATH_PI_2 1.5707963267948966192313216916397514420985846996875529
00067 #define SINFO_MATH_PI_4 0.7853981633974483096156608458198757210492923498437765
00068 
00069 
00070 
00071 #define SINFO_STREHL_M1                       8.0  //7.9
00072 #define SINFO_STREHL_M2                       1.1  //1.33
00073 #define SINFO_STREHL_BOX_SIZE                 64
00074 #define SINFO_STREHL_WINDOW                   6
00075 #define SINFO_PSF_SZ                          4
00076 #define SINFO_RSTAR                           32//25
00077 #define SINFO_BKG_R1                          32//25
00078 #define SINFO_BKG_R2                          33//27
00079 #define SINFO_STREHL_ERROR_COEFFICIENT    SINFO_MATH_PI * 0.007 / 0.0271
00080 #ifndef SINFO_STREHL_RAD_CENTRAL
00081 #define SINFO_STREHL_RAD_CENTRAL 5
00082 #endif
00083 
00084 //constants for perfect PSF generation
00085 // Dimension of the support for generating the perfect PFS
00086 #define SINFO_PSF_DIM   1024//256
00087 #define SINFO_PSF_BLOCKS   63//11
00088 
00089 #define SINFO_PSF_BIN    16 // Pixels over "pixel_size"
00090 #define SINFO_PSF_NPOINT 10000// number of encircled energy sampling points
00091 #define SINFO_BKG_BOX_SZ 8
00092 /*----------------------------------------------------------------------------
00093                              Function Definitions
00094  ---------------------------------------------------------------------------*/
00095 static cpl_error_code
00096 sinfo_add_com_psf_qclog(const char* fname,cpl_table** qclog_tbl);
00097 
00098 
00099 static cpl_error_code
00100 sinfo_get_star_features(const cpl_image* im,
00101                         const int radius,
00102             const int xpos,
00103             const int ypos,
00104                         double* xc,
00105                         double* yc,
00106                         double* pick,
00107                         double* flux,
00108                         double* bkg);
00109 
00110 static double
00111 sinfo_find_min_of_four(const double n1,
00112                        const double n2,
00113                        const double n3,
00114                        const double n4);
00115 
00116 static cpl_table*
00117 sinfo_get_strehl_from_2images(cpl_image* ima1,
00118                              cpl_image* ima2,
00119                              cpl_frame* frm1,
00120                   cpl_frame* frm2);
00121 
00122 
00123 static int
00124 sinfo_get_strehl_input1(cpl_frame* frm1,
00125                 double* dispersion,
00126                 double* centralWave,
00127                 double* ws,
00128                 double* we,
00129                 double* pscale,
00130                 double* exptime,
00131             double* strehl_star_rad,
00132                 double* strehl_bg_rmin,
00133                 double* strehl_bg_rmax);
00134 
00135 static int
00136 sinfo_get_strehl_input2(cpl_frame* frm1,cpl_frame* frm2,
00137                double* dispersion,
00138                double* centralWave,
00139                double* ws,
00140                double* we,
00141                double* pscale1,
00142                double* pscale2,
00143                double* exptime1,
00144                double* exptime2,
00145                double* strehl_star_rad1,
00146                double* strehl_star_rad2,
00147                double* strehl_bg_rmin1,
00148                double* strehl_bg_rmin2,
00149                double* strehl_bg_rmax1,
00150                double* strehl_bg_rmax2);
00151 
00152 
00153 static void
00154 sinfo_check_borders(cpl_size* val,const int max,const int thresh);
00155 
00156 static void
00157 sinfo_get_safe_box(int* llx,
00158                    int* lly,
00159                    int* urx,
00160                    int* ury,
00161                    const int xpos,
00162                    const int ypos,
00163                    const int box,
00164                    const int szx,
00165                    const int szy);
00166 
00167 static int
00168 sinfo_get_strehl_from_slice(cpl_imagelist* cube,
00169                             double disp,
00170                             double cWave,
00171                             double ws,
00172                             double we,
00173                             double pscale,
00174                             double strehl_star_radius,
00175                             double strehl_bg_r1,
00176                             double strehl_bg_r2,
00177                             double* strehl,
00178                             double* strehl_err);
00179 
00180 
00181 static cpl_table*
00182 sinfo_get_encircled_energy(cpl_frameset* sof,
00183                            cpl_image* img,
00184                            double* fwhm_x,
00185                double* fwhm_y,
00186                            cpl_table** qclog);
00187 
00188 static double
00189 sinfo_get_strehl_from_ima(cpl_image* ima,
00190                           cpl_frame* frame);
00191 
00192 static int
00193 sinfo_get_strehl_from_image(cpl_image* img,
00194                             double ws,
00195                             double we,
00196                             double pscale,
00197                             double strehl_star_radius,
00198                             double strehl_bg_r1,
00199                             double strehl_bg_r2,
00200                             double* strehl,
00201                 double* strehl_err);
00202 
00203 
00204 
00205 static cpl_table*
00206 sinfo_get_strehl_from_cube(cpl_imagelist* cube,
00207                            char* name,
00208                            cpl_frame* frame);
00209 
00210 static int
00211 sinfo_get_frm12(cpl_frameset* sof,cpl_frame** frm1,cpl_frame** frm2);
00212 
00213 
00222 /*----------------------------------------------------------------------------
00223    Function     :       sinfo_new_psf()
00224    In           :       ini_file: file name of according .ini file
00225    Out          :       integer (0 if it worked, -1 if it doesn't)
00226    Job          :
00227 
00228  sinfo_new_psf.py does the image reconstruction of a set of sky-subtracted,
00229  flatfielded,
00230  bad pixel corrected and slope of the spectra aligned exposures of a bright
00231  star with continuum spectrum. The resulting image can be used to determine
00232  the PSF
00233 
00234  ---------------------------------------------------------------------------*/
00235 
00236 int
00237 sinfo_new_psf (const char* plugin_id,
00238                cpl_parameterlist* config,
00239                cpl_frameset* sof, cpl_frameset* ref_set)
00240 {
00241 
00242   cpl_imagelist* cube1=NULL;
00243   cpl_imagelist* cube2=NULL;
00244   cpl_image * med_img1=NULL ;
00245   cpl_image * med_img2=NULL ;
00246 
00247   cpl_table* ao_performance=NULL;
00248   cpl_table* enc_energy=NULL;
00249 
00250   cpl_frame* frm1=NULL;
00251   cpl_frame* frm2=NULL;
00252 
00253   cpl_table* qclog_tbl=NULL;
00254   cpl_frameset* stk=NULL;
00255   cpl_propertylist* plist =NULL;
00256 
00257   psf_config * cfg =NULL;
00258 
00259   int nsample=0;
00260   int i = 0;
00261   int status=0;
00262 
00263 
00264 
00265   int strehl_sw=0;
00266   int ilx1=0;
00267   int ily1=0;
00268   int ilx2=0;
00269   int ily2=0;
00270 
00271   float cx1=0;
00272   float cy1=0;
00273   float cx2=0;
00274   float cy2=0;
00275 
00276   double fwhm_x=0;
00277   double fwhm_y=0;
00278   double lam=0;
00279   double strehl=0;
00280   double strehl1=0;
00281   double strehl2=0;
00282 
00283   char fname1[MAX_NAME_SIZE];
00284   char fname2[MAX_NAME_SIZE];
00285 
00286   char key_name[MAX_NAME_SIZE];
00287 
00288   char obs_name1[MAX_NAME_SIZE];
00289   char hlamp_st='F';
00290   char shut2_st='F';
00291   cpl_table* tmp_tbl=NULL;
00292 
00293 
00294   /*
00295        -----------------------------------------------------------------
00296        1) parse the file names and parameters to the psf_config data
00297           structure cfg
00298        -----------------------------------------------------------------
00299   */
00300 
00301   sinfo_msg("Parsing cpl input");
00302   check_nomsg(stk=cpl_frameset_new());
00303 
00304   cknull(cfg = sinfo_parse_cpl_input_psf(sof,&stk),
00305       "error parsing cpl input");
00306 
00307   /* TODO the following generate a small leak of 72 bytes */
00308   strehl_sw=sinfo_get_strehl_type(sof);
00309   if(strehl_sw==0) {
00310     sinfo_msg("One target Strehl computation");
00311     if(sinfo_is_fits_file(cfg->inFrame) != 1) {
00312       sinfo_msg_error("Input file %s is not FITS",cfg->inFrame);
00313       goto cleanup;
00314     } else {
00315       strcpy(fname1,cfg->inFrame);
00316     }
00317 
00318      if(NULL != cpl_frameset_find(sof,PRO_COADD_PSF)) {
00319       frm1 = cpl_frameset_find(sof,PRO_COADD_PSF);
00320     } else if(NULL != cpl_frameset_find(sof,PRO_OBS_PSF)) {
00321       frm1 = cpl_frameset_find(sof,PRO_OBS_PSF);
00322     } else if(NULL != cpl_frameset_find(sof,PRO_COADD_STD)) {
00323       frm1 = cpl_frameset_find(sof,PRO_COADD_STD);
00324     } else if(NULL != cpl_frameset_find(sof,PRO_OBS_STD)) {
00325       frm1 = cpl_frameset_find(sof,PRO_OBS_STD);
00326     } else if(NULL != cpl_frameset_find(sof,PRO_COADD_OBJ)) {
00327       frm1 = cpl_frameset_find(sof,PRO_COADD_OBJ);
00328     } else if(NULL != cpl_frameset_find(sof,PRO_OBS_OBJ)) {
00329       frm1 = cpl_frameset_find(sof,PRO_OBS_OBJ);
00330     } else {
00331       sinfo_msg_error("Frame %s  or %s or %s  or %s or %s  or %s not found!",
00332               PRO_COADD_PSF,PRO_OBS_PSF,
00333               PRO_COADD_STD,PRO_OBS_STD,
00334               PRO_COADD_OBJ,PRO_OBS_OBJ);
00335       goto cleanup;
00336     }
00337 
00338     sinfo_get_obsname(frm1,obs_name1);
00339     check_nomsg(hlamp_st=sinfo_get_keyvalue_bool(frm1,KEY_NAME_LAMP_HALO));
00340     check_nomsg(shut2_st=sinfo_get_keyvalue_bool(frm1,KEY_NAME_SHUT2_ST));
00341 
00342 
00343     check_nomsg(cube1 = cpl_imagelist_load(fname1,CPL_TYPE_FLOAT,0));
00344     cknull(med_img1=sinfo_new_median_cube(cube1),
00345       " could not do sinfo_medianCube()");
00346 
00347     check_nomsg(ilx1=cpl_image_get_size_x(med_img1));
00348     check_nomsg(ily1=cpl_image_get_size_y(med_img1));
00349 
00350     cx1 = ilx1 / 2. + 0.5;
00351     cy1 = ily1 / 2. + 0.5;
00352 
00353     cknull(ao_performance=sinfo_get_strehl_from_cube(cube1,fname1,frm1),
00354        "error computing strehl");
00355     strehl=sinfo_get_strehl_from_ima(med_img1,frm1);
00356     sinfo_free_imagelist(&cube1);
00357   } else {
00358     sinfo_msg("Two target Strehl computation");
00359     sinfo_get_frm12(sof,&frm1,&frm2);
00360     strcpy(fname1,cpl_frame_get_filename(frm1));
00361     strcpy(fname2,cpl_frame_get_filename(frm2));
00362 
00363     check_nomsg(cube1 = cpl_imagelist_load(fname1,CPL_TYPE_FLOAT,0));
00364     check_nomsg(cube2 = cpl_imagelist_load(fname2,CPL_TYPE_FLOAT,0));
00365     cknull(med_img1=sinfo_new_median_cube(cube1),"Computing median on cube");
00366     cknull(med_img2=sinfo_new_median_cube(cube2),"Computing median on cube");
00367     check_nomsg(cpl_image_save(med_img1,"med_img1.fits",CPL_BPP_IEEE_FLOAT,
00368                    NULL,CPL_IO_DEFAULT));
00369     check_nomsg(cpl_image_save(med_img2,"med_img2.fits",CPL_BPP_IEEE_FLOAT,
00370                    NULL,CPL_IO_DEFAULT));
00371 
00372 
00373     check_nomsg(ilx1=cpl_image_get_size_x(med_img1));
00374     check_nomsg(ily1=cpl_image_get_size_y(med_img1));
00375     check_nomsg(ilx2=cpl_image_get_size_x(med_img2));
00376     check_nomsg(ily2=cpl_image_get_size_y(med_img2));
00377 
00378     cx1 = ilx1 / 2. + 0.5;
00379     cy1 = ily1 / 2. + 0.5;
00380     cx2 = ilx2 / 2. + 0.5;
00381     cy2 = ily2 / 2. + 0.5;
00382 
00383 
00384     sinfo_free_imagelist(&cube1);
00385     sinfo_free_imagelist(&cube2);
00386 
00387     cknull(tmp_tbl=sinfo_get_strehl_from_2images(med_img1,med_img2,frm1,frm2),
00388        "Computing strehl");
00389     check_nomsg(strehl=cpl_table_get_double(tmp_tbl,"strehl",0,&status));
00390     sinfo_free_table(&tmp_tbl);
00391     strehl1=sinfo_get_strehl_from_ima(med_img1,frm1);
00392     sinfo_msg_debug("Strehl on 1st image=%f",strehl);
00393     strehl2=sinfo_get_strehl_from_ima(med_img2,frm2);
00394     sinfo_msg_debug("Strehl on 2nd image=%f",strehl);
00395 
00396     cknull_nomsg(qclog_tbl = sinfo_qclog_init());
00397     check_nomsg(sinfo_add_com_psf_qclog(fname1,&qclog_tbl));
00398     if(irplib_isnan(strehl1)) strehl1=-100.;
00399     ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC STREHL025",strehl1,
00400             "STREHL 25 mas","%f"));
00401     ck0(sinfo_pro_save_ima(med_img1,ref_set,sof,PSF_MED_CUB_025_FILENAME,
00402                PRO_MED_COADD_PSF,qclog_tbl,plugin_id,config),
00403     "cannot save ima %s", PSF_MED_CUB_100_FILENAME);
00404     sinfo_free_table(&qclog_tbl);
00405 
00406 
00407     cknull_nomsg(qclog_tbl = sinfo_qclog_init());
00408     check_nomsg(sinfo_add_com_psf_qclog(fname2,&qclog_tbl));
00409     if(irplib_isnan(strehl2)) strehl2=-100.;
00410     ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC STREHL100",strehl2,
00411             "STREHL 100 mas","%f"));
00412 
00413     if(irplib_isnan(strehl)) strehl=-100.;
00414 
00415     ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC STREHL",strehl,
00416             "STREHL from both pixel scale images","%f"));
00417     ck0(sinfo_pro_save_ima(med_img2,ref_set,sof,PSF_MED_CUB_100_FILENAME,
00418                PRO_MED_COADD_PSF,qclog_tbl,plugin_id,config),
00419     "cannot save ima %s", PSF_MED_CUB_100_FILENAME);
00420 
00421     sinfo_free_table(&qclog_tbl);
00422     sinfo_free_image(&med_img2);
00423 
00424   }
00425   /* STREHL computation */
00426 
00427   check_nomsg(nsample=cpl_table_get_nrow(ao_performance));
00428   cknull_nomsg(qclog_tbl = sinfo_qclog_init());
00429   check_nomsg(sinfo_add_com_psf_qclog(fname1,&qclog_tbl));
00430 
00431   if(strehl_sw==0) {
00432     if(irplib_isnan(strehl)) strehl=-100.;
00433 
00434   ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC STREHL",strehl,
00435             "STREHL from image","%f"));
00436 
00437   }
00438 
00439   check_nomsg(strehl=cpl_table_get_column_median(ao_performance,"strehl"));
00440 
00441   ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC STREHL MED",strehl,
00442             "STREHL MEDIAN","%f"));
00443 
00444   check_nomsg(strehl=cpl_table_get_column_mean(ao_performance,"strehl"));
00445 
00446   ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC STREHL AVG",strehl,
00447             "STREHL AVERAGE","%f"));
00448   /*
00449   strehl=sinfo_get_strehl_from_ima(med_img1,frm1);
00450 
00451   ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC STREHL AVG",strehl,
00452             "STREHL AVERAGE","%f"));
00453   */
00454   for(i=1;i<nsample;i++) {
00455 
00456     check_nomsg(strehl=cpl_table_get_double(ao_performance,"strehl",
00457                                             i,&status));
00458     if(irplib_isnan(strehl)) strehl=-100.;
00459 
00460     snprintf(key_name,MAX_NAME_SIZE-1,"%s%d","QC STREHL",i);
00461     ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,strehl,"STREHL","%f"));
00462 
00463     check_nomsg(lam=cpl_table_get_double(ao_performance,"wavelength",
00464                                          i,&status));
00465     snprintf(key_name,MAX_NAME_SIZE-1,"%s%d","QC LAMBDA",i);
00466     ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,lam,
00467                                      "WAVELENGTH","%f"));
00468 
00469   }
00470 
00471   check_nomsg(strehl=cpl_table_get_column_median(ao_performance,
00472                                                  "strehl_error"));
00473   ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC STREHL MEDERR",strehl,
00474                                    "STREHL ERROR MEDIAN","%f"));
00475   ck0_nomsg(sinfo_qclog_add_string(qclog_tbl,"OBS NAME",obs_name1,
00476                                    "OB name","%s"));
00477   ck0_nomsg(sinfo_qclog_add_bool(qclog_tbl,PAF_NAME_LAMP_HALO,hlamp_st,
00478                                   KEY_NAME_LAMP_HALO,"%d"));
00479   ck0_nomsg(sinfo_qclog_add_bool(qclog_tbl,PAF_NAME_SHUT2_ST,shut2_st,
00480                                   KEY_NAME_SHUT2_ST,"%d"));
00481 
00482   ck0(sinfo_pro_save_tbl(ao_performance,ref_set,sof,
00483                   PSF_AO_PERFORMANCE_OUT_FILENAME,
00484              PRO_AO_PERFORMANCE,qclog_tbl,plugin_id,config),
00485     "cannot save tbl %s", PSF_AO_PERFORMANCE_OUT_FILENAME);
00486 
00487   sinfo_free_table(&qclog_tbl);
00488   sinfo_free_table(&ao_performance);
00489 
00490   /* Encircled energy & FWHM computation */
00491   cknull_nomsg(qclog_tbl=sinfo_qclog_init());
00492   cknull(enc_energy=sinfo_get_encircled_energy(sof,
00493                            med_img1,
00494                            &fwhm_x,
00495                            &fwhm_y,
00496                            &qclog_tbl),
00497            "Computing encircled energy");
00498 
00499   ck0(sinfo_pro_save_tbl(enc_energy,ref_set,sof,PSF_ENC_ENERGY_OUT_FILENAME,
00500              PRO_ENC_ENERGY,qclog_tbl,plugin_id,config),
00501       "cannot save tbl %s", PSF_ENC_ENERGY_OUT_FILENAME);
00502 
00503   sinfo_free_table(&qclog_tbl);
00504   sinfo_free_table(&enc_energy);
00505 
00506   /* QC log */
00507   cknull_nomsg(qclog_tbl = sinfo_qclog_init());
00508   ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC FWHMX",fwhm_x,
00509                                    "QC FWHM X","%f"));
00510   ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC FWHMY",fwhm_y,
00511                                    "QC FWHM Y","%f"));
00512   ck0_nomsg(sinfo_qclog_add_bool(qclog_tbl,PAF_NAME_LAMP_HALO,
00513                                  hlamp_st,KEY_NAME_LAMP_HALO,"%d"));
00514   ck0_nomsg(sinfo_qclog_add_bool(qclog_tbl,PAF_NAME_SHUT2_ST,shut2_st,
00515                                  KEY_NAME_SHUT2_ST,"%d"));
00516 
00517   ck0(sinfo_pro_save_ima(med_img1,ref_set,sof,cfg->outName,PRO_PSF,
00518              qclog_tbl,plugin_id,config),
00519       "cannot save ima %s", cfg->outName);
00520 
00521   sinfo_free_table(&qclog_tbl);
00522   sinfo_new_set_wcs_image(med_img1,cfg->outName,cx1, cy1);
00523   sinfo_free_image(&med_img1);
00524   sinfo_free_frameset(&stk);
00525   sinfo_free_psf(&cfg);
00526   return 0;
00527 
00528  cleanup:
00529 
00530   sinfo_free_table(&qclog_tbl);
00531   sinfo_free_imagelist(&cube2);
00532   sinfo_free_imagelist(&cube1);
00533   sinfo_free_table(&enc_energy);
00534   sinfo_free_image(&med_img1);
00535   sinfo_free_table(&ao_performance);
00536   sinfo_free_propertylist(&plist) ;
00537   sinfo_free_psf(&cfg);
00538   sinfo_free_frameset(&stk);
00539 
00540   return -1 ;
00541 
00542 }
00543 
00544 
00545 
00546 
00547 static cpl_error_code
00548 sinfo_add_com_psf_qclog(const char* fname,cpl_table** qclog_tbl)
00549 {
00550 
00551   cpl_propertylist* plist=NULL;
00552 
00553   /* QC log */
00554   cknull(plist = cpl_propertylist_load(fname, 0),
00555      "getting header from reference ima frame %s",fname);
00556 
00557   if (sinfo_propertylist_has(plist, KEY_NAME_LOOP_STATE)) {
00558     sinfo_qclog_add_string(*qclog_tbl,KEY_NAME_LOOP_STATE,
00559                       cpl_propertylist_get_string(plist,KEY_NAME_LOOP_STATE),
00560                       KEY_HELP_LOOP_STATE,"%s");
00561   }
00562 
00563 
00564 
00565   if (sinfo_propertylist_has(plist, KEY_NAME_LOOP_LGS)) {
00566     sinfo_qclog_add_int(*qclog_tbl,KEY_NAME_LOOP_LGS,
00567                       cpl_propertylist_get_int(plist,KEY_NAME_LOOP_LGS),
00568                       KEY_HELP_LOOP_LGS,"%d");
00569   }
00570 
00571 
00572   if (sinfo_propertylist_has(plist, KEY_NAME_INS1_MODE)) {
00573     sinfo_qclog_add_string(*qclog_tbl,KEY_NAME_INS1_MODE,
00574                       cpl_propertylist_get_string(plist,KEY_NAME_INS1_MODE),
00575                       KEY_HELP_INS1_MODE,"%s");
00576   }
00577 
00578 
00579  cleanup:
00580   sinfo_free_propertylist(&plist);
00581 
00582   if (cpl_error_get_code() != CPL_ERROR_NONE) {
00583     return cpl_error_get_code();
00584   } else {
00585     return CPL_ERROR_NONE;
00586   }
00587 
00588 
00589 }
00590 
00591 static int
00592 sinfo_get_strehl_from_image(cpl_image* img,
00593                             double ws,
00594                             double we,
00595                             double pscale,
00596                             double strehl_star_radius,
00597                             double strehl_bg_r1,
00598                             double strehl_bg_r2,
00599                             double* strehl,
00600                             double* strehl_err)
00601 {
00602   cpl_errorstate clean_state = cpl_errorstate_get();
00603 
00604   cpl_image* img_dup=NULL;
00605 
00606   double dlam=0.;
00607   double lam=0.;
00608 
00609   double max_ima_cx=0.;
00610   double max_ima_cy=0.;
00611 
00612   double psf_peak=0.;
00613   double psf_flux=0.;
00614   double bkg_noise=0.;
00615   double star_bkg=0.;
00616   double star_peak=0.;
00617   double star_flux=0.;
00618 
00619   cpl_size max_ima_x=0;
00620   cpl_size max_ima_y=0;
00621   int wllx=0;
00622   int wlly=0;
00623   int wurx=0;
00624   int wury=0;
00625   int ima_szx=0;
00626   int ima_szy=0;
00627 
00628 
00629   lam = (double)0.5*(ws+we);
00630   dlam=we-ws;
00631   sinfo_msg_debug("ws=%f we=%f dl=%f",ws,we,dlam);
00632   check_nomsg(img_dup=cpl_image_duplicate(img));
00633   sinfo_clean_nan(&img_dup);
00634   check_nomsg(cpl_image_get_maxpos(img_dup,&max_ima_x,&max_ima_y));
00635   sinfo_free_image(&img_dup);
00636 
00637   check_nomsg(ima_szx=cpl_image_get_size_x(img));
00638   check_nomsg(ima_szy=cpl_image_get_size_y(img));
00639   sinfo_check_borders(&max_ima_x,ima_szx,SINFO_STREHL_WINDOW);
00640   sinfo_check_borders(&max_ima_y,ima_szy,SINFO_STREHL_WINDOW);
00641   sinfo_get_safe_box(&wllx,&wlly,&wurx,&wury,max_ima_x,max_ima_y,SINFO_PSF_SZ,
00642   ima_szx,ima_szy);
00643 
00644   //cpl_image_get_maxpos_window(img,wllx,wlly,wurx,wury,&max_ima_x,&max_ima_y);
00645 
00646   check_nomsg(max_ima_cx=cpl_image_get_centroid_x_window(img,wllx,wlly,
00647                                                          wurx,wury));
00648   check_nomsg(max_ima_cy=cpl_image_get_centroid_y_window(img,wllx,wlly,
00649   wurx,wury));
00650 
00651 
00652   if(CPL_ERROR_NONE != sinfo_strehl_compute_one(img,
00653                         SINFO_STREHL_M1,
00654                         SINFO_STREHL_M2,
00655                         lam,
00656                         dlam,
00657                         pscale,
00658                         max_ima_x,
00659                         max_ima_y,
00660                         strehl_star_radius,
00661                         strehl_bg_r1,
00662                         strehl_bg_r2,
00663                         SINFO_STREHL_BOX_SIZE,
00664                         strehl,
00665                         strehl_err,
00666                         &star_bkg,
00667                         &star_peak,
00668                         &star_flux,
00669                         &psf_peak,
00670                         &psf_flux,
00671                         &bkg_noise)) {
00672 
00673 
00674     *strehl=-1;
00675     *strehl_err=0;
00676     irplib_error_recover(clean_state,"Problem computing strehl");
00677 
00678   }
00679 
00680   return 0;
00681 
00682  cleanup:
00683 
00684   return -1;
00685 
00686 }
00687 
00688 
00689 
00690 
00691 
00692 
00693 static int
00694 sinfo_get_strehl_from_slice(cpl_imagelist* cube,
00695                             double disp,
00696                             double cWave,
00697                             double ws,
00698                             double we,
00699                             double pscale,
00700                             double strehl_star_radius,
00701                             double strehl_bg_r1,
00702                             double strehl_bg_r2,
00703                             double* strehl,
00704                             double* strehl_err)
00705 {
00706 
00707 
00708   cpl_errorstate clean_state = cpl_errorstate_get();
00709 
00710 
00711   cpl_image* img_dup=NULL;
00712   cpl_image* img=NULL;
00713 
00714   double dlam=0.;
00715   double lam=0.;
00716 
00717   double max_ima_cx=0.;
00718   double max_ima_cy=0.;
00719   double psf_peak=0.;
00720   double psf_flux=0.;
00721   double bkg_noise=0.;
00722   double star_bkg=0.;
00723   double star_peak=0.;
00724   double star_flux=0.;
00725 
00726   cpl_size max_ima_x=0;
00727   cpl_size max_ima_y=0;
00728   int wllx=0;
00729   int wlly=0;
00730   int wurx=0;
00731   int wury=0;
00732   int ima_szx=0;
00733   int ima_szy=0;
00734 
00735 
00736   lam = (double)0.5*(ws+we);
00737   dlam=we-ws;
00738 
00739 
00740   img=sinfo_new_average_cube_to_image_between_waves(cube,disp,cWave,ws,we);
00741   check_nomsg(img_dup=cpl_image_duplicate(img));
00742   sinfo_clean_nan(&img_dup);
00743   check_nomsg(cpl_image_get_maxpos(img_dup,&max_ima_x,&max_ima_y));
00744   check_nomsg(cpl_image_delete(img_dup));
00745 
00746 
00747   check_nomsg(ima_szx=cpl_image_get_size_x(img));
00748   check_nomsg(ima_szy=cpl_image_get_size_y(img));
00749   sinfo_check_borders(&max_ima_x,ima_szx,SINFO_STREHL_WINDOW);
00750   sinfo_check_borders(&max_ima_y,ima_szy,SINFO_STREHL_WINDOW);
00751 
00752 
00753   sinfo_get_safe_box(&wllx,&wlly,&wurx,&wury,max_ima_x,max_ima_y,SINFO_PSF_SZ,
00754                                ima_szx,ima_szy);
00755 
00756   /*
00757   cpl_image_get_maxpos_window(img,wllx,wlly,wurx,wury,&max_ima_x,&max_ima_y);
00758    */
00759   check_nomsg(max_ima_cx=cpl_image_get_centroid_x_window(img,wllx,wlly,
00760                                                          wurx,wury));
00761 
00762 
00763 
00764   check_nomsg(max_ima_cy=cpl_image_get_centroid_y_window(img,wllx,wlly,
00765                                                          wurx,wury));
00766 
00767 
00768 
00769   if(CPL_ERROR_NONE != irplib_strehl_mark_bad_and_compute(img,
00770                                              SINFO_STREHL_M1,
00771                                              SINFO_STREHL_M2,
00772                                              lam,
00773                                              dlam,
00774                                              pscale,
00775                                              SINFO_STREHL_BOX_SIZE,
00776                                              max_ima_x,
00777                                              max_ima_y,
00778                                              strehl_star_radius,
00779                                              strehl_bg_r1,
00780                                              strehl_bg_r2,
00781                                              NOISE_HSIZE,
00782                                              NOISE_NSAMPLES,
00783                                              strehl,
00784                                              strehl_err,
00785                                              &star_bkg,
00786                                              &star_peak,
00787                                              &star_flux,
00788                                              &psf_peak,
00789                                              &psf_flux,
00790                                              &bkg_noise)) {
00791 
00792 
00793      *strehl=-1;
00794      *strehl_err=0;
00795       irplib_error_recover(clean_state,"Problem computing strehl");
00796 
00797   }
00798 
00799   /*
00800   cpl_msg_info(__func__,"stehl=%f err=%f star_bkg=%f star_peak=%f star_flux=%f",
00801                           *strehl,*strehl_err,star_bkg,star_peak,star_flux);
00802   cpl_msg_info(__func__,"psf_peak=%f psf_flux=%f bkg_noise=%f",
00803                          psf_peak,psf_flux,bkg_noise);
00804   */
00805   sinfo_free_image(&img);
00806 
00807 
00808   return 0;
00809 
00810  cleanup:
00811   return -1;
00812 
00813 }
00814 
00815 
00816 
00817 cpl_table* sinfo_get_encircled_energy(cpl_frameset* sof,
00818                                       cpl_image* img,
00819                                       double* fwhm_x,
00820                                       double* fwhm_y,
00821                                       cpl_table** qclog_tbl)
00822 {
00823 
00824   cpl_errorstate clean_state = cpl_errorstate_get();
00825 
00826   cpl_image* img_dup=NULL;
00827   cpl_size max_ima_x=0;
00828   cpl_size max_ima_y=0;
00829   int wllx=0;
00830   int wlly=0;
00831   int wurx=0;
00832   int wury=0;
00833   const double d_mirror = 8.;
00834   const double factor = 180/PI_NUMB*3600.;
00835   double max_ima_cx=0;
00836   double max_ima_cy=0;
00837 
00838   double norm=0.;
00839   double xc=0.;
00840   double yc=0.;
00841   double sx=0.;
00842   double sy=0.;
00843 
00844   double flux=0;
00845   double flux_max=0;
00846   double pix_scale=0;
00847   double lam=0.;
00848   double pscale=0.;
00849   int dr_difr=0;
00850 
00851   double r=0.;
00852   double bkg=0.;
00853   int i=0;
00854   int ni=0;
00855   int ir_difr=0;
00856   int dr=0;
00857   int rmin=0;
00858 
00859   char band[MAX_NAME_SIZE];
00860   char spat_res[MAX_NAME_SIZE];
00861 
00862   cpl_table* enc_energy=NULL;
00863   cpl_frame* frame=NULL;
00864 
00865   int ima_szx=0;
00866   int ima_szy=0;
00867 
00868 
00869 
00870   if(NULL != cpl_frameset_find(sof,PRO_COADD_PSF)) {
00871     frame = cpl_frameset_find(sof,PRO_COADD_PSF);
00872   } else if(NULL != cpl_frameset_find(sof,PRO_OBS_PSF)) {
00873     frame = cpl_frameset_find(sof,PRO_OBS_PSF);
00874   } else if(NULL != cpl_frameset_find(sof,PRO_COADD_STD)) {
00875     frame = cpl_frameset_find(sof,PRO_COADD_STD);
00876   } else if(NULL != cpl_frameset_find(sof,PRO_OBS_STD)) {
00877     frame = cpl_frameset_find(sof,PRO_OBS_STD);
00878   } else if(NULL != cpl_frameset_find(sof,PRO_COADD_OBJ)) {
00879     frame = cpl_frameset_find(sof,PRO_COADD_OBJ);
00880   } else if(NULL != cpl_frameset_find(sof,PRO_OBS_OBJ)) {
00881     frame = cpl_frameset_find(sof,PRO_OBS_OBJ);
00882   } else {
00883     sinfo_msg_error("Frame %s  or %s or  %s  or %s or %s  or %s not found!",
00884             PRO_COADD_PSF,PRO_OBS_PSF,
00885             PRO_COADD_STD, PRO_OBS_STD,
00886             PRO_COADD_OBJ, PRO_OBS_OBJ);
00887     return NULL;
00888   }
00889 
00890   sinfo_get_spatial_res(frame,spat_res);
00891   sinfo_get_band(frame,band);
00892   pix_scale=atof(spat_res);
00893   lam=sinfo_get_wave_cent(band);
00894   /* factor 2 due to change of detector to 2K */
00895   pscale=0.5*pix_scale;
00896 
00897 
00898 
00899   dr_difr=factor*1.22*lam*1.e-6/d_mirror/pscale;
00900   ir_difr=floor(dr_difr+0.5);
00901   if (pix_scale==0.025) {
00902     ni=10;
00903     rmin=ir_difr;
00904     dr=rmin;
00905   } else {
00906     ni=15;
00907     sinfo_msg_warning("Reset diffraction limit");
00908     ir_difr=10;
00909     rmin=1;
00910     dr=2;
00911   }
00912 
00913   sinfo_msg("Diffraction limit: %d",ir_difr);
00914 
00915   check_nomsg(img_dup=cpl_image_duplicate(img));
00916   sinfo_clean_nan(&img_dup);
00917   check_nomsg(cpl_image_get_maxpos(img_dup,&max_ima_x,&max_ima_y));
00918   sinfo_free_image(&img_dup);
00919 
00920 
00921 
00922   check_nomsg(ima_szx=cpl_image_get_size_x(img));
00923   check_nomsg(ima_szy=cpl_image_get_size_y(img));
00924   sinfo_check_borders(&max_ima_x,ima_szx,SINFO_STREHL_WINDOW);
00925   sinfo_check_borders(&max_ima_y,ima_szy,SINFO_STREHL_WINDOW);
00926   sinfo_get_safe_box(&wllx,&wlly,&wurx,&wury,max_ima_x,max_ima_y,SINFO_PSF_SZ,
00927                                ima_szx,ima_szy);
00928 
00929   check_nomsg(max_ima_cx=cpl_image_get_centroid_x_window(img,wllx,wlly,
00930                                                          wurx,wury));
00931   check_nomsg(max_ima_cy=cpl_image_get_centroid_y_window(img,wllx,wlly,
00932                                                          wurx,wury));
00933 
00934 
00935   cpl_image_save(img, "bad_image_psf_c.fits",CPL_BPP_IEEE_DOUBLE, NULL, CPL_IO_CREATE);
00936   sinfo_msg("@@@@ sinfo_get_encircled_energy() max_ima_x[%" CPL_SIZE_FORMAT "] max_ima_y[%" CPL_SIZE_FORMAT "] psf_sz[%d]", max_ima_x,
00937           max_ima_y,
00938           SINFO_PSF_SZ);
00939   if(CPL_ERROR_NONE != cpl_image_fit_gaussian(img,max_ima_x,max_ima_y,
00940                                               SINFO_PSF_SZ,
00941                                               &norm,&xc,&yc,&sx,&sy,
00942                                               fwhm_x,fwhm_y)) {
00943 
00944 
00945       irplib_error_recover(clean_state,"Gaussian fit failed");
00946 
00947   }
00948 
00949  check_nomsg(enc_energy = cpl_table_new(ni));
00950  check_nomsg(cpl_table_new_column(enc_energy,"r_pix", CPL_TYPE_INT));
00951  check_nomsg(cpl_table_new_column(enc_energy,"r_mas", CPL_TYPE_DOUBLE));
00952  check_nomsg(cpl_table_new_column(enc_energy,"r_dif", CPL_TYPE_DOUBLE));
00953  check_nomsg(cpl_table_new_column(enc_energy,"abs_energy" , CPL_TYPE_DOUBLE));
00954  check_nomsg(cpl_table_new_column(enc_energy,"rel_energy" , CPL_TYPE_DOUBLE));
00955  /* encircled energy computation */
00956  check_nomsg(bkg=irplib_strehl_ring_background(img,max_ima_x,max_ima_y,
00957                     SINFO_BKG_R1,SINFO_BKG_R2,IRPLIB_BG_METHOD_AVER_REJ)) ;
00958  r=rmin+(ni-1)*dr;
00959  check_nomsg(flux_max=irplib_strehl_disk_flux(img,max_ima_x,max_ima_y,r,bkg));
00960  r=rmin;
00961 
00962  for(i=0; i<ni; i++)
00963    {
00964      check_nomsg(flux=irplib_strehl_disk_flux(img,max_ima_x,max_ima_y,r,bkg));
00965      check_nomsg(cpl_table_set_int(enc_energy,"r_pix",i,r));
00966      check_nomsg(cpl_table_set_double(enc_energy,"r_mas",i,r*pscale));
00967      check_nomsg(cpl_table_set_double(enc_energy,"r_dif",i,r/ir_difr));
00968      check_nomsg(cpl_table_set_double(enc_energy,"abs_energy",i,flux));
00969      check_nomsg(cpl_table_set_double(enc_energy,"rel_energy",i,flux/flux_max));
00970      r+=dr;
00971 
00972    }
00973 
00974  //sinfo_msg("max ima=%d %d\n",max_ima_x,max_ima_y);
00975  //sinfo_msg("centroid ima=%f %f\n",max_ima_cx,max_ima_cy);
00976  //sinfo_msg("gauss info=%f %f %f %f %f %f %f\n",
00977  //                         norm,xc,yc,sx,sy,*fwhm_x,*fwhm_y);
00978 
00979  check_nomsg(flux=irplib_strehl_disk_flux(img,max_ima_x,max_ima_y,
00980                                           ir_difr,bkg));
00981  ck0_nomsg(sinfo_qclog_add_double(*qclog_tbl,"QC ENC CORE",
00982                                   flux/flux_max,
00983                                   "Encircled energy within PSF core","%f"));
00984 
00985  return enc_energy;
00986 
00987  cleanup:
00988   sinfo_free_image(&img_dup);
00989 
00990   return NULL;
00991 }
00992 
00993 
00994 static cpl_table* sinfo_get_strehl_from_cube(cpl_imagelist* cube,
00995                                             char* name,
00996                                             cpl_frame* frame)
00997 {
00998   cpl_table* strehl_tbl=NULL;
00999 
01000   double dispersion=0.;
01001   double centralWave=0.;
01002   double wrange=0;
01003   double wstart=0;
01004   double wstep=0;
01005   double wend=0;
01006   double ws=0;
01007   double we=0;
01008   double pix_scale=0;
01009   double lam=0;
01010   double dlam=0;
01011   double pscale = 0;
01012 
01013   double strehl_star_radius=0;
01014   double strehl_bg_r1=0;
01015   double strehl_bg_r2=0;
01016   double strehl=0;
01017   double strehl_err=0;
01018   char spat_res[MAX_NAME_SIZE];
01019   cpl_propertylist* plist=NULL;
01020 
01021   int naxis3=0;
01022   int nsample=0;
01023   int i=0;
01024 
01025 
01026   sinfo_get_spatial_res(frame,spat_res);
01027   pix_scale=atof(spat_res);
01028   sinfo_msg("Camera pixel scale=%f",pix_scale);
01029   /* factor 2 due to change of detector to 2K */
01030   pscale=0.5*pix_scale;
01031 
01032   strehl_star_radius=SINFO_BKG_R1*pscale;
01033   strehl_bg_r1=SINFO_BKG_R1*pscale;
01034   strehl_bg_r2=SINFO_BKG_R2*pscale;
01035 
01036   plist=cpl_propertylist_load(name,0);
01037   dispersion=sinfo_pfits_get_cdelt3(plist);
01038   centralWave=sinfo_pfits_get_crval3(plist);
01039   naxis3=sinfo_pfits_get_naxis3(plist);
01040   sinfo_free_propertylist(&plist);
01041   wrange=dispersion*naxis3;
01042 
01043   wstart = centralWave - (float) (cpl_imagelist_get_size(cube) / 2)*
01044                                  dispersion+dispersion;
01045   wend  =wstart + dispersion * cpl_imagelist_get_size(cube);
01046   wstep=0.025;
01047  /*
01048    note:
01049     -wstep as we do not hit the borders where the
01050     sinfo_gaussian fit has a problem
01051   */
01052   nsample=(int)((wend-wstart-wstep)/wstep);
01053   check_nomsg(strehl_tbl = cpl_table_new(nsample));
01054   check_nomsg(cpl_table_new_column(strehl_tbl,"wavelength",CPL_TYPE_DOUBLE));
01055   check_nomsg(cpl_table_new_column(strehl_tbl,"strehl",CPL_TYPE_DOUBLE));
01056   check_nomsg(cpl_table_new_column(strehl_tbl,"strehl_error",CPL_TYPE_DOUBLE));
01057 
01058 
01059   for(i=1;i<nsample;i++) {
01060 
01061     ws=wstart+wstep*i;
01062     we=ws+wstep;
01063 
01064     lam = (double)0.5*(ws+we);
01065     dlam=wstep;
01066 
01067     check(sinfo_get_strehl_from_slice(cube,
01068                                 dispersion,
01069                                 centralWave,
01070                                 ws,
01071                                 we,
01072                                 pscale,
01073                                 strehl_star_radius,
01074                                 strehl_bg_r1,
01075                                 strehl_bg_r2,
01076                                 &strehl,
01077                       &strehl_err),"Error computing strehl");
01078 
01079 
01080        if((isnan(lam) ==0) &&
01081           (isnan(lam) ==0) &&
01082           (isnan(lam) ==0)) {
01083      check_nomsg(cpl_table_set_double(strehl_tbl,"wavelength",i,lam));
01084      check_nomsg(cpl_table_set_double(strehl_tbl,"strehl",i,strehl));
01085      check_nomsg(cpl_table_set_double(strehl_tbl,"strehl_error",i,
01086                      strehl_err));
01087 
01088        }
01089   }
01090 
01091   return strehl_tbl;
01092 
01093  cleanup:
01094   return NULL;
01095 
01096 
01097 }
01098 
01099 
01100 static double
01101 sinfo_get_strehl_from_ima(cpl_image* ima,
01102                                         cpl_frame* frame)
01103 {
01104 
01105   double dispersion=0.;
01106   double centralWave=0.;
01107   double wstart=0;
01108   double wend=0;
01109   double pscale = 0;
01110 
01111   double strehl_star_radius=0;
01112   double strehl_bg_r1=0;
01113   double strehl_bg_r2=0;
01114   double strehl=0;
01115   double strehl_err=0;
01116   double exptime=0;
01117 
01118 
01119 
01120   ck0_nomsg(sinfo_get_strehl_input1(frame,&dispersion,&centralWave,
01121                                    &wstart,&wend,&pscale,&exptime,
01122                            &strehl_star_radius,&strehl_bg_r1,
01123                     &strehl_bg_r2));
01124 
01125 
01126   check(sinfo_get_strehl_from_image(ima,
01127                                 wstart,
01128                                 wend,
01129                                 pscale,
01130                                 strehl_star_radius,
01131                                 strehl_bg_r1,
01132                                 strehl_bg_r2,
01133                                 &strehl,
01134                 &strehl_err),"Computing Strehl");
01135 
01136 
01137 
01138 
01139 
01140  cleanup:
01141   return strehl;
01142 
01143 
01144 }
01145 
01146 static int
01147 sinfo_get_frm12(cpl_frameset* sof,cpl_frame** frm1,cpl_frame** frm2){
01148 
01149   cpl_frameset* obs=NULL;
01150   int nobs=0;
01151   float eps=0.0001;
01152   float* pix_scale=NULL;
01153   int i=0;
01154   cpl_frame* frame=NULL;
01155 
01156   obs = cpl_frameset_new();
01157   sinfo_contains_frames_kind(sof,obs,PRO_OBS_PSF);
01158   nobs=cpl_frameset_get_size(obs);
01159   if (nobs < 1) {
01160      sinfo_contains_frames_kind(sof,obs,PRO_OBS_STD);
01161      nobs=cpl_frameset_get_size(obs);
01162   }
01163 
01164   nobs=cpl_frameset_get_size(obs);
01165 
01166 
01167   if (nobs < 1) {
01168      sinfo_contains_frames_kind(sof,obs,PRO_OBS_OBJ);
01169      nobs=cpl_frameset_get_size(obs);
01170   }
01171 
01172   nobs=cpl_frameset_get_size(obs);
01173 
01174   if (nobs < 1) {
01175     return -1;
01176   } else {
01177     pix_scale=cpl_calloc(nobs,sizeof(float));
01178     for(i=0;i<nobs;i++) {
01179       frame=cpl_frameset_get_frame(obs,i);
01180       pix_scale[i]=sinfo_pfits_get_pixelscale(
01181                            (char*)cpl_frame_get_filename(frame));
01182       if(fabs(pix_scale[i]-0.025)< eps) {
01183         *frm1=cpl_frame_duplicate(frame);
01184       } else if (fabs(pix_scale[i]-0.1) <eps) {
01185         *frm2=cpl_frame_duplicate(frame);
01186       } else {
01187         sinfo_msg_error("No proper frame found for strehl computation");
01188     return -1;
01189       }
01190     }
01191   }
01192   cpl_free(pix_scale);
01193   cpl_frameset_delete(obs);
01194 
01195   return 0;
01196 
01197 }
01198 
01199 
01200 
01201 
01202 static int
01203 sinfo_get_strehl_input1(cpl_frame* frm,
01204                double* dispersion,
01205                double* centralWave,
01206                double* wstart,
01207                double* wend,
01208                double* pscale,
01209                double* exptime,
01210                double* strehl_star_rad,
01211                double* strehl_bg_rmin,
01212                double* strehl_bg_rmax)
01213 
01214 {
01215 
01216   cpl_propertylist* plist=NULL;
01217   char res[MAX_NAME_SIZE];
01218   double pix_scale=0;
01219   double wrange=0;
01220   char fname[MAX_NAME_SIZE];
01221   int naxis3=0;
01222 
01223   sinfo_get_spatial_res(frm,res);
01224   pix_scale=atof(res);
01225 
01226   /* factor 2 due to change of detector to 2K
01227   *pscale=0.5*pix_scale;
01228   */
01229 
01230 
01231   *pscale=pix_scale;
01232 
01233   *strehl_star_rad=SINFO_RSTAR*(*pscale);
01234   *strehl_bg_rmin=SINFO_BKG_R1*(*pscale);
01235   *strehl_bg_rmax=SINFO_BKG_R2*(*pscale);
01236 
01237   strcpy(fname,cpl_frame_get_filename(frm));
01238   check_nomsg(plist=cpl_propertylist_load(fname,0));
01239   check_nomsg(*dispersion=sinfo_pfits_get_cdelt3(plist));
01240   *centralWave=sinfo_pfits_get_crval3(plist);
01241   check_nomsg(naxis3=sinfo_pfits_get_naxis3(plist));
01242   *exptime=sinfo_pfits_get_exp_time(plist);
01243   sinfo_free_propertylist(&plist);
01244 
01245   wrange=(*dispersion)*naxis3;
01246 
01247   *wstart = *centralWave - (wrange / 2) +(*dispersion);
01248   *wend   = *wstart + wrange;
01249 
01250 
01251  cleanup:
01252   if (cpl_error_get_code() != CPL_ERROR_NONE) {
01253     return -1;
01254   } else {
01255     return 0;
01256   }
01257 
01258 }
01259 
01260 
01261 static int
01262 sinfo_get_strehl_input2(cpl_frame* frm1,
01263                        cpl_frame* frm2,
01264                double* dispersion,
01265                double* centralWave,
01266                double* wstart,
01267                double* wend,
01268                double* pscale1,
01269                double* pscale2,
01270                double* exptime1,
01271                double* exptime2,
01272                double* strehl_star_rad1,
01273                double* strehl_star_rad2,
01274                double* strehl_bg_rmin1,
01275                double* strehl_bg_rmin2,
01276                double* strehl_bg_rmax1,
01277                double* strehl_bg_rmax2)
01278 
01279 {
01280 
01281   cpl_propertylist* plist=NULL;
01282   char res1[MAX_NAME_SIZE];
01283   char res2[MAX_NAME_SIZE];
01284   double pix_scale1=0;
01285   double pix_scale2=0;
01286   double wrange=0;
01287   char fname1[MAX_NAME_SIZE];
01288   char fname2[MAX_NAME_SIZE];
01289   int naxis3=0;
01290 
01291   sinfo_get_spatial_res(frm1,res1);
01292   sinfo_get_spatial_res(frm2,res2);
01293   pix_scale1=atof(res1);
01294   pix_scale2=atof(res2);
01295   /* factor 2 due to change of detector to 2K
01296   *pscale1=0.5*pix_scale1;
01297   *pscale2=0.5*pix_scale2;
01298   */
01299 
01300   *pscale1=pix_scale1;
01301   *pscale2=pix_scale2;
01302 
01303 
01304   *strehl_star_rad1=SINFO_RSTAR*(*pscale1);
01305   *strehl_bg_rmin1=SINFO_BKG_R1*(*pscale1);
01306   *strehl_bg_rmax1=SINFO_BKG_R2*(*pscale1);
01307 
01308   *strehl_star_rad2=SINFO_RSTAR*(*pscale2);
01309   *strehl_bg_rmin2=SINFO_BKG_R1*(*pscale2);
01310   *strehl_bg_rmax2=SINFO_BKG_R2*(*pscale2);
01311 
01312   strcpy(fname1,cpl_frame_get_filename(frm1));
01313   check_nomsg(plist=cpl_propertylist_load(fname1,0));
01314   check_nomsg(*dispersion=sinfo_pfits_get_cdelt3(plist));
01315   *centralWave=sinfo_pfits_get_crval3(plist);
01316   check_nomsg(naxis3=sinfo_pfits_get_naxis3(plist));
01317   *exptime1=sinfo_pfits_get_exp_time(plist);
01318   sinfo_free_propertylist(&plist);
01319   strcpy(fname2,cpl_frame_get_filename(frm2));
01320 
01321 
01322   check_nomsg(plist=cpl_propertylist_load(fname2,0));
01323   *exptime2=sinfo_pfits_get_exp_time(plist);
01324   sinfo_free_propertylist(&plist);
01325 
01326 
01327 
01328   wrange=(*dispersion)*naxis3;
01329 
01330   *wstart = *centralWave - (wrange / 2) +(*dispersion);
01331   *wend   = *wstart + wrange;
01332 
01333 
01334  cleanup:
01335   if (cpl_error_get_code() != CPL_ERROR_NONE) {
01336     return -1;
01337   } else {
01338     return 0;
01339   }
01340 
01341 }
01342 
01343 
01344 
01345 static cpl_table*
01346 sinfo_get_strehl_from_2images(cpl_image* ima1,
01347                   cpl_image* ima2,
01348                   cpl_frame* frm1,
01349                   cpl_frame* frm2)
01350 {
01351 
01352   cpl_table* strehl_tbl=NULL;
01353 
01354 
01355   double dispersion=0.;
01356   double centralWave=0.;
01357   double wstart=0;
01358   double wstep=0;
01359   double wend=0;
01360   double lam=0;
01361   double dlam=0;
01362   double pscale1 = 0;
01363   double pscale2 = 0;
01364 
01365   double strehl_star_rad1=0;
01366   double strehl_star_rad2=0;
01367   double strehl_bg_rmin1=0;
01368   double strehl_bg_rmin2=0;
01369   double strehl_bg_rmax1=0;
01370   double strehl_bg_rmax2=0;
01371   double strehl=0;
01372   double strehl_err=0;
01373 
01374   int nsample=1;
01375   double exptime1=0;
01376   double exptime2=0;
01377   cpl_image* img_dup=NULL;
01378 
01379   cpl_size max_ima1_x=0;
01380   cpl_size max_ima1_y=0;
01381 
01382   cpl_size max_ima2_x=0;
01383 
01384 
01385   cpl_size max_ima2_y=0;
01386   double star_bkg=0;
01387   double star_peak=0;
01388   double star_flux=0;
01389 
01390   double psf_peak=0;
01391   double psf_flux=0;
01392   double bkg_noise=0;
01393 
01394   cpl_errorstate clean_state = cpl_errorstate_get();
01395 
01396   ck0_nomsg(sinfo_get_strehl_input2(frm1,frm2,&dispersion, &centralWave,
01397                                    &wstart,&wend,&pscale1,&pscale2,
01398                                    &exptime1,&exptime2,
01399                                    &strehl_star_rad1,&strehl_star_rad2,
01400                                    &strehl_bg_rmin1,&strehl_bg_rmin2,
01401                                    &strehl_bg_rmax1,&strehl_bg_rmax2));
01402 
01403 
01404 
01405 
01406 
01407   check_nomsg(img_dup=cpl_image_duplicate(ima1));
01408   sinfo_clean_nan(&img_dup);
01409   check_nomsg(cpl_image_get_maxpos(img_dup,&max_ima1_x,&max_ima1_y));
01410   sinfo_free_image(&img_dup);
01411 
01412 
01413   check_nomsg(img_dup=cpl_image_duplicate(ima2));
01414   sinfo_clean_nan(&img_dup);
01415   check_nomsg(cpl_image_get_maxpos(img_dup,&max_ima2_x,&max_ima2_y));
01416   sinfo_free_image(&img_dup);
01417 
01418   /*
01419      note:
01420      -wstep as we do not hit the borders where the
01421      sinfo_gaussian fit has a problem
01422   */
01423 
01424 
01425 
01426   check_nomsg(strehl_tbl = cpl_table_new(nsample));
01427   check_nomsg(cpl_table_new_column(strehl_tbl,"wavelength",CPL_TYPE_DOUBLE));
01428   check_nomsg(cpl_table_new_column(strehl_tbl,"strehl",CPL_TYPE_DOUBLE));
01429   check_nomsg(cpl_table_new_column(strehl_tbl,"strehl_error",CPL_TYPE_DOUBLE));
01430   wstep  = wend-wstart;
01431 
01432 
01433 
01434   lam = (double)0.5*(wstart+wend);
01435   dlam=wstep;
01436   sinfo_msg("lambda=%f dlambda=%f",lam,dlam);
01437   sinfo_msg("wstart=%f wend=%f",wstart,wend);
01438   sinfo_msg("wstep=%f",wstep);
01439 
01440 
01441   if(CPL_ERROR_NONE != sinfo_strehl_compute_two(ima1,ima2,
01442                         SINFO_STREHL_M1,SINFO_STREHL_M2,
01443                         lam,
01444                         pscale1,pscale2,
01445                         exptime1,exptime2,
01446                         max_ima1_x,max_ima1_y,
01447                         max_ima2_x,max_ima2_y,
01448                         strehl_star_rad1,
01449                                             strehl_bg_rmin1,
01450                         strehl_bg_rmax1,
01451                         &strehl,&strehl_err,&star_bkg,
01452                         &star_peak,&star_flux,
01453                         &psf_peak,&psf_flux,&bkg_noise))
01454     {
01455 
01456       strehl=-1;
01457       strehl_err=0;
01458       irplib_error_recover(clean_state,
01459                "Problem computing strehl, set it to -1");
01460 
01461     }
01462 
01463 
01464   if((isnan(lam) ==0) &&
01465      (isnan(lam) ==0) &&
01466      (isnan(lam) ==0)) {
01467     check_nomsg(cpl_table_set_double(strehl_tbl,"wavelength",0,lam));
01468     check_nomsg(cpl_table_set_double(strehl_tbl,"strehl",0,strehl));
01469     check_nomsg(cpl_table_set_double(strehl_tbl,"strehl_error",
01470                      0,strehl_err));
01471 
01472   }
01473 
01474 
01475 
01476   return strehl_tbl;
01477  cleanup:
01478 
01479 
01480   return NULL;
01481 }
01482 
01483 
01484 
01485 /*---------------------------------------------------------------------------*/
01520 /*---------------------------------------------------------------------------*/
01521 #define irplib_assure_code cpl_ensure_code
01522 int sinfo_strehl_compute_two(
01523         const cpl_image *   im1,
01524         const cpl_image *   im2,
01525         double              m1,
01526         double              m2,
01527         double              lam,
01528         double              pscale1,
01529         double              pscale2,
01530         double              exptime1,
01531         double              exptime2,
01532         int                 xpos1,
01533         int                 ypos1,
01534         int                 xpos2,
01535         int                 ypos2,
01536         double              r1,
01537         double              r2,
01538         double              r3,
01539         double          *   strehl,
01540         double          *   strehl_err,
01541         double          *   star_bkg,
01542         double          *   star_peak,
01543         double          *   star_flux,
01544         double          *   psf_peak,
01545         double          *   psf_flux,
01546         double          *   bg_noise)
01547 {
01548     double psf_peak1=0;
01549     double psf_peak2=0;
01550     double psf_flux1=0;
01551     double psf_flux2=0;
01552     double star_bkg1=0;
01553     double star_bkg2=0;
01554     double star_flux1=0;
01555     double star_flux2=0;
01556     double star_peak1=0;
01557     double star_peak2=0;
01558 
01559     const double   window_size = 5.0 ;
01560     double         star_radius, max_radius ;
01561     double       ring[4];
01562 
01563     double prat=pscale2/pscale1;
01564     double prat2=prat*prat;
01565     double trat=exptime1/exptime2;
01566     double frat=sinfo_scale_flux(pscale1,pscale2,exptime1,exptime2);
01567     double xc=0;
01568     double yc=0;
01569 
01570     int sx=0;
01571     int sy=0;
01572     int d=16;
01573     cpl_errorstate initial_errorstate = cpl_errorstate_get();
01574 
01575 
01576     /* Test inputs */
01577     irplib_assure_code(im1 != NULL,         CPL_ERROR_NULL_INPUT);
01578     irplib_assure_code(im2 != NULL,         CPL_ERROR_NULL_INPUT);
01579     irplib_assure_code(strehl != NULL,     CPL_ERROR_NULL_INPUT);
01580     irplib_assure_code(strehl_err != NULL, CPL_ERROR_NULL_INPUT);
01581     irplib_assure_code(star_bkg != NULL,    CPL_ERROR_NULL_INPUT);
01582     irplib_assure_code(star_peak != NULL,  CPL_ERROR_NULL_INPUT);
01583     irplib_assure_code(star_flux != NULL,  CPL_ERROR_NULL_INPUT);
01584     irplib_assure_code(psf_peak != NULL,   CPL_ERROR_NULL_INPUT);
01585     irplib_assure_code(psf_flux != NULL,   CPL_ERROR_NULL_INPUT);
01586 
01587     irplib_assure_code(pscale1 > 0.0,      CPL_ERROR_ILLEGAL_INPUT);
01588     irplib_assure_code(pscale2 > 0.0,      CPL_ERROR_ILLEGAL_INPUT);
01589 
01590     irplib_assure_code(xpos1-window_size > 0, CPL_ERROR_ACCESS_OUT_OF_RANGE);
01591     irplib_assure_code(ypos1-window_size > 0, CPL_ERROR_ACCESS_OUT_OF_RANGE);
01592     irplib_assure_code(xpos2-window_size > 0, CPL_ERROR_ACCESS_OUT_OF_RANGE);
01593     irplib_assure_code(ypos2-window_size > 0, CPL_ERROR_ACCESS_OUT_OF_RANGE);
01594 
01595     irplib_assure_code(xpos1+window_size <= cpl_image_get_size_x(im1),
01596                        CPL_ERROR_ACCESS_OUT_OF_RANGE);
01597     irplib_assure_code(ypos1+window_size <= cpl_image_get_size_y(im1),
01598                        CPL_ERROR_ACCESS_OUT_OF_RANGE);
01599 
01600     irplib_assure_code(xpos2+window_size <= cpl_image_get_size_x(im2),
01601                        CPL_ERROR_ACCESS_OUT_OF_RANGE);
01602     irplib_assure_code(ypos2+window_size <= cpl_image_get_size_y(im2),
01603                        CPL_ERROR_ACCESS_OUT_OF_RANGE);
01604 
01605     irplib_assure_code(r1 > 0.0,      CPL_ERROR_ILLEGAL_INPUT);
01606     irplib_assure_code(r2 > 0.0,      CPL_ERROR_ILLEGAL_INPUT);
01607     irplib_assure_code(r3 > r2,       CPL_ERROR_ILLEGAL_INPUT);
01608 
01609     /* Computing a Strehl ratio is a story between an ideal PSF */
01610     /* and a candidate image supposed to approximate this ideal PSF. */
01611 
01612     /* Generate first appropriate PSF to find max peak: same pscale as
01613        the one of the image where we compute the flux */
01614 
01615 
01616     sx=cpl_image_get_size_x(im1);
01617     sy=cpl_image_get_size_y(im1);
01618 
01619 
01620     psf_flux1 = 1.0; // The psf flux, cpl_image_get_flux(psf), is always 1
01621     psf_flux2 = 1.0; // The psf flux, cpl_image_get_flux(psf), is always 1
01622     *psf_flux=1.0;
01623     ring[0] = xpos2;
01624     ring[1] = ypos2;
01625     ring[2] = r2/pscale2;
01626     ring[3] = r3/pscale2;
01627 
01628     sinfo_msg_debug("star_pos=%d %d %d %d",xpos1,ypos1,xpos2,ypos2);
01629     sinfo_msg_debug("star_ring=%f %f %f %f",ring[0],ring[1],ring[2],ring[3]);
01630 
01631     /* Compute star_radius in pixels */
01632     star_radius = r1/pscale2;
01633 
01634      /* Find the peak value on the central part of the candidate image */
01635 
01636 
01637     /* Find the peak value on the central part of the candidate image */
01638     max_radius = window_size < star_radius ? window_size : star_radius;
01639 
01640     check_nomsg(sinfo_get_star_features(im1,d,xpos1,ypos1,&xc,&yc,
01641                                         &star_peak1,&star_flux1,&star_bkg1));
01642 
01643 
01644     *star_peak=star_peak1;
01645 
01646     check_nomsg(sinfo_compute_psf(m1,m2/m1,lam*1.e-6,pscale1,xc,yc,1.,
01647                   &psf_peak1));
01648 
01649     check_nomsg(sinfo_get_star_features(im2,d,xpos2,ypos2,&xc,&yc,
01650                                         &star_peak2,&star_flux2,&star_bkg2));
01651 
01652     *star_flux=star_flux2;
01653     *star_bkg=star_bkg2;
01654 
01655     check_nomsg(sinfo_compute_psf(m1,m2/m1,lam*1.e-6,pscale2,xc,yc,1.,
01656                   &psf_peak2));
01657 
01658 
01659 
01660 
01661     sinfo_msg_debug("p1=%g p2=%g",*star_peak,star_peak2);
01662     sinfo_msg_debug("corr peak: p1=%g p2=%g",*star_peak,star_peak2/frat);
01663     sinfo_msg_debug("corr bkg: bkg1=%g bkg2=%g",star_bkg1/frat,*star_bkg);
01664     sinfo_msg_debug("rel diff: %g",
01665               fabs(star_peak2/frat- *star_peak)/(star_peak2/frat));
01666 
01667 
01668 
01669     sinfo_msg_debug("Rescaled star_flux1=%g star_flux2=%g",
01670                  star_flux1*trat,*star_flux);
01671 
01672     //Check that flux value as measured on im1 and on 1m2 are close one
01673     //to another. Note that flux1, measured on im1, need to be rescaled
01674     //by exposure time to match to flux2=star_flux
01675     if ( fabs((star_flux1*frat-*star_flux)/(*star_flux)) > 0.25) {
01676       sinfo_msg_debug("Star flux rel diff: %g",
01677                         fabs((star_flux1*frat-*star_flux)/(*star_flux)));
01678     }
01679 
01680     //Check that pick value as measured on im1 and on 1m2 are close one
01681     //to another. Note that peak2, measured on im2, need to be rescaled
01682     //by exposure time and pixel scale to match to peak1=star_peak
01683     if ( fabs(star_peak2-star_peak1*frat)/(star_peak2) > 0.25) {
01684       sinfo_msg_debug("Star pick rel diff: %g",
01685                         fabs(star_peak2-star_peak1*frat)/(star_peak2));
01686     }
01687     sinfo_msg_debug("ak1 star peak=%g",*star_peak);
01688     irplib_assure_code(*star_peak > 0.0,      CPL_ERROR_ILLEGAL_OUTPUT);
01689     *star_peak=star_peak1;
01690 
01691     *star_bkg=star_bkg2;
01692     *star_flux=star_flux2;
01693 
01694     sinfo_msg_debug("ak2");
01695 
01696     //psf1 = irplib_strehl_generate_psf(m1, m2, lam, dlam, pscale1, size*4);
01697     //psf_peak1 = cpl_image_get_max(psf1) ;
01698 
01699 
01700 
01701     /* Compute Strehl */
01702     //*strehl = (*star_peak *prat2/trat/ *star_flux) / (*psf_peak / *psf_flux);
01703     *strehl = (*star_peak/(*star_flux*trat)) / (psf_peak1 );
01704     //*strehl = (*star_peak/(*star_flux)) / (psf_peak1 / *psf_flux) ;
01705     sinfo_msg_debug("peak=%g flux1=%f flux2=%f flux=%f cflux=%g "
01706                     "fct=%g psf_peak=%g",
01707           *star_peak,star_flux1,star_flux2,*star_flux,
01708               *star_flux/frat*prat2,prat2/frat,psf_peak1);
01709     sinfo_msg_debug("=======strehl=%g",*strehl);
01710     /*
01711     if (*strehl > 1)
01712         cpl_msg_warning(cpl_func, "Extreme Strehl-ratio=%g, star_peak=%g, "
01713                         "star_flux=%g, psf_peak=%g, psf_flux=%g", *strehl,
01714                         *star_peak, *star_flux, *psf_peak, *psf_flux);
01715 
01716 
01717     // Compute Strehl error
01718     if (cpl_flux_get_noise_ring(im2, ring, noise_box_sz, noise_nsamples,
01719                                 bg_noise, NULL) == CPL_ERROR_NONE) {
01720         *strehl_err = SINFO_STREHL_ERROR_COEFFICIENT * (*bg_noise) * pscale2 *
01721             star_radius * star_radius / *star_flux;
01722         irplib_assure_code(*strehl_err >= 0.0,       CPL_ERROR_ILLEGAL_OUTPUT);
01723     } else {
01724       sinfo_msg_warning("Problem computing noise");
01725     }
01726     */
01727     *bg_noise=0;
01728 
01729     cleanup:
01730 
01731 
01732     if (!cpl_errorstate_is_equal(initial_errorstate)) {
01733         /* Dump the error history since recipe execution start.
01734            At this point the recipe cannot recover from the error */
01735         cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
01736     }
01737 
01738   if (cpl_error_get_code() != CPL_ERROR_NONE) {
01739     return cpl_error_get_code();
01740   } else {
01741     return CPL_ERROR_NONE;
01742   }
01743 
01744 }
01745 
01746 
01747 
01748 
01749 static cpl_error_code
01750 sinfo_get_star_features(const cpl_image* im,
01751                         const int radius,
01752             const int xpos,
01753             const int ypos,
01754                         double* xc,
01755                         double* yc,
01756                         double* peak,
01757                         double* flux,
01758                         double* bkg)
01759 {
01760   int sx=0;
01761   int sy=0;
01762   int ixm=0;
01763   int iym=0;
01764   int llx=0;
01765   int lly=0;
01766   int urx=0;
01767   int ury=0;
01768   int dim_new=0;
01769   double kappa=2;
01770   double xm=0;
01771   double ym=0;
01772   double bkg_stdev=0;
01773   int bkg_sx=SINFO_BKG_BOX_SZ;
01774   int bkg_sy=SINFO_BKG_BOX_SZ;
01775 
01776   cpl_bivector* iqe=NULL;
01777   double* piqe=NULL;
01778   cpl_image* im_new=NULL;
01779 
01780   sx=cpl_image_get_size_x(im);
01781   sy=cpl_image_get_size_y(im);
01782 
01783   sinfo_msg_debug("star_radius=%d",radius);
01784   //We find the image centroid
01785   if(NULL != (iqe=cpl_image_iqe(im,sx/2-radius,sy/2-radius,
01786                 sx/2+radius,sy/2+radius))) {
01787 
01788 
01789     piqe=cpl_bivector_get_x_data(iqe);
01790     //*star_peak=piqe[5];
01791     xm=piqe[0];
01792     ym=piqe[1];
01793     //Extract a square sub-image of minimal size not to hit the image borders
01794     //centered on the previous image centroid
01795     sinfo_msg_debug("Max ima: %g %g",xm,ym);
01796     sinfo_msg_debug("Find min of: %g %g %g %g",xm,sx-xm,ym,sy-ym);
01797     ixm=floor(xm);
01798     iym=floor(ym);
01799     sinfo_msg_debug("ixm=%d iym=%d",ixm,iym);
01800     dim_new=floor(sinfo_find_min_of_four(xm,sx-xm,ym,sy-ym));
01801     sinfo_msg_debug("dim_new=%d",dim_new);
01802     llx=(ixm-dim_new > 1) ? ixm-dim_new : 1;
01803     lly=(iym-dim_new > 1) ? iym-dim_new : 1;
01804     urx=(ixm+dim_new < sx) ? ixm+dim_new : sx;
01805     ury=(iym+dim_new < sy) ? iym+dim_new : sy;
01806     sinfo_msg_debug("llx=%d lly=%d urx=%d ury=%d",llx,lly,urx,ury);
01807     check_nomsg(im_new=cpl_image_extract(im,llx,lly,urx,ury));
01808 
01809     //compute the background of this last image
01810     check_nomsg(sinfo_get_bkg_4corners(im_new,bkg_sx,bkg_sy,bkg,&bkg_stdev));
01811 
01812 
01813 
01814     sinfo_free_bivector(&iqe);
01815 
01816     //Determine the image pick on the new coordinate system
01817     iqe=cpl_image_iqe(im_new,dim_new-radius,dim_new-radius,
01818               dim_new+radius,dim_new+radius);
01819     sinfo_msg_debug("xc=%g yc=%g",piqe[0],piqe[1]);
01820     *xc=piqe[0]-dim_new-1;
01821     *yc=piqe[1]-dim_new-1;
01822 
01823 
01824     sinfo_msg_debug("xc=%g yc=%g",*xc,*yc);
01825     //*peak=piqe[5];
01826     *peak=cpl_image_get_max_window(im_new,dim_new-radius,dim_new-radius,
01827                    dim_new+radius,dim_new+radius);
01828 
01829     sinfo_get_flux_above_bkg(im_new,kappa,bkg_stdev,flux);
01830     *peak -= (*bkg);
01831     sinfo_msg_debug("star peak=%g bkg=%g",*peak,*bkg);
01832 
01833 
01834     sinfo_free_bivector(&iqe);
01835 
01836 
01837   } else {
01838     sinfo_msg_warning("IQE fit failed");
01839     cpl_error_reset();
01840     sinfo_msg_debug("xc=%d yc=%d radius=%d",xpos,ypos,radius);
01841     *xc=xpos-sx/2;
01842     *yc=ypos-sy/2;
01843     sinfo_msg_debug("xc=%g yc=%g",*xc,*yc);
01844     check_nomsg(sinfo_get_bkg_4corners(im,bkg_sx,bkg_sy,bkg,&bkg_stdev));
01845     check_nomsg(sinfo_get_safe_box(&llx, &lly, &urx, &ury, xpos,ypos,radius,
01846                    64,64));
01847     check_nomsg(*peak=cpl_image_get_max_window(im,llx,lly,urx,ury)-(*bkg));
01848     sinfo_get_flux_above_bkg(im,kappa,bkg_stdev,flux);
01849     sinfo_msg_debug("star peak=%g bkg=%g",*peak,*bkg);
01850 
01851 
01852   }
01853 
01854 
01855 
01856  cleanup:
01857   sinfo_free_image(&im_new);
01858   sinfo_free_bivector(&iqe);
01859 
01860 
01861 
01862 
01863   if (cpl_error_get_code() != CPL_ERROR_NONE) {
01864     return cpl_error_get_code();
01865   } else {
01866     return CPL_ERROR_NONE;
01867   }
01868 
01869 }
01870 
01871 
01872 
01873 
01874 
01875 
01876 /*----------------------------------------------------------------------------*/
01903 /*----------------------------------------------------------------------------*/
01904 cpl_error_code
01905 sinfo_strehl_compute_one(const cpl_image *   im,
01906                                      double              m1,
01907                                      double              m2,
01908                                      double              lam,
01909                                      double              dlam,
01910                                      double              pscale,
01911                                      int                 xpos,
01912                                      int                 ypos,
01913                                      double              r1,
01914                                      double              r2,
01915                                      double              r3,
01916                                      int                 size,
01917                                      double          *   strehl,
01918                                      double          *   strehl_err,
01919                                      double          *   star_bkg,
01920                                      double          *   star_peak,
01921                                      double          *   star_flux,
01922                                      double          *   psf_peak,
01923                                      double          *   psf_flux,
01924                                      double          *   bg_noise)
01925 {
01926     cpl_image  * psf;
01927     double       star_radius;
01928 
01929     /* FIXME: Arbitrary choice of image border */
01930     const double window_size = (double)(SINFO_STREHL_RAD_CENTRAL);
01931 
01932     /* Determined empirically by C. Lidman for Strehl error computation */
01933     //Commented as not used
01934     //const double strehl_error_coefficient = SINFO_MATH_PI * 0.007 / 0.0271;
01935 
01936 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 0, 0)
01937     double       ring[4];
01938 #else
01939     /* FIXME: Remove this branch once CPL 3.X is no longer supported */
01940     int          ring[4];
01941 #endif
01942     cpl_bivector* iqe1=NULL;
01943     double xc=0;
01944     double yc=0;
01945     int d=16;
01946 
01947 
01948 
01949     /* Check compile-time constant */
01950     cpl_ensure_code(window_size > 0.0,  CPL_ERROR_ILLEGAL_INPUT);
01951 
01952     /* Test inputs */
01953     cpl_ensure_code(im != NULL,         CPL_ERROR_NULL_INPUT);
01954     cpl_ensure_code(strehl != NULL,     CPL_ERROR_NULL_INPUT);
01955     cpl_ensure_code(strehl_err != NULL, CPL_ERROR_NULL_INPUT);
01956     cpl_ensure_code(star_bkg != NULL,    CPL_ERROR_NULL_INPUT);
01957     cpl_ensure_code(star_peak != NULL,  CPL_ERROR_NULL_INPUT);
01958     cpl_ensure_code(star_flux != NULL,  CPL_ERROR_NULL_INPUT);
01959     cpl_ensure_code(psf_peak != NULL,   CPL_ERROR_NULL_INPUT);
01960     cpl_ensure_code(psf_flux != NULL,   CPL_ERROR_NULL_INPUT);
01961 
01962     cpl_ensure_code(pscale > 0.0,      CPL_ERROR_ILLEGAL_INPUT);
01963 
01964 
01965     cpl_ensure_code(r1 > 0.0,      CPL_ERROR_ILLEGAL_INPUT);
01966     cpl_ensure_code(r2 > 0.0,      CPL_ERROR_ILLEGAL_INPUT);
01967 
01968     cpl_ensure_code(r3 > r2,       CPL_ERROR_ILLEGAL_INPUT);
01969 
01970 
01971     /* Computing a Strehl ratio is a story between an ideal PSF */
01972     check_nomsg(sinfo_compute_psf(m1,m2/m1,lam*1.e-6,pscale,xc,yc,
01973                   1.,psf_peak));
01974   /* and a candidate image supposed to approximate this ideal PSF. */
01975 
01976     /* Generate first appropriate PSF to find max peak */
01977 
01978     psf = irplib_strehl_generate_psf(m1, m2, lam, dlam, pscale, size);
01979     cpl_ensure_code(psf != NULL,      CPL_ERROR_ILLEGAL_OUTPUT);
01980 
01981     /* Compute flux in PSF and find max peak */
01982     *psf_peak = cpl_image_get_max(psf);
01983 
01984     cpl_image_delete(psf);
01985 
01986 
01987 
01988 
01989     cpl_ensure( *psf_peak > 0.0, CPL_ERROR_ILLEGAL_OUTPUT,CPL_ERROR_ILLEGAL_OUTPUT); /* The ideal PSF has a positive maximum */
01990     *psf_flux = 1.0; /* The psf flux, cpl_image_get_flux(psf), is always 1 */
01991 
01992 
01993     /* Compute star_radius in pixels */
01994     star_radius = r1/pscale;
01995 
01996 
01997     check_nomsg(sinfo_get_star_features(im,d,xpos,ypos,&xc,&yc,
01998                     star_peak,star_flux,star_bkg));
01999 
02000 
02001     check_nomsg(sinfo_compute_psf(m1,m2/m1,lam*1.e-6,pscale,xc,yc,1.,psf_peak));
02002 
02003 
02004 
02005     *star_peak -= *star_bkg;
02006 
02007 
02008     cpl_ensure_code(*star_peak > 0.0,      CPL_ERROR_ILLEGAL_OUTPUT);
02009 
02010 
02011     /* Compute Strehl */
02012     /* (StarPeak / StarFlux) / (PsfPeak / PsfFlux) */
02013     sinfo_msg_debug("Star flux=%g", *star_flux);
02014     sinfo_msg_debug("Star peak=%g", *star_peak);
02015     sinfo_msg_debug("PSF  flux=%g", *psf_flux);
02016     sinfo_msg_debug("PSF  peak=%g", *psf_peak);
02017 
02018     *strehl = (*star_peak * *psf_flux ) / ( *star_flux * *psf_peak);
02019 
02020 
02021 
02022      if (*strehl > 1)
02023         cpl_msg_warning(cpl_func, "Extreme Strehl-ratio=%g, star_peak=%g, "
02024                         "star_flux=%g, psf_peak=%g, psf_flux=%g", *strehl,
02025                         *star_peak, *star_flux, *psf_peak, *psf_flux);
02026 
02027     /* Compute Strehl error */
02028     ring[0] = xpos;
02029     ring[1] = ypos;
02030     ring[2] = r2/pscale;
02031     ring[3] = r3/pscale;
02032     /*
02033     *strehl_err = strehl_error_coefficient * (*bg_noise) * pscale *
02034         star_radius * star_radius / *star_flux;
02035 
02036     // This check should not be able to fail, but just to be sure
02037     cpl_ensure_code(*strehl_err >= 0.0,       CPL_ERROR_ILLEGAL_OUTPUT);
02038     */
02039     *bg_noise=0;
02040 
02041 
02042  cleanup:
02043     sinfo_free_bivector(&iqe1);
02044     if (cpl_error_get_code() != CPL_ERROR_NONE) {
02045       return cpl_error_get_code();
02046     } else {
02047       return CPL_ERROR_NONE;
02048     }
02049 
02050 
02051 }
02052 
02053 
02054 
02055 static void
02056 sinfo_check_borders(cpl_size* val,const int max,const int thresh)
02057 {
02058 
02059   *val = ((*val-thresh) > 0) ? *val : thresh;
02060   *val = ((*val+thresh) < max) ? *val : max-thresh-1;
02061   return;
02062 }
02063 
02064 static void
02065 sinfo_get_safe_box(int* llx,
02066                    int* lly,
02067                    int* urx,
02068                    int* ury,
02069                    const int xpos,
02070                    const int ypos,
02071                    const int box,
02072                    const int szx,
02073                    const int szy)
02074 
02075 {
02076   *llx= ((xpos-box)>0)   ? (xpos-box) : 1;
02077   *lly= ((ypos-box)>0)   ? (ypos-box) : 1;
02078   *urx= ((xpos+box)<szx) ? (xpos+box) : szx-1 ;
02079   *ury= ((ypos+box)<szy) ? (ypos+box) : szy-1 ;
02080 
02081   return;
02082 }
02083 
02084 
02085 
02086 
02087 
02088 /*---------------------------------------------------------------------------*/
02098 /*---------------------------------------------------------------------------*/
02099 cpl_error_code
02100 sinfo_get_bkg_4corners(const cpl_image *img,
02101                const int bkg_sx,
02102                        const int bkg_sy,
02103                        double* bkg,
02104                        double* std)
02105 {
02106 
02107   int sx=0;
02108   int sy=0;
02109   cpl_image* img_bkg=NULL;
02110   *bkg=0;
02111 
02112   cknull(img,"NULL input image!");
02113   check_nomsg(sx=cpl_image_get_size_x(img));
02114   check_nomsg(sy=cpl_image_get_size_y(img));
02115 
02116   check_nomsg(img_bkg=cpl_image_new(2*bkg_sx,2*bkg_sy,CPL_TYPE_FLOAT));
02117   check_nomsg(cpl_image_copy(img_bkg,cpl_image_extract(img,1,1,bkg_sx,bkg_sy),
02118                  1,1));
02119 
02120   check_nomsg(cpl_image_copy(img_bkg,cpl_image_extract(img,sx-bkg_sx,1,
02121                                sx,bkg_sy),bkg_sx+1,1));
02122   check_nomsg(cpl_image_copy(img_bkg,cpl_image_extract(img,1,sy-bkg_sy,
02123                                bkg_sx,sy),1,bkg_sy+1));
02124 
02125   check_nomsg(cpl_image_copy(img_bkg,
02126                  cpl_image_extract(img,sx-bkg_sx,sy-bkg_sy,sx,sy),
02127                  bkg_sx+1,bkg_sy+1));
02128 
02129   check_nomsg(*bkg=cpl_image_get_median(img_bkg));
02130   check_nomsg(*std=cpl_image_get_stdev(img_bkg));
02131   sinfo_msg_debug("sky bkg: %f",*bkg);
02132   sinfo_msg_debug("sky stdev: %f",*std);
02133 
02134 
02135 cleanup:
02136   sinfo_free_image(&img_bkg);
02137 
02138   if (cpl_error_get_code() != CPL_ERROR_NONE) {
02139     return cpl_error_get_code();
02140   } else {
02141     return CPL_ERROR_NONE;
02142   }
02143 
02144 
02145 }
02146 
02159 /*---------------------------------------------------------------------------*/
02160 cpl_error_code
02161 sinfo_compute_psf(const double dia,
02162           const double occ,
02163           const double lambda,
02164           const double psize,
02165           const double cx,
02166           const double cy,
02167           const double anamorph,
02168           double* psf_peak)
02169 {
02170 
02171   int bin=SINFO_PSF_BIN;
02172   int npoints=SINFO_PSF_NPOINT;
02173 
02174   int dim=SINFO_PSF_DIM;
02175   int blocks=SINFO_PSF_BLOCKS;
02176   int sx=dim;
02177   int sy=dim;
02178 
02179 
02180   int i=0;
02181   int j=0;
02182   double k=0;
02183 
02184   int ii=0;
02185   int jj=0;
02186   int start=0;
02187 
02188   double nyquist=lambda/dia/2.*206265/psize*bin;
02189   double cor=0.;
02190   double v0=0;
02191   double ll[npoints];
02192   double part[npoints];
02193   double ee;
02194   double dll=0;
02195   double tot1=0;
02196   double tot2=0;
02197 
02198 
02199   double fct=0;
02200 
02201   double* pxx=NULL;
02202   double* pyy=NULL;
02203   double* prr=NULL;
02204   double* ppsf0=NULL;
02205 
02206   double* pcor=NULL;
02207   double* pairy=NULL;
02208   double* pw=NULL;
02209 
02210   cpl_image* img_xx=NULL;
02211   cpl_image* img_yy=NULL;
02212   cpl_image* img_rr=NULL;
02213   cpl_image* img_rrcor=NULL;
02214   cpl_image* img_airy=NULL;
02215   cpl_image* img_w=NULL;
02216   cpl_image* img_psf0=NULL;
02217 
02218 
02219 
02220   sinfo_msg_debug("lambda=%g",lambda);
02221   sinfo_msg_debug("dia=%f",dia);
02222   sinfo_msg_debug("psize=%f",psize);
02223   sinfo_msg_debug("bin=%d",bin);
02224   sinfo_msg_debug("nyquist=%f",nyquist);
02225 
02226   check_nomsg(img_xx=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE));
02227   img_yy=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
02228   img_rr=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
02229   img_rrcor=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
02230 
02231   pxx=cpl_image_get_data_double(img_xx);
02232   pyy=cpl_image_get_data_double(img_yy);
02233   prr=cpl_image_get_data_double(img_rr);
02234 
02235   for(j=0;j<sy;j++) {
02236     for(i=0;i<sx;i++) {
02237       //xz plane increasing along y
02238       pxx[j*sx+i]=(i-sx/2-cx*bin)/nyquist*SINFO_MATH_PI/2;
02239       //yz plane increasing along x
02240       pyy[j*sx+i]=(j-sy/2-cy*bin)/nyquist*SINFO_MATH_PI/2*anamorph;
02241 
02242       //combinex xyz surface
02243       prr[j*sx+i]=sqrt(pxx[j*sx+i]*pxx[j*sx+i]+pyy[j*sx+i]*pyy[j*sx+i]);
02244     }
02245   }
02246 
02247   /*
02248   check_nomsg(cpl_image_save(img_xx,"out_xx.fits", CPL_BPP_IEEE_DOUBLE,
02249                  NULL,CPL_IO_DEFAULT));
02250 
02251   check_nomsg(cpl_image_save(img_yy,"out_yy.fits", CPL_BPP_IEEE_DOUBLE,
02252                  NULL,CPL_IO_DEFAULT));
02253 
02254   check_nomsg(cpl_image_save(img_rr,"out_rr.fits", CPL_BPP_IEEE_DOUBLE,
02255                  NULL,CPL_IO_DEFAULT));
02256 
02257   */
02258 
02259   img_rrcor=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
02260 
02261   cor=1./(1.-occ*occ);
02262   cor*=cor;
02263 
02264   img_rrcor=cpl_image_duplicate(img_rr);
02265   cpl_image_multiply_scalar(img_rrcor,cor);
02266   pcor=cpl_image_get_data_double(img_rrcor);
02267 
02268   /*
02269   check_nomsg(cpl_image_save(img_rrcor,"out_rrcor.fits", CPL_BPP_IEEE_DOUBLE,
02270                  NULL,CPL_IO_DEFAULT));
02271   */
02272 
02273   img_airy=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
02274   pairy=cpl_image_get_data_double(img_airy);
02275 
02276 
02277   if (occ == 0.0) {
02278 
02279     for(j=0;j<sx;j++) {
02280       for(i=0;i<sy;i++) {
02281     fct=(2.*j1(prr[j*sx+i])/prr[j*sx+i]);
02282     pairy[j*sx+i]=fct*fct;
02283 
02284       }
02285     }
02286 
02287   } else {
02288     for(j=0;j<sy;j++) {
02289       for(i=0;i<sx;i++) {
02290 
02291     fct=(2.*j1(prr[j*sx+i])/prr[j*sx+i]-occ*occ*2.*j1(pcor[j*sx+i])/pcor[j*sx+i]);
02292     pairy[j*sx+i]=cor*fct*fct;
02293 
02294       }
02295     }
02296   }
02297 
02298   /*
02299   check_nomsg(cpl_image_save(img_airy,"out_airy.fits", CPL_BPP_IEEE_DOUBLE,
02300                  NULL,CPL_IO_DEFAULT));
02301 
02302   */
02303 
02304   //To remove an expected NAN value at the PSF centre we re-set PSF(centre)=1
02305   img_w=cpl_image_duplicate(img_airy);
02306   pw=cpl_image_get_data_double(img_w);
02307   pairy=cpl_image_get_data_double(img_airy);
02308 
02309   for(j=0;j<sy;j++) {
02310     for(i=0;i<sx;i++) {
02311       if(!irplib_isnan(pairy[i+j*sx]) && (pairy[i+j*sx] ==0)) {
02312     pairy[i+j*sx]=1.;
02313         sinfo_msg_debug("====> %f",pairy[i+j*sx]);
02314       }
02315     }
02316   }
02317   pairy[sx/2+sy/2*sx]=1.;
02318 
02319   sinfo_msg_debug("total-airy=%f",cpl_image_get_flux(img_airy));
02320 
02321   /*
02322   check_nomsg(cpl_image_save(img_airy,"out_airy1.fits", CPL_BPP_IEEE_DOUBLE,
02323                  NULL,CPL_IO_DEFAULT));
02324 
02325   */
02326 
02327 
02328   // Computation of EE
02329 
02330 
02331   v0=prr[0+dim/4-1];
02332   sinfo_msg_debug("v0=%12.10g",v0);
02333   for(i=0;i<npoints;i++) {
02334     ll[i]=(double)i/npoints*v0;
02335    }
02336   dll=ll[1]-ll[0];
02337   cor=1./(1.-occ*occ);
02338 
02339   for(i=0;i<npoints;i++) {
02340     part[i]=2.*j1(ll[i])/ll[i];
02341   }
02342   part[0]=1.0;
02343 
02344   tot1=0.;
02345   for(i=0;i<npoints;i++) {
02346     tot1+=j1(occ*ll[i])*part[i]*dll;
02347   }
02348   sinfo_msg_debug("tot=%10.8f",tot1);
02349 
02350 
02351   sinfo_msg_debug("cor=%10.8f",cor);
02352 
02353   ee=(1.-j0(v0)*j0(v0));
02354 
02355   sinfo_msg_debug("(1-j0(v0)*j0(v0))=%10.8f",ee);
02356 
02357 
02358   ee-=(j1(v0))*(j1(v0));
02359   sinfo_msg_debug("j1^2=%10.8f",(j1(v0))*(j1(v0)));
02360   sinfo_msg_debug("ee=%10.8f",ee);
02361 
02362   sinfo_msg_debug("factor=%10.8f",
02363           occ*occ*(1-j0(occ*v0)*j0(occ*v0)-j1(occ*v0)*j1(occ*v0)));
02364 
02365 
02366   ee+=occ*occ*(1-j0(occ*v0)*j0(occ*v0)-j1(occ*v0)*j1(occ*v0));
02367   sinfo_msg_debug("ee=%10.8f",ee);
02368 
02369   ee-=2.*occ*tot1;
02370   sinfo_msg_debug("ee=%10.8f",ee);
02371 
02372   ee*=cor;
02373   sinfo_msg_debug("ee=%10.8f",ee);
02374 
02375 
02376   tot1=0;
02377   pairy=cpl_image_get_data_double(img_airy);
02378   prr=cpl_image_get_data_double(img_rr);
02379   for(j=0;j<sy;j++) {
02380     for(i=0;i<sx;i++) {
02381       if(!irplib_isnan(pairy[i+j*sx]) && (prr[i+j*sx] <v0)) {
02382     tot1+=pairy[i+j*sx]*ee;
02383     //sinfo_msg_debug("tot=%f",tot1);
02384 
02385       }
02386     }
02387   }
02388 
02389   sinfo_msg_debug("tot=%10.8f",tot1);
02390   cpl_image_divide_scalar(img_airy,tot1);
02391 
02392   /*
02393   check_nomsg(cpl_image_save(img_airy,"out_airy2.fits", CPL_BPP_IEEE_DOUBLE,
02394                  NULL,CPL_IO_DEFAULT));
02395 
02396   */
02397 
02398 
02399   // Computation of maximum
02400 
02401   sinfo_msg_debug("dim=%d blocks=%d,bin=%d",dim,blocks,bin);
02402   start=(dim/2-1)-(blocks/2*bin-1)-bin/2;
02403   sinfo_msg_debug("start=%d",start);
02404 
02405   img_psf0=cpl_image_new(blocks,blocks,CPL_TYPE_DOUBLE);
02406   ppsf0=cpl_image_get_data_double(img_psf0);
02407   tot1=0.;
02408   tot2=0.;
02409 
02410   for(j=0;j<blocks;j++) {
02411     for(i=0;i<blocks;i++) {
02412       tot1=0;
02413       for(jj=start+j*bin;jj<start+(j+1)*bin-1;jj++){
02414     for(ii=start+i*bin;ii<start+(i+1)*bin-1;ii++){
02415           if(!irplib_isnan(pairy[ii+jj*sx])) {
02416         tot1+=pairy[ii+jj*sx];
02417       }
02418     }
02419       }
02420       ppsf0[i+j*blocks]=tot1;
02421       tot2+=tot1;
02422     }
02423   }
02424 
02425   cpl_image_divide_scalar(img_psf0,tot2);
02426   /*
02427   check_nomsg(cpl_image_save(img_psf0,"out_psf0.fits", CPL_BPP_IEEE_DOUBLE,
02428                  NULL,CPL_IO_DEFAULT));
02429 
02430   */
02431   k=180.*3600./SINFO_MATH_PI;
02432   sinfo_msg_debug("k=%f",k);
02433   sinfo_msg_debug("radius of first zero: 1.22*lambda/d*k:=%f",
02434             1.22*lambda/dia*k);
02435   sinfo_msg_debug("tot: %f",tot2);
02436   sinfo_msg_debug("max: %f",cpl_image_get_max(img_psf0)*tot2);
02437   sinfo_msg_debug("max/tot: %f",cpl_image_get_max(img_psf0));
02438   *psf_peak=cpl_image_get_max(img_psf0);
02439 
02440   sinfo_msg_debug("d=%g ob=%g w=%g ps=%g cx=%g cy=%g a=%g peak=%10.8g",
02441             dia,occ,lambda,psize,cx,cy,anamorph,*psf_peak);
02442 
02443 
02444 
02445  cleanup:
02446   sinfo_free_image(&img_xx);
02447   sinfo_free_image(&img_yy);
02448   sinfo_free_image(&img_rr);
02449   sinfo_free_image(&img_rrcor);
02450   sinfo_free_image(&img_airy);
02451 
02452 
02453   if (cpl_error_get_code() != CPL_ERROR_NONE) {
02454     return cpl_error_get_code();
02455   } else {
02456     return CPL_ERROR_NONE;
02457   }
02458 
02459 }
02460 
02461 
02462 cpl_error_code
02463 sinfo_get_flux_above_bkg(const cpl_image* img,
02464                          const float kappa,
02465                          const float std,
02466                          double* f)
02467 {
02468 
02469   const float* pimg=NULL;
02470   int sx=0;
02471   int sy=0;
02472   int i=0;
02473   int j=0;
02474   int k=0;
02475   float tot=0;
02476 
02477   cpl_image* timg=NULL;
02478   double sky_bkg=0;
02479   double sky_std=0;
02480 
02481   timg=cpl_image_duplicate(img);
02482   cpl_image_subtract_scalar(timg,std);
02483   check_nomsg(sinfo_get_bkg_4corners(timg,SINFO_BKG_BOX_SZ,SINFO_BKG_BOX_SZ,
02484                      &sky_bkg,&sky_std));
02485 
02486   check_nomsg(pimg=cpl_image_get_data_float_const(timg));
02487 
02488   sx=cpl_image_get_size_x(img);
02489   sy=cpl_image_get_size_y(img);
02490 
02491   for(j=0;j<sy;j++) {
02492     for(i=0;i<sx;i++) {
02493       if(!irplib_isnan(pimg[i+j*sx]) &&
02494           (pimg[i+j*sx]>(sky_bkg+kappa*sky_std))) {
02495     tot+=(double)pimg[i+j*sx];
02496     k++;
02497       }
02498     }
02499   }
02500 
02501   *f=(double)(tot-k*sky_bkg);
02502 
02503  cleanup:
02504   sinfo_free_image(&timg);
02505 
02506   if (cpl_error_get_code() != CPL_ERROR_NONE) {
02507     return cpl_error_get_code();
02508   } else {
02509     return CPL_ERROR_NONE;
02510   }
02511 
02512 }
02513 
02514 
02515 
02516 /*
02517 cpl_error_code
02518 sinfo_get_centroid(const cpl_image* img,
02519                    const int d,
02520                    const double xc,
02521                    const double yc,
02522                    double* xcen,
02523                    double* ycen,
02524                    double* xfwhm,
02525                    double* yfwhm,
02526                    double* angle)
02527 {
02528 
02529   cpl_bivector* q=NULL;
02530   int sx=0;
02531   int sy=0;
02532   double* pq=NULL;
02533   double peak=0;
02534   double bkg=0;
02535 
02536   check_nomsg(sx=cpl_image_get_size_x(img));
02537   check_nomsg(sy=cpl_image_get_size_y(img));
02538 
02539   check_nomsg(q=cpl_image_iqe(img,sx/2-d,sy/2-d,sx/2+d,sy/2+d));
02540   pq=cpl_bivector_get_data(q);
02541 
02542   *xcen=pq[0];
02543   *ycen=pq[1];
02544   *xfwhm=pq[2];
02545   *yfwhm=pq[3];
02546   *angle=pq[4];
02547   peak=pq[5];
02548   bkg=pq[6];
02549 
02550 
02551  cleanup:
02552 
02553   sinfo_free_bivector(&q);
02554 
02555   if (cpl_error_get_code() != CPL_ERROR_NONE) {
02556     return cpl_error_get_code();
02557   } else {
02558     return CPL_ERROR_NONE;
02559   }
02560 
02561 }
02562 */
02563 
02564 
02565 
02566 static double
02567 sinfo_find_min_of_four(const double n1,
02568                        const double n2,
02569                        const double n3,
02570                        const double n4)
02571 {
02572   double min=0;
02573   min = (n1 < n2) ? n1 : n2;
02574   min = (min < n3) ? min : n3;
02575   min = (min < n4) ? min : n4;
02576   return min;
02577 }
02578 
02579 double
02580 sinfo_scale_flux(const double p1,
02581                  const double p2,
02582                  const double t1,
02583                  const double t2)
02584 {
02585 
02586   return (p2/p1)*(p2/p1)*(t2/t1);
02587 
02588 }
02589 
02590 

Generated on 3 Mar 2013 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1