SINFONI Pipeline Reference Manual  2.5.2
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  double threshold=0;
130  double lo_cut=0;
131  double hi_cut=0;
132  cpl_mask* mask=NULL;
133  cpl_image* tmp=NULL;
134  cpl_stats* stats=NULL;
135  int i=0;
136 
137  tmp=cpl_image_extract(img,llx,lly,urx,ury);
138  cpl_image_accept_all(tmp);
139  for(i=0;i<nclip;i++) {
140 
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_image* img_on1=NULL;
202  cpl_image* img_on2=NULL;
203  cpl_image* img_on_dif=NULL;
204 
205  cpl_image* img_of1=NULL;
206  cpl_image* img_of2=NULL;
207  cpl_image* img_of_dif=NULL;
208 
209  cpl_table* res_tbl=NULL;
210  cpl_vector* dit_on=NULL;
211  cpl_vector* dit_of=NULL;
212  cpl_vector* exptime_on=NULL;
213  cpl_vector* exptime_of=NULL;
214  cpl_propertylist* plist=NULL;
215 
216  int non=0;
217  int nof=0;
218  int nfr=0;
219  int llx;
220  int lly;
221  int urx;
222  int ury;
223 
224  double avg_on1=0;
225  double avg_on2=0;
226  double avg_of1=0;
227  double avg_of2=0;
228  double avg_on_dif=0;
229  double avg_of_dif=0;
230  double std=0;
231 
232  double sig_on_dif=0;
233  double sig_of_dif=0;
234  const char* name=NULL;
235  int i=0;
236  int m=0;
237 
238  double gain=0;
239  double dit_ref=0;
240  double dit_tmp=0;
241  double exptime_ref=0;
242  double exptime_tmp=0;
243 
244 
245  non = cpl_frameset_get_size(son);
246  nof = cpl_frameset_get_size(sof);
247  nfr = (non <= nof) ? non : nof;
248 
249  dit_on=cpl_vector_new(nfr);
250  dit_of=cpl_vector_new(nfr);
251  exptime_on=cpl_vector_new(nfr);
252  exptime_of=cpl_vector_new(nfr);
253 
254  for(i=0;i<nfr;i++) {
255 
256  frm=IRPLIB_FRAMESET_GET(son,i);
257  name=cpl_frame_get_filename(frm);
258  plist=cpl_propertylist_load(name,0);
259  dit_ref=irplib_pfits_get_dit(plist);
260  exptime_ref=(double)irplib_pfits_get_exp_time(plist);
261  cpl_propertylist_delete(plist);
262  cpl_vector_set(dit_on,i,dit_ref);
263  cpl_vector_set(exptime_on,i,exptime_ref);
264 
265  frm=IRPLIB_FRAMESET_GET(sof,i);
266  name=cpl_frame_get_filename(frm);
267  plist=cpl_propertylist_load(name,0);
268  dit_ref=irplib_pfits_get_dit(plist);
269  exptime_ref=(double)irplib_pfits_get_exp_time(plist);
270  cpl_propertylist_delete(plist);
271  cpl_vector_set(dit_of,i,dit_ref);
272  cpl_vector_set(exptime_of,i,exptime_ref);
273 
274  }
275 
276 
277  llx=zone[0];
278  lly=zone[1];
279  urx=zone[2];
280  ury=zone[3];
281 
282 
283 
284  res_tbl=cpl_table_new(nfr);
285  cpl_table_new_column(res_tbl,"adu", CPL_TYPE_DOUBLE);
286  cpl_table_new_column(res_tbl,"gain", CPL_TYPE_DOUBLE);
287 
288  for(i=0;i<nfr;i++) {
289  frm=IRPLIB_FRAMESET_GET(son,i);
290  name=cpl_frame_get_filename(frm);
291  img_on1=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
292 
293  frm=IRPLIB_FRAMESET_GET(sof,i);
294  name=cpl_frame_get_filename(frm);
295  img_of1=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
296 
297 
298  dit_ref=cpl_vector_get(dit_on,i);
299  exptime_ref=cpl_vector_get(exptime_on,i);
300 
301 
302  for(m=0;m<nfr; m++) {
303  if(m != i) {
304  frm=IRPLIB_FRAMESET_GET(son,m);
305  name=cpl_frame_get_filename(frm);
306  dit_tmp=cpl_vector_get(dit_on,m);
307  exptime_tmp=cpl_vector_get(exptime_on,m);
308  if(dit_tmp == dit_ref && exptime_tmp == exptime_ref) {
309  img_on2=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
310  frm=IRPLIB_FRAMESET_GET(sof,m);
311  name=cpl_frame_get_filename(frm);
312  img_of2=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
313 
314  img_on_dif=cpl_image_subtract_create(img_on1,img_on2);
315  img_of_dif=cpl_image_subtract_create(img_of1,img_of2);
316 
317  irplib_get_clean_mean_window(img_on1,llx,lly,urx,ury,kappa,
318  nclip,&avg_on1,&std);
319  irplib_get_clean_mean_window(img_on2,llx,lly,urx,ury,kappa,
320  nclip,&avg_on2,&std);
321  irplib_get_clean_mean_window(img_of1,llx,lly,urx,ury,kappa,
322  nclip,&avg_of1,&std);
323  irplib_get_clean_mean_window(img_of2,llx,lly,urx,ury,kappa,
324  nclip,&avg_of2,&std);
325  irplib_get_clean_mean_window(img_on_dif,llx,lly,urx,ury,kappa,
326  nclip,&avg_on_dif,&sig_on_dif);
327  irplib_get_clean_mean_window(img_of_dif,llx,lly,urx,ury,kappa,
328  nclip,&avg_of_dif,&sig_of_dif);
329 
330  cpl_image_delete(img_on2);
331  cpl_image_delete(img_of2);
332  cpl_image_delete(img_on_dif);
333  cpl_image_delete(img_of_dif);
334 
335  gain=((avg_on1+avg_on2)-(avg_of1+avg_of2))/
336  ((sig_on_dif*sig_on_dif)-(sig_of_dif*sig_of_dif));
337 
338  cpl_table_set_double(res_tbl,"gain",m,gain);
339  cpl_table_set_double(res_tbl,"adu",m,
340  ((avg_on1+avg_on2)/2-(avg_of1+avg_of2)/2));
341 
342  }
343  }
344  }
345  cpl_image_delete(img_on1);
346  cpl_image_delete(img_of1);
347  }
348 
349 
350  cpl_vector_delete(dit_on);
351  cpl_vector_delete(dit_of);
352  cpl_vector_delete(exptime_on);
353  cpl_vector_delete(exptime_of);
354 
355  return res_tbl;
356 
357 }
358 
359 /* --------------------------------------------------------------------------*/
369 /*---------------------------------------------------------------------------*/
370 
371 
372 cpl_table* irplib_compute_linearity(cpl_frameset* son, cpl_frameset* sof)
373 {
374 
375 
376  cpl_frame* frm=NULL;
377 
378  int* status=0;
379  int non=0;
380  int nof=0;
381  int nfr=0;
382  int i=0;
383  double med_on=0;
384  double avg_on=0;
385  double med_of=0;
386  double avg_of=0;
387  double med_dit=0;
388  double avg_dit=0;
389 
390  double med=0;
391  double avg=0;
392 
393  const char* name=NULL;
394  cpl_image* img=NULL;
395  cpl_vector* vec_adl=NULL;
396  cpl_vector* vec_dit=NULL;
397  cpl_vector* vec_avg=NULL;
398  cpl_vector* vec_med=NULL;
399  cpl_vector* vec_avg_dit=NULL;
400  cpl_vector* vec_med_dit=NULL;
401  cpl_propertylist* plist=NULL;
402 
403  double dit=0;
404  cpl_table* lin_tbl=NULL;
405 
406 
407  non = cpl_frameset_get_size(son);
408  nof = cpl_frameset_get_size(sof);
409  nfr = (non <= nof) ? non : nof;
410 
411  lin_tbl=cpl_table_new(nfr);
412  cpl_table_new_column(lin_tbl,"med", CPL_TYPE_DOUBLE);
413  cpl_table_new_column(lin_tbl,"avg", CPL_TYPE_DOUBLE);
414  cpl_table_new_column(lin_tbl,"med_dit", CPL_TYPE_DOUBLE);
415  cpl_table_new_column(lin_tbl,"avg_dit", CPL_TYPE_DOUBLE);
416  cpl_table_new_column(lin_tbl,"dit", CPL_TYPE_DOUBLE);
417  vec_med=cpl_vector_new(nfr);
418  vec_avg=cpl_vector_new(nfr);
419  vec_med_dit=cpl_vector_new(nfr);
420  vec_avg_dit=cpl_vector_new(nfr);
421  vec_dit=cpl_vector_new(nfr);
422  vec_adl=cpl_vector_new(nfr);
423  for(i=0;i<nfr;i++) {
424  frm=IRPLIB_FRAMESET_GET(son,i);
425  name=cpl_frame_get_filename(frm);
426  img=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
427  med_on=cpl_image_get_median(img);
428  avg_on=cpl_image_get_mean(img);
429  cpl_image_delete(img);
430 
431  frm=IRPLIB_FRAMESET_GET(sof,i);
432  name=cpl_frame_get_filename(frm);
433  img=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
434  med_of=cpl_image_get_median(img);
435  avg_of=cpl_image_get_mean(img);
436  cpl_image_delete(img);
437  med=med_on-med_of;
438  avg=avg_on-avg_of;
439  plist=cpl_propertylist_load(name,0);
440  dit=(double)irplib_pfits_get_dit(plist);
441  cpl_propertylist_delete(plist);
442  avg_dit=avg/dit;
443  med_dit=med/dit;
444 
445  cpl_vector_set(vec_dit,i,dit);
446  cpl_vector_set(vec_avg,i,avg);
447  cpl_vector_set(vec_med,i,med);
448  cpl_vector_set(vec_avg_dit,i,avg_dit);
449  cpl_vector_set(vec_med_dit,i,med_dit);
450 
451 
452  cpl_table_set_double(lin_tbl,"dit",i,dit);
453  cpl_table_set_double(lin_tbl,"med",i,med);
454  cpl_table_set_double(lin_tbl,"avg",i,avg);
455  cpl_table_set_double(lin_tbl,"med_dit",i,med_dit);
456  cpl_table_set_double(lin_tbl,"avg_dit",i,avg_dit);
457 
458  }
459  cpl_table_new_column(lin_tbl,"adl", CPL_TYPE_DOUBLE);
460  med_dit=cpl_vector_get_mean(vec_med_dit);
461  avg_dit=cpl_vector_get_mean(vec_avg_dit);
462 
463  for(i=0;i<nfr;i++) {
464  dit = cpl_table_get_double(lin_tbl,"dit",i,status);
465  cpl_vector_set(vec_adl,i,dit*med_dit);
466  cpl_table_set_double(lin_tbl,"adl",i,dit*med_dit);
467  }
468 
469 
470  cpl_vector_delete(vec_dit);
471  cpl_vector_delete(vec_adl);
472  cpl_vector_delete(vec_avg);
473  cpl_vector_delete(vec_med);
474  cpl_vector_delete(vec_avg_dit);
475  cpl_vector_delete(vec_med_dit);
476 
477 
478  return lin_tbl;
479 
480 }
481 
482 
483 /*----------------------------------------------------------------------------*/
492 /*----------------------------------------------------------------------------*/
494  cpl_imagelist * ilist,
495  const char * detlin_a,
496  const char * detlin_b,
497  const char * detlin_c)
498 {
499  cpl_image * ima ;
500  cpl_image * imb ;
501  cpl_image * imc ;
502  float * pima ;
503  float * pimb ;
504  float * pimc ;
505  float * pdata ;
506  int nx, ny, ni ;
507  double coeff_1, coeff_2, val ;
508  int i, j ;
509 
510  /* Test entries */
511  if (!ilist || !detlin_a || !detlin_b || !detlin_c) return -1 ;
512 
513  /* Load the 3 coeffs images */
514  ima = cpl_image_load(detlin_a, CPL_TYPE_FLOAT, 0, 0) ;
515  imb = cpl_image_load(detlin_b, CPL_TYPE_FLOAT, 0, 0) ;
516  imc = cpl_image_load(detlin_c, CPL_TYPE_FLOAT, 0, 0) ;
517  if (!ima || !imb || !imc) {
518  cpl_msg_error(cpl_func, "Cannot load the detlin images") ;
519  if (ima) cpl_image_delete(ima) ;
520  if (imb) cpl_image_delete(imb) ;
521  if (imc) cpl_image_delete(imc) ;
522  return -1 ;
523  }
524  pima = cpl_image_get_data_float(ima) ;
525  pimb = cpl_image_get_data_float(imb) ;
526  pimc = cpl_image_get_data_float(imc) ;
527 
528  /* Test sizes */
529  nx = cpl_image_get_size_x(cpl_imagelist_get(ilist, 0)) ;
530  ny = cpl_image_get_size_y(cpl_imagelist_get(ilist, 0)) ;
531  ni = cpl_imagelist_get_size(ilist) ;
532  if ((cpl_image_get_size_x(ima) != nx) ||
533  (cpl_image_get_size_x(imb) != nx) ||
534  (cpl_image_get_size_x(imc) != nx) ||
535  (cpl_image_get_size_y(ima) != ny) ||
536  (cpl_image_get_size_y(imb) != ny) ||
537  (cpl_image_get_size_y(imc) != ny)) {
538  cpl_msg_error(cpl_func, "Incompatible sizes") ;
539  cpl_image_delete(ima) ;
540  cpl_image_delete(imb) ;
541  cpl_image_delete(imc) ;
542  return -1 ;
543  }
544 
545  /* Loop on pixels */
546  for (i=0 ; i<nx*ny ; i++) {
547  /* Compute the coefficients */
548  if (fabs(pima[i]) < 1e-30) {
549  coeff_1 = coeff_2 = (double)0.0 ;
550  } else {
551  coeff_1 = (double)pimb[i] / (double)pima[i] ;
552  coeff_2 = (double)pimc[i] / (double)pima[i] ;
553  }
554  /* Correct this pixel in each plane */
555  for (j=0 ; j<ni ; j++) {
556  pdata = cpl_image_get_data_float(cpl_imagelist_get(ilist, j)) ;
557  val = (double)pdata[i] ;
558  pdata[i]=(float)(val+coeff_1*val*val+coeff_2*val*val*val) ;
559  }
560  }
561  /* Free and return */
562  cpl_image_delete(ima) ;
563  cpl_image_delete(imb) ;
564  cpl_image_delete(imc) ;
565  return 0 ;
566 }
567 
568 /*----------------------------------------------------------------------------*/
577 /*----------------------------------------------------------------------------*/
579  cpl_imagelist * ilist,
580  const char * flat,
581  const char * dark,
582  const char * bpm)
583 {
584  cpl_image * dark_image ;
585  cpl_image * flat_image ;
586  cpl_mask * bpm_im_bin ;
587  cpl_image * bpm_im_int ;
588  int i ;
589 
590  /* Test entries */
591  if (ilist == NULL) return -1 ;
592 
593  /* Dark correction */
594  if (dark != NULL) {
595  cpl_msg_info(cpl_func, "Subtract the dark to the images") ;
596  /* Load the dark image */
597  if ((dark_image = cpl_image_load(dark, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
598  cpl_msg_error(cpl_func, "Cannot load the dark %s", dark) ;
599  return -1 ;
600  }
601  /* Apply the dark correction to the images */
602  if (cpl_imagelist_subtract_image(ilist, dark_image)!=CPL_ERROR_NONE) {
603  cpl_msg_error(cpl_func, "Cannot apply the dark to the images") ;
604  cpl_image_delete(dark_image) ;
605  return -1 ;
606  }
607  cpl_image_delete(dark_image) ;
608  }
609 
610  /* Flat-field correction */
611  if (flat != NULL) {
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_msg_info(cpl_func, "Correct the bad pixels in the images") ;
630  /* Load the bad pixels image */
631  if ((bpm_im_int = cpl_image_load(bpm, CPL_TYPE_INT, 0, 0)) == NULL) {
632  cpl_msg_error(cpl_func, "Cannot load the bad pixel map %s", bpm) ;
633  return -1 ;
634  }
635  /* Convert the map from integer to binary */
636  bpm_im_bin = cpl_mask_threshold_image_create(bpm_im_int, -0.5, 0.5) ;
637  cpl_mask_not(bpm_im_bin) ;
638  cpl_image_delete(bpm_im_int) ;
639  /* Apply the bad pixels cleaning */
640  for (i=0 ; i<cpl_imagelist_get_size(ilist) ; i++) {
641  cpl_image_reject_from_mask(cpl_imagelist_get(ilist, i), bpm_im_bin);
642  if (cpl_detector_interpolate_rejected(
643  cpl_imagelist_get(ilist, i)) != CPL_ERROR_NONE) {
644  cpl_msg_error(cpl_func, "Cannot clean the bad pixels in obj %d",
645  i+1);
646  cpl_mask_delete(bpm_im_bin) ;
647  return -1 ;
648  }
649  }
650  cpl_mask_delete(bpm_im_bin) ;
651  }
652 
653  /* Return */
654  return 0 ;
655 }
656