DETMON Pipeline Reference Manual  1.3.0
irplib_calib.c
1 /* $Id: irplib_calib.c,v 1.19 2013-03-01 10:26:22 llundin Exp $
2  *
3  * This file is part of the irplib package
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: llundin $
23  * $Date: 2013-03-01 10:26:22 $
24  * $Revision: 1.19 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <math.h>
37 #include <cpl.h>
38 
39 #include "irplib_calib.h"
40 
41 static int
42 irplib_get_clean_mean_window(cpl_image* img,
43  const int llx,
44  const int lly,
45  const int urx, int ury,
46  const int kappa,
47  const int nclip,
48  double* clean_mean,
49  double* clean_stdev);
50 
51 /*-----------------------------------------------------------------------------
52  Defines
53  -----------------------------------------------------------------------------*/
54 
55 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(6, 3, 0)
56 #define IRPLIB_FRAMESET_GET cpl_frameset_get_position
57 #else
58 /* Remove this branch once CPL versions less than 6.3 are no longer supported */
59 #define IRPLIB_FRAMESET_GET cpl_frameset_get_frame
60 #endif
61 
62 
63 static double irplib_pfits_get_dit(const cpl_propertylist * plist);
64 static double irplib_pfits_get_exp_time(const cpl_propertylist* plist);
65 /*----------------------------------------------------------------------------*/
69 /*----------------------------------------------------------------------------*/
70 
72 /*---------------------------------------------------------------------------*/
79 /*---------------------------------------------------------------------------*/
80 static double irplib_pfits_get_dit(const cpl_propertylist * plist)
81 {
82  return cpl_propertylist_get_double(plist,"ESO DET DIT");
83 }
84 
85 /*---------------------------------------------------------------------------*/
91 /*---------------------------------------------------------------------------*/
92 static double irplib_pfits_get_exp_time(const cpl_propertylist* plist)
93 {
94 
95  return cpl_propertylist_get_double(plist,"EXPTIME");
96 
97 }
98 
99 
115 static int
116 irplib_get_clean_mean_window(cpl_image* img,
117  const int llx,
118  const int lly,
119  const int urx, int ury,
120  const int kappa,
121  const int nclip,
122  double* clean_mean,
123  double* clean_stdev)
124 {
125 
126 
127  double mean=0;
128  double stdev=0;
129  cpl_image* tmp=NULL;
130  cpl_stats* stats=NULL;
131  int i=0;
132 
133  tmp=cpl_image_extract(img,llx,lly,urx,ury);
134  cpl_image_accept_all(tmp);
135  for(i=0;i<nclip;i++) {
136 
137  double threshold=0;
138  double lo_cut=0;
139  double hi_cut=0;
140  cpl_mask* mask=NULL;
141 
142  cpl_stats_delete(stats);
143  stats = cpl_stats_new_from_image(tmp, CPL_STATS_MEAN | CPL_STATS_STDEV);
144  mean = cpl_stats_get_mean(stats);
145  stdev = cpl_stats_get_stdev(stats);
146 
147  threshold=kappa*stdev;
148  lo_cut=mean-threshold;
149  hi_cut=mean+threshold;
150 
151  cpl_image_accept_all(tmp);
152  mask=cpl_mask_threshold_image_create(tmp,lo_cut,hi_cut);
153 
154  cpl_mask_not(mask);
155  cpl_image_reject_from_mask(tmp,mask);
156  cpl_mask_delete(mask);
157 
158 
159  }
160  *clean_mean=mean;
161  *clean_stdev=stdev;
162  cpl_image_delete(tmp);
163  cpl_stats_delete(stats);
164 
165  return 0;
166 
167 
168 }
169 
170 
171 
172 /*---------------------------------------------------------------------------*/
187 /*---------------------------------------------------------------------------*/
188 
189 
190 cpl_table*
192  cpl_frameset* son,
193  cpl_frameset* sof,
194  int* zone,
195  const int kappa,
196  const int nclip)
197 {
198 
199  cpl_frame* frm=NULL;
200 
201  cpl_table* res_tbl=NULL;
202  cpl_vector* dit_on=NULL;
203  cpl_vector* dit_of=NULL;
204  cpl_vector* exptime_on=NULL;
205  cpl_vector* exptime_of=NULL;
206 
207  int non=0;
208  int nof=0;
209  int nfr=0;
210  int llx;
211  int lly;
212  int urx;
213  int ury;
214 
215  const char* name=NULL;
216  int i=0;
217 
218  double dit_ref=0;
219  double exptime_ref=0;
220 
221 
222  non = cpl_frameset_get_size(son);
223  nof = cpl_frameset_get_size(sof);
224  nfr = (non <= nof) ? non : nof;
225 
226  dit_on=cpl_vector_new(nfr);
227  dit_of=cpl_vector_new(nfr);
228  exptime_on=cpl_vector_new(nfr);
229  exptime_of=cpl_vector_new(nfr);
230 
231  for(i=0;i<nfr;i++) {
232  cpl_propertylist* plist=NULL;
233 
234  frm=IRPLIB_FRAMESET_GET(son,i);
235  name=cpl_frame_get_filename(frm);
236  plist=cpl_propertylist_load(name,0);
237  dit_ref=irplib_pfits_get_dit(plist);
238  exptime_ref=(double)irplib_pfits_get_exp_time(plist);
239  cpl_propertylist_delete(plist);
240  cpl_vector_set(dit_on,i,dit_ref);
241  cpl_vector_set(exptime_on,i,exptime_ref);
242 
243  frm=IRPLIB_FRAMESET_GET(sof,i);
244  name=cpl_frame_get_filename(frm);
245  plist=cpl_propertylist_load(name,0);
246  dit_ref=irplib_pfits_get_dit(plist);
247  exptime_ref=(double)irplib_pfits_get_exp_time(plist);
248  cpl_propertylist_delete(plist);
249  cpl_vector_set(dit_of,i,dit_ref);
250  cpl_vector_set(exptime_of,i,exptime_ref);
251 
252  }
253 
254 
255  llx=zone[0];
256  lly=zone[1];
257  urx=zone[2];
258  ury=zone[3];
259 
260 
261 
262  res_tbl=cpl_table_new(nfr);
263  cpl_table_new_column(res_tbl,"adu", CPL_TYPE_DOUBLE);
264  cpl_table_new_column(res_tbl,"gain", CPL_TYPE_DOUBLE);
265 
266  for(i=0;i<nfr;i++) {
267  cpl_image* img_on1=NULL;
268  cpl_image* img_of1=NULL;
269  int m=0;
270 
271  frm=IRPLIB_FRAMESET_GET(son,i);
272  name=cpl_frame_get_filename(frm);
273  img_on1=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
274 
275  frm=IRPLIB_FRAMESET_GET(sof,i);
276  name=cpl_frame_get_filename(frm);
277  img_of1=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
278 
279 
280  dit_ref=cpl_vector_get(dit_on,i);
281  exptime_ref=cpl_vector_get(exptime_on,i);
282 
283 
284  for(m=0;m<nfr; m++) {
285  if(m != i) {
286  double dit_tmp=0;
287  double exptime_tmp=0;
288 
289  frm=IRPLIB_FRAMESET_GET(son,m);
290  name=cpl_frame_get_filename(frm);
291  dit_tmp=cpl_vector_get(dit_on,m);
292  exptime_tmp=cpl_vector_get(exptime_on,m);
293  if(dit_tmp == dit_ref && exptime_tmp == exptime_ref) {
294  cpl_image* img_on2=NULL;
295  cpl_image* img_on_dif=NULL;
296 
297  cpl_image* img_of2=NULL;
298  cpl_image* img_of_dif=NULL;
299 
300  double avg_on1=0;
301  double avg_on2=0;
302  double avg_of1=0;
303  double avg_of2=0;
304  double avg_on_dif=0;
305  double avg_of_dif=0;
306  double std=0;
307  double sig_on_dif=0;
308  double sig_of_dif=0;
309  double gain=0;
310 
311  img_on2=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
312  frm=IRPLIB_FRAMESET_GET(sof,m);
313  name=cpl_frame_get_filename(frm);
314  img_of2=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
315 
316  img_on_dif=cpl_image_subtract_create(img_on1,img_on2);
317  img_of_dif=cpl_image_subtract_create(img_of1,img_of2);
318 
319  irplib_get_clean_mean_window(img_on1,llx,lly,urx,ury,kappa,
320  nclip,&avg_on1,&std);
321  irplib_get_clean_mean_window(img_on2,llx,lly,urx,ury,kappa,
322  nclip,&avg_on2,&std);
323  irplib_get_clean_mean_window(img_of1,llx,lly,urx,ury,kappa,
324  nclip,&avg_of1,&std);
325  irplib_get_clean_mean_window(img_of2,llx,lly,urx,ury,kappa,
326  nclip,&avg_of2,&std);
327  irplib_get_clean_mean_window(img_on_dif,llx,lly,urx,ury,kappa,
328  nclip,&avg_on_dif,&sig_on_dif);
329  irplib_get_clean_mean_window(img_of_dif,llx,lly,urx,ury,kappa,
330  nclip,&avg_of_dif,&sig_of_dif);
331 
332  cpl_image_delete(img_on2);
333  cpl_image_delete(img_of2);
334  cpl_image_delete(img_on_dif);
335  cpl_image_delete(img_of_dif);
336 
337  gain=((avg_on1+avg_on2)-(avg_of1+avg_of2))/
338  ((sig_on_dif*sig_on_dif)-(sig_of_dif*sig_of_dif));
339 
340  cpl_table_set_double(res_tbl,"gain",m,gain);
341  cpl_table_set_double(res_tbl,"adu",m,
342  ((avg_on1+avg_on2)/2-(avg_of1+avg_of2)/2));
343 
344  }
345  }
346  }
347  cpl_image_delete(img_on1);
348  cpl_image_delete(img_of1);
349  }
350 
351 
352  cpl_vector_delete(dit_on);
353  cpl_vector_delete(dit_of);
354  cpl_vector_delete(exptime_on);
355  cpl_vector_delete(exptime_of);
356 
357  return res_tbl;
358 
359 }
360 
361 /* --------------------------------------------------------------------------*/
371 /*---------------------------------------------------------------------------*/
372 
373 
374 cpl_table* irplib_compute_linearity(cpl_frameset* son, cpl_frameset* sof)
375 {
376 
377  int non=0;
378  int nof=0;
379  int nfr=0;
380  int i=0;
381  double med_dit=0;
382  /*double avg_dit=0;*/
383 
384  cpl_vector* vec_adl=NULL;
385  cpl_vector* vec_dit=NULL;
386  cpl_vector* vec_avg=NULL;
387  cpl_vector* vec_med=NULL;
388  cpl_vector* vec_avg_dit=NULL;
389  cpl_vector* vec_med_dit=NULL;
390 
391  double dit=0;
392  cpl_table* lin_tbl=NULL;
393 
394 
395  non = cpl_frameset_get_size(son);
396  nof = cpl_frameset_get_size(sof);
397  nfr = (non <= nof) ? non : nof;
398 
399  lin_tbl=cpl_table_new(nfr);
400  cpl_table_new_column(lin_tbl,"med", CPL_TYPE_DOUBLE);
401  cpl_table_new_column(lin_tbl,"avg", CPL_TYPE_DOUBLE);
402  cpl_table_new_column(lin_tbl,"med_dit", CPL_TYPE_DOUBLE);
403  cpl_table_new_column(lin_tbl,"avg_dit", CPL_TYPE_DOUBLE);
404  cpl_table_new_column(lin_tbl,"dit", CPL_TYPE_DOUBLE);
405  vec_med=cpl_vector_new(nfr);
406  vec_avg=cpl_vector_new(nfr);
407  vec_med_dit=cpl_vector_new(nfr);
408  vec_avg_dit=cpl_vector_new(nfr);
409  vec_dit=cpl_vector_new(nfr);
410  vec_adl=cpl_vector_new(nfr);
411  for(i=0;i<nfr;i++) {
412  cpl_frame* frm=NULL;
413 
414  double med_on=0;
415  double avg_on=0;
416  double med_of=0;
417  double avg_of=0;
418 
419  double med=0;
420  double avg=0;
421  double avg_dit=0;
422 
423  const char* name=NULL;
424  cpl_image* img=NULL;
425  cpl_propertylist* plist=NULL;
426 
427  frm=IRPLIB_FRAMESET_GET(son,i);
428  name=cpl_frame_get_filename(frm);
429  img=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
430  med_on=cpl_image_get_median(img);
431  avg_on=cpl_image_get_mean(img);
432  cpl_image_delete(img);
433 
434  frm=IRPLIB_FRAMESET_GET(sof,i);
435  name=cpl_frame_get_filename(frm);
436  img=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
437  med_of=cpl_image_get_median(img);
438  avg_of=cpl_image_get_mean(img);
439  cpl_image_delete(img);
440  med=med_on-med_of;
441  avg=avg_on-avg_of;
442  plist=cpl_propertylist_load(name,0);
443  dit=(double)irplib_pfits_get_dit(plist);
444  cpl_propertylist_delete(plist);
445  avg_dit=avg/dit;
446  med_dit=med/dit;
447 
448  cpl_vector_set(vec_dit,i,dit);
449  cpl_vector_set(vec_avg,i,avg);
450  cpl_vector_set(vec_med,i,med);
451  cpl_vector_set(vec_avg_dit,i,avg_dit);
452  cpl_vector_set(vec_med_dit,i,med_dit);
453 
454 
455  cpl_table_set_double(lin_tbl,"dit",i,dit);
456  cpl_table_set_double(lin_tbl,"med",i,med);
457  cpl_table_set_double(lin_tbl,"avg",i,avg);
458  cpl_table_set_double(lin_tbl,"med_dit",i,med_dit);
459  cpl_table_set_double(lin_tbl,"avg_dit",i,avg_dit);
460 
461  }
462  cpl_table_new_column(lin_tbl,"adl", CPL_TYPE_DOUBLE);
463  med_dit=cpl_vector_get_mean(vec_med_dit);
464  /*avg_dit=cpl_vector_get_mean(vec_avg_dit);*/
465 
466  for(i=0;i<nfr;i++) {
467  int* status=0;
468  dit = cpl_table_get_double(lin_tbl,"dit",i,status);
469  cpl_vector_set(vec_adl,i,dit*med_dit);
470  cpl_table_set_double(lin_tbl,"adl",i,dit*med_dit);
471  }
472 
473 
474  cpl_vector_delete(vec_dit);
475  cpl_vector_delete(vec_adl);
476  cpl_vector_delete(vec_avg);
477  cpl_vector_delete(vec_med);
478  cpl_vector_delete(vec_avg_dit);
479  cpl_vector_delete(vec_med_dit);
480 
481 
482  return lin_tbl;
483 
484 }
485 
486 
487 /*----------------------------------------------------------------------------*/
496 /*----------------------------------------------------------------------------*/
498  cpl_imagelist * ilist,
499  const char * detlin_a,
500  const char * detlin_b,
501  const char * detlin_c)
502 {
503  cpl_image * ima ;
504  cpl_image * imb ;
505  cpl_image * imc ;
506  float * pima ;
507  float * pimb ;
508  float * pimc ;
509  float * pdata ;
510  int nx, ny, ni ;
511  double coeff_1, coeff_2, val ;
512  int i, j ;
513 
514  /* Test entries */
515  if (!ilist || !detlin_a || !detlin_b || !detlin_c) return -1 ;
516 
517  /* Load the 3 coeffs images */
518  ima = cpl_image_load(detlin_a, CPL_TYPE_FLOAT, 0, 0) ;
519  imb = cpl_image_load(detlin_b, CPL_TYPE_FLOAT, 0, 0) ;
520  imc = cpl_image_load(detlin_c, CPL_TYPE_FLOAT, 0, 0) ;
521  if (!ima || !imb || !imc) {
522  cpl_msg_error(cpl_func, "Cannot load the detlin images") ;
523  if (ima) cpl_image_delete(ima) ;
524  if (imb) cpl_image_delete(imb) ;
525  if (imc) cpl_image_delete(imc) ;
526  return -1 ;
527  }
528  pima = cpl_image_get_data_float(ima) ;
529  pimb = cpl_image_get_data_float(imb) ;
530  pimc = cpl_image_get_data_float(imc) ;
531 
532  /* Test sizes */
533  nx = cpl_image_get_size_x(cpl_imagelist_get(ilist, 0)) ;
534  ny = cpl_image_get_size_y(cpl_imagelist_get(ilist, 0)) ;
535  ni = cpl_imagelist_get_size(ilist) ;
536  if ((cpl_image_get_size_x(ima) != nx) ||
537  (cpl_image_get_size_x(imb) != nx) ||
538  (cpl_image_get_size_x(imc) != nx) ||
539  (cpl_image_get_size_y(ima) != ny) ||
540  (cpl_image_get_size_y(imb) != ny) ||
541  (cpl_image_get_size_y(imc) != ny)) {
542  cpl_msg_error(cpl_func, "Incompatible sizes") ;
543  cpl_image_delete(ima) ;
544  cpl_image_delete(imb) ;
545  cpl_image_delete(imc) ;
546  return -1 ;
547  }
548 
549  /* Loop on pixels */
550  for (i=0 ; i<nx*ny ; i++) {
551  /* Compute the coefficients */
552  if (fabs(pima[i]) < 1e-30) {
553  coeff_1 = coeff_2 = (double)0.0 ;
554  } else {
555  coeff_1 = (double)pimb[i] / (double)pima[i] ;
556  coeff_2 = (double)pimc[i] / (double)pima[i] ;
557  }
558  /* Correct this pixel in each plane */
559  for (j=0 ; j<ni ; j++) {
560  pdata = cpl_image_get_data_float(cpl_imagelist_get(ilist, j)) ;
561  val = (double)pdata[i] ;
562  pdata[i]=(float)(val+coeff_1*val*val+coeff_2*val*val*val) ;
563  }
564  }
565  /* Free and return */
566  cpl_image_delete(ima) ;
567  cpl_image_delete(imb) ;
568  cpl_image_delete(imc) ;
569  return 0 ;
570 }
571 
572 /*----------------------------------------------------------------------------*/
581 /*----------------------------------------------------------------------------*/
583  cpl_imagelist * ilist,
584  const char * flat,
585  const char * dark,
586  const char * bpm)
587 {
588  /* Test entries */
589  if (ilist == NULL) return -1 ;
590 
591  /* Dark correction */
592  if (dark != NULL) {
593  cpl_image * dark_image ;
594  cpl_msg_info(cpl_func, "Subtract the dark to the images") ;
595  /* Load the dark image */
596  if ((dark_image = cpl_image_load(dark, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
597  cpl_msg_error(cpl_func, "Cannot load the dark %s", dark) ;
598  return -1 ;
599  }
600  /* Apply the dark correction to the images */
601  if (cpl_imagelist_subtract_image(ilist, dark_image)!=CPL_ERROR_NONE) {
602  cpl_msg_error(cpl_func, "Cannot apply the dark to the images") ;
603  cpl_image_delete(dark_image) ;
604  return -1 ;
605  }
606  cpl_image_delete(dark_image) ;
607  }
608 
609  /* Flat-field correction */
610  if (flat != NULL) {
611  cpl_image * flat_image ;
612  cpl_msg_info(cpl_func, "Divide the images by the flatfield") ;
613  /* Load the flat image */
614  if ((flat_image = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
615  cpl_msg_error(cpl_func, "Cannot load the flat field %s", flat) ;
616  return -1 ;
617  }
618  /* Apply the flatfield correction to the images */
619  if (cpl_imagelist_divide_image(ilist, flat_image)!=CPL_ERROR_NONE) {
620  cpl_msg_error(cpl_func, "Cannot apply the flatfield to the images") ;
621  cpl_image_delete(flat_image) ;
622  return -1 ;
623  }
624  cpl_image_delete(flat_image) ;
625  }
626 
627  /* Correct the bad pixels if requested */
628  if (bpm != NULL) {
629  cpl_mask * bpm_im_bin ;
630  cpl_image * bpm_im_int ;
631  int i ;
632  cpl_msg_info(cpl_func, "Correct the bad pixels in the images") ;
633  /* Load the bad pixels image */
634  if ((bpm_im_int = cpl_image_load(bpm, CPL_TYPE_INT, 0, 0)) == NULL) {
635  cpl_msg_error(cpl_func, "Cannot load the bad pixel map %s", bpm) ;
636  return -1 ;
637  }
638  /* Convert the map from integer to binary */
639  bpm_im_bin = cpl_mask_threshold_image_create(bpm_im_int, -0.5, 0.5) ;
640  cpl_mask_not(bpm_im_bin) ;
641  cpl_image_delete(bpm_im_int) ;
642  /* Apply the bad pixels cleaning */
643  for (i=0 ; i<cpl_imagelist_get_size(ilist) ; i++) {
644  cpl_image_reject_from_mask(cpl_imagelist_get(ilist, i), bpm_im_bin);
645  if (cpl_detector_interpolate_rejected(
646  cpl_imagelist_get(ilist, i)) != CPL_ERROR_NONE) {
647  cpl_msg_error(cpl_func, "Cannot clean the bad pixels in obj %d",
648  i+1);
649  cpl_mask_delete(bpm_im_bin) ;
650  return -1 ;
651  }
652  }
653  cpl_mask_delete(bpm_im_bin) ;
654  }
655 
656  /* Return */
657  return 0 ;
658 }
659 
cpl_table * irplib_compute_gain(cpl_frameset *son, cpl_frameset *sof, int *zone, const int kappa, const int nclip)
Computes the detector's gain.
Definition: irplib_calib.c:191
int irplib_detlin_correct(cpl_imagelist *ilist, const char *detlin_a, const char *detlin_b, const char *detlin_c)
Apply the detector linearity correction.
Definition: irplib_calib.c:497
cpl_table * irplib_compute_linearity(cpl_frameset *son, cpl_frameset *sof)
Computes the detector's linearity.
Definition: irplib_calib.c:374
int irplib_flat_dark_bpm_calib(cpl_imagelist *ilist, const char *flat, const char *dark, const char *bpm)
Apply the calibration to the frames.
Definition: irplib_calib.c:582