00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef HAVE_CONFIG_H
00033 # include <config.h>
00034 #endif
00035
00036
00037
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
00060 #include "sinfo_dfs.h"
00061
00062
00063
00064
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
00085
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
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
00224
00225
00226
00227
00228
00229
00230
00231
00232
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
00297
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
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
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
00450
00451
00452
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
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
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
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
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
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
00801
00802
00803
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
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
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
00975
00976
00977
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
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
01049
01050
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,¢ralWave,
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
01227
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
01296
01297
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, ¢ralWave,
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
01420
01421
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
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
01610
01611
01612
01613
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;
01621 psf_flux2 = 1.0;
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
01632 star_radius = r1/pscale2;
01633
01634
01635
01636
01637
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
01673
01674
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
01681
01682
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
01697
01698
01699
01700
01701
01702
01703 *strehl = (*star_peak/(*star_flux*trat)) / (psf_peak1 );
01704
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
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727 *bg_noise=0;
01728
01729 cleanup:
01730
01731
01732 if (!cpl_errorstate_is_equal(initial_errorstate)) {
01733
01734
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
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
01791 xm=piqe[0];
01792 ym=piqe[1];
01793
01794
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
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
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
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
01930 const double window_size = (double)(SINFO_STREHL_RAD_CENTRAL);
01931
01932
01933
01934
01935
01936 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 0, 0)
01937 double ring[4];
01938 #else
01939
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
01950 cpl_ensure_code(window_size > 0.0, CPL_ERROR_ILLEGAL_INPUT);
01951
01952
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
01972 check_nomsg(sinfo_compute_psf(m1,m2/m1,lam*1.e-6,pscale,xc,yc,
01973 1.,psf_peak));
01974
01975
01976
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
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);
01990 *psf_flux = 1.0;
01991
01992
01993
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
02012
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
02028 ring[0] = xpos;
02029 ring[1] = ypos;
02030 ring[2] = r2/pscale;
02031 ring[3] = r3/pscale;
02032
02033
02034
02035
02036
02037
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
02238 pxx[j*sx+i]=(i-sx/2-cx*bin)/nyquist*SINFO_MATH_PI/2;
02239
02240 pyy[j*sx+i]=(j-sy/2-cy*bin)/nyquist*SINFO_MATH_PI/2*anamorph;
02241
02242
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
02249
02250
02251
02252
02253
02254
02255
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
02270
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
02300
02301
02302
02303
02304
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
02323
02324
02325
02326
02327
02328
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
02384
02385 }
02386 }
02387 }
02388
02389 sinfo_msg_debug("tot=%10.8f",tot1);
02390 cpl_image_divide_scalar(img_airy,tot1);
02391
02392
02393
02394
02395
02396
02397
02398
02399
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
02428
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
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
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