X-shooter Pipeline Reference Manual 3.8.15
xsh_subtract.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: 2013-04-25 14:06:28 $
23 * $Revision: 1.159 $
24 * $Name: not supported by cvs2svn $
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#include <xsh_cpl_size.h>
31/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------
42 Includes
43 ----------------------------------------------------------------------------*/
44#include <math.h>
45#include <xsh_utils.h>
46#include <xsh_drl.h>
47#include <xsh_pfits.h>
48#include <xsh_error.h>
49#include <xsh_msg.h>
50#include <xsh_badpixelmap.h>
51#include <xsh_utils_image.h>
52#include <xsh_data_order.h>
53#include <xsh_data_grid.h>
54
55/*---------------------------------------------------------------------------
56 Typedefs
57 ---------------------------------------------------------------------------*/
59 0,0,0,0,
60 0,0,0,0}; //XSH_ORDERS_UVB=12
61
63 0,0,0,0,
64 0,0,0,0}; //XSH_ORDERS_UVB=12
65
66
68 0,0,0,0,0,
69 0,0,0,0,0}; //XSH_ORDERS_VIS=15
70
72 50,50,70,50,50,
73 50,50,50,50,50}; //XSH_ORDERS_VIS=15
74
75
77 0,50,50,80,
78 70,50,50,50,
79 50,50,50,50}; //XSH_ORDERS_NIR=16
80
81
83 0,50,100,60,
84 90,70,50,50,
85 50,50,50,50}; //XSH_ORDERS_NIR=16
86
87/*---------------------------------------------------------------------------
88 Functions prototypes
89 ---------------------------------------------------------------------------*/
90static cpl_image*
91xsh_image_generate_background(const int sx, const int sy, const polynomial *background_pol);
92
93static cpl_image*
94xsh_background_poly(xsh_pre* image, cpl_table** grid_tbl,xsh_background_param* back_par);
95
96/*---------------------------------------------------------------------------
97 Implementation
98 ---------------------------------------------------------------------------*/
99
100
119cpl_frame*
120xsh_subtract_bias( cpl_frame *frame,
121 cpl_frame *bias,
122 xsh_instrument* instr,
123 const char * type,
124 const int pre_overscan_corr,
125 const int save_tmp)
126{
127 /* MUST BE DEALLOCATED in caller */
128 cpl_frame * result = NULL;
129 /* ALLOCATED locally */
130 xsh_pre* xframe = NULL;
131 xsh_pre* xbias = NULL;
132 /* Others */
133 char resultname[256];
134 //int binx=0;
135 //int biny=0;
136 char tag[256];
137 double avg=0;
138
139 /* check input */
140 XSH_ASSURE_NOT_NULL( frame);
141 XSH_ASSURE_NOT_NULL( bias);
142 XSH_ASSURE_NOT_NULL( instr);
143
144 /* load the frames */
145 check( xframe = xsh_pre_load( frame, instr));
146 check( xbias = xsh_pre_load( bias, instr));
147
148 //check(binx=xsh_pfits_get_binx(xbias->data_header));
149 //check(biny=xsh_pfits_get_biny(xbias->data_header));
150 /* do the subtract operation */
151 if(pre_overscan_corr==0) {
152 check( xsh_pre_subtract( xframe, xbias));
153 } else {
154 /* The master bias level is set to 0
155 before subtraction if the overscan was already set by the user
156 in order to correct for the bias structures */
157 check(avg=cpl_image_get_mean(xbias->data));
158 check(xsh_pre_subtract_scalar(xbias,avg));
159 check( xsh_pre_subtract( xframe, xbias));
160 }
161 /* save result */
162 sprintf(tag,"%sON_%s",type,xsh_instrument_arm_tostring (instr));
163
164 /* Sabine does not like binning in file name
165 sprintf(resultname,"%s_%dx%d.fits",tag,binx,biny);
166 */
167 sprintf(resultname,"%s.fits",tag);
168
169 check( xsh_pfits_set_pcatg( xframe->data_header, tag));
170 check( result = xsh_pre_save ( xframe, resultname, tag,save_tmp));
171 check( cpl_frame_set_tag( result,tag));
172
173 cleanup:
174 if ( cpl_error_get_code() != CPL_ERROR_NONE) {
175 xsh_free_frame( &result);
176 }
177 xsh_pre_free( &xframe);
178 xsh_pre_free( &xbias);
179 return result;
180}
181
182
183
184/*---------------------------------------------------------------------------*/
193/*---------------------------------------------------------------------------*/
194cpl_frameset* xsh_subtract_nir_on_off(cpl_frameset* on, cpl_frameset* off,
195 xsh_instrument* instr){
196 /* MUST BE DEALLOCATED in caller */
197 cpl_frameset * result = NULL;
198 /* ALLOCATED locally */
199 cpl_frame* res = NULL;
200 /* Others */
201 char resultname[256];
202 int i = 0, size_on = 0, size_off = 0;
203
204 /* check input parameters */
207 XSH_ASSURE_NOT_NULL(instr);
208
209 check(size_on = cpl_frameset_get_size(on));
210 check(size_off = cpl_frameset_get_size(off));
211
212 XSH_ASSURE_NOT_ILLEGAL(size_on == size_off);
213
214 XSH_NEW_FRAMESET(result);
215
216 /* Loop on frames */
217 for ( i=0; i< size_on; i++) {
218 cpl_frame* on_f = NULL;
219 cpl_frame* off_f = NULL;
220
221 check( on_f = cpl_frameset_get_frame(on,i));
222 check( off_f = cpl_frameset_get_frame(off,i));
223 sprintf(resultname, "ON-OFF_%d.fits",i);
224
225 check( res = xsh_subtract_dark(on_f, off_f, resultname, instr));
226 check(cpl_frameset_insert(result, res));
227 xsh_add_temporary_file(resultname);
228 }
229
230 cleanup:
231 if (cpl_error_get_code() != CPL_ERROR_NONE) {
232 xsh_free_frameset(&result);
233 xsh_free_frame(&res);
234 }
235 return result;
236}
237/*---------------------------------------------------------------------------*/
246/*---------------------------------------------------------------------------*/
247cpl_frame * xsh_subtract_dark(cpl_frame * frame,cpl_frame * dark,
248 const char* filename, xsh_instrument* instr)
249{
250 /* MUST BE DEALLOCATED in caller */
251 cpl_frame * result = NULL;
252 /* ALLOCATED locally */
253 xsh_pre* xframe = NULL;
254 xsh_pre* xdark = NULL;
255 /* Others */
256 double exptime = 0.0;
257 double dit_raw=0;
258 double dit_dark=0;
259 double dit_tol=0.001;
260 const char* tag=NULL;
261
262 /* check input parameters */
263 XSH_ASSURE_NOT_NULL(frame);
265 XSH_ASSURE_NOT_NULL(filename);
266 XSH_ASSURE_NOT_NULL(instr);
267
268 /* load the frames */
269 check(xframe = xsh_pre_load(frame, instr));
270 check(xdark = xsh_pre_load(dark, instr));
271
272 /* compute the master to the same exptime */
273 if (xsh_instrument_get_arm(instr) != XSH_ARM_NIR) {
274 exptime = xframe->exptime;
275 assure(exptime > 0,CPL_ERROR_ILLEGAL_INPUT,
276 "EXPTIME must be greater than 0 : %f",exptime);
278 } else {
279 dit_raw=xsh_pfits_get_dit(xframe->data_header);
280 dit_dark=xsh_pfits_get_dit(xdark->data_header);
281 XSH_ASSURE_NOT_ILLEGAL_MSG( fabs(dit_raw-dit_dark) < dit_tol,"Make sure dark has same DIT as raw data");
282 }
283 /* do the subtract operation */
284 check(xsh_pre_subtract(xframe,xdark));
285 /* save result */
286 tag=cpl_frame_get_tag(frame);
287 check(result = xsh_pre_save (xframe, filename, tag,0));
288 check(cpl_frame_set_tag (result,tag));
289
290 cleanup:
291 if (cpl_error_get_code () != CPL_ERROR_NONE) {
292 xsh_free_frame(&result);
293 }
294 xsh_pre_free(&xframe);
295 xsh_pre_free(&xdark);
296 return result;
297}
298
299
300inline static void xsh_fill_bkg_mask_range(const int y, const int nx, const int xmin,
301 const int xmax, const int x_hbox,
302 const int decode_bp, int* qual,
303 int* pmask, int* size) {
304 int x = 0;
305 int xcen=0;
306 int xs=0;
307 int xe=0;
308 int offset = nx*y;
309 if((xmax-xmin+1) >= 2*x_hbox+1) {
310 xcen = 0.5*(xmin+xmax);
311 xs = xcen-x_hbox;
312 xe = xcen+x_hbox;
313 xs = (xs > 0) ? xs: 0;
314 xe = (xe < nx) ? xe: nx-1;
315
316 for (x = xs; x <= xe; x++) {
317 if ( (qual[offset + x] & decode_bp) == 0) {
318 pmask[offset + x] = 1;
319 (*size)++;
320 }
321 }
322
323 } else {
324 //xsh_msg("skip range [%d-%d,%d]",xmin,xmax,offset/2048);
325 }
326 return;
327}
328
329
330/*---------------------------------------------------------------------------*/
346/*---------------------------------------------------------------------------*/
347static xsh_grid*
349 const int x_hbox , xsh_instrument *instr,const char* prefix) {
350 xsh_grid *grid = NULL;
351
352 int ord = 0;
353 int x = 0;
354 int y = 0;
355 int xmin = 0;
356 int xmax = 0;
357 //int xcen = 0;
358
359 float x1 = 0, x2 = 0;
360 int* pmask = NULL;
361 int* pqual = NULL;
362 cpl_image* mask = NULL;
363 int nx = pre->nx;
364 int ny = pre->ny;
365 int lost = 0;
366 float* pdata = NULL;
367
368 int size = 0;
369 /* margin: UVB=4 VIS=7, NIR=2 */
370 int pix = 0;
371 float sx_illum = 0;
372 float sx_backg = 0;
373 int decode_bp=0;
374 int* qual=NULL;
375 //float* errs=NULL;
376 float* perrs=NULL;
377 int y_skip_up=0;
378 int y_skip_lo=0;
379 int x_margin1=0;
380 int x_margin2=0;
381 //int x_margin3=0;
382 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
383 y_skip_lo=20;
384 y_skip_up=20;
385 x_margin1=40;
386 x_margin2=80;
387 //x_margin3=62;
388 } else if (xsh_instrument_get_arm(instr) == XSH_ARM_UVB) {
389 x_margin1=21;
390 x_margin2=135;
391 if ( strcmp(prefix,"MFLAT_D2") == 0 ) {
392 y_skip_lo=0;
393 y_skip_up=0;
394 }
395
396 } else if (xsh_instrument_get_arm(instr) == XSH_ARM_VIS) {
397 x_margin1=30;
398 x_margin2=134;
399 //x_margin3=62;
400 }
401 decode_bp=instr->decode_bp;
402
403 qual=cpl_image_get_data_int(pre->qual);
404 //errs=cpl_image_get_data_float(pre->errs);
405
406 mask = cpl_image_new(nx, ny, CPL_TYPE_INT);
407 pmask = cpl_image_get_data_int(mask);
408 xsh_msg("prepare mask data");
409 for (y = 1; y < ny; y++) {
410
411 /* special case for NIR: some orders cover only part of the detector
412 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
413 if ((y <= orderlist->list[orderlist->size - 2].starty)
414 || y >= orderlist->list[orderlist->size - 2].endy) {
415 // add to grid
416 x1=1;
417 x2=
418 for (x = x1; x <= x2; x++) {
419 pmask[y * nx + x] = 1;
420 }
421 }
422 }
423 */
424 for (ord = orderlist->size - 1; ord > 0; ord--) {
425 int starty, endy;
426 starty = orderlist->list[ord - 1].starty;
427 endy = orderlist->list[ord - 1].endy;
428 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
429 y_skip_lo=xsh_bkg_yskip_lo_nir[ord];
430 y_skip_up=xsh_bkg_yskip_up_nir[ord];
431 }
432 if (xsh_instrument_get_arm(instr) == XSH_ARM_UVB) {
433 y_skip_lo=xsh_bkg_yskip_lo_uvb[ord];
434 y_skip_up=xsh_bkg_yskip_up_uvb[ord];
435 }
436 starty += y_skip_lo;
437 endy -= y_skip_up;
438
439 /* Special case: NIR: If outside order, then skip */
440 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
441 if (y <= starty || y >= endy) {
442 lost++;
443 continue;
444 }
445 } else {
446 if (ord < (orderlist->size - 1)) {
447 if (y <= starty || y >= endy) {
448 lost++;
449 continue;
450 }
451 }
452 }
453
454
455 if( ord >0 ) {
456 /* as we scan the order list from greater to lower order number, x1 < x2 */
457 x1 = xsh_order_list_eval(orderlist, orderlist->list[ord].edguppoly, y);
458 x2 = xsh_order_list_eval(orderlist, orderlist->list[ord - 1].edglopoly,
459 y);
460 xmin = x1;
461 xmax = x2;
462 //xsh_msg("ord=%d absord=%d x1=%g x2=%g",ord,orderlist->list[ord].absorder,x1,x2);
463 xsh_fill_bkg_mask_range(y,nx,xmin,xmax,x_hbox,decode_bp,qual,pmask,&size);
464
465 }
466
467
468 if (ord == orderlist->size - 1) {
469 if ( strcmp(prefix,"MFLAT_D2") == 0 ) {
470 /* special case: last order, on the left hand side of detector:
471 * as the pipeline skips two orders we first estimate what is on the latest
472 * detected order the size of the illuminated region and the one of the not
473 * illuminated one so that we can set properly mask points only in the not illuminated */
474
475
476
477 if (y <= starty || y >= endy) {
478 lost++;
479 continue;
480 }
481
482 x1 = xsh_order_list_eval(orderlist,
483 orderlist->list[orderlist->size - 1].edglopoly, y);
484 x2 = xsh_order_list_eval(orderlist,
485 orderlist->list[orderlist->size - 1].edguppoly, y);
486
487 sx_illum = x2 - x1;
488 x1 = xsh_order_list_eval(orderlist,
489 orderlist->list[orderlist->size - 1].edguppoly, y);
490 x2 = xsh_order_list_eval(orderlist,
491 orderlist->list[orderlist->size - 2].edglopoly, y);
492
493 sx_backg = x2 - x1;
494 x2 = xsh_order_list_eval(orderlist,
495 orderlist->list[orderlist->size - 1].edglopoly, y);
496 x1 = x2 - sx_backg;
497
498 xmin = x1;
499 xmax = x2;
500
501 xsh_fill_bkg_mask_range(y , nx, xmin, xmax, x_hbox, decode_bp,qual, pmask,
502 &size);
503
504 // For D2 left side we trace the bkg in inverse orderr: 1st we compute positions then we check on y
505 x2 = x1 - sx_illum;
506 x1 = x2-sx_backg;
507 xmin = x1+x_hbox-20;
508 xmax = x2-x_hbox-10;
509 int xmin1=xmin;
510 int xmax1=xmax;
511
512 if (y <= 650 || y >= endy) {
513 lost++;
514 continue;
515 }
516
517 xsh_fill_bkg_mask_range(y , nx, xmin1, xmax1, x_hbox, decode_bp,qual, pmask,
518 &size);
519
520
521 x2 = x1 - sx_illum; /* note that in the latest x2 definition x_hbox war already taken out */
522 x1 = x2-sx_backg;
523 xmin = x1+x_hbox-50;
524 xmax = x2-x_hbox-40;
525 int xmin2=xmin;
526 int xmax2=xmax;
527
528
529
530 // this is the last order traced on the left
531 if (y <= 1600 || y >= endy) {
532 lost++;
533 continue;
534 }
535
536
537 xsh_fill_bkg_mask_range(y , nx, xmin2, xmax2, x_hbox, decode_bp,qual, pmask,
538 &size);
539
540
541
542
543 /*
544
545 x2 = x1 - sx_illum; // note that in the latest x2 definition x_hbox war already taken out
546 xmin = 1;
547 xmax = x2-x_hbox-60;
548
549
550
551 xsh_fill_bkg_mask_range(y , nx, xmin, xmax, x_hbox, decode_bp,qual, pmask,
552 &size);
553 */
554
555 continue;
556 /* end special case for UVB-D2 flats */
557 } else {
558
559 /* special case: last order, on the left hand side of detector:
560 * as the pipeline skips one order we first estimate what is on the latest
561 * detected order the size of the illuminated region and the one of the not
562 * illuminated one so that we can set properly mask points only in the not illuminated */
563
564 if (xsh_instrument_get_arm(instr) != XSH_ARM_UVB) {
565 x1 = xsh_order_list_eval(orderlist,
566 orderlist->list[orderlist->size - 1].edglopoly, y);
567 x2 = xsh_order_list_eval(orderlist,
568 orderlist->list[orderlist->size - 1].edguppoly, y);
569
570 sx_illum = x2 - x1;
571 x1 = xsh_order_list_eval(orderlist,
572 orderlist->list[orderlist->size - 1].edguppoly, y);
573 x2 = xsh_order_list_eval(orderlist,
574 orderlist->list[orderlist->size - 2].edglopoly, y);
575
576 sx_backg = x2 - x1;
577 x2 = xsh_order_list_eval(orderlist,
578 orderlist->list[orderlist->size - 1].edglopoly, y);
579 x1 = x2 - sx_backg + x_hbox;
580 x2 -= x_hbox;
581
582 xmin = x1;
583 xmax = x2;
584
585 xsh_fill_bkg_mask_range(y , nx, xmin, xmax, x_hbox, decode_bp,qual, pmask,
586 &size);
587
588 }
589 /* extreme left between edge and last traced order:
590 x2 = xsh_order_list_eval(orderlist,
591 orderlist->list[orderlist->size - 1].edglopoly, y);
592 xmin = 1;
593 //note that in the latest x2 definition x_hbox war already taken out
594 x2 = x2 - sx_backg - sx_illum;
595 xmax = x2;
596 xmax -= x_hbox;
597
598 xsh_fill_bkg_mask_range(y , nx, xmin, xmax, x_hbox, decode_bp,qual, pmask,
599 &size);
600 */
601 continue;
602 }
603 } else {
604
605 if ( strcmp(prefix,"MFLAT_D2") == 0 ) {
606
607 if (ord == orderlist->size - 2) {
608 if (y <= starty || y >= endy) {
609 xsh_msg("starty=%d endy=%d yskip=%d %d",starty,endy,y_skip_lo,y_skip_up);
610 lost++;
611 continue;
612 }
613 }
614 }
615
616 }
617
618 if (ord == 1) {
619
620 x1 = xsh_order_list_eval(orderlist, orderlist->list[0].edguppoly, y);
621 xmin = x1;
622 xmax = x1+x_margin1;
623 xsh_fill_bkg_mask_range(y,nx,xmin,xmax,x_hbox,decode_bp,qual,pmask,&size);
624 if( xsh_instrument_get_arm(instr) != XSH_ARM_NIR ) {
625
626 xmin = xmax;
627 xmax = xmin+x_margin2;
628 xsh_fill_bkg_mask_range(y,nx,xmin,xmax,x_hbox,decode_bp,qual,pmask,&size);
629
630 }
631 /*
632 if( xsh_instrument_get_arm(instr) == XSH_ARM_VIS ) {
633 xmin = xmax;
634 xmax = xmin+x_margin3;
635 xsh_fill_bkg_mask_range(y,nx,xmin,xmax,x_hbox,decode_bp,qual,pmask,&size);
636
637 }
638 */
639
640 continue;
641 //}
642
643 } /* end case ord = 1 */
644
645 } /* end loop over orders */
646
647 } /* end loop over y */
648
649
650 check( grid = xsh_grid_create(size));
651 char name[256];
652 sprintf(name,"bkg_mask_%s.fits",prefix);
653 //cpl_image_save(mask, name, XSH_PRE_DATA_BPP, NULL,CPL_IO_DEFAULT);
654
655 pdata = cpl_image_get_data_float(pre->data);
656 perrs = cpl_image_get_data_float(pre->errs);
657 pqual = cpl_image_get_data_int(pre->qual);
658
659 for (y = 1; y < ny; y++) {
660 for (x = 1; x < nx; x++) {
661 pix = y * nx + x;
662 if ((pmask[pix] == 1) && ((pqual[pix] & instr->decode_bp) == 0)) {
663 check( xsh_grid_add(grid, x, y, pdata[pix],perrs[pix],pqual[pix]));
664 }
665 }
666 }
667
668
669
670 check( xsh_grid_sort(grid));
671
672 cleanup:
673 xsh_free_image(&mask);
674 return grid;
675}
676#if 0
677/*---------------------------------------------------------------------------*/
693/*---------------------------------------------------------------------------*/
694static xsh_grid*
695xsh_crea_grid_from_samples(xsh_pre *pre, xsh_order_list *orderlist,
696 xsh_background_param *background_par, xsh_instrument *instr) {
697
698
699 xsh_grid *grid = NULL;
700
701 double *tab = NULL;
702
703 int grid_size_x = 0, grid_size_y = 0;
704 int incr = 0, i = 0, y = 0, lost = 0;
705 int status = 0;
706 int x = 0;
707 float x1 = 0, x2 = 0, dx = 0;
708 double medflux = 0.0;
709
710 /* create the grid */
711 grid_size_x = orderlist->size + 5;
712 grid_size_y = background_par->sampley + 2;
713
714 assure(background_par->sampley > 0, CPL_ERROR_ILLEGAL_INPUT,
715 "parameter background-nb-y=%d "
716 "must be set to a positive value", background_par->sampley);
717 XSH_ASSURE_NOT_ILLEGAL(background_par->radius_x >= 0);
718 XSH_ASSURE_NOT_ILLEGAL(background_par->radius_y >= 0);
719
720 assure(
721 grid_size_y > 0 && grid_size_y < pre->ny,
722 CPL_ERROR_ILLEGAL_INPUT,
723 "grid_size_y=%d must be in (0,%d) range "
724 "parameter background-nb-y=%d "
725 "may have been set to a too large or too small value", grid_size_y, pre->ny, background_par->sampley);
726
727 check( grid = xsh_grid_create( grid_size_x*grid_size_y));
728
729 /* allocate share memory for medflux */
730 assure(
731 background_par->radius_x<pre->nx,
732 CPL_ERROR_ILLEGAL_INPUT,
733 "parameter -background-radius-x (%d) must be > 0 and < %d", background_par->radius_x, pre->nx);
734 assure(
735 background_par->radius_y<pre->ny,
736 CPL_ERROR_ILLEGAL_INPUT,
737 "parameter -background-radius-y (%d) must be > 0 and < %d", background_par->radius_y, pre->ny);
738
739 int box_sizex = 2 * background_par->radius_x + 1;
740 int box_sizey = 2 * background_par->radius_y + 1;
741 XSH_MALLOC(tab, double, box_sizex*box_sizey);
742
743 /* compute incr along Y axis */
744incr = (int) ceil((float) pre->ny / (float) background_par->sampley);
745 int sizey = 0;
746 int oy = 0;
747 /* Step 1 : Fill the grid */
748 for (y = 1; y <= (pre->ny - 1 + incr); y += incr) {
749
750 /* force to do the last line */
751 if ((y + incr) > pre->ny) {
752 y = pre->ny;
753 }
754
755 /* special cases in Y */
756 if ((y == 1) || (y == pre->ny)) {
757 sizey = background_par->radius_y + 1;
758 oy = 0;
759 } else {
760 sizey = box_sizey;
761 oy = -background_par->radius_y;
762 }
763
764 /* Special case: X = 1, estimate flux at left hand side detector edge */
765 /* computes flux level in window box using a median method,
766 considering only good pixel codes.*/
767
768 check(
769 medflux = xsh_pre_data_window_median_flux_pa(pre, 1, y+oy, box_sizex, sizey, tab,&status));
770
771 if (status == 0) {
772 /* special case for NIR: some orders cover only part of the detector */
773 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
774 if ((y <= orderlist->list[orderlist->size - 2].starty)
775 || y >= orderlist->list[orderlist->size - 2].endy) {
776 /* add to grid */
777 check( xsh_grid_add(grid, 1, y, medflux,1,0));
778 } else {
779 lost++;
780 }
781 } else {
782 check( xsh_grid_add(grid, 1, y, medflux,1,0));
783 }
784 } else {
785 lost++;
786 }
787
788 /* Points in [orderN->edgeup, order0->edgeup] */
789 for (i = orderlist->size - 1; i > 0; i--) {
790 int starty, endy;
791 starty = orderlist->list[i - 1].starty;
792 endy = orderlist->list[i - 1].endy;
793
794 /* Special case: NIR: If outside order, then skip */
795 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
796 if (y <= starty || y >= endy) {
797 lost++;
798 continue;
799 }
800 }
801
802 /* TODO: drop this special case */
803 if (starty == -999) {
804 /* this condition can happen only if qc_mode=TRUE and some order
805 has edges with S/N less than the user defined threshold
806 it is used for QC in order to make recipe more robust and
807 generate all QC. Normal users should set qc_mode=FALSE.
808 */
809 xsh_msg("PROBLEMS");
810 check(xsh_grid_add(grid, 0, y, 0.,1,0));
811 lost++;
812 break;
813 }
814
815 /* calculate the center of the inter-order region */
816 check(
817 x1 = xsh_order_list_eval( orderlist, orderlist->list[i].edguppoly, y));
818 check(
819 x2 = xsh_order_list_eval( orderlist, orderlist->list[i-1].edglopoly, y));
820 /* compute x */
821 x = floor(0.5 * (x1 + x2 + 1));
822 dx = 0.5 * (x2 - x1);
823 xsh_msg_dbg_high("x %d dx %f", x, dx);
824
825 if ((x > (background_par->radius_x + 1)) && (box_sizex < dx)) {
826 /* In most of the cases we are far enough from the detector left
827 hand side, and the inter-order space between two adjacent edges
828 is large enough to be able to evaluate the inter-order background
829 flux level. In this case we estimate the median flux in
830 window box */
831 check(
832 medflux = xsh_pre_data_window_median_flux_pa(pre,x-background_par->radius_x, y+oy, box_sizex,sizey,tab,&status));
833 if (status == 0) {
834 check( xsh_grid_add(grid, x, y, medflux,1,0));
835 } else {
836 lost++;
837 }
838 } else {
839 /* there are a few cases where previous condition is not verifyed.
840 These pixels are lost. We count them. */
841 lost++;
842 }
843
844 /* special case X in ]0, orderN->edgelow] */
845 if (i == (orderlist->size - 1)) {
846 check(
847 x2 = xsh_order_list_eval( orderlist, orderlist->list[i].edglopoly, y));
848 x = x2 - dx;
849 if (dx < 0) {
850 xsh_msg("Monitor dx=%d x=%g y=%d", x, dx, y);
851 }
852 if (x > (background_par->radius_x + 1)) {
853 check(
854 medflux = xsh_pre_data_window_median_flux_pa(pre, x-background_par->radius_x, y+oy, box_sizex, sizey, tab,&status));
855 if (status == 0) {
856 check(xsh_grid_add(grid, x, y, medflux,1,0));
857 } else {
858 lost++;
859 }
860 } else {
861 lost++;
862 }
863 }
864
865 /* special case X in ]order0->edgeup, pre->nx] */
866 if (i == 1) {
867 check(
868 x1 = xsh_order_list_eval( orderlist, orderlist->list[0].edguppoly, y));
869 /* special case in VIS */
870 if (xsh_instrument_get_arm(instr) == XSH_ARM_VIS) {
871 check(
872 x2 = xsh_order_list_eval( orderlist, orderlist->list[0].edglopoly, y));
873 x = x1 + (x1 - x2) * 1.2;
874 } else {
875 x = x1 + dx;
876 }
877 if ((x > (background_par->radius_x + 1))
878 && (x + background_par->radius_x < pre->nx)) {
879 check(
880 medflux = xsh_pre_data_window_median_flux_pa(pre, x-background_par->radius_x, y+oy, box_sizex, sizey, tab,&status));
881 if (status == 0) {
882 check(xsh_grid_add(grid, x, y, medflux,1,0));
883 } else {
884 lost++;
885 }
886 } else {
887 lost++;
888 }
889
890 } /* if i==1 */
891
892 }/* end loop over i (orders) */
893
894 /* Special case of: X=pre->nx (right hand size of detector, in PRE format) */
895 check(
896 medflux = xsh_pre_data_window_median_flux_pa(pre, pre->nx-background_par->radius_x, y+oy, background_par->radius_x+1, sizey, tab,&status));
897
898 if (status == 0) {
899 /* special case for NIR: some orders cover only part of the detector */
900 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
901 if ((y <= orderlist->list[0].starty) || y >= orderlist->list[0].endy) {
902 /* add to grid */
903 check( xsh_grid_add(grid, x, y, medflux,1,0));
904 } else {
905 lost++;
906 }
907 } else {
908 check( xsh_grid_add(grid, x, y, medflux,1,0));
909 }
910 } else {
911 lost++;
912 }
913
914 } /* end loop over Y */
915
916 xsh_msg_dbg_low("Nb of lost points %d ", lost);
917 xsh_msg_dbg_low("Nb of grid points %d ", xsh_grid_get_index(grid));
918
919 /* sort the grid points */
920 check( xsh_grid_sort(grid));
921
922 cleanup: return grid;
923
924}
925#endif
926
927/*---------------------------------------------------------------------------*/
946/*---------------------------------------------------------------------------*/
947cpl_frame* xsh_subtract_background( cpl_frame *frame,
948 cpl_frame *edges_order_tab_frame,
949 xsh_background_param *background_par,
950 xsh_instrument *instr,
951 const char *prefix,
952 cpl_frame **grid_frame,
953 cpl_frame **backg_frame,
954 const int save_bkg,
955 const int save_grid,
956 const int save_sub_bkg)
957{
958 /* MUST BE DEALLOCATED in caller */
959 cpl_frame *result = NULL;
960 /* ALLOCATED locally */
961 xsh_order_list *orderlist = NULL;
962 xsh_pre *pre = NULL;
963 xsh_grid *grid = NULL;
964 cpl_image *background_img = NULL;
965 /* Others */
966 //float *data = NULL;
967
968 char *fname = NULL;
969 char *pcatg = NULL;
970
971 cpl_propertylist *plist = NULL;
972 cpl_table *grid_tbl = NULL;
973
974 /* check parameters */
975 XSH_ASSURE_NOT_NULL_MSG( instr, "Instrument structure setting");
976 XSH_ASSURE_NOT_NULL_MSG( frame,"Input frame");
977 XSH_ASSURE_NOT_NULL_MSG( edges_order_tab_frame,"Edge table");
978 XSH_ASSURE_NOT_NULL_MSG( background_par,"Background params");
979 XSH_ASSURE_NOT_NULL_MSG( grid_frame,"Grid frame");
980 XSH_ASSURE_NOT_NULL_MSG( backg_frame,"Background frame");
981
982 /* load data */
983 check( pre = xsh_pre_load(frame, instr));
984 check( orderlist = xsh_order_list_load( edges_order_tab_frame, instr));
985 xsh_order_list_set_bin_x( orderlist, pre->binx);
986 xsh_order_list_set_bin_y( orderlist, pre->biny);
987 //check( data = cpl_image_get_data_float(pre->data));
988
989 /* create grid */
990
991 /* grid need to to be erased */
992 check(grid=xsh_crea_grid_from_mask(pre, orderlist,background_par->edges_margin/pre->binx,instr,prefix));
993 //check(grid=xsh_crea_grid_from_samples(pre,orderlist,background_par,instr));
994
995 /* generate background image: only poly method (UVES-like) offered: 2D poly fit to data points */
996 //check( result = xsh_pre_save( pre, "test.fits", "test", 1));
997
998 xsh_msg("generate background image: poly");
999 grid_tbl = xsh_grid2table(grid);
1000 xsh_grid_free( &grid);
1001
1002 //check( cpl_table_save( grid_tbl, plist, NULL, "test.fits", CPL_IO_DEFAULT));
1003
1004
1005 check( background_img = xsh_background_poly(pre, &grid_tbl,background_par));
1006 xsh_msg("Prepare final products");
1007 /* prepare final products */
1008 XSH_NAME_PREFIX_LAMP_MODE_ARM( pcatg, prefix, "_BACK", "", instr);
1009 XSH_NAME_PREFIX_LAMP_MODE_ARM( fname, prefix, "_BACK", ".fits", instr);
1010 plist=cpl_propertylist_new();
1011 double crpix1=1.;
1012 double crval1=1.;
1013 double cdelt1=xsh_instrument_get_binx(instr);
1014
1015 double crpix2=1.;
1016 double crval2=1.;
1017 double cdelt2=xsh_instrument_get_biny(instr);
1018
1019 check( xsh_pfits_set_pcatg( plist, pcatg));
1020 xsh_pfits_set_wcs(plist,crpix1,crval1,cdelt1,crpix2,crval2,cdelt2);
1021 check( cpl_image_save( background_img, fname, CPL_BPP_IEEE_FLOAT,
1022 plist, CPL_IO_DEFAULT));
1023 if(!save_bkg) {
1025 }
1026
1027 xsh_free_propertylist( &plist);
1028
1029 check( *backg_frame = xsh_frame_product( fname, pcatg,
1030 CPL_FRAME_TYPE_IMAGE, CPL_FRAME_GROUP_CALIB,
1031 CPL_FRAME_LEVEL_FINAL));
1032
1033
1034 check( cpl_image_subtract( pre->data, background_img));
1035
1036 XSH_FREE( fname);
1037 XSH_FREE( pcatg);
1038 XSH_NAME_PREFIX_LAMP_MODE_ARM( fname, prefix, "_SUB_BACK", ".fits", instr);
1039 XSH_NAME_PREFIX_LAMP_MODE_ARM( pcatg, prefix, "_SUB_BACK", "", instr);
1040
1041 check( xsh_pfits_set_pcatg( pre->data_header, pcatg));
1042
1043 if(save_sub_bkg==0) {
1044 check( result = xsh_pre_save( pre, fname, pcatg, 1));
1045 } else {
1046 check( result = xsh_pre_save( pre, fname, pcatg, 0));
1047 }
1048 //xsh_add_temporary_file(fname);
1049
1050 check(cpl_frame_set_tag (result, pcatg));
1051 check(cpl_frame_set_type (result, CPL_FRAME_TYPE_IMAGE));
1052 check(cpl_frame_set_group (result, CPL_FRAME_GROUP_CALIB));
1053 check(cpl_frame_set_level (result, CPL_FRAME_LEVEL_FINAL));
1054
1055 /*
1056 if(!save_tmp) {
1057 xsh_add_temporary_file(fname);
1058 }
1059 */
1060 XSH_FREE( fname);
1061 XSH_FREE( pcatg);
1062 XSH_NAME_PREFIX_LAMP_MODE_ARM( fname, prefix, "_GRID_BACK", ".fits", instr);
1063 XSH_NAME_PREFIX_LAMP_MODE_ARM( pcatg, prefix, "_GRID_BACK", "", instr);
1064
1065 plist = cpl_propertylist_new();
1066 check( xsh_pfits_set_pcatg( plist, pcatg));
1067 check( cpl_table_save( grid_tbl, plist, NULL, fname, CPL_IO_DEFAULT));
1068 xsh_free_propertylist( &plist);
1069 xsh_free_table( &grid_tbl);
1070
1071 if(save_grid==0) {
1073 }
1074
1075
1076 *grid_frame =xsh_frame_product(fname,pcatg,CPL_FRAME_TYPE_TABLE,
1077 CPL_FRAME_GROUP_CALIB,CPL_FRAME_LEVEL_FINAL);
1078
1079
1080 cleanup:
1081
1082 if (cpl_error_get_code () != CPL_ERROR_NONE) {
1083 xsh_free_frame(&result);
1084 }
1085
1086 xsh_free_propertylist(&plist);
1087 xsh_order_list_free( &orderlist);
1088 XSH_FREE( fname);
1089 XSH_FREE( pcatg);
1090 //xsh_grid_free( &grid);
1091 xsh_pre_free( &pre);
1092 xsh_free_image( &background_img);
1093
1094 return result;
1095}
1096
1097/*----------------------------------------------------------------------------*/
1109/*----------------------------------------------------------------------------*/
1110
1111static cpl_image*
1112xsh_image_generate_background(const int sx, const int sy, const polynomial *background_pol)
1113{
1114 int x, y;
1115 cpl_image* image_bkg=NULL;
1116 float *background_data = NULL;
1117 int offset=0;
1118
1119 image_bkg=cpl_image_new(sx,sy,XSH_PRE_DATA_TYPE);
1120 background_data = cpl_image_get_data_float(image_bkg);
1121
1122 for (y = 1; y <= sy; y++)
1123 {
1124 offset=(y-1)*sx;
1125 for (x = 1; x <= sx; x++)
1126 {
1127 background_data[(x-1) + offset] = xsh_polynomial_evaluate_2d(background_pol,x,y);
1128 }
1129 }/* for each pixel... */
1130
1131
1132 return image_bkg;
1133}
1134
1135static cpl_image*
1136xsh_background_poly(xsh_pre* pre, cpl_table** grid_tab,xsh_background_param* background_par) {
1137
1138 /* Sampling done. Fit poly. */
1139 polynomial* background = NULL;
1140 double mse = 0, rmse = 0; /* mse, rms of fit */
1141 cpl_size total_clipped = 0;
1142 cpl_image* bkg_img = NULL;
1143
1144 int degx = background_par->poly_deg_x;
1145 int degy = background_par->poly_deg_y;
1146 double kappa = background_par->poly_kappa;
1147 xsh_msg("degx=%d degy=%d kappa=%g", degx, degy, kappa);
1148 //int nrow=0;
1149 //int i=0;
1150
1151 //double* pres=NULL;
1152 //double* pfit=NULL;
1153 //double* px=NULL;
1154 //double* py=NULL;
1155
1156
1157 //check(cpl_table_save(t,NULL,NULL,"grid_table.fits",CPL_IO_DEFAULT));
1158
1159 {
1160 cpl_size n_clipped;
1161 do {
1162 cpl_size deg_xy = (degx + 1) * (degy + 1);
1163 assure(
1164 cpl_table_get_nrow(*grid_tab) > (degx + 1)*(degy + 1),
1165 CPL_ERROR_ILLEGAL_OUTPUT,
1166 "Too few sample points available (%" CPL_SIZE_FORMAT " point(s)) to make the fit "
1167 "(more than %" CPL_SIZE_FORMAT " points needed). "
1168 "Increase number of sample points or increase kappa", cpl_table_get_nrow(*grid_tab), deg_xy);
1169
1170 /* Fit, calculate Zfit */
1171 xsh_polynomial_delete(&background);
1172 check_msg(
1173 background = xsh_polynomial_regression_2d( *grid_tab, "X", "Y", "INT", "ERR", degx, degy, "INTfit", NULL, NULL, &mse, NULL, NULL, kappa, -1),
1174 "Error fitting polynomial");
1175
1176 /* Residual := INT - INTfit */
1177 cpl_table_duplicate_column(*grid_tab, "Residual", *grid_tab, "INT");
1178 cpl_table_subtract_columns(*grid_tab, "Residual", "INTfit");
1179
1180 /* Calculate standard eviation of residuals */
1181 rmse = cpl_table_get_column_stdev(*grid_tab, "Residual");
1182
1183 xsh_msg_dbg_medium("rmse=%g", rmse);
1184 /* Kappa-sigma clipping */
1185 if (kappa > 0) {
1186 check_msg(
1187 n_clipped = xsh_select_table_rows( *grid_tab, "Residual", CPL_GREATER_THAN, kappa * rmse),
1188 "Error selecting rows");
1189 /*
1190 check_msg(
1191 n_clipped += xsh_select_table_rows( *grd_tab, "Residual", CPL_LESS_THAN, -kappa * rmse),
1192 "Error selecting rows");
1193 */
1194 } else {
1195 n_clipped = 0;
1196 }
1197
1198 total_clipped += n_clipped;
1199 /*
1200 xsh_msg_dbg_medium(
1201 "RMS = %f. %" CPL_SIZE_FORMAT " of %" CPL_SIZE_FORMAT " points rejected in kappa-sigma clipping", rmse, n_clipped, cpl_table_get_nrow(t));
1202 */
1203 xsh_msg(
1204 "RMS = %f. %" CPL_SIZE_FORMAT " of %" CPL_SIZE_FORMAT " points rejected in kappa-sigma clipping", rmse, n_clipped, cpl_table_get_nrow(*grid_tab));
1205
1206 cpl_table_erase_selected(*grid_tab);
1207
1208 if (n_clipped > 0) {
1209 cpl_table_erase_column(*grid_tab, "INTfit");
1210 cpl_table_erase_column(*grid_tab, "Residual");
1211 }
1212
1213 } while (n_clipped > 0);
1214 }
1215
1216 /*
1217 nrow=cpl_table_get_nrow(t);
1218 pres=cpl_table_get_data_double(t,"Residual");
1219 pfit=cpl_table_get_data_double(t,"INTfit");
1220 px=cpl_table_get_data_double(t,"X");
1221 py=cpl_table_get_data_double(t,"Y");
1222
1223 for(i=0;i<nrow;i++) {
1224 (grid->list[i])->fit=pfit[i];
1225 (grid->list[i])->res=pres[i];
1226 }
1227 */
1228
1229 //cpl_table_save(*grid_tab,NULL,NULL,"pippo.fits",CPL_IO_DEFAULT);
1230 /* Try to do some quality checking of the background subtraction.
1231 The number of rejected points (the signal)
1232 is often around 10-20 % */
1233 {
1234 double percentage = 100.0 * ((double) total_clipped)
1235 / (total_clipped + cpl_table_get_nrow(*grid_tab));
1236
1237 if (kappa > 0) {
1239 "%" CPL_SIZE_FORMAT " of %" CPL_SIZE_FORMAT " points (%.2f %%) were rejected in "
1240 "kappa-sigma clipping. RMS = %.2f ADU", total_clipped, cpl_table_get_nrow(*grid_tab) + total_clipped, percentage, sqrt(mse));
1241 }
1242
1243
1244 }
1245
1246 check_msg( bkg_img=xsh_image_generate_background(pre->nx,pre->ny, background),
1247 "Error generating background polynomial");
1248
1249 cleanup:
1250
1251 xsh_polynomial_delete(&background);
1252 return bkg_img;
1253
1254}
1255
1256
1257
static double exptime
static int starty
static int endy
void xsh_grid_add(xsh_grid *grid, int x, int y, double data, double errs, int qual)
add a point to a grid
xsh_grid * xsh_grid_create(int size)
Create a grid.
void xsh_grid_sort(xsh_grid *grid)
sort grid points
int xsh_grid_get_index(xsh_grid *grid)
get the number of elements in the grid
void xsh_grid_free(xsh_grid **grid)
Free a grid.
cpl_table * xsh_grid2table(xsh_grid *grid)
Dump main info about a grid.
void xsh_order_list_set_bin_y(xsh_order_list *list, int bin)
Set the bin of image in y.
void xsh_order_list_set_bin_x(xsh_order_list *list, int bin)
Set the bin of image in x.
xsh_order_list * xsh_order_list_load(cpl_frame *frame, xsh_instrument *instr)
load an order list from a frame
void xsh_order_list_free(xsh_order_list **list)
free memory associated to an order_list
double xsh_order_list_eval(xsh_order_list *list, cpl_polynomial *poly, double y)
Evaluate an order list poly.
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_multiply_scalar(const xsh_pre *pre, double x)
multiply a frame in PRE format by a scalar
void xsh_pre_free(xsh_pre **pre)
Free a xsh_pre structure.
Definition: xsh_data_pre.c:823
void xsh_pre_subtract_scalar(const xsh_pre *pre, double x)
subtract a scalar from a frame in PRE format
double xsh_pre_data_window_median_flux_pa(xsh_pre *pre, int x, int y, int size_x, int size_y, double *tab, int *status)
compute median sample value on the data window with preallocated memory tab. Only good pixels codes a...
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 XSH_ASSURE_NOT_NULL_MSG(pointer, msg)
Definition: xsh_error.h:103
#define XSH_ASSURE_NOT_ILLEGAL(cond)
Definition: xsh_error.h:107
#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
#define XSH_ASSURE_NOT_ILLEGAL_MSG(cond, msg)
Definition: xsh_error.h:111
#define XSH_ASSURE_NOT_NULL(pointer)
Definition: xsh_error.h:99
const char * xsh_instrument_arm_tostring(xsh_instrument *i)
Get the string associated with an arm.
int xsh_instrument_get_binx(xsh_instrument *instrument)
int xsh_instrument_get_biny(xsh_instrument *instrument)
XSH_ARM xsh_instrument_get_arm(xsh_instrument *i)
Get an arm on instrument structure.
int size
int * y
int * x
#define xsh_msg_dbg_medium(...)
Definition: xsh_msg.h:44
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
#define xsh_msg_dbg_low(...)
Definition: xsh_msg.h:48
#define xsh_msg_dbg_high(...)
Definition: xsh_msg.h:40
void xsh_pfits_set_pcatg(cpl_propertylist *plist, const char *value)
Write the PCATG value.
Definition: xsh_pfits.c:1008
double xsh_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: xsh_pfits.c:1405
cpl_error_code xsh_pfits_set_wcs(cpl_propertylist *header, const double crpix1, const double crval1, const double cdelt1, const double crpix2, const double crval2, const double cdelt2)
Definition: xsh_pfits.c:4364
int xsh_bkg_yskip_lo_uvb[XSH_ORDERS_UVB]
Definition: xsh_subtract.c:58
int xsh_bkg_yskip_up_vis[XSH_ORDERS_VIS]
Definition: xsh_subtract.c:71
cpl_frame * xsh_subtract_background(cpl_frame *frame, cpl_frame *edges_order_tab_frame, xsh_background_param *background_par, xsh_instrument *instr, const char *prefix, cpl_frame **grid_frame, cpl_frame **backg_frame, const int save_bkg, const int save_grid, const int save_sub_bkg)
Subtract the inter-order background from PRE frame.
Definition: xsh_subtract.c:947
static cpl_image * xsh_background_poly(xsh_pre *image, cpl_table **grid_tbl, xsh_background_param *back_par)
cpl_frameset * xsh_subtract_nir_on_off(cpl_frameset *on, cpl_frameset *off, xsh_instrument *instr)
(NIR only) subtract the OFF set of files from the On set of files
Definition: xsh_subtract.c:194
cpl_frame * xsh_subtract_bias(cpl_frame *frame, cpl_frame *bias, xsh_instrument *instr, const char *type, const int pre_overscan_corr, const int save_tmp)
Subtract the master bias frame from PRE frame.
Definition: xsh_subtract.c:120
static void xsh_fill_bkg_mask_range(const int y, const int nx, const int xmin, const int xmax, const int x_hbox, const int decode_bp, int *qual, int *pmask, int *size)
Definition: xsh_subtract.c:300
int xsh_bkg_yskip_up_uvb[XSH_ORDERS_UVB]
Definition: xsh_subtract.c:62
static xsh_grid * xsh_crea_grid_from_mask(xsh_pre *pre, xsh_order_list *orderlist, const int x_hbox, xsh_instrument *instr, const char *prefix)
Generates sampling grid using sampling boxes distributed along inter-order background regions.
Definition: xsh_subtract.c:348
cpl_frame * xsh_subtract_dark(cpl_frame *frame, cpl_frame *dark, const char *filename, xsh_instrument *instr)
subtract the master dark frame from PRE frame
Definition: xsh_subtract.c:247
int xsh_bkg_yskip_lo_vis[XSH_ORDERS_VIS]
Definition: xsh_subtract.c:67
static cpl_image * xsh_image_generate_background(const int sx, const int sy, const polynomial *background_pol)
Subtract the previously defined background.
int xsh_bkg_yskip_lo_nir[XSH_ORDERS_NIR]
Definition: xsh_subtract.c:76
int xsh_bkg_yskip_up_nir[XSH_ORDERS_NIR]
Definition: xsh_subtract.c:82
void xsh_polynomial_delete(polynomial **p)
Delete a polynomial.
double xsh_polynomial_evaluate_2d(const polynomial *p, double x1, double x2)
Evaluate a 2d polynomial.
polynomial * xsh_polynomial_regression_2d(cpl_table *t, const char *X1, const char *X2, const char *Y, const char *sigmaY, int degree1, int degree2, const char *polynomial_fit, const char *residual_square, const char *variance_fit, double *mse, double *red_chisq, polynomial **variance, double kappa, double min_reject)
Fit a 2d polynomial to three table columns.
Definition: xsh_utils.c:3423
int xsh_select_table_rows(cpl_table *t, const char *column, cpl_table_select_operator operator, double value)
Select table rows.
Definition: xsh_utils.c:3784
void xsh_free_image(cpl_image **i)
Deallocate an image and set the pointer to NULL.
Definition: xsh_utils.c:2116
void xsh_free_frame(cpl_frame **f)
Deallocate a frame and set the pointer to NULL.
Definition: xsh_utils.c:2269
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_table(cpl_table **t)
Deallocate a table and set the pointer to NULL.
Definition: xsh_utils.c:2133
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
Definition: xsh_utils.c:2179
void xsh_add_temporary_file(const char *name)
Add temporary file to temprary files list.
Definition: xsh_utils.c:1432
xsh_order * list
cpl_polynomial * edguppoly
cpl_polynomial * edglopoly
cpl_image * qual
Definition: xsh_data_pre.h:71
float exptime
Definition: xsh_data_pre.h:92
cpl_image * data
Definition: xsh_data_pre.h:65
cpl_propertylist * data_header
Definition: xsh_data_pre.h:66
int biny
Definition: xsh_data_pre.h:80
int binx
Definition: xsh_data_pre.h:80
cpl_image * errs
Definition: xsh_data_pre.h:68
#define XSH_ORDERS_NIR
#define XSH_ORDERS_VIS
@ XSH_ARM_UVB
@ XSH_ARM_NIR
@ XSH_ARM_VIS
#define XSH_ORDERS_UVB
#define XSH_NAME_PREFIX_LAMP_MODE_ARM(name, prefix, id, ext, instr)
#define XSH_PRE_DATA_TYPE
Definition: xsh_data_pre.h:42
int nx
double kappa
Definition: xsh_detmon_lg.c:81
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_FREE(POINTER)
Definition: xsh_utils.h:92
#define XSH_MALLOC(POINTER, TYPE, SIZE)
Definition: xsh_utils.h:49
#define XSH_NEW_FRAMESET(POINTER)
Definition: xsh_utils.h:84