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 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <math.h>
00037 #include <cpl.h>
00038
00039 #include "irplib_calib.h"
00040
00041 static int
00042 irplib_get_clean_mean_window(cpl_image* img,
00043 const int llx,
00044 const int lly,
00045 const int urx, int ury,
00046 const int kappa,
00047 const int nclip,
00048 double* clean_mean,
00049 double* clean_stdev);
00050
00051
00052
00053
00054
00055 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(6, 3, 0)
00056 #define IRPLIB_FRAMESET_GET cpl_frameset_get_position
00057 #else
00058
00059 #define IRPLIB_FRAMESET_GET cpl_frameset_get_frame
00060 #endif
00061
00062
00063 static double irplib_pfits_get_dit(const cpl_propertylist * plist);
00064 static double irplib_pfits_get_exp_time(const cpl_propertylist* plist);
00065
00069
00070
00072
00079
00080 static double irplib_pfits_get_dit(const cpl_propertylist * plist)
00081 {
00082 return cpl_propertylist_get_double(plist,"ESO DET DIT");
00083 }
00084
00085
00091
00092 static double irplib_pfits_get_exp_time(const cpl_propertylist* plist)
00093 {
00094
00095 return cpl_propertylist_get_double(plist,"EXPTIME");
00096
00097 }
00098
00099
00115 static int
00116 irplib_get_clean_mean_window(cpl_image* img,
00117 const int llx,
00118 const int lly,
00119 const int urx, int ury,
00120 const int kappa,
00121 const int nclip,
00122 double* clean_mean,
00123 double* clean_stdev)
00124 {
00125
00126
00127 double mean=0;
00128 double stdev=0;
00129 double threshold=0;
00130 double lo_cut=0;
00131 double hi_cut=0;
00132 cpl_mask* mask=NULL;
00133 cpl_image* tmp=NULL;
00134 cpl_stats* stats=NULL;
00135 int i=0;
00136
00137 tmp=cpl_image_extract(img,llx,lly,urx,ury);
00138 cpl_image_accept_all(tmp);
00139 for(i=0;i<nclip;i++) {
00140
00141
00142 cpl_stats_delete(stats);
00143 stats = cpl_stats_new_from_image(tmp, CPL_STATS_MEAN | CPL_STATS_STDEV);
00144 mean = cpl_stats_get_mean(stats);
00145 stdev = cpl_stats_get_stdev(stats);
00146
00147 threshold=kappa*stdev;
00148 lo_cut=mean-threshold;
00149 hi_cut=mean+threshold;
00150
00151 cpl_image_accept_all(tmp);
00152 mask=cpl_mask_threshold_image_create(tmp,lo_cut,hi_cut);
00153
00154 cpl_mask_not(mask);
00155 cpl_image_reject_from_mask(tmp,mask);
00156 cpl_mask_delete(mask);
00157
00158
00159 }
00160 *clean_mean=mean;
00161 *clean_stdev=stdev;
00162 cpl_image_delete(tmp);
00163 cpl_stats_delete(stats);
00164
00165 return 0;
00166
00167
00168 }
00169
00170
00171
00172
00187
00188
00189
00190 cpl_table*
00191 irplib_compute_gain(
00192 cpl_frameset* son,
00193 cpl_frameset* sof,
00194 int* zone,
00195 const int kappa,
00196 const int nclip)
00197 {
00198
00199 cpl_frame* frm=NULL;
00200
00201 cpl_image* img_on1=NULL;
00202 cpl_image* img_on2=NULL;
00203 cpl_image* img_on_dif=NULL;
00204
00205 cpl_image* img_of1=NULL;
00206 cpl_image* img_of2=NULL;
00207 cpl_image* img_of_dif=NULL;
00208
00209 cpl_table* res_tbl=NULL;
00210 cpl_vector* dit_on=NULL;
00211 cpl_vector* dit_of=NULL;
00212 cpl_vector* exptime_on=NULL;
00213 cpl_vector* exptime_of=NULL;
00214 cpl_propertylist* plist=NULL;
00215
00216 int non=0;
00217 int nof=0;
00218 int nfr=0;
00219 int llx;
00220 int lly;
00221 int urx;
00222 int ury;
00223
00224 double avg_on1=0;
00225 double avg_on2=0;
00226 double avg_of1=0;
00227 double avg_of2=0;
00228 double avg_on_dif=0;
00229 double avg_of_dif=0;
00230 double std=0;
00231
00232 double sig_on_dif=0;
00233 double sig_of_dif=0;
00234 const char* name=NULL;
00235 int i=0;
00236 int m=0;
00237
00238 double gain=0;
00239 double dit_ref=0;
00240 double dit_tmp=0;
00241 double exptime_ref=0;
00242 double exptime_tmp=0;
00243
00244
00245 non = cpl_frameset_get_size(son);
00246 nof = cpl_frameset_get_size(sof);
00247 nfr = (non <= nof) ? non : nof;
00248
00249 dit_on=cpl_vector_new(nfr);
00250 dit_of=cpl_vector_new(nfr);
00251 exptime_on=cpl_vector_new(nfr);
00252 exptime_of=cpl_vector_new(nfr);
00253
00254 for(i=0;i<nfr;i++) {
00255
00256 frm=IRPLIB_FRAMESET_GET(son,i);
00257 name=cpl_frame_get_filename(frm);
00258 plist=cpl_propertylist_load(name,0);
00259 dit_ref=irplib_pfits_get_dit(plist);
00260 exptime_ref=(double)irplib_pfits_get_exp_time(plist);
00261 cpl_propertylist_delete(plist);
00262 cpl_vector_set(dit_on,i,dit_ref);
00263 cpl_vector_set(exptime_on,i,exptime_ref);
00264
00265 frm=IRPLIB_FRAMESET_GET(sof,i);
00266 name=cpl_frame_get_filename(frm);
00267 plist=cpl_propertylist_load(name,0);
00268 dit_ref=irplib_pfits_get_dit(plist);
00269 exptime_ref=(double)irplib_pfits_get_exp_time(plist);
00270 cpl_propertylist_delete(plist);
00271 cpl_vector_set(dit_of,i,dit_ref);
00272 cpl_vector_set(exptime_of,i,exptime_ref);
00273
00274 }
00275
00276
00277 llx=zone[0];
00278 lly=zone[1];
00279 urx=zone[2];
00280 ury=zone[3];
00281
00282
00283
00284 res_tbl=cpl_table_new(nfr);
00285 cpl_table_new_column(res_tbl,"adu", CPL_TYPE_DOUBLE);
00286 cpl_table_new_column(res_tbl,"gain", CPL_TYPE_DOUBLE);
00287
00288 for(i=0;i<nfr;i++) {
00289 frm=IRPLIB_FRAMESET_GET(son,i);
00290 name=cpl_frame_get_filename(frm);
00291 img_on1=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
00292
00293 frm=IRPLIB_FRAMESET_GET(sof,i);
00294 name=cpl_frame_get_filename(frm);
00295 img_of1=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
00296
00297
00298 dit_ref=cpl_vector_get(dit_on,i);
00299 exptime_ref=cpl_vector_get(exptime_on,i);
00300
00301
00302 for(m=0;m<nfr; m++) {
00303 if(m != i) {
00304 frm=IRPLIB_FRAMESET_GET(son,m);
00305 name=cpl_frame_get_filename(frm);
00306 dit_tmp=cpl_vector_get(dit_on,m);
00307 exptime_tmp=cpl_vector_get(exptime_on,m);
00308 if(dit_tmp == dit_ref && exptime_tmp == exptime_ref) {
00309 img_on2=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
00310 frm=IRPLIB_FRAMESET_GET(sof,m);
00311 name=cpl_frame_get_filename(frm);
00312 img_of2=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
00313
00314 img_on_dif=cpl_image_subtract_create(img_on1,img_on2);
00315 img_of_dif=cpl_image_subtract_create(img_of1,img_of2);
00316
00317 irplib_get_clean_mean_window(img_on1,llx,lly,urx,ury,kappa,
00318 nclip,&avg_on1,&std);
00319 irplib_get_clean_mean_window(img_on2,llx,lly,urx,ury,kappa,
00320 nclip,&avg_on2,&std);
00321 irplib_get_clean_mean_window(img_of1,llx,lly,urx,ury,kappa,
00322 nclip,&avg_of1,&std);
00323 irplib_get_clean_mean_window(img_of2,llx,lly,urx,ury,kappa,
00324 nclip,&avg_of2,&std);
00325 irplib_get_clean_mean_window(img_on_dif,llx,lly,urx,ury,kappa,
00326 nclip,&avg_on_dif,&sig_on_dif);
00327 irplib_get_clean_mean_window(img_of_dif,llx,lly,urx,ury,kappa,
00328 nclip,&avg_of_dif,&sig_of_dif);
00329
00330 cpl_image_delete(img_on2);
00331 cpl_image_delete(img_of2);
00332 cpl_image_delete(img_on_dif);
00333 cpl_image_delete(img_of_dif);
00334
00335 gain=((avg_on1+avg_on2)-(avg_of1+avg_of2))/
00336 ((sig_on_dif*sig_on_dif)-(sig_of_dif*sig_of_dif));
00337
00338 cpl_table_set_double(res_tbl,"gain",m,gain);
00339 cpl_table_set_double(res_tbl,"adu",m,
00340 ((avg_on1+avg_on2)/2-(avg_of1+avg_of2)/2));
00341
00342 }
00343 }
00344 }
00345 cpl_image_delete(img_on1);
00346 cpl_image_delete(img_of1);
00347 }
00348
00349
00350 cpl_vector_delete(dit_on);
00351 cpl_vector_delete(dit_of);
00352 cpl_vector_delete(exptime_on);
00353 cpl_vector_delete(exptime_of);
00354
00355 return res_tbl;
00356
00357 }
00358
00359
00369
00370
00371
00372 cpl_table* irplib_compute_linearity(cpl_frameset* son, cpl_frameset* sof)
00373 {
00374
00375
00376 cpl_frame* frm=NULL;
00377
00378 int* status=0;
00379 int non=0;
00380 int nof=0;
00381 int nfr=0;
00382 int i=0;
00383 double med_on=0;
00384 double avg_on=0;
00385 double med_of=0;
00386 double avg_of=0;
00387 double med_dit=0;
00388 double avg_dit=0;
00389
00390 double med=0;
00391 double avg=0;
00392
00393 const char* name=NULL;
00394 cpl_image* img=NULL;
00395 cpl_vector* vec_adl=NULL;
00396 cpl_vector* vec_dit=NULL;
00397 cpl_vector* vec_avg=NULL;
00398 cpl_vector* vec_med=NULL;
00399 cpl_vector* vec_avg_dit=NULL;
00400 cpl_vector* vec_med_dit=NULL;
00401 cpl_propertylist* plist=NULL;
00402
00403 double dit=0;
00404 cpl_table* lin_tbl=NULL;
00405
00406
00407 non = cpl_frameset_get_size(son);
00408 nof = cpl_frameset_get_size(sof);
00409 nfr = (non <= nof) ? non : nof;
00410
00411 lin_tbl=cpl_table_new(nfr);
00412 cpl_table_new_column(lin_tbl,"med", CPL_TYPE_DOUBLE);
00413 cpl_table_new_column(lin_tbl,"avg", CPL_TYPE_DOUBLE);
00414 cpl_table_new_column(lin_tbl,"med_dit", CPL_TYPE_DOUBLE);
00415 cpl_table_new_column(lin_tbl,"avg_dit", CPL_TYPE_DOUBLE);
00416 cpl_table_new_column(lin_tbl,"dit", CPL_TYPE_DOUBLE);
00417 vec_med=cpl_vector_new(nfr);
00418 vec_avg=cpl_vector_new(nfr);
00419 vec_med_dit=cpl_vector_new(nfr);
00420 vec_avg_dit=cpl_vector_new(nfr);
00421 vec_dit=cpl_vector_new(nfr);
00422 vec_adl=cpl_vector_new(nfr);
00423 for(i=0;i<nfr;i++) {
00424 frm=IRPLIB_FRAMESET_GET(son,i);
00425 name=cpl_frame_get_filename(frm);
00426 img=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
00427 med_on=cpl_image_get_median(img);
00428 avg_on=cpl_image_get_mean(img);
00429 cpl_image_delete(img);
00430
00431 frm=IRPLIB_FRAMESET_GET(sof,i);
00432 name=cpl_frame_get_filename(frm);
00433 img=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
00434 med_of=cpl_image_get_median(img);
00435 avg_of=cpl_image_get_mean(img);
00436 cpl_image_delete(img);
00437 med=med_on-med_of;
00438 avg=avg_on-avg_of;
00439 plist=cpl_propertylist_load(name,0);
00440 dit=(double)irplib_pfits_get_dit(plist);
00441 cpl_propertylist_delete(plist);
00442 avg_dit=avg/dit;
00443 med_dit=med/dit;
00444
00445 cpl_vector_set(vec_dit,i,dit);
00446 cpl_vector_set(vec_avg,i,avg);
00447 cpl_vector_set(vec_med,i,med);
00448 cpl_vector_set(vec_avg_dit,i,avg_dit);
00449 cpl_vector_set(vec_med_dit,i,med_dit);
00450
00451
00452 cpl_table_set_double(lin_tbl,"dit",i,dit);
00453 cpl_table_set_double(lin_tbl,"med",i,med);
00454 cpl_table_set_double(lin_tbl,"avg",i,avg);
00455 cpl_table_set_double(lin_tbl,"med_dit",i,med_dit);
00456 cpl_table_set_double(lin_tbl,"avg_dit",i,avg_dit);
00457
00458 }
00459 cpl_table_new_column(lin_tbl,"adl", CPL_TYPE_DOUBLE);
00460 med_dit=cpl_vector_get_mean(vec_med_dit);
00461 avg_dit=cpl_vector_get_mean(vec_avg_dit);
00462
00463 for(i=0;i<nfr;i++) {
00464 dit = cpl_table_get_double(lin_tbl,"dit",i,status);
00465 cpl_vector_set(vec_adl,i,dit*med_dit);
00466 cpl_table_set_double(lin_tbl,"adl",i,dit*med_dit);
00467 }
00468
00469
00470 cpl_vector_delete(vec_dit);
00471 cpl_vector_delete(vec_adl);
00472 cpl_vector_delete(vec_avg);
00473 cpl_vector_delete(vec_med);
00474 cpl_vector_delete(vec_avg_dit);
00475 cpl_vector_delete(vec_med_dit);
00476
00477
00478 return lin_tbl;
00479
00480 }
00481
00482
00483
00492
00493 int irplib_detlin_correct(
00494 cpl_imagelist * ilist,
00495 const char * detlin_a,
00496 const char * detlin_b,
00497 const char * detlin_c)
00498 {
00499 cpl_image * ima ;
00500 cpl_image * imb ;
00501 cpl_image * imc ;
00502 float * pima ;
00503 float * pimb ;
00504 float * pimc ;
00505 float * pdata ;
00506 int nx, ny, ni ;
00507 double coeff_1, coeff_2, val ;
00508 int i, j ;
00509
00510
00511 if (!ilist || !detlin_a || !detlin_b || !detlin_c) return -1 ;
00512
00513
00514 ima = cpl_image_load(detlin_a, CPL_TYPE_FLOAT, 0, 0) ;
00515 imb = cpl_image_load(detlin_b, CPL_TYPE_FLOAT, 0, 0) ;
00516 imc = cpl_image_load(detlin_c, CPL_TYPE_FLOAT, 0, 0) ;
00517 if (!ima || !imb || !imc) {
00518 cpl_msg_error(cpl_func, "Cannot load the detlin images") ;
00519 if (ima) cpl_image_delete(ima) ;
00520 if (imb) cpl_image_delete(imb) ;
00521 if (imc) cpl_image_delete(imc) ;
00522 return -1 ;
00523 }
00524 pima = cpl_image_get_data_float(ima) ;
00525 pimb = cpl_image_get_data_float(imb) ;
00526 pimc = cpl_image_get_data_float(imc) ;
00527
00528
00529 nx = cpl_image_get_size_x(cpl_imagelist_get(ilist, 0)) ;
00530 ny = cpl_image_get_size_y(cpl_imagelist_get(ilist, 0)) ;
00531 ni = cpl_imagelist_get_size(ilist) ;
00532 if ((cpl_image_get_size_x(ima) != nx) ||
00533 (cpl_image_get_size_x(imb) != nx) ||
00534 (cpl_image_get_size_x(imc) != nx) ||
00535 (cpl_image_get_size_y(ima) != ny) ||
00536 (cpl_image_get_size_y(imb) != ny) ||
00537 (cpl_image_get_size_y(imc) != ny)) {
00538 cpl_msg_error(cpl_func, "Incompatible sizes") ;
00539 cpl_image_delete(ima) ;
00540 cpl_image_delete(imb) ;
00541 cpl_image_delete(imc) ;
00542 return -1 ;
00543 }
00544
00545
00546 for (i=0 ; i<nx*ny ; i++) {
00547
00548 if (fabs(pima[i]) < 1e-30) {
00549 coeff_1 = coeff_2 = (double)0.0 ;
00550 } else {
00551 coeff_1 = (double)pimb[i] / (double)pima[i] ;
00552 coeff_2 = (double)pimc[i] / (double)pima[i] ;
00553 }
00554
00555 for (j=0 ; j<ni ; j++) {
00556 pdata = cpl_image_get_data_float(cpl_imagelist_get(ilist, j)) ;
00557 val = (double)pdata[i] ;
00558 pdata[i]=(float)(val+coeff_1*val*val+coeff_2*val*val*val) ;
00559 }
00560 }
00561
00562 cpl_image_delete(ima) ;
00563 cpl_image_delete(imb) ;
00564 cpl_image_delete(imc) ;
00565 return 0 ;
00566 }
00567
00568
00577
00578 int irplib_flat_dark_bpm_calib(
00579 cpl_imagelist * ilist,
00580 const char * flat,
00581 const char * dark,
00582 const char * bpm)
00583 {
00584 cpl_image * dark_image ;
00585 cpl_image * flat_image ;
00586 cpl_mask * bpm_im_bin ;
00587 cpl_image * bpm_im_int ;
00588 int i ;
00589
00590
00591 if (ilist == NULL) return -1 ;
00592
00593
00594 if (dark != NULL) {
00595 cpl_msg_info(cpl_func, "Subtract the dark to the images") ;
00596
00597 if ((dark_image = cpl_image_load(dark, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00598 cpl_msg_error(cpl_func, "Cannot load the dark %s", dark) ;
00599 return -1 ;
00600 }
00601
00602 if (cpl_imagelist_subtract_image(ilist, dark_image)!=CPL_ERROR_NONE) {
00603 cpl_msg_error(cpl_func, "Cannot apply the dark to the images") ;
00604 cpl_image_delete(dark_image) ;
00605 return -1 ;
00606 }
00607 cpl_image_delete(dark_image) ;
00608 }
00609
00610
00611 if (flat != NULL) {
00612 cpl_msg_info(cpl_func, "Divide the images by the flatfield") ;
00613
00614 if ((flat_image = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00615 cpl_msg_error(cpl_func, "Cannot load the flat field %s", flat) ;
00616 return -1 ;
00617 }
00618
00619 if (cpl_imagelist_divide_image(ilist, flat_image)!=CPL_ERROR_NONE) {
00620 cpl_msg_error(cpl_func, "Cannot apply the flatfield to the images") ;
00621 cpl_image_delete(flat_image) ;
00622 return -1 ;
00623 }
00624 cpl_image_delete(flat_image) ;
00625 }
00626
00627
00628 if (bpm != NULL) {
00629 cpl_msg_info(cpl_func, "Correct the bad pixels in the images") ;
00630
00631 if ((bpm_im_int = cpl_image_load(bpm, CPL_TYPE_INT, 0, 0)) == NULL) {
00632 cpl_msg_error(cpl_func, "Cannot load the bad pixel map %s", bpm) ;
00633 return -1 ;
00634 }
00635
00636 bpm_im_bin = cpl_mask_threshold_image_create(bpm_im_int, -0.5, 0.5) ;
00637 cpl_mask_not(bpm_im_bin) ;
00638 cpl_image_delete(bpm_im_int) ;
00639
00640 for (i=0 ; i<cpl_imagelist_get_size(ilist) ; i++) {
00641 cpl_image_reject_from_mask(cpl_imagelist_get(ilist, i), bpm_im_bin);
00642 if (cpl_detector_interpolate_rejected(
00643 cpl_imagelist_get(ilist, i)) != CPL_ERROR_NONE) {
00644 cpl_msg_error(cpl_func, "Cannot clean the bad pixels in obj %d",
00645 i+1);
00646 cpl_mask_delete(bpm_im_bin) ;
00647 return -1 ;
00648 }
00649 }
00650 cpl_mask_delete(bpm_im_bin) ;
00651 }
00652
00653
00654 return 0 ;
00655 }
00656