00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030 #include <xsh_cpl_size.h>
00031
00038
00041
00042
00043
00044 #include <math.h>
00045 #include <xsh_utils.h>
00046 #include <xsh_drl.h>
00047 #include <xsh_pfits.h>
00048 #include <xsh_error.h>
00049 #include <xsh_msg.h>
00050 #include <xsh_badpixelmap.h>
00051 #include <xsh_utils_image.h>
00052 #include <xsh_data_order.h>
00053 #include <xsh_data_grid.h>
00054
00055
00056
00057
00058 int xsh_bkg_yskip_lo_uvb[XSH_ORDERS_UVB]={0,0,0,0,
00059 0,0,0,0,
00060 0,0,0,0};
00061
00062 int xsh_bkg_yskip_up_uvb[XSH_ORDERS_UVB]={0,0,0,0,
00063 0,0,0,0,
00064 0,0,0,0};
00065
00066
00067 int xsh_bkg_yskip_lo_vis[XSH_ORDERS_VIS]={0,0,0,0,0,
00068 0,0,0,0,0,
00069 0,0,0,0,0};
00070
00071 int xsh_bkg_yskip_up_vis[XSH_ORDERS_VIS]={0,0,0,0,0,
00072 50,50,70,50,50,
00073 50,50,50,50,50};
00074
00075
00076 int xsh_bkg_yskip_lo_nir[XSH_ORDERS_NIR]={0,0,0,0,
00077 0,50,50,80,
00078 70,50,50,50,
00079 50,50,50,50};
00080
00081
00082 int xsh_bkg_yskip_up_nir[XSH_ORDERS_NIR]={0,0,0,0,
00083 0,50,100,60,
00084 90,70,50,50,
00085 50,50,50,50};
00086
00087
00088
00089
00090 static cpl_image*
00091 xsh_image_generate_background(const int sx, const int sy, const polynomial *background_pol);
00092
00093 static cpl_image*
00094 xsh_background_poly(xsh_pre* image, cpl_table** grid_tbl,xsh_background_param* back_par);
00095
00096
00097
00098
00099
00100
00119 cpl_frame*
00120 xsh_subtract_bias( cpl_frame *frame,
00121 cpl_frame *bias,
00122 xsh_instrument* instr,
00123 const char * type,
00124 const int pre_overscan_corr,
00125 const int save_tmp)
00126 {
00127
00128 cpl_frame * result = NULL;
00129
00130 xsh_pre* xframe = NULL;
00131 xsh_pre* xbias = NULL;
00132
00133 char resultname[256];
00134
00135
00136 char tag[256];
00137 double avg=0;
00138
00139
00140 XSH_ASSURE_NOT_NULL( frame);
00141 XSH_ASSURE_NOT_NULL( bias);
00142 XSH_ASSURE_NOT_NULL( instr);
00143
00144
00145 check( xframe = xsh_pre_load( frame, instr));
00146 check( xbias = xsh_pre_load( bias, instr));
00147
00148
00149
00150
00151 if(pre_overscan_corr==0) {
00152 check( xsh_pre_subtract( xframe, xbias));
00153 } else {
00154
00155
00156
00157 check(avg=cpl_image_get_mean(xbias->data));
00158 check(xsh_pre_subtract_scalar(xbias,avg));
00159 check( xsh_pre_subtract( xframe, xbias));
00160 }
00161
00162 sprintf(tag,"%sON_%s",type,xsh_instrument_arm_tostring (instr));
00163
00164
00165
00166
00167 sprintf(resultname,"%s.fits",tag);
00168
00169 check( xsh_pfits_set_pcatg( xframe->data_header, tag));
00170 check( result = xsh_pre_save ( xframe, resultname, tag,save_tmp));
00171 check( cpl_frame_set_tag( result,tag));
00172
00173 cleanup:
00174 if ( cpl_error_get_code() != CPL_ERROR_NONE) {
00175 xsh_free_frame( &result);
00176 }
00177 xsh_pre_free( &xframe);
00178 xsh_pre_free( &xbias);
00179 return result;
00180 }
00181
00182
00183
00184
00193
00194 cpl_frameset* xsh_subtract_nir_on_off(cpl_frameset* on, cpl_frameset* off,
00195 xsh_instrument* instr){
00196
00197 cpl_frameset * result = NULL;
00198
00199 cpl_frame* res = NULL;
00200
00201 char resultname[256];
00202 int i = 0, size_on = 0, size_off = 0;
00203
00204
00205 XSH_ASSURE_NOT_NULL(on);
00206 XSH_ASSURE_NOT_NULL(off);
00207 XSH_ASSURE_NOT_NULL(instr);
00208
00209 check(size_on = cpl_frameset_get_size(on));
00210 check(size_off = cpl_frameset_get_size(off));
00211
00212 XSH_ASSURE_NOT_ILLEGAL(size_on == size_off);
00213
00214 XSH_NEW_FRAMESET(result);
00215
00216
00217 for ( i=0; i< size_on; i++) {
00218 cpl_frame* on_f = NULL;
00219 cpl_frame* off_f = NULL;
00220
00221 check( on_f = cpl_frameset_get_frame(on,i));
00222 check( off_f = cpl_frameset_get_frame(off,i));
00223 sprintf(resultname, "ON-OFF_%d.fits",i);
00224
00225 check( res = xsh_subtract_dark(on_f, off_f, resultname, instr));
00226 check(cpl_frameset_insert(result, res));
00227 xsh_add_temporary_file(resultname);
00228 }
00229
00230 cleanup:
00231 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00232 xsh_free_frameset(&result);
00233 xsh_free_frame(&res);
00234 }
00235 return result;
00236 }
00237
00246
00247 cpl_frame * xsh_subtract_dark(cpl_frame * frame,cpl_frame * dark,
00248 const char* filename, xsh_instrument* instr)
00249 {
00250
00251 cpl_frame * result = NULL;
00252
00253 xsh_pre* xframe = NULL;
00254 xsh_pre* xdark = NULL;
00255
00256 double exptime = 0.0;
00257 double dit_raw=0;
00258 double dit_dark=0;
00259 double dit_tol=0.001;
00260 const char* tag=NULL;
00261
00262
00263 XSH_ASSURE_NOT_NULL(frame);
00264 XSH_ASSURE_NOT_NULL(dark);
00265 XSH_ASSURE_NOT_NULL(filename);
00266 XSH_ASSURE_NOT_NULL(instr);
00267
00268
00269 check(xframe = xsh_pre_load(frame, instr));
00270 check(xdark = xsh_pre_load(dark, instr));
00271
00272
00273 if (xsh_instrument_get_arm(instr) != XSH_ARM_NIR) {
00274 exptime = xframe->exptime;
00275 assure(exptime > 0,CPL_ERROR_ILLEGAL_INPUT,
00276 "EXPTIME must be greater than 0 : %f",exptime);
00277 check(xsh_pre_multiply_scalar(xdark,exptime));
00278 } else {
00279 dit_raw=xsh_pfits_get_dit(xframe->data_header);
00280 dit_dark=xsh_pfits_get_dit(xdark->data_header);
00281 XSH_ASSURE_NOT_ILLEGAL_MSG( fabs(dit_raw-dit_dark) < dit_tol,"Make sure dark has same DIT as raw data");
00282 }
00283
00284 check(xsh_pre_subtract(xframe,xdark));
00285
00286 tag=cpl_frame_get_tag(frame);
00287 check(result = xsh_pre_save (xframe, filename, tag,0));
00288 check(cpl_frame_set_tag (result,tag));
00289
00290 cleanup:
00291 if (cpl_error_get_code () != CPL_ERROR_NONE) {
00292 xsh_free_frame(&result);
00293 }
00294 xsh_pre_free(&xframe);
00295 xsh_pre_free(&xdark);
00296 return result;
00297 }
00298
00299
00300 inline static void xsh_fill_bkg_mask_range(const int y, const int nx, const int xmin,
00301 const int xmax, const int x_hbox,
00302 const int decode_bp, int* qual,
00303 int* pmask, int* size) {
00304 int x = 0;
00305 int xcen=0;
00306 int xs=0;
00307 int xe=0;
00308 int offset = nx*y;
00309 if((xmax-xmin+1) >= 2*x_hbox+1) {
00310 xcen = 0.5*(xmin+xmax);
00311 xs = xcen-x_hbox;
00312 xe = xcen+x_hbox;
00313 xs = (xs > 0) ? xs: 0;
00314 xe = (xe < nx) ? xe: nx-1;
00315
00316 for (x = xs; x <= xe; x++) {
00317 if ( (qual[offset + x] & decode_bp) == 0) {
00318 pmask[offset + x] = 1;
00319 (*size)++;
00320 }
00321 }
00322
00323 } else {
00324
00325 }
00326 return;
00327 }
00328
00329
00330
00346
00347 static xsh_grid*
00348 xsh_crea_grid_from_mask(xsh_pre *pre, xsh_order_list *orderlist,
00349 const int x_hbox , xsh_instrument *instr,const char* prefix) {
00350 xsh_grid *grid = NULL;
00351
00352 int ord = 0;
00353 int x = 0;
00354 int y = 0;
00355 int xmin = 0;
00356 int xmax = 0;
00357
00358
00359 float x1 = 0, x2 = 0;
00360 int* pmask = NULL;
00361 int* pqual = NULL;
00362 cpl_image* mask = NULL;
00363 int nx = pre->nx;
00364 int ny = pre->ny;
00365 int lost = 0;
00366 float* pdata = NULL;
00367
00368 int size = 0;
00369
00370 int pix = 0;
00371 float sx_illum = 0;
00372 float sx_backg = 0;
00373 int decode_bp=0;
00374 int* qual=NULL;
00375
00376 float* perrs=NULL;
00377 int y_skip_up=0;
00378 int y_skip_lo=0;
00379 int x_margin1=0;
00380 int x_margin2=0;
00381
00382 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
00383 y_skip_lo=20;
00384 y_skip_up=20;
00385 x_margin1=40;
00386 x_margin2=80;
00387
00388 } else if (xsh_instrument_get_arm(instr) == XSH_ARM_UVB) {
00389 x_margin1=21;
00390 x_margin2=135;
00391 if ( strcmp(prefix,"MFLAT_D2") == 0 ) {
00392 y_skip_lo=0;
00393 y_skip_up=0;
00394 }
00395
00396 } else if (xsh_instrument_get_arm(instr) == XSH_ARM_VIS) {
00397 x_margin1=30;
00398 x_margin2=134;
00399
00400 }
00401 decode_bp=instr->decode_bp;
00402
00403 qual=cpl_image_get_data_int(pre->qual);
00404
00405
00406 mask = cpl_image_new(nx, ny, CPL_TYPE_INT);
00407 pmask = cpl_image_get_data_int(mask);
00408 xsh_msg("prepare mask data");
00409 for (y = 1; y < ny; y++) {
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 for (ord = orderlist->size - 1; ord > 0; ord--) {
00425 int starty, endy;
00426 starty = orderlist->list[ord - 1].starty;
00427 endy = orderlist->list[ord - 1].endy;
00428 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
00429 y_skip_lo=xsh_bkg_yskip_lo_nir[ord];
00430 y_skip_up=xsh_bkg_yskip_up_nir[ord];
00431 }
00432 if (xsh_instrument_get_arm(instr) == XSH_ARM_UVB) {
00433 y_skip_lo=xsh_bkg_yskip_lo_uvb[ord];
00434 y_skip_up=xsh_bkg_yskip_up_uvb[ord];
00435 }
00436 starty += y_skip_lo;
00437 endy -= y_skip_up;
00438
00439
00440 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
00441 if (y <= starty || y >= endy) {
00442 lost++;
00443 continue;
00444 }
00445 } else {
00446 if (ord < (orderlist->size - 1)) {
00447 if (y <= starty || y >= endy) {
00448 lost++;
00449 continue;
00450 }
00451 }
00452 }
00453
00454
00455 if( ord >0 ) {
00456
00457 x1 = xsh_order_list_eval(orderlist, orderlist->list[ord].edguppoly, y);
00458 x2 = xsh_order_list_eval(orderlist, orderlist->list[ord - 1].edglopoly,
00459 y);
00460 xmin = x1;
00461 xmax = x2;
00462
00463 xsh_fill_bkg_mask_range(y,nx,xmin,xmax,x_hbox,decode_bp,qual,pmask,&size);
00464
00465 }
00466
00467
00468 if (ord == orderlist->size - 1) {
00469 if ( strcmp(prefix,"MFLAT_D2") == 0 ) {
00470
00471
00472
00473
00474
00475
00476
00477 if (y <= starty || y >= endy) {
00478 lost++;
00479 continue;
00480 }
00481
00482 x1 = xsh_order_list_eval(orderlist,
00483 orderlist->list[orderlist->size - 1].edglopoly, y);
00484 x2 = xsh_order_list_eval(orderlist,
00485 orderlist->list[orderlist->size - 1].edguppoly, y);
00486
00487 sx_illum = x2 - x1;
00488 x1 = xsh_order_list_eval(orderlist,
00489 orderlist->list[orderlist->size - 1].edguppoly, y);
00490 x2 = xsh_order_list_eval(orderlist,
00491 orderlist->list[orderlist->size - 2].edglopoly, y);
00492
00493 sx_backg = x2 - x1;
00494 x2 = xsh_order_list_eval(orderlist,
00495 orderlist->list[orderlist->size - 1].edglopoly, y);
00496 x1 = x2 - sx_backg;
00497
00498 xmin = x1;
00499 xmax = x2;
00500
00501 xsh_fill_bkg_mask_range(y , nx, xmin, xmax, x_hbox, decode_bp,qual, pmask,
00502 &size);
00503
00504
00505 x2 = x1 - sx_illum;
00506 x1 = x2-sx_backg;
00507 xmin = x1+x_hbox-20;
00508 xmax = x2-x_hbox-10;
00509 int xmin1=xmin;
00510 int xmax1=xmax;
00511
00512 if (y <= 650 || y >= endy) {
00513 lost++;
00514 continue;
00515 }
00516
00517 xsh_fill_bkg_mask_range(y , nx, xmin1, xmax1, x_hbox, decode_bp,qual, pmask,
00518 &size);
00519
00520
00521 x2 = x1 - sx_illum;
00522 x1 = x2-sx_backg;
00523 xmin = x1+x_hbox-50;
00524 xmax = x2-x_hbox-40;
00525 int xmin2=xmin;
00526 int xmax2=xmax;
00527
00528
00529
00530
00531 if (y <= 1600 || y >= endy) {
00532 lost++;
00533 continue;
00534 }
00535
00536
00537 xsh_fill_bkg_mask_range(y , nx, xmin2, xmax2, x_hbox, decode_bp,qual, pmask,
00538 &size);
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 continue;
00556
00557 } else {
00558
00559
00560
00561
00562
00563
00564 if (xsh_instrument_get_arm(instr) != XSH_ARM_UVB) {
00565 x1 = xsh_order_list_eval(orderlist,
00566 orderlist->list[orderlist->size - 1].edglopoly, y);
00567 x2 = xsh_order_list_eval(orderlist,
00568 orderlist->list[orderlist->size - 1].edguppoly, y);
00569
00570 sx_illum = x2 - x1;
00571 x1 = xsh_order_list_eval(orderlist,
00572 orderlist->list[orderlist->size - 1].edguppoly, y);
00573 x2 = xsh_order_list_eval(orderlist,
00574 orderlist->list[orderlist->size - 2].edglopoly, y);
00575
00576 sx_backg = x2 - x1;
00577 x2 = xsh_order_list_eval(orderlist,
00578 orderlist->list[orderlist->size - 1].edglopoly, y);
00579 x1 = x2 - sx_backg + x_hbox;
00580 x2 -= x_hbox;
00581
00582 xmin = x1;
00583 xmax = x2;
00584
00585 xsh_fill_bkg_mask_range(y , nx, xmin, xmax, x_hbox, decode_bp,qual, pmask,
00586 &size);
00587
00588 }
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601 continue;
00602 }
00603 } else {
00604
00605 if ( strcmp(prefix,"MFLAT_D2") == 0 ) {
00606
00607 if (ord == orderlist->size - 2) {
00608 if (y <= starty || y >= endy) {
00609 xsh_msg("starty=%d endy=%d yskip=%d %d",starty,endy,y_skip_lo,y_skip_up);
00610 lost++;
00611 continue;
00612 }
00613 }
00614 }
00615
00616 }
00617
00618 if (ord == 1) {
00619
00620 x1 = xsh_order_list_eval(orderlist, orderlist->list[0].edguppoly, y);
00621 xmin = x1;
00622 xmax = x1+x_margin1;
00623 xsh_fill_bkg_mask_range(y,nx,xmin,xmax,x_hbox,decode_bp,qual,pmask,&size);
00624 if( xsh_instrument_get_arm(instr) != XSH_ARM_NIR ) {
00625
00626 xmin = xmax;
00627 xmax = xmin+x_margin2;
00628 xsh_fill_bkg_mask_range(y,nx,xmin,xmax,x_hbox,decode_bp,qual,pmask,&size);
00629
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 continue;
00641
00642
00643 }
00644
00645 }
00646
00647 }
00648
00649
00650 check( grid = xsh_grid_create(size));
00651 char name[256];
00652 sprintf(name,"bkg_mask_%s.fits",prefix);
00653
00654
00655 pdata = cpl_image_get_data_float(pre->data);
00656 perrs = cpl_image_get_data_float(pre->errs);
00657 pqual = cpl_image_get_data_int(pre->qual);
00658
00659 for (y = 1; y < ny; y++) {
00660 for (x = 1; x < nx; x++) {
00661 pix = y * nx + x;
00662 if ((pmask[pix] == 1) && ((pqual[pix] & instr->decode_bp) == 0)) {
00663 check( xsh_grid_add(grid, x, y, pdata[pix],perrs[pix],pqual[pix]));
00664 }
00665 }
00666 }
00667
00668
00669
00670 check( xsh_grid_sort(grid));
00671
00672 cleanup:
00673 xsh_free_image(&mask);
00674 return grid;
00675 }
00676
00677
00693
00694 static xsh_grid*
00695 xsh_crea_grid_from_samples(xsh_pre *pre, xsh_order_list *orderlist,
00696 xsh_background_param *background_par, xsh_instrument *instr) {
00697
00698
00699 xsh_grid *grid = NULL;
00700
00701 double *tab = NULL;
00702
00703 int grid_size_x = 0, grid_size_y = 0;
00704 int incr = 0, i = 0, y = 0, lost = 0;
00705 int status = 0;
00706 int x = 0;
00707 float x1 = 0, x2 = 0, dx = 0;
00708 double medflux = 0.0;
00709
00710
00711 grid_size_x = orderlist->size + 5;
00712 grid_size_y = background_par->sampley + 2;
00713
00714 assure(background_par->sampley > 0, CPL_ERROR_ILLEGAL_INPUT,
00715 "parameter background-nb-y=%d "
00716 "must be set to a positive value", background_par->sampley);
00717 XSH_ASSURE_NOT_ILLEGAL(background_par->radius_x >= 0);
00718 XSH_ASSURE_NOT_ILLEGAL(background_par->radius_y >= 0);
00719
00720 assure(
00721 grid_size_y > 0 && grid_size_y < pre->ny,
00722 CPL_ERROR_ILLEGAL_INPUT,
00723 "grid_size_y=%d must be in (0,%d) range "
00724 "parameter background-nb-y=%d "
00725 "may have been set to a too large or too small value", grid_size_y, pre->ny, background_par->sampley);
00726
00727 check( grid = xsh_grid_create( grid_size_x*grid_size_y));
00728
00729
00730 assure(
00731 background_par->radius_x<pre->nx,
00732 CPL_ERROR_ILLEGAL_INPUT,
00733 "parameter -background-radius-x (%d) must be > 0 and < %d", background_par->radius_x, pre->nx);
00734 assure(
00735 background_par->radius_y<pre->ny,
00736 CPL_ERROR_ILLEGAL_INPUT,
00737 "parameter -background-radius-y (%d) must be > 0 and < %d", background_par->radius_y, pre->ny);
00738
00739 int box_sizex = 2 * background_par->radius_x + 1;
00740 int box_sizey = 2 * background_par->radius_y + 1;
00741 XSH_MALLOC(tab, double, box_sizex*box_sizey);
00742
00743
00744 incr = (int) ceil((float) pre->ny / (float) background_par->sampley);
00745 int sizey = 0;
00746 int oy = 0;
00747
00748 for (y = 1; y <= (pre->ny - 1 + incr); y += incr) {
00749
00750
00751 if ((y + incr) > pre->ny) {
00752 y = pre->ny;
00753 }
00754
00755
00756 if ((y == 1) || (y == pre->ny)) {
00757 sizey = background_par->radius_y + 1;
00758 oy = 0;
00759 } else {
00760 sizey = box_sizey;
00761 oy = -background_par->radius_y;
00762 }
00763
00764
00765
00766
00767
00768 check(
00769 medflux = xsh_pre_data_window_median_flux_pa(pre, 1, y+oy, box_sizex, sizey, tab,&status));
00770
00771 if (status == 0) {
00772
00773 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
00774 if ((y <= orderlist->list[orderlist->size - 2].starty)
00775 || y >= orderlist->list[orderlist->size - 2].endy) {
00776
00777 check( xsh_grid_add(grid, 1, y, medflux,1,0));
00778 } else {
00779 lost++;
00780 }
00781 } else {
00782 check( xsh_grid_add(grid, 1, y, medflux,1,0));
00783 }
00784 } else {
00785 lost++;
00786 }
00787
00788
00789 for (i = orderlist->size - 1; i > 0; i--) {
00790 int starty, endy;
00791 starty = orderlist->list[i - 1].starty;
00792 endy = orderlist->list[i - 1].endy;
00793
00794
00795 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
00796 if (y <= starty || y >= endy) {
00797 lost++;
00798 continue;
00799 }
00800 }
00801
00802
00803 if (starty == -999) {
00804
00805
00806
00807
00808
00809 xsh_msg("PROBLEMS");
00810 check(xsh_grid_add(grid, 0, y, 0.,1,0));
00811 lost++;
00812 break;
00813 }
00814
00815
00816 check(
00817 x1 = xsh_order_list_eval( orderlist, orderlist->list[i].edguppoly, y));
00818 check(
00819 x2 = xsh_order_list_eval( orderlist, orderlist->list[i-1].edglopoly, y));
00820
00821 x = floor(0.5 * (x1 + x2 + 1));
00822 dx = 0.5 * (x2 - x1);
00823 xsh_msg_dbg_high("x %d dx %f", x, dx);
00824
00825 if ((x > (background_par->radius_x + 1)) && (box_sizex < dx)) {
00826
00827
00828
00829
00830
00831 check(
00832 medflux = xsh_pre_data_window_median_flux_pa(pre,x-background_par->radius_x, y+oy, box_sizex,sizey,tab,&status));
00833 if (status == 0) {
00834 check( xsh_grid_add(grid, x, y, medflux,1,0));
00835 } else {
00836 lost++;
00837 }
00838 } else {
00839
00840
00841 lost++;
00842 }
00843
00844
00845 if (i == (orderlist->size - 1)) {
00846 check(
00847 x2 = xsh_order_list_eval( orderlist, orderlist->list[i].edglopoly, y));
00848 x = x2 - dx;
00849 if (dx < 0) {
00850 xsh_msg("Monitor dx=%d x=%g y=%d", x, dx, y);
00851 }
00852 if (x > (background_par->radius_x + 1)) {
00853 check(
00854 medflux = xsh_pre_data_window_median_flux_pa(pre, x-background_par->radius_x, y+oy, box_sizex, sizey, tab,&status));
00855 if (status == 0) {
00856 check(xsh_grid_add(grid, x, y, medflux,1,0));
00857 } else {
00858 lost++;
00859 }
00860 } else {
00861 lost++;
00862 }
00863 }
00864
00865
00866 if (i == 1) {
00867 check(
00868 x1 = xsh_order_list_eval( orderlist, orderlist->list[0].edguppoly, y));
00869
00870 if (xsh_instrument_get_arm(instr) == XSH_ARM_VIS) {
00871 check(
00872 x2 = xsh_order_list_eval( orderlist, orderlist->list[0].edglopoly, y));
00873 x = x1 + (x1 - x2) * 1.2;
00874 } else {
00875 x = x1 + dx;
00876 }
00877 if ((x > (background_par->radius_x + 1))
00878 && (x + background_par->radius_x < pre->nx)) {
00879 check(
00880 medflux = xsh_pre_data_window_median_flux_pa(pre, x-background_par->radius_x, y+oy, box_sizex, sizey, tab,&status));
00881 if (status == 0) {
00882 check(xsh_grid_add(grid, x, y, medflux,1,0));
00883 } else {
00884 lost++;
00885 }
00886 } else {
00887 lost++;
00888 }
00889
00890 }
00891
00892 }
00893
00894
00895 check(
00896 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));
00897
00898 if (status == 0) {
00899
00900 if (xsh_instrument_get_arm(instr) == XSH_ARM_NIR) {
00901 if ((y <= orderlist->list[0].starty) || y >= orderlist->list[0].endy) {
00902
00903 check( xsh_grid_add(grid, x, y, medflux,1,0));
00904 } else {
00905 lost++;
00906 }
00907 } else {
00908 check( xsh_grid_add(grid, x, y, medflux,1,0));
00909 }
00910 } else {
00911 lost++;
00912 }
00913
00914 }
00915
00916 xsh_msg_dbg_low("Nb of lost points %d ", lost);
00917 xsh_msg_dbg_low("Nb of grid points %d ", xsh_grid_get_index(grid));
00918
00919
00920 check( xsh_grid_sort(grid));
00921
00922 cleanup: return grid;
00923
00924 }
00925
00926
00945
00946 cpl_frame* xsh_subtract_background( cpl_frame *frame,
00947 cpl_frame *edges_order_tab_frame,
00948 xsh_background_param *background_par,
00949 xsh_instrument *instr,
00950 const char *prefix,
00951 cpl_frame **grid_frame,
00952 cpl_frame **backg_frame,
00953 const int save_bkg,
00954 const int save_grid,
00955 const int save_sub_bkg)
00956 {
00957
00958 cpl_frame *result = NULL;
00959
00960 xsh_order_list *orderlist = NULL;
00961 xsh_pre *pre = NULL;
00962 xsh_grid *grid = NULL;
00963 cpl_image *background_img = NULL;
00964
00965
00966
00967 char *fname = NULL;
00968 char *pcatg = NULL;
00969
00970 cpl_propertylist *plist = NULL;
00971 cpl_table *grid_tbl = NULL;
00972
00973
00974 XSH_ASSURE_NOT_NULL_MSG( instr, "Instrument structure setting");
00975 XSH_ASSURE_NOT_NULL_MSG( frame,"Input frame");
00976 XSH_ASSURE_NOT_NULL_MSG( edges_order_tab_frame,"Edge table");
00977 XSH_ASSURE_NOT_NULL_MSG( background_par,"Background params");
00978 XSH_ASSURE_NOT_NULL_MSG( grid_frame,"Grid frame");
00979 XSH_ASSURE_NOT_NULL_MSG( backg_frame,"Background frame");
00980
00981
00982 check( pre = xsh_pre_load(frame, instr));
00983 check( orderlist = xsh_order_list_load( edges_order_tab_frame, instr));
00984 xsh_order_list_set_bin_x( orderlist, pre->binx);
00985 xsh_order_list_set_bin_y( orderlist, pre->biny);
00986
00987
00988
00989
00990
00991 check(grid=xsh_crea_grid_from_mask(pre, orderlist,background_par->edges_margin/pre->binx,instr,prefix));
00992
00993
00994
00995
00996
00997 xsh_msg("generate background image: poly");
00998 grid_tbl = xsh_grid2table(grid);
00999
01000 if( xsh_instrument_get_arm(instr) != XSH_ARM_UVB ) {
01001 xsh_grid_free( &grid);
01002 }
01003
01004
01005
01006
01007 check( background_img = xsh_background_poly(pre, &grid_tbl,background_par));
01008 xsh_msg("Prepare final products");
01009
01010 XSH_NAME_PREFIX_LAMP_MODE_ARM( pcatg, prefix, "_BACK", "", instr);
01011 XSH_NAME_PREFIX_LAMP_MODE_ARM( fname, prefix, "_BACK", ".fits", instr);
01012 plist=cpl_propertylist_new();
01013 double crpix1=1.;
01014 double crval1=1.;
01015 double cdelt1=xsh_instrument_get_binx(instr);
01016
01017 double crpix2=1.;
01018 double crval2=1.;
01019 double cdelt2=xsh_instrument_get_biny(instr);
01020
01021 check( xsh_pfits_set_pcatg( plist, pcatg));
01022 xsh_pfits_set_wcs(plist,crpix1,crval1,cdelt1,crpix2,crval2,cdelt2);
01023 check( cpl_image_save( background_img, fname, CPL_BPP_IEEE_FLOAT,
01024 plist, CPL_IO_DEFAULT));
01025 if(!save_bkg) {
01026 xsh_add_temporary_file(fname);
01027 }
01028
01029 xsh_free_propertylist( &plist);
01030
01031 check( *backg_frame = xsh_frame_product( fname, pcatg,
01032 CPL_FRAME_TYPE_IMAGE, CPL_FRAME_GROUP_CALIB,
01033 CPL_FRAME_LEVEL_FINAL));
01034
01035
01036 check( cpl_image_subtract( pre->data, background_img));
01037
01038 XSH_FREE( fname);
01039 XSH_FREE( pcatg);
01040 XSH_NAME_PREFIX_LAMP_MODE_ARM( fname, prefix, "_SUB_BACK", ".fits", instr);
01041 XSH_NAME_PREFIX_LAMP_MODE_ARM( pcatg, prefix, "_SUB_BACK", "", instr);
01042
01043 check( xsh_pfits_set_pcatg( pre->data_header, pcatg));
01044
01045 if(save_sub_bkg==0) {
01046 check( result = xsh_pre_save( pre, fname, pcatg, 1));
01047 } else {
01048 check( result = xsh_pre_save( pre, fname, pcatg, 0));
01049 }
01050
01051
01052 check(cpl_frame_set_tag (result, pcatg));
01053 check(cpl_frame_set_type (result, CPL_FRAME_TYPE_IMAGE));
01054 check(cpl_frame_set_group (result, CPL_FRAME_GROUP_CALIB));
01055 check(cpl_frame_set_level (result, CPL_FRAME_LEVEL_FINAL));
01056
01057
01058
01059
01060
01061
01062 XSH_FREE( fname);
01063 XSH_FREE( pcatg);
01064 XSH_NAME_PREFIX_LAMP_MODE_ARM( fname, prefix, "_GRID_BACK", ".fits", instr);
01065 XSH_NAME_PREFIX_LAMP_MODE_ARM( pcatg, prefix, "_GRID_BACK", "", instr);
01066
01067 plist = cpl_propertylist_new();
01068 check( xsh_pfits_set_pcatg( plist, pcatg));
01069 check( cpl_table_save( grid_tbl, plist, NULL, fname, CPL_IO_DEFAULT));
01070 xsh_free_propertylist( &plist);
01071 xsh_free_table( &grid_tbl);
01072
01073 if(save_grid==0) {
01074 xsh_add_temporary_file(fname);
01075 }
01076
01077
01078 *grid_frame =xsh_frame_product(fname,pcatg,CPL_FRAME_TYPE_TABLE,
01079 CPL_FRAME_GROUP_CALIB,CPL_FRAME_LEVEL_FINAL);
01080
01081
01082 cleanup:
01083
01084 if (cpl_error_get_code () != CPL_ERROR_NONE) {
01085 xsh_free_frame(&result);
01086 }
01087
01088 xsh_free_propertylist(&plist);
01089 xsh_order_list_free( &orderlist);
01090 XSH_FREE( fname);
01091 XSH_FREE( pcatg);
01092
01093 xsh_pre_free( &pre);
01094 xsh_free_image( &background_img);
01095
01096 return result;
01097 }
01098
01099
01111
01112
01113 static cpl_image*
01114 xsh_image_generate_background(const int sx, const int sy, const polynomial *background_pol)
01115 {
01116 int x, y;
01117 cpl_image* image_bkg=NULL;
01118 float *background_data = NULL;
01119 int offset=0;
01120
01121 image_bkg=cpl_image_new(sx,sy,XSH_PRE_DATA_TYPE);
01122 background_data = cpl_image_get_data_float(image_bkg);
01123
01124 for (y = 1; y <= sy; y++)
01125 {
01126 offset=(y-1)*sx;
01127 for (x = 1; x <= sx; x++)
01128 {
01129 background_data[(x-1) + offset] = xsh_polynomial_evaluate_2d(background_pol,x,y);
01130 }
01131 }
01132
01133
01134 return image_bkg;
01135 }
01136
01137 static cpl_image*
01138 xsh_background_poly(xsh_pre* pre, cpl_table** grid_tab,xsh_background_param* background_par) {
01139
01140
01141 polynomial* background = NULL;
01142 double mse = 0, rmse = 0;
01143 cpl_size total_clipped = 0;
01144 cpl_image* bkg_img = NULL;
01145
01146 int degx = background_par->poly_deg_x;
01147 int degy = background_par->poly_deg_y;
01148 double kappa = background_par->poly_kappa;
01149 xsh_msg("degx=%d degy=%d kappa=%g", degx, degy, kappa);
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 {
01162 cpl_size n_clipped;
01163 do {
01164 cpl_size deg_xy = (degx + 1) * (degy + 1);
01165 assure(
01166 cpl_table_get_nrow(*grid_tab) > (degx + 1)*(degy + 1),
01167 CPL_ERROR_ILLEGAL_OUTPUT,
01168 "Too few sample points available (%" CPL_SIZE_FORMAT " point(s)) to make the fit "
01169 "(more than %" CPL_SIZE_FORMAT " points needed). "
01170 "Increase number of sample points or increase kappa", cpl_table_get_nrow(*grid_tab), deg_xy);
01171
01172
01173 xsh_polynomial_delete(&background);
01174 check_msg(
01175 background = xsh_polynomial_regression_2d( *grid_tab, "X", "Y", "INT", "ERR", degx, degy, "INTfit", NULL, NULL, &mse, NULL, NULL, kappa, -1),
01176 "Error fitting polynomial");
01177
01178
01179 cpl_table_duplicate_column(*grid_tab, "Residual", *grid_tab, "INT");
01180 cpl_table_subtract_columns(*grid_tab, "Residual", "INTfit");
01181
01182
01183 rmse = cpl_table_get_column_stdev(*grid_tab, "Residual");
01184
01185 xsh_msg_dbg_medium("rmse=%g", rmse);
01186
01187 if (kappa > 0) {
01188 check_msg(
01189 n_clipped = xsh_select_table_rows( *grid_tab, "Residual", CPL_GREATER_THAN, kappa * rmse),
01190 "Error selecting rows");
01191
01192
01193
01194
01195
01196 } else {
01197 n_clipped = 0;
01198 }
01199
01200 total_clipped += n_clipped;
01201
01202
01203
01204
01205 xsh_msg(
01206 "RMS = %f. %" CPL_SIZE_FORMAT " of %" CPL_SIZE_FORMAT " points rejected in kappa-sigma clipping", rmse, n_clipped, cpl_table_get_nrow(*grid_tab));
01207
01208 cpl_table_erase_selected(*grid_tab);
01209
01210 if (n_clipped > 0) {
01211 cpl_table_erase_column(*grid_tab, "INTfit");
01212 cpl_table_erase_column(*grid_tab, "Residual");
01213 }
01214
01215 } while (n_clipped > 0);
01216 }
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235 {
01236 double percentage = 100.0 * ((double) total_clipped)
01237 / (total_clipped + cpl_table_get_nrow(*grid_tab));
01238
01239 if (kappa > 0) {
01240 xsh_msg_dbg_medium(
01241 "%" CPL_SIZE_FORMAT " of %" CPL_SIZE_FORMAT " points (%.2f %%) were rejected in "
01242 "kappa-sigma clipping. RMS = %.2f ADU", total_clipped, cpl_table_get_nrow(*grid_tab) + total_clipped, percentage, sqrt(mse));
01243 }
01244
01245
01246 }
01247
01248 check_msg( bkg_img=xsh_image_generate_background(pre->nx,pre->ny, background),
01249 "Error generating background polynomial");
01250
01251 cleanup:
01252
01253 xsh_polynomial_delete(&background);
01254 return bkg_img;
01255
01256 }
01257
01258
01259