X-shooter Pipeline Reference Manual 3.8.15
xsh_compute_linearity.c
Go to the documentation of this file.
1/* *
2 * This file is part of the ESO X-shooter Pipeline *
3 * Copyright (C) 2006 European Southern Observatory *
4 * *
5 * This library is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
18 * */
19
20/*
21 * $Author: amodigli $
22 * $Date: 2012-12-01 18:42:28 $
23 * $Revision: 1.50 $
24 * $Name: not supported by cvs2svn $
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30
31/*----------------------------------------------------------------------------*/
39/*----------------------------------------------------------------------------*/
42/*-----------------------------------------------------------------------------
43 Includes
44 -----------------------------------------------------------------------------*/
45
46#include <math.h>
47#include <xsh_drl.h>
48
49#include <xsh_badpixelmap.h>
50#include <xsh_data_pre.h>
51#include <xsh_dfs.h>
52#include <xsh_pfits.h>
53#include <xsh_error.h>
54#include <xsh_msg.h>
55#include <xsh_fit.h>
56
58
59#include <cpl.h>
60
61#define USE_CPL_POLYNOMIAL
62#define OPTIMIZE_IMAGE_HANDLING
63
64/*-----------------------------------------------------------------------------
65 Functions prototypes
66 -----------------------------------------------------------------------------*/
67
68/*-----------------------------------------------------------------------------
69 Implementation
70 -----------------------------------------------------------------------------*/
71
80static int
81orderCompare (const void *one, const void *two)
82{
83 TIME_FRAME *un = (TIME_FRAME *) one;
84 TIME_FRAME *deux = (TIME_FRAME *) two;
85
86 if (un->exptime <= deux->exptime)
87 return -1;
88 else
89 return 1;
90}
91
100static int
101onoffCompare (const void *one, const void *two)
102{
103 TIME_FRAME *un = (TIME_FRAME *) one;
104 TIME_FRAME *deux = (TIME_FRAME *) two;
105
106 if (un->on_off <= deux->on_off)
107 return 1;
108 else
109 return -1;
110}
111
120cpl_frameset * xsh_subtract_on_off( cpl_frameset *set,
122{
123 cpl_frame *currOn = NULL, *currOff = NULL;
124 cpl_frameset * subSet = NULL ;
125 int nframes, i ;
126 xsh_pre * subtracted = NULL ;
127 xsh_pre *preOn = NULL, * preOff = NULL ;
128
129 /*
130 Subtraction: 1-2, 3-4, ...
131 */
132 xsh_msg( "===> Subtract on_off" ) ;
133
134 nframes = cpl_frameset_get_size( set ) ;
135 subSet = cpl_frameset_new() ;
136 assure( subSet != NULL, cpl_error_get_code(),
137 "Cant create new frameset" ) ;
138
139 for( i = 0 ; i<nframes ; i+=2 ) {
140 const char *filename = NULL;
141 currOn = cpl_frameset_get_frame(set,i);
142 assure( currOn != NULL, cpl_error_get_code(),
143 "Cant get frame of frameset" ) ;
144 filename = cpl_frame_get_filename (currOn);
145 xsh_msg_dbg_low( " Subtracting ON : %s", filename ) ;
146 check_msg( preOn = xsh_pre_load( currOn, instrument ),
147 "Cant load PRE ON" ) ;
148
149 currOff = cpl_frameset_get_frame (set,i+1);
150 assure( currOff != NULL, cpl_error_get_code(),
151 "Cant get frame of frameset" ) ;
152 filename = cpl_frame_get_filename (currOff);
153 xsh_msg_dbg_low( " OFF: %s", filename ) ;
154 check_msg( preOff = xsh_pre_load( currOff, instrument ),
155 "Cant load PRE frame OFF" ) ;
156
157 /* Now substract images, save and add to frameset */
158 subtracted = xsh_pre_duplicate(preOn);
159 xsh_pre_subtract( subtracted, preOff ) ;
160 assure( subtracted != NULL, cpl_error_get_code(),
161 "Cant subtract images" ) ;
162 /* save subtracted */
163 {
164 cpl_frame * saved = NULL ;
165 char outname[128] ;
166 const char *tag = XSH_LINEARITY_NIR ;
167
168 sprintf( outname, "linear_sub_set_%d.fits", i ) ;
169 saved = xsh_pre_save( subtracted, outname, tag,1 ) ;
170 assure( saved != NULL, cpl_error_get_code(),
171 "Cant save subtracted frame" ) ;
172 /* Add a valid TAG (missing in the function xsh_pre_save) */
173 check_msg( cpl_frame_set_tag( saved, tag ),
174 "Cant set frame tag" ) ;
175 /* insert into frameset */
176 check_msg( cpl_frameset_insert( subSet, saved ),
177 "Cant insert frame %d into subSet", i ) ;
178 }
179 /* Cleanup memory */
180 xsh_pre_free( &preOn ) ;
181 xsh_pre_free( &preOff ) ;
182 xsh_pre_free( &subtracted ) ;
183 }
184
185 cleanup:
186 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
187 xsh_free_frameset( &subSet ) ;
188 subSet = NULL ;
189 }
190 xsh_pre_free( &preOn ) ;
191 xsh_pre_free( &preOff ) ;
192 xsh_pre_free( &subtracted ) ;
193 return subSet ;
194}
195
209int
211 double exp_toler, cpl_frameset ** groupSet)
212{
213 /* for all frames in the frame set, get the EXPTIME or DIT (if NIR)
214 group by same EXPTIME (or DIT if NIR) (+- exp_toler)
215 and by ON/OFF flags (if NIR)
216 returns the number of groups and the list of framesets
217 */
218 int i, ngroups = 0;
219 int nframes = 0;
220 TIME_FRAME *expOrdered = NULL;
221 TIME_FRAME *porder = NULL;
222 cpl_frame *current = NULL;
223 double temps = 0.0;
224 int onoff = 0;
225 cpl_frameset **pgrpset = NULL;
226
227 nframes = cpl_frameset_get_size (raws);
228 xsh_msg( "Nb of Frames = %d", nframes ) ;
229
230 expOrdered = cpl_malloc (nframes * sizeof (TIME_FRAME));
231 assure (expOrdered != NULL, cpl_error_get_code (),
232 "Cant create tempory time+fframe array");
233
234 porder = expOrdered;
235
236 for ( i = 0 ; i<nframes ; i++, porder++) {
237 const char *filename;
238 cpl_propertylist *header;
239 current = NULL ;
240
241 current = cpl_frameset_get_frame (raws,i);
242
243 assure( current != NULL, CPL_ERROR_ILLEGAL_INPUT,
244 "Cant get Frame #%d from frameset", i ) ;
245 /* Load propertylist of current frame */
246 filename = cpl_frame_get_filename (current);
247 xsh_msg_dbg_low ("load propertylist file %s\n", filename);
248 check_msg (header = cpl_propertylist_load (filename, 0),
249 "Could not load header of file '%s'", filename);
250
251 /* Get EXPTIME (or DIT in case of NIR) and store */
252 if ( instrument->arm == XSH_ARM_NIR )
253 porder->exptime = xsh_pfits_get_dit (header);
254 else porder->exptime = xsh_pfits_get_exptime( header ) ;
255
256 porder->frame = current;
257 if ( instrument->arm == XSH_ARM_NIR ) {
258 bool onoffs = false;
259 check(onoffs = xsh_pfits_get_lamp_on_off( header )) ;
260 if ( onoffs ) porder->on_off = 1;
261 else porder->on_off = 0 ;
262 }
263 xsh_msg_dbg_low ("Exptime[%d] = %lf", i, porder->exptime);
264 xsh_free_propertylist( &header ) ;
265 }
266
267 /* Order the array by increasing EXPTIME/DIT */
268 xsh_msg_dbg_low ("==== Before qsort");
269 qsort (expOrdered, nframes, sizeof (TIME_FRAME), orderCompare);
270
271 /* In addition, if NIR, separate ON and OFF frames */
272 {
273 TIME_FRAME *first = expOrdered;
274 //TIME_FRAME *last ;
275 int nb = 0 ;
276
277 temps = expOrdered->exptime ;
278
279 for (i = 0, porder = expOrdered; i < nframes; i++, porder++) {
280 if ( porder->exptime == temps ) {
281 //last = porder ;
282 nb++ ;
283 }
284 else {
285 xsh_msg_dbg_low( "Call ON/OFF compare (%d frames)", nb ) ;
286 qsort( first, nb, sizeof (TIME_FRAME), onoffCompare ) ;
287 first = porder ;
288 nb = 1 ;
289 temps = porder->exptime ;
290 }
291 }
292 /* Do the last group */
293 qsort( first, nb, sizeof (TIME_FRAME), onoffCompare ) ;
294 }
295
296 /* if ( cpl_msg_get_level() == CPL_MSG_DEBUG ) */ {
297 xsh_msg_dbg_low ("==== After qsort");
298 for (i = 0, porder = expOrdered; i < nframes; i++, porder++)
299 xsh_msg_dbg_low(" DIT[%d] = %lf (ON/OFF = %d)", i, porder->exptime,
300 porder->on_off);
301 }
302
303 /* Now create groups */
304 porder = expOrdered;
305 temps = porder->exptime;
306 onoff = porder->on_off ;
307
308 pgrpset = groupSet;
309
310 xsh_msg_dbg_low ("New frameset 0 starting at Frame 0" );
311 *pgrpset = cpl_frameset_new ();
312 check_msg (cpl_frameset_insert (*pgrpset, porder->frame),
313 "Cant insert frame %d in group %d", i, ngroups);
314 porder++;
315 ngroups = 1;
316 for (i = 1; i < nframes; i++, porder++) {
317 if (fabs (porder->exptime - temps) > exp_toler ||
318 porder->on_off != onoff ) {
319 xsh_msg_dbg_low ("New frameset %d starting at Frame %d", ngroups, i);
320 ngroups++;
321 temps = porder->exptime;
322 onoff = porder->on_off ;
323 pgrpset++;
324 *pgrpset = cpl_frameset_new ();
325 assure( *pgrpset != NULL, cpl_error_get_code(),
326 "Cant create new framest" ) ;
327 }
328 else
329 xsh_msg_dbg_low ("Same group frame %d - %lf vs %lf", i,
330 porder->exptime, temps);
331 xsh_msg_dbg_low ("Add frame %d to frameset group %d", i, ngroups);
332 check_msg (cpl_frameset_insert (*pgrpset, porder->frame),
333 "Cant insert frame %d in group %d", i, ngroups);
334 }
335
336 cleanup:
337 if ( expOrdered != NULL ) cpl_free( expOrdered ) ;
338 return ngroups;
339}
340
341#if !defined(USE_CPL_POLYNOMIAL)
342
359static cpl_imagelist *xsh_imagelist_fit_polynomial( cpl_imagelist * medlist,
360 double *dit, int nframes,
361 int nx, int ny,
362 int degree )
363{
364 int ll, ix, iy ;
365 cpl_vector * pixvect = NULL;
366 cpl_vector * temps = NULL;
367 cpl_polynomial *poly = NULL;
368 cpl_imagelist *poly_list = NULL,
370 *final_list = NULL ;
371 float **pixbuf = NULL ;
372 cpl_binary **maskbuf = NULL ;
374 assure( medlist != NULL, CPL_ERROR_NULL_INPUT,
375 "Input list of median images is NUL !" ) ;
376
377 poly_list = cpl_imagelist_new() ;
378 assure( poly_list != NULL, cpl_error_get_code(),
379 "Cant create imagelist" ) ;
380 /*
381 Create the "data cube" (image list) to store the polynomial coefficients
382 */
383 for ( ll = 0 ; ll<= degree ; ll++ ) {
384 cpl_image *newone = NULL ;
385
386 newone = cpl_image_new( nx, ny, CPL_TYPE_DOUBLE ) ;
387 assure( newone != NULL, cpl_error_get_code(),
388 "Cant create new image" ) ;
389 cpl_imagelist_set( poly_list, newone, ll ) ;
390 }
391
392 /*
393 Loop over pixels.
394 Populate a data vector with the content of same pixel of all
395 the images
396 Fit polynomial
397 Populate the resulting imagelist with the polynome coefficients
398 */
399 xsh_msg( "Polynomial Fit - XSH version - nb of frames: %d", nframes ) ;
400#if 1
401 /*
402 For better efficiency, one could/should use the pointer to pixel data
403 in the image instead of using cpl_image_get function.
404 Use cpl_image_get_data (input frames are PRE format ==> Float data)
405 */
406
407 pixbuf = cpl_malloc( nframes * sizeof(double *) ) ;
408 assure( pixbuf != NULL, cpl_error_get_code(),
409 "Cant allocate memory for pixel data" ) ;
410 maskbuf = cpl_malloc( nframes * sizeof(cpl_binary *) ) ;
411 assure( maskbuf != NULL, cpl_error_get_code(),
412 "Cant allocate memory for BPM data" ) ;
413 /* Creating list of data and masks */
414 for( ll = 0 ; ll < nframes ; ll++ ) {
415 cpl_image *pcur = cpl_imagelist_get( medlist, ll ) ;
416
417 *(pixbuf+ll) = cpl_image_get_data( pcur ) ;
418 *(maskbuf+ll) = cpl_mask_get_data( cpl_image_get_bpm( pcur ) ) ;
419 }
420
421 /* Loop over pixels */
422 for ( iy = 0 ; iy < ny ; iy++ )
423 for( ix = 0 ; ix < nx ; ix++ ) {
424 cpl_binary ** pmask = maskbuf ;
425 float ** cur = pixbuf ;
426 int npix = 0 ;
427
428 pixvect = cpl_vector_new( nframes ) ;
429 assure( pixvect != NULL, cpl_error_get_code(),
430 "Cant create PixVect Vector" ) ;
431 temps = cpl_vector_new( nframes ) ;
432 assure( temps != NULL, cpl_error_get_code(),
433 "Cant create Time Vector" ) ;
434 xsh_msg_dbg_low( "++ Fit one pixel: %d,%d", ix, iy ) ;
435
436 for( ll = 0 ; ll<nframes ; ll++ , pmask++, cur++ ) {
437 double pixval ;
438 cpl_binary rej ;
439 float *pcur = *cur ;
440 cpl_binary *mask = *pmask ;
441
442 pixval = *(pcur + (iy*nx) + ix ) ;
443 rej = *(mask + (iy*nx) + ix ) ;
444 if ( rej == 0 ) {
445 cpl_vector_set( temps, ll, *(dit+ll) ) ;
446 cpl_vector_set( pixvect, ll, pixval ) ;
447 npix++ ;
448 }
449 }
450 xsh_msg_dbg_low( " Nb of pixels: %d", npix ) ;
451 /* Adjust the size of the vector to npix */
452 if ( npix != nframes ) {
453 cpl_vector_set_size( temps, npix ) ;
454 cpl_vector_set_size( pixvect, npix ) ;
455 }
456 /* Now fit */
457 poly = xsh_polynomial_fit_1d_create( temps, pixvect,
458 degree, NULL ) ;
459 xsh_free_vector( &temps ) ;
460 xsh_free_vector( &pixvect ) ;
461 assure( poly != NULL, CPL_ERROR_ILLEGAL_INPUT,
462 "Error calling xsh_polynomial_fit_1d_create" ) ;
463 /* And fill the resulting coefficients frames */
464 for( ll = 0 ; ll <= degree ; ll++ ) {
465 cpl_image_set( cpl_imagelist_get( poly_list, ll ),
466 ix+1, iy+1, cpl_polynomial_get_coeff( poly, &ll ) ) ;
467 }
468 xsh_free_polynomial( &poly ) ;
469 }
470#else
471 for ( iy = 1 ; iy <= ny ; iy++ )
472 for( ix = 1 ; ix <= nx ; ix++ ) {
473 int npix = 0 ;
474
475 pixvect = cpl_vector_new( nframes ) ;
476 assure( pixvect != NULL, cpl_error_get_code(),
477 "Cant create PixVect Vector" ) ;
478 temps = cpl_vector_new( nframes ) ;
479 assure( temps != NULL, cpl_error_get_code(),
480 "Cant create Time Vector" ) ;
481 xsh_msg_dbg_low( "++ Fit one pixel: %d,%d", ix, iy ) ;
482 for( ll = 0 ; ll < nframes ; ll++ ) {
483 double pixval ;
484 int rej ;
485 cpl_image *cur = NULL ;
486 cur = cpl_imagelist_get( medlist, ll ) ;
487 assure( cur != NULL, cpl_error_get_code(),
488 "Cant get image #%d from liste" ) ;
489 /* Add pixel value to vector */
490 pixval = cpl_image_get( cur, ix, iy, &rej ) ;
491 xsh_msg_dbg_low( " Pixval: %lf", pixval ) ;
492 if ( rej == 0 ) {
493 cpl_vector_set( temps, ll, *(dit+ll) ) ;
494 cpl_vector_set( pixvect, ll, pixval ) ;
495 npix++ ;
496 }
497 }
498 xsh_msg_dbg_low( " Nb of pixels: %d", npix ) ;
499 /* Adjust the size of the vector to npix */
500 if ( npix != nframes ) {
501 cpl_vector_set_size( temps, npix ) ;
502 cpl_vector_set_size( pixvect, npix ) ;
503 }
504 /* Now fit */
505 poly = xsh_polynomial_fit_1d_create( temps, pixvect,
506 degree, NULL ) ;
507 assure( poly != NULL, cpl_error_get_code(),
508 "Error calling xsh_polynomial_fit_1d_create" ) ;
509 xsh_free_vector( &temps ) ;
510 xsh_free_vector( &pixvect ) ;
511 /* And fill the resulting coefficients frames */
512 //xsh_msg( " Pixel %d,%d:", ix, iy ) ;
513 for( ll = 0 ; ll <= degree ; ll++ ) {
514 cpl_image_set( cpl_imagelist_get( poly_list, ll ),
515 ix, iy, cpl_polynomial_get_coeff( poly, &ll ) ) ;
516 }
517 xsh_free_polynomial( &poly ) ;
518 }
519#endif
520
521 final_list = cpl_imagelist_duplicate( poly_list ) ;
522
523 cleanup:
524 xsh_free_imagelist( &poly_list ) ;
525 xsh_free_polynomial( &poly ) ;
526 xsh_free_vector( &temps ) ;
527 xsh_free_vector( &pixvect ) ;
528 xsh_free_imagelist( &poly_list ) ;
529 cpl_free( pixbuf ) ;
530 cpl_free( maskbuf ) ;
531
532 return final_list ;
533}
534#endif
535
546cpl_frame *
548 xsh_clipping_param * lin_clipping,const int decode_bp)
549{
550 cpl_image * resBpmap = NULL ;
551 int nframes = 0 ;
552 cpl_frame * resFrame = NULL ;
553 int i = 0, ix = 0, iy = 0, nx = 0, ny = 0;
554 int nbad, totbad = 0 ;
555 cpl_imagelist *medList = NULL ;
556 cpl_imagelist *bpmapList = NULL ;
557 cpl_frame *current = NULL ;
558 cpl_propertylist *bpmap_header = NULL ;
560 double *Dit = NULL;
561#if defined(USE_CPL_POLYNOMIAL)
562 cpl_vector * v_dit = NULL ;
563 // cpl_image * img_err = NULL ;
564#endif
565 cpl_imagelist * polyList = NULL ;
568 xsh_msg( "==> xsh_compute_linearity" ) ;
569 assure (medSet != NULL, CPL_ERROR_ILLEGAL_INPUT, "Frameset is NULL");
570 nframes = cpl_frameset_get_size (medSet);
571
572
573 /* Create an imagelist from the medSet frameset
574 Create the imagelist of bad pixel maps (to build the general one)
575 */
576 medList = cpl_imagelist_new() ;
577 assure( medList != NULL, cpl_error_get_code(),
578 "Cant create medList" ) ;
579 bpmapList = cpl_imagelist_new() ;
580 assure( bpmapList != NULL, cpl_error_get_code(),
581 "Cant create bpmapList" ) ;
582
583 current = cpl_frameset_get_frame( medSet,0 ) ;
584 assure( current != NULL, cpl_error_get_code(),
585 "Cant get current frame" ) ;
586
587 /* get the Detector Integration Time */
588 Dit = cpl_malloc( nframes * sizeof(double) ) ;
589 assure( Dit != NULL, cpl_error_get_code(),
590 "Cant allocate Dit array" ) ;
591#if defined(USE_CPL_POLYNOMIAL)
592 v_dit = cpl_vector_wrap( nframes, Dit ) ;
593 assure( v_dit != NULL, cpl_error_get_code(),
594 "Cant create v_dit vector" ) ;
595#endif
596 xsh_msg( "Loop over all frames" ) ;
597
598 for( i = 0 ; i<nframes ; i++ ) {
599 const char *filename ;
600 cpl_propertylist *header = NULL ;
601 cpl_image * curimage = NULL ;
602 cpl_image *curbpmap = NULL ;
603
604 filename = cpl_frame_get_filename(current);
605 assure( filename != NULL, cpl_error_get_code(),
606 "Cant get filename from frame %d", i ) ;
607
608 curimage = cpl_image_load( filename, XSH_PRE_DATA_TYPE, 0, 0 ) ;
609 assure( curimage != NULL, cpl_error_get_code(),
610 "Cant get curimage from frame %d", i ) ;
611
612 cpl_imagelist_set( medList, curimage, i ) ;
613 header = cpl_propertylist_load( filename, 0 ) ;
614 assure( header != NULL, cpl_error_get_code(),
615 "Cant get header of frame %d", i ) ;
616
617 xsh_msg_dbg_low( " Getting EXPTIME/DIT[%d]", i ) ;
618 /* Get EXPTIME (or DIT in case of NIR) and store */
619 if ( instrument->arm == XSH_ARM_NIR )
620 *(Dit+i) = xsh_pfits_get_dit( header ) ;
621 else *(Dit+i) = xsh_pfits_get_exptime( header ) ;
622 cpl_propertylist_delete( header ) ;
623
624 if ( i == 0 ) {
625 nx = cpl_image_get_size_x( curimage ) ;
626 ny = cpl_image_get_size_y( curimage ) ;
627 }
628
629 /* Now get the bad pixel map from this frame (extension Nb 2) */
630 xsh_msg_dbg_low( " Loading BpMap[%d]", i ) ;
631
632 curbpmap = cpl_image_load( filename, CPL_TYPE_INT, 0, 2 ) ;
633 assure( curbpmap != NULL, cpl_error_get_code(),
634 "Cant load bpmap frame #%d", i ) ;
635 cpl_imagelist_set( bpmapList, curbpmap, i ) ;
636 if ( i == 0 ) {
637 bpmap_header = cpl_propertylist_load( filename, 2 ) ;
638 assure( bpmap_header != NULL, cpl_error_get_code(),
639 "Cant get bpmap header of frame %d", i ) ;
640 }
641 current = cpl_frameset_get_frame( medSet,i+1 ) ;
642 xsh_msg_dbg_low( "-- Next Frame" ) ;
643 }
644
645 /* Collapse all bad pixel maps from the frameset into a single one */
646 xsh_msg( "Collapsing BpMaps's" ) ;
647
648 resBpmap = xsh_bpmap_collapse_bpmap_create ( bpmapList,decode_bp ) ;
649 assure( resBpmap != NULL, cpl_error_get_code(),
650 "Cant create collapsed bpmap" ) ;
651 /* memory cleanup */
652 xsh_msg_dbg_low( "Freeing bpmapList" ) ;
653 xsh_free_imagelist( &bpmapList ) ;
654
655 /* Insert bad pixels into the images of the list before fitting */
656 for( i = 0 ; i<nframes ; i++ ) {
657 xsh_set_image_cpl_bpmap ( cpl_imagelist_get( medList, i ),
658 resBpmap, decode_bp ) ;
659 }
660
661#if defined(USE_CPL_POLYNOMIAL)
662 /* CPL imagelist Polynomial fit */
663 xsh_msg( "Now fit polynomial - CPL version" ) ;
664
665 /* Use the function provided by J.Larsen (not the "real" CPL one) */
666 polyList = xsh_fit_imagelist_polynomial( v_dit, medList, 0,
668 CPL_FALSE, NULL ) ;
669 // polyList = cpl_imagelist_fit_polynomial( medList, Dit,
670 // LINEAR_POLYNOMIAL_DEGREE ) ;
671 assure( polyList != NULL, cpl_error_get_code(),
672 "Cant fit polynomial - CPL version" ) ;
673 xsh_msg( "Polynomial Fit Finished - CPL Version" ) ;
674#else
675 /*
676 The cpl function cpl_imagelist_fit_polynomial does not work
677 as expected. Hence we have to create our own fit function,
678 based on the CPL function xsh_polynomial_fit_1d_create
679 */
680 xsh_msg( "Now fit polynomial - XSH version" ) ;
681 polyList = xsh_imagelist_fit_polynomial( medList, Dit, nframes, nx, ny,
683 assure( polyList != NULL, cpl_error_get_code(),
684 "Cant fit polynomial - XSH version" ) ;
685 xsh_msg( "Polynomial Fit Finished - XSH Version" ) ;
686#endif
687 /* The cpl bad pixels of polyList are not set according to the bad pixels
688 of the input image list ==> do it now
689 */
690 for( i = 0 ; i<=LINEAR_POLYNOMIAL_DEGREE ; i++ ) {
691 check(xsh_set_image_cpl_bpmap ( cpl_imagelist_get( polyList, i ),
692 resBpmap, decode_bp )) ;
693 }
694
695 /* Check linearity per pixel */
696 xsh_msg_dbg_low( "Clipping sigma: %f", lin_clipping->sigma ) ;
697
698 for( i=0; i <= LINEAR_POLYNOMIAL_DEGREE ; i++ ) {
699 /* Check linearity for each polynome parameter */
700 cpl_image *pplane = NULL ;
701 int iter = 0 ;
702 double mean = 0.0, stdev = 0.0, med = 0.0;
703
704 pplane = cpl_imagelist_get( polyList, i ) ;
705 assure( pplane != NULL, cpl_error_get_code(),
706 "Gant get plane Nb %d", i ) ;
707 /* Iteration:
708 Calculate average and sigma (taking into account bad pixels)
709 mark bad pixels (bad pixel map is empty for the 1st iteration)
710 */
711
712 xsh_msg( "Sigma clipping on coefficient %d", i ) ;
713 for( iter = 0 ; iter<lin_clipping->niter ; iter++ ) {
714#if defined(OPTIMIZE_IMAGE_HANDLING)
715 double *pdata = NULL ;
716 cpl_binary *pbpm = NULL ;
717#endif
718 xsh_msg( " Iteration Nb %d/%d", iter+1, lin_clipping->niter ) ;
719 /* Calculate mean and stdev of current parameter image pplane */
720 mean = cpl_image_get_mean( pplane ) ;
721 stdev = cpl_image_get_stdev( pplane ) ;
722 med = cpl_image_get_median( pplane ) ;
723 xsh_msg( " Mean: %lf, stdev: %lf, Median: %lf",
724 mean, stdev, med ) ;
725 /* Loop over good pixels
726 compare current pplane value with sigma*lin_clipping->sigma
727 Mark bad pixels
728 */
729 nbad = 0 ;
730#if defined(OPTIMIZE_IMAGE_HANDLING)
731 pdata = cpl_image_get_data_double( pplane ) ;
732 assure( pdata != NULL, cpl_error_get_code(),
733 "Cant get pplane[%d] data", i ) ;
734 pbpm = cpl_mask_get_data( cpl_image_get_bpm( pplane ) ) ;
735 assure( pdata != NULL, cpl_error_get_code(),
736 "Cant get pplane[%d] bpm", i ) ;
737
738 for( iy = 0; iy < ny ; iy++ )
739 for( ix = 0 ; ix < nx ; ix++ ) {
740 double coeff = *(pdata + ix + (iy*nx)) ;
741 cpl_binary rej = *(pbpm + ix + (iy*nx)) ;
742 if ( rej != 0 ) {
743 xsh_msg_dbg_low( " **** rejected %d,%d", ix+1, iy+1 ) ;
744 continue ;
745 }
746#else
747 for( iy = 1 ; iy <= ny ; iy++ )
748 for( ix = 1 ; ix<=nx ; ix++ ) {
749 int rej ;
750 double coeff = cpl_image_get( pplane, ix, iy, &rej ) ;
751 if ( rej != 0 ) {
752 xsh_msg_dbg_low( " **** rejected %d,%d", ix, iy ) ;
753 continue ;
754 }
755#endif
756 //xsh_msg( " **** %d,%d -> %lf", ix, iy, coeff ) ;
757 if ( fabs( coeff - mean) > stdev*lin_clipping->sigma ) {
758 xsh_msg_dbg_low( " BAD PIXEL at %d,%d - %lf vs %lf",
759 ix, iy, mean, coeff ) ;
760 /* add bad pixel to this pseudo image for next iteration*/
761#if defined(OPTIMIZE_IMAGE_HANDLING)
762 cpl_image_reject( pplane, ix+1, iy+1 ) ;
763 /* add to the global bad pixel map */
764 xsh_bpmap_set_bad_pixel( resBpmap, ix+1, iy+1,
766#else
767 cpl_image_reject( pplane, ix, iy ) ;
768 /* add to the global bad pixel map */
769 xsh_bpmap_set_bad_pixel( resBpmap, ix, iy,
771#endif
772 nbad++ ;
773 }
774 }
775 xsh_msg( " Nbad: %d", nbad ) ;
776 if ( nbad == 0 ) break ; // stop iteration if no bad detected
777 totbad += nbad ;
778 }
779 /* Now add mean, rms and med of each coefficient to bpmap header */
780 xsh_pfits_set_qc_multi( bpmap_header, (void *)&mean,
782 xsh_msg_dbg_low( "%s (%d) = %lf", XSH_QC_BP_MAP_LINi_MEAN, i, mean ) ;
783 xsh_pfits_set_qc_multi( bpmap_header, (void *)&med,
785 xsh_msg_dbg_low( "%s (%d) = %lf", XSH_QC_BP_MAP_LINi_MED, i, med ) ;
786 xsh_pfits_set_qc_multi( bpmap_header, (void *)&stdev,
788 xsh_msg_dbg_low( "%s (%d) = %lf", XSH_QC_BP_MAP_LINi_RMS, i, stdev ) ;
789 }
790 xsh_msg( "====> Total Non linear pixels: %d", totbad ) ;
791 /* Add the total nb of bad pixels to the bpmap header */
792 {
793 int nbadpix = cpl_image_count_rejected( resBpmap ) ;
794 xsh_pfits_set_qc( bpmap_header, (void *)&nbadpix,
796 xsh_msg_dbg_low( "%s = %d", XSH_QC_BP_MAP_NBADPIX, nbadpix ) ;
797 }
798
799
800 /* Finished */
801 /* Save bpmap image file */
802 {
803 char bpmapFname[132] ;
804 const char *sarm = xsh_instrument_arm_tostring( instrument ) ;
805
806 sprintf( bpmapFname, "LINEARITY_BAD_PIXEL_MAP_%s.fits", sarm ) ;
807 check_msg( cpl_image_save( resBpmap, bpmapFname, CPL_BPP_32_SIGNED,
808 bpmap_header, CPL_IO_DEFAULT ),
809 "Cant save resulting BpMap image" ) ;
810 //xsh_add_temporary_file(bpmapFname);
811
812 /* insert bpmap into resFrame */
813
814 check(resFrame=xsh_frame_product(bpmapFname,
816 instrument),
817 CPL_FRAME_TYPE_IMAGE,
818 CPL_FRAME_GROUP_PRODUCT,
819 CPL_FRAME_LEVEL_FINAL));
820
821 }
822
823 cleanup:
824 if ( Dit != NULL ) cpl_free( Dit ) ;
825 xsh_free_imagelist( &polyList ) ;
826 xsh_free_imagelist( &bpmapList ) ;
827 xsh_free_imagelist( &medList ) ;
828 xsh_free_propertylist( &bpmap_header ) ;
829 xsh_free_image( &resBpmap ) ;
830
831 return resFrame ;
832
833}
834
835/*----------------------------------------------------------------------------*/
836
static int degree
static xsh_instrument * instrument
cpl_image * xsh_bpmap_collapse_bpmap_create(cpl_imagelist *liste, const int decode_bp)
void xsh_bpmap_set_bad_pixel(cpl_image *bpmap, int ix, int iy, int flag)
void xsh_set_image_cpl_bpmap(cpl_image *image, cpl_image *bpmap, const int decode_bp)
static int onoffCompare(const void *one, const void *two)
cpl_frame * xsh_compute_linearity(cpl_frameset *medSet, xsh_instrument *instrument, xsh_clipping_param *lin_clipping, const int decode_bp)
int xsh_linear_group_by_exptime(cpl_frameset *raws, xsh_instrument *instrument, double exp_toler, cpl_frameset **groupSet)
static int orderCompare(const void *one, const void *two)
cpl_frameset * xsh_subtract_on_off(cpl_frameset *set, xsh_instrument *instrument)
xsh_pre * xsh_pre_duplicate(const xsh_pre *pre)
Copy a PRE structure.
Definition: xsh_data_pre.c:953
xsh_pre * xsh_pre_load(cpl_frame *frame, xsh_instrument *instr)
Load a xsh_pre structure from a frame.
Definition: xsh_data_pre.c:849
void xsh_pre_free(xsh_pre **pre)
Free a xsh_pre structure.
Definition: xsh_data_pre.c:823
void xsh_pre_subtract(xsh_pre *self, const xsh_pre *right)
Subtract one PRE image from another The data units are subtracted data = data1 - data2 The error imag...
cpl_frame * xsh_pre_save(const xsh_pre *pre, const char *filename, const char *tag, int temp)
Save PRE on disk.
#define assure(CONDITION, ERROR_CODE,...)
Definition: xsh_error.h:54
#define check(COMMAND)
Definition: xsh_error.h:71
#define check_msg(COMMAND,...)
Definition: xsh_error.h:62
cpl_imagelist * xsh_fit_imagelist_polynomial(const cpl_vector *x_pos, const cpl_imagelist *values, int mindeg, int maxdeg, cpl_boolean is_eqdist, cpl_image *fiterror)
Fit a polynomial to each pixel in a list of images.
Definition: xsh_fit.c:171
const char * xsh_instrument_arm_tostring(xsh_instrument *i)
Get the string associated with an arm.
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
#define xsh_msg_dbg_low(...)
Definition: xsh_msg.h:48
bool xsh_pfits_get_lamp_on_off(const cpl_propertylist *plist)
find out the Lamp status (ON/OFF)
Definition: xsh_pfits.c:1607
double xsh_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: xsh_pfits.c:1405
double xsh_pfits_get_exptime(const cpl_propertylist *plist)
find out the exposure time
Definition: xsh_pfits.c:2254
void xsh_pfits_set_qc_multi(cpl_propertylist *plist, void *value, const char *kw, xsh_instrument *instrument, int idx)
void xsh_pfits_set_qc(cpl_propertylist *plist, void *value, const char *kw, xsh_instrument *instrument)
void xsh_free_polynomial(cpl_polynomial **p)
Deallocate a polynomial and set the pointer to NULL.
Definition: xsh_utils.c:2194
void xsh_free_vector(cpl_vector **v)
Deallocate a vector and set the pointer to NULL.
Definition: xsh_utils.c:2284
void xsh_free_image(cpl_image **i)
Deallocate an image and set the pointer to NULL.
Definition: xsh_utils.c:2116
void xsh_free_frameset(cpl_frameset **f)
Deallocate a frame set and set the pointer to NULL.
Definition: xsh_utils.c:2254
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
Definition: xsh_utils.c:2179
void xsh_free_imagelist(cpl_imagelist **i)
Deallocate an image list and set the pointer to NULL.
Definition: xsh_utils.c:2164
unsigned int first
Definition: irplib_error.c:88
cpl_frame * frame
#define QFLAG_NON_LINEAR_PIXEL
#define LINEAR_POLYNOMIAL_DEGREE
@ XSH_ARM_NIR
#define XSH_PRE_DATA_TYPE
Definition: xsh_data_pre.h:42
int nx
int ny
cpl_frame * xsh_frame_product(const char *fname, const char *tag, cpl_frame_type type, cpl_frame_group group, cpl_frame_level level)
Creates a frame with given characteristics.
Definition: xsh_dfs.c:930
#define XSH_GET_TAG_FROM_ARM(TAG, instr)
Definition: xsh_dfs.h:1548
#define XSH_BP_MAP_LIN
Definition: xsh_dfs.h:615
#define XSH_LINEARITY_NIR
Definition: xsh_dfs.h:385
#define XSH_QC_BP_MAP_LINi_RMS
Definition: xsh_pfits_qc.h:168
#define XSH_QC_BP_MAP_LINi_MEAN
Definition: xsh_pfits_qc.h:166
#define XSH_QC_BP_MAP_LINi_MED
Definition: xsh_pfits_qc.h:167
#define XSH_QC_BP_MAP_NBADPIX
Definition: xsh_pfits_qc.h:165
cpl_polynomial * xsh_polynomial_fit_1d_create(const cpl_vector *x_pos, const cpl_vector *values, int degree, double *mse)