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