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