CR2RE Pipeline Reference Manual 1.6.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 "irplib_calib.h"
37
38#include <math.h>
39
40/*-----------------------------------------------------------------------------
41 Static Function Prototypes
42 -----------------------------------------------------------------------------*/
43
44static int
45irplib_get_clean_mean_window(cpl_image* img,
46 const int llx,
47 const int lly,
48 const int urx, int ury,
49 const int kappa,
50 const int nclip,
51 double* clean_mean,
52 double* clean_stdev);
53
54static double irplib_pfits_get_dit(const cpl_propertylist * plist);
55static double irplib_pfits_get_exp_time(const cpl_propertylist* plist);
56/*----------------------------------------------------------------------------*/
60/*----------------------------------------------------------------------------*/
61
63/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73static double irplib_pfits_get_dit(const cpl_propertylist * plist)
74{
75 cpl_errorstate prestate = cpl_errorstate_get();
76 double dit = cpl_propertylist_get_double(plist, "ESO DET DIT");
77
78 if (!cpl_errorstate_is_equal(prestate)) {
79 /* Key not present (or with wrong type, or something) */
80 cpl_errorstate prestate2 = cpl_errorstate_get();
81
82 dit = cpl_propertylist_get_double(plist, "ESO DET SEQ1 DIT");
83
84 if (cpl_errorstate_is_equal(prestate2)) {
85 /* Key present (with expected type): recover */
86 cpl_errorstate_set(prestate);
87 } else {
88 cpl_error_set_where(cpl_func); /* Propagate error */
89 }
90 }
91
92 return dit;
93}
94
95/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104static double irplib_pfits_get_exp_time(const cpl_propertylist* plist)
105{
106
107 return cpl_propertylist_get_double(plist,"EXPTIME");
108
109}
110
111
127static int
128irplib_get_clean_mean_window(cpl_image* img,
129 const int llx,
130 const int lly,
131 const int urx, int ury,
132 const int kappa,
133 const int nclip,
134 double* clean_mean,
135 double* clean_stdev)
136{
137
138
139 double mean=0;
140 double stdev=0;
141 cpl_image* tmp=NULL;
142 cpl_stats* stats=NULL;
143 int i=0;
144
145 tmp=cpl_image_extract(img,llx,lly,urx,ury);
146 cpl_image_accept_all(tmp);
147 for(i=0;i<nclip;i++) {
148
149 double threshold=0;
150 double lo_cut=0;
151 double hi_cut=0;
152 cpl_mask* mask=NULL;
153
154 cpl_stats_delete(stats);
155 stats = cpl_stats_new_from_image(tmp, CPL_STATS_MEAN | CPL_STATS_STDEV);
156 mean = cpl_stats_get_mean(stats);
157 stdev = cpl_stats_get_stdev(stats);
158
159 threshold=kappa*stdev;
160 lo_cut=mean-threshold;
161 hi_cut=mean+threshold;
162
163 cpl_image_accept_all(tmp);
164 mask=cpl_mask_threshold_image_create(tmp,lo_cut,hi_cut);
165
166 cpl_mask_not(mask);
167 cpl_image_reject_from_mask(tmp,mask);
168 cpl_mask_delete(mask);
169
170
171 }
172 *clean_mean=mean;
173 *clean_stdev=stdev;
174 cpl_image_delete(tmp);
175 cpl_stats_delete(stats);
176
177 return 0;
178
179
180}
181
182
183
184/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201
202cpl_table*
204 cpl_frameset* son,
205 cpl_frameset* sof,
206 int* zone,
207 const int kappa,
208 const int nclip)
209{
210
211 cpl_frame* frm=NULL;
212
213 cpl_table* res_tbl=NULL;
214 cpl_vector* dit_on=NULL;
215 cpl_vector* dit_of=NULL;
216 cpl_vector* exptime_on=NULL;
217 cpl_vector* exptime_of=NULL;
218
219 int non=0;
220 int nof=0;
221 int nfr=0;
222 int llx;
223 int lly;
224 int urx;
225 int ury;
226
227 const char* name=NULL;
228 int i=0;
229
230 double dit_ref=0;
231 double exptime_ref=0;
232
233
234 non = cpl_frameset_get_size(son);
235 nof = cpl_frameset_get_size(sof);
236 nfr = (non <= nof) ? non : nof;
237
238 dit_on=cpl_vector_new(nfr);
239 dit_of=cpl_vector_new(nfr);
240 exptime_on=cpl_vector_new(nfr);
241 exptime_of=cpl_vector_new(nfr);
242
243 for(i=0;i<nfr;i++) {
244 cpl_propertylist* plist=NULL;
245
246 frm=cpl_frameset_get_position(son,i);
247 name=cpl_frame_get_filename(frm);
248 plist=cpl_propertylist_load(name,0);
249 dit_ref=irplib_pfits_get_dit(plist);
250 exptime_ref=(double)irplib_pfits_get_exp_time(plist);
251 cpl_propertylist_delete(plist);
252 cpl_vector_set(dit_on,i,dit_ref);
253 cpl_vector_set(exptime_on,i,exptime_ref);
254
255 frm=cpl_frameset_get_position(sof,i);
256 name=cpl_frame_get_filename(frm);
257 plist=cpl_propertylist_load(name,0);
258 dit_ref=irplib_pfits_get_dit(plist);
259 exptime_ref=(double)irplib_pfits_get_exp_time(plist);
260 cpl_propertylist_delete(plist);
261 cpl_vector_set(dit_of,i,dit_ref);
262 cpl_vector_set(exptime_of,i,exptime_ref);
263
264 }
265
266
267 llx=zone[0];
268 lly=zone[1];
269 urx=zone[2];
270 ury=zone[3];
271
272
273
274 res_tbl=cpl_table_new(nfr);
275 cpl_table_new_column(res_tbl,"adu", CPL_TYPE_DOUBLE);
276 cpl_table_new_column(res_tbl,"gain", CPL_TYPE_DOUBLE);
277
278 for(i=0;i<nfr;i++) {
279 cpl_image* img_on1=NULL;
280 cpl_image* img_of1=NULL;
281 int m=0;
282
283 frm=cpl_frameset_get_position(son,i);
284 name=cpl_frame_get_filename(frm);
285 img_on1=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
286
287 frm=cpl_frameset_get_position(sof,i);
288 name=cpl_frame_get_filename(frm);
289 img_of1=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
290
291
292 dit_ref=cpl_vector_get(dit_on,i);
293 exptime_ref=cpl_vector_get(exptime_on,i);
294
295
296 for(m=0;m<nfr; m++) {
297 if(m != i) {
298 double dit_tmp=0;
299 double exptime_tmp=0;
300
301 frm=cpl_frameset_get_position(son,m);
302 name=cpl_frame_get_filename(frm);
303 dit_tmp=cpl_vector_get(dit_on,m);
304 exptime_tmp=cpl_vector_get(exptime_on,m);
305 if(dit_tmp == dit_ref && exptime_tmp == exptime_ref) {
306 cpl_image* img_on2=NULL;
307 cpl_image* img_on_dif=NULL;
308
309 cpl_image* img_of2=NULL;
310 cpl_image* img_of_dif=NULL;
311
312 double avg_on1=0;
313 double avg_on2=0;
314 double avg_of1=0;
315 double avg_of2=0;
316 double avg_on_dif=0;
317 double avg_of_dif=0;
318 double std=0;
319 double sig_on_dif=0;
320 double sig_of_dif=0;
321 double gain=0;
322
323 img_on2=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
324 frm=cpl_frameset_get_position(sof,m);
325 name=cpl_frame_get_filename(frm);
326 img_of2=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
327
328 img_on_dif=cpl_image_subtract_create(img_on1,img_on2);
329 img_of_dif=cpl_image_subtract_create(img_of1,img_of2);
330
331 irplib_get_clean_mean_window(img_on1,llx,lly,urx,ury,kappa,
332 nclip,&avg_on1,&std);
333 irplib_get_clean_mean_window(img_on2,llx,lly,urx,ury,kappa,
334 nclip,&avg_on2,&std);
335 irplib_get_clean_mean_window(img_of1,llx,lly,urx,ury,kappa,
336 nclip,&avg_of1,&std);
337 irplib_get_clean_mean_window(img_of2,llx,lly,urx,ury,kappa,
338 nclip,&avg_of2,&std);
339 irplib_get_clean_mean_window(img_on_dif,llx,lly,urx,ury,kappa,
340 nclip,&avg_on_dif,&sig_on_dif);
341 irplib_get_clean_mean_window(img_of_dif,llx,lly,urx,ury,kappa,
342 nclip,&avg_of_dif,&sig_of_dif);
343
344 cpl_image_delete(img_on2);
345 cpl_image_delete(img_of2);
346 cpl_image_delete(img_on_dif);
347 cpl_image_delete(img_of_dif);
348
349 gain=((avg_on1+avg_on2)-(avg_of1+avg_of2))/
350 ((sig_on_dif*sig_on_dif)-(sig_of_dif*sig_of_dif));
351
352 cpl_table_set_double(res_tbl,"gain",m,gain);
353 cpl_table_set_double(res_tbl,"adu",m,
354 ((avg_on1+avg_on2)/2-(avg_of1+avg_of2)/2));
355
356 }
357 }
358 }
359 cpl_image_delete(img_on1);
360 cpl_image_delete(img_of1);
361 }
362
363
364 cpl_vector_delete(dit_on);
365 cpl_vector_delete(dit_of);
366 cpl_vector_delete(exptime_on);
367 cpl_vector_delete(exptime_of);
368
369 return res_tbl;
370
371}
372
373/* --------------------------------------------------------------------------*/
383/*---------------------------------------------------------------------------*/
384
385
386cpl_table* irplib_compute_linearity(cpl_frameset* son, cpl_frameset* sof)
387{
388
389 int non=0;
390 int nof=0;
391 int nfr=0;
392 int i=0;
393 double med_dit=0;
394 /*double avg_dit=0;*/
395
396 cpl_vector* vec_adl=NULL;
397 cpl_vector* vec_dit=NULL;
398 cpl_vector* vec_avg=NULL;
399 cpl_vector* vec_med=NULL;
400 cpl_vector* vec_avg_dit=NULL;
401 cpl_vector* vec_med_dit=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 cpl_frame* frm=NULL;
425
426 double med_on=0;
427 double avg_on=0;
428 double med_of=0;
429 double avg_of=0;
430
431 double med=0;
432 double avg=0;
433 double avg_dit=0;
434
435 const char* name=NULL;
436 cpl_image* img=NULL;
437 cpl_propertylist* plist=NULL;
438
439 frm=cpl_frameset_get_position(son,i);
440 name=cpl_frame_get_filename(frm);
441 img=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
442 med_on=cpl_image_get_median(img);
443 avg_on=cpl_image_get_mean(img);
444 cpl_image_delete(img);
445
446 frm=cpl_frameset_get_position(sof,i);
447 name=cpl_frame_get_filename(frm);
448 img=cpl_image_load(name,CPL_TYPE_FLOAT,0,0);
449 med_of=cpl_image_get_median(img);
450 avg_of=cpl_image_get_mean(img);
451 cpl_image_delete(img);
452 med=med_on-med_of;
453 avg=avg_on-avg_of;
454 plist=cpl_propertylist_load(name,0);
455 dit=(double)irplib_pfits_get_dit(plist);
456 cpl_propertylist_delete(plist);
457 avg_dit=avg/dit;
458 med_dit=med/dit;
459
460 cpl_vector_set(vec_dit,i,dit);
461 cpl_vector_set(vec_avg,i,avg);
462 cpl_vector_set(vec_med,i,med);
463 cpl_vector_set(vec_avg_dit,i,avg_dit);
464 cpl_vector_set(vec_med_dit,i,med_dit);
465
466
467 cpl_table_set_double(lin_tbl,"dit",i,dit);
468 cpl_table_set_double(lin_tbl,"med",i,med);
469 cpl_table_set_double(lin_tbl,"avg",i,avg);
470 cpl_table_set_double(lin_tbl,"med_dit",i,med_dit);
471 cpl_table_set_double(lin_tbl,"avg_dit",i,avg_dit);
472
473 }
474 cpl_table_new_column(lin_tbl,"adl", CPL_TYPE_DOUBLE);
475 med_dit=cpl_vector_get_mean(vec_med_dit);
476 /*avg_dit=cpl_vector_get_mean(vec_avg_dit);*/
477
478 for(i=0;i<nfr;i++) {
479 int* status=0;
480 dit = cpl_table_get_double(lin_tbl,"dit",i,status);
481 cpl_vector_set(vec_adl,i,dit*med_dit);
482 cpl_table_set_double(lin_tbl,"adl",i,dit*med_dit);
483 }
484
485
486 cpl_vector_delete(vec_dit);
487 cpl_vector_delete(vec_adl);
488 cpl_vector_delete(vec_avg);
489 cpl_vector_delete(vec_med);
490 cpl_vector_delete(vec_avg_dit);
491 cpl_vector_delete(vec_med_dit);
492
493
494 return lin_tbl;
495
496}
497
498
499/*----------------------------------------------------------------------------*/
508/*----------------------------------------------------------------------------*/
510 cpl_imagelist * ilist,
511 const char * detlin_a,
512 const char * detlin_b,
513 const char * detlin_c)
514{
515 cpl_image * ima ;
516 cpl_image * imb ;
517 cpl_image * imc ;
518 float * pima ;
519 float * pimb ;
520 float * pimc ;
521 float * pdata ;
522 int nx, ny, ni ;
523 double coeff_1, coeff_2, val ;
524 int i, j ;
525
526 /* Test entries */
527 if (!ilist || !detlin_a || !detlin_b || !detlin_c) return -1 ;
528
529 /* Load the 3 coeffs images */
530 ima = cpl_image_load(detlin_a, CPL_TYPE_FLOAT, 0, 0) ;
531 imb = cpl_image_load(detlin_b, CPL_TYPE_FLOAT, 0, 0) ;
532 imc = cpl_image_load(detlin_c, CPL_TYPE_FLOAT, 0, 0) ;
533 if (!ima || !imb || !imc) {
534 cpl_msg_error(cpl_func, "Cannot load the detlin images") ;
535 if (ima) cpl_image_delete(ima) ;
536 if (imb) cpl_image_delete(imb) ;
537 if (imc) cpl_image_delete(imc) ;
538 return -1 ;
539 }
540 pima = cpl_image_get_data_float(ima) ;
541 pimb = cpl_image_get_data_float(imb) ;
542 pimc = cpl_image_get_data_float(imc) ;
543
544 /* Test sizes */
545 nx = cpl_image_get_size_x(cpl_imagelist_get(ilist, 0)) ;
546 ny = cpl_image_get_size_y(cpl_imagelist_get(ilist, 0)) ;
547 ni = cpl_imagelist_get_size(ilist) ;
548 if ((cpl_image_get_size_x(ima) != nx) ||
549 (cpl_image_get_size_x(imb) != nx) ||
550 (cpl_image_get_size_x(imc) != nx) ||
551 (cpl_image_get_size_y(ima) != ny) ||
552 (cpl_image_get_size_y(imb) != ny) ||
553 (cpl_image_get_size_y(imc) != ny)) {
554 cpl_msg_error(cpl_func, "Incompatible sizes") ;
555 cpl_image_delete(ima) ;
556 cpl_image_delete(imb) ;
557 cpl_image_delete(imc) ;
558 return -1 ;
559 }
560
561 /* Loop on pixels */
562 for (i=0 ; i<nx*ny ; i++) {
563 /* Compute the coefficients */
564 if (fabs(pima[i]) < 1e-30) {
565 coeff_1 = coeff_2 = (double)0.0 ;
566 } else {
567 coeff_1 = (double)pimb[i] / (double)pima[i] ;
568 coeff_2 = (double)pimc[i] / (double)pima[i] ;
569 }
570 /* Correct this pixel in each plane */
571 for (j=0 ; j<ni ; j++) {
572 pdata = cpl_image_get_data_float(cpl_imagelist_get(ilist, j)) ;
573 val = (double)pdata[i] ;
574 pdata[i]=(float)(val+coeff_1*val*val+coeff_2*val*val*val) ;
575 }
576 }
577 /* Free and return */
578 cpl_image_delete(ima) ;
579 cpl_image_delete(imb) ;
580 cpl_image_delete(imc) ;
581 return 0 ;
582}
583
584/*----------------------------------------------------------------------------*/
593/*----------------------------------------------------------------------------*/
595 cpl_imagelist * ilist,
596 const char * flat,
597 const char * dark,
598 const char * bpm)
599{
600 /* Test entries */
601 if (ilist == NULL) return -1 ;
602
603 /* Dark correction */
604 if (dark != NULL) {
605 cpl_image * dark_image ;
606 cpl_msg_info(cpl_func, "Subtract the dark to the images") ;
607 /* Load the dark image */
608 if ((dark_image = cpl_image_load(dark, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
609 cpl_msg_error(cpl_func, "Cannot load the dark %s", dark) ;
610 return -1 ;
611 }
612 /* Apply the dark correction to the images */
613 if (cpl_imagelist_subtract_image(ilist, dark_image)!=CPL_ERROR_NONE) {
614 cpl_msg_error(cpl_func, "Cannot apply the dark to the images") ;
615 cpl_image_delete(dark_image) ;
616 return -1 ;
617 }
618 cpl_image_delete(dark_image) ;
619 }
620
621 /* Flat-field correction */
622 if (flat != NULL) {
623 cpl_image * flat_image ;
624 cpl_msg_info(cpl_func, "Divide the images by the flatfield") ;
625 /* Load the flat image */
626 if ((flat_image = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
627 cpl_msg_error(cpl_func, "Cannot load the flat field %s", flat) ;
628 return -1 ;
629 }
630 /* Apply the flatfield correction to the images */
631 if (cpl_imagelist_divide_image(ilist, flat_image)!=CPL_ERROR_NONE) {
632 cpl_msg_error(cpl_func, "Cannot apply the flatfield to the images") ;
633 cpl_image_delete(flat_image) ;
634 return -1 ;
635 }
636 cpl_image_delete(flat_image) ;
637 }
638
639 /* Correct the bad pixels if requested */
640 if (bpm != NULL) {
641 cpl_mask * bpm_im_bin ;
642 cpl_image * bpm_im_int ;
643 int i ;
644 cpl_msg_info(cpl_func, "Correct the bad pixels in the images") ;
645 /* Load the bad pixels image */
646 if ((bpm_im_int = cpl_image_load(bpm, CPL_TYPE_INT, 0, 0)) == NULL) {
647 cpl_msg_error(cpl_func, "Cannot load the bad pixel map %s", bpm) ;
648 return -1 ;
649 }
650 /* Convert the map from integer to binary */
651 bpm_im_bin = cpl_mask_threshold_image_create(bpm_im_int, -0.5, 0.5) ;
652 cpl_mask_not(bpm_im_bin) ;
653 cpl_image_delete(bpm_im_int) ;
654 /* Apply the bad pixels cleaning */
655 for (i=0 ; i<cpl_imagelist_get_size(ilist) ; i++) {
656 cpl_image_reject_from_mask(cpl_imagelist_get(ilist, i), bpm_im_bin);
657 if (cpl_detector_interpolate_rejected(
658 cpl_imagelist_get(ilist, i)) != CPL_ERROR_NONE) {
659 cpl_msg_error(cpl_func, "Cannot clean the bad pixels in obj %d",
660 i+1);
661 cpl_mask_delete(bpm_im_bin) ;
662 return -1 ;
663 }
664 }
665 cpl_mask_delete(bpm_im_bin) ;
666 }
667
668 /* Return */
669 return 0 ;
670}
671
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:203
cpl_table * irplib_compute_linearity(cpl_frameset *son, cpl_frameset *sof)
Computes the detector's linearity.
Definition: irplib_calib.c:386
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:594
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:509