X-shooter Pipeline Reference Manual 3.8.15
test-xsh_flux_conservation.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-04-26 14:10:08 $
23 * $Revision: 1.13 $
24 */
25#ifdef HAVE_CONFIG_H
26# include <config.h>
27#endif
28
29/*--------------------------------------------------------------------------*/
35/*--------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------
39 Includes
40 ---------------------------------------------------------------------------*/
41
42
43#include <cpl.h>
44#include <xsh_data_instrument.h>
45#include <xsh_pfits.h>
46#include <xsh_msg.h>
47#include <xsh_utils.h>
48#include <xsh_utils_image.h>
49#include <xsh_data_order.h>
50#include <tests.h>
51#include <math.h>
52
53#include <xsh_cpl_size.h>
54
55/*---------------------------------------------------------------------------
56 Defines
57 ---------------------------------------------------------------------------*/
58#define MODULE_ID "XSH_FLUX_CONSERVATION"
59/*---------------------------------------------------------------------------
60 Functions prototypes
61 ---------------------------------------------------------------------------*/
62
63/*--------------------------------------------------------------------------*/
70/*--------------------------------------------------------------------------*/
71
72/*
73 1 polynome (same for all orders)
74 constant coeff incresed by 20 for each order
75*/
76
77static const double poly0_coeff[] = {
78 280., 0.3, -0.0025 } ;
79static const double step = 40. ;
80
81static int nx = 400, ny = 400 ;
82static int starty = 10, endy = 380 ;
83static int dimension = 1, degree = 2, width = 10 ;
84static int norder = 3 ;
85static double exptime = 1. ;
86static const char * img_name = "dtc_img.fits" ;
87static const char * tbl_name = "dtc_tbl.fits" ;
88static const char * dtc_pre_name = "dtc_img_pre.fits" ;
89
90static double
91derivative_x(const double a1, const double a2, const double x){
92
93 return a1+2*a2*x;
94
95}
96
97static double
98derivative_y(const double a1, const double a2, const double y){
99
100 return a1+2*a2*y;
101
102}
103static void verify_order_table( cpl_frame * result )
104{
105 const char *hname ;
106
107 cpl_propertylist * header = NULL ;
108 double residavg = 0. ;
109
110 xsh_msg( " ====== verify_order_tables" ) ;
111
112 /* Get propertylist of new order_table
113 check RESIDAVG, should be < 1 pixel
114 */
115 check( hname = cpl_frame_get_filename( result ) ) ;
116 check( header = cpl_propertylist_load( hname, 0 ) ) ;
118 CPL_TYPE_DOUBLE, &residavg ) ) ;
119
120 assure( residavg < 1., CPL_ERROR_ILLEGAL_INPUT, "Error Too large" ) ;
121 xsh_msg( " Orders Detected OK, RESIDAVG = %lf", residavg ) ;
122
123 cleanup:
124 xsh_free_propertylist(&header);
125 return ;
126}
127
128int main(void)
129{
131 xsh_order_list * list = NULL ;
132 cpl_polynomial * poly0 = NULL ;
133 cpl_polynomial * poly1 = NULL ;
134 cpl_polynomial * poly2 = NULL ;
135 cpl_image *image = NULL ;
136 cpl_image *bias = NULL;
137 cpl_frame * img_frame = NULL, * tbl_frame = NULL, * dtc_frame = NULL,
138 * result_frame = NULL ;
139 xsh_pre * img_pre = NULL ;
140 xsh_clipping_param dcn_clipping ;
141 xsh_detect_continuum_param detect_param;
142
143 XSH_INSTRCONFIG *iconfig ;
144 cpl_propertylist * img_header ;
145
146
147 cpl_vector* xprofile=NULL;
148 cpl_vector* yprofile=NULL;
149 cpl_polynomial* poly_u=NULL;
150 cpl_polynomial* poly_v=NULL;
151 const int dim=2;
152 cpl_size pows[dim];
153 cpl_image* warped=NULL;
154 cpl_image* wone=NULL;
155 cpl_image* one=NULL;
156 cpl_image* dXdx=NULL;
157 cpl_image* dYdy=NULL;
158 cpl_image* dXdy=NULL;
159 cpl_image* dYdx=NULL;
160 cpl_image* corr=NULL;
161
162 cpl_vector* sup=NULL;
163 double* psup=NULL;
164 cpl_vector* inf=NULL;
165 double* pinf=NULL;
166
167 float* pdXdx=NULL;
168 float* pdYdy=NULL;
169 float* pdXdy=NULL;
170 float* pdYdx=NULL;
171 float* pcor=NULL;
172
173 int j=0;
174 int i=0;
175 cpl_size deg=0;
176 double f_org=0;
177 double f_cor=0;
178 double f_add=0;
179 double f_bad=0;
180 double f_end=0;
181 double add=0.1;
182 cpl_frame* resid_frame=NULL;
183
186 xsh_msg("detect_continuum");
191 xsh_instrument_set_recipe_id( instrument, "xsh_orderpos" ) ;
192
193 xsh_msg( " recipe_id: %s", instrument->recipe_id ) ;
194
196 iconfig->orders = norder ;
197
198 xsh_msg( "Create Order List with %d orders", norder ) ;
200
201 xsh_msg( "Create polynomials of degree %d", degree ) ;
202 poly0 = cpl_polynomial_new( dimension ) ;
203 poly1 = cpl_polynomial_new( dimension ) ;
204 poly2 = cpl_polynomial_new( dimension ) ;
205
206 /* Set polynomial coefficients */
207 {
208 deg = 0 ;
209
210 cpl_polynomial_set_coeff( poly0, &deg, poly0_coeff[deg] ) ;
211 cpl_polynomial_set_coeff( poly1, &deg, poly0_coeff[deg] + step ) ;
212 cpl_polynomial_set_coeff( poly2, &deg, poly0_coeff[deg] + 2*step ) ;
213
214 for( deg = 1 ; deg<= degree ; deg++ ) {
215 cpl_polynomial_set_coeff( poly0, &deg, poly0_coeff[deg] ) ;
216 cpl_polynomial_set_coeff( poly1, &deg, poly0_coeff[deg] ) ;
217 cpl_polynomial_set_coeff( poly2, &deg, poly0_coeff[deg] ) ;
218 }
219 }
220
221 xsh_msg( "Add to order list" ) ;
222 add_to_order_list( list, 0, 1, poly0, width, starty, endy ) ;
223 add_to_order_list( list, 1, 2, poly1, width, starty, endy ) ;
224 add_to_order_list( list, 2, 3, poly2, width, starty, endy ) ;
225
226 xsh_order_list_dump( list, "orders.dmp" ) ;
227
228 /* Save image and create Frame accordingly */
229 img_frame = cpl_frame_new() ;
230 img_header = mkHeader( iconfig, nx, ny, exptime ) ;
231
232 check( image = create_order_image( list, nx, ny ) ) ;
233 cpl_image_save( image, img_name, CPL_BPP_IEEE_DOUBLE, img_header,
234 CPL_IO_DEFAULT);
235
236 cpl_frame_set_filename( img_frame, img_name ) ;
237 cpl_frame_set_tag( img_frame, "ORDERDEF_VIS_D2" );
238 cpl_frame_set_level( img_frame, CPL_FRAME_LEVEL_TEMPORARY);
239 cpl_frame_set_group( img_frame, CPL_FRAME_GROUP_RAW ) ;
240
241 /* Save this frame as a PRE frame */
242 bias = xsh_test_create_bias_image( "BIAS.fits" ,nx, ny, instrument);
243 check( img_pre = xsh_pre_create( img_frame, NULL, bias, instrument,0,CPL_FALSE));
244 xsh_msg( "Saving PRE image \"%s\"", dtc_pre_name ) ;
245 check_msg( dtc_frame = xsh_pre_save( img_pre, dtc_pre_name, "TEST",1 ),
246 "Cant save pre structure" ) ;
247 cpl_frame_set_filename( dtc_frame, dtc_pre_name ) ;
248 cpl_frame_set_tag( dtc_frame, "ORDERDEF_UVB_D2" );
249 cpl_frame_set_level( dtc_frame, CPL_FRAME_LEVEL_TEMPORARY);
250 cpl_frame_set_group( dtc_frame, CPL_FRAME_GROUP_RAW ) ;
251
252 /* Save order table frame */
253 check( tbl_frame = xsh_order_list_save( list, instrument, tbl_name,"ORDERDEF_UVB_D2",ny) ) ;
254
255
256 // Now warps the image
257 poly_u=cpl_polynomial_new(2);
258 poly_v=cpl_polynomial_new(2);
259
260
261 pows[0]=0;
262 pows[1]=0;
263 cpl_polynomial_set_coeff(poly_v,pows,poly0_coeff[0]);
264
265
266 pows[0]=0;
267 pows[1]=1;
268 cpl_polynomial_set_coeff(poly_v,pows,-poly0_coeff[1]);
269
270
271 pows[0]=0;
272 pows[1]=2;
273 cpl_polynomial_set_coeff(poly_v,pows,-poly0_coeff[2]);
274
275
276 pows[0]=0;
277 pows[1]=1;
278 cpl_polynomial_set_coeff(poly_u,pows,1.);
279 cpl_polynomial_dump(poly_u,stdout);
280 cpl_polynomial_dump(poly_v,stdout);
281
282 check(warped=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
283 check(one=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
284 check(cpl_image_add_scalar(one,1.));
285 check(xprofile=cpl_vector_new(nx));
286 check(yprofile=cpl_vector_new(ny));
287 cpl_vector_fill_kernel_profile(xprofile, CPL_KERNEL_DEFAULT,
288 CPL_KERNEL_DEF_WIDTH);
289 cpl_vector_fill_kernel_profile(yprofile, CPL_KERNEL_DEFAULT,
290 CPL_KERNEL_DEF_WIDTH);
291/*
292 check(cpl_image_warp_polynomial(warped,img_pre->data,poly_u,poly_v,
293 xprofile,CPL_KERNEL_DEF_WIDTH,
294 yprofile,CPL_KERNEL_DEF_WIDTH));
295*/
296 xsh_free_vector(&xprofile);
297 xsh_free_vector(&yprofile);
298
299 xsh_free_image(&warped);
300 check(warped=xsh_warp_image_generic(img_pre->data,CPL_KERNEL_TANH,poly_u,poly_v));
301 check(wone=xsh_warp_image_generic(one,CPL_KERNEL_TANH,poly_u,poly_v));
302 check(cpl_image_divide(warped,wone));
303 xsh_free_image(&wone);
304
305 check(f_org=cpl_image_get_flux(img_pre->data));
306 check(f_bad=cpl_image_get_flux_window(warped,1,140,nx,216));
307
308 xsh_msg("Flux PRE frame: %g",f_org);
309 xsh_msg("Flux warp frame: %g",f_bad);
310
311 // Construct derivatives images
312 check(dXdx=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
313 check(dYdy=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
314 check(dXdy=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
315 check(dYdx=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
316 check(corr=cpl_image_new(nx,ny,CPL_TYPE_FLOAT));
317
318 check(pdXdx=cpl_image_get_data_float(dXdx));
319 check(pdYdy=cpl_image_get_data_float(dYdy));
320 check(pdXdy=cpl_image_get_data_float(dXdy));
321 check(pdYdx=cpl_image_get_data_float(dYdx));
322 check(pcor=cpl_image_get_data_float(corr));
323
324 check(sup=cpl_vector_new(2));
325 check(psup=cpl_vector_get_data(sup));
326 check(inf=cpl_vector_new(2));
327 check(pinf=cpl_vector_get_data(inf));
328
329 //Fill images with derivatives
330 for(j=1;j<ny-1;j++) {
331 for(i=1;i<nx-1;i++) {
332 psup[0]=(double)(i+1);
333 psup[1]=(double)j;
334
335 pinf[0]=(double)(i-1);
336 pinf[1]=(double)j;
337
338 pdXdx[i+j*nx]=1.;
339 /* In our case poly_v=1
340 check(pdXdx[i+j*nx]=(cpl_polynomial_eval(poly_u,sup)-
341 cpl_polynomial_eval(poly_u,inf)));
342
343 */
344
345/*
346 pdYdx[i+j*nx]=(cpl_polynomial_eval(poly_v,sup)-
347 cpl_polynomial_eval(poly_v,inf));
348*/
349
350 pdYdx[i+j*nx]=derivative_x(poly0_coeff[1],poly0_coeff[2],(double)i);
351
352 psup[0]=(double)i;
353 psup[1]=(double)(j+1);
354
355 pinf[0]=(double)i;
356 pinf[1]=(double)(j-1);
357
358/*
359 pdXdy[i+j*nx]=(cpl_polynomial_eval(poly_u,sup)-
360 cpl_polynomial_eval(poly_u,inf));
361*/
362 pdXdy[i+j*nx]=0.;
363
364 pdYdy[i+j*nx]=derivative_y(poly0_coeff[1],poly0_coeff[2],(double)j);
365
366
367 //xsh_msg("i=%d j=%d pdYdx=%g pdXdy=%g",i,j,pdYdx[i+j*nx],pdXdy[i+j*nx]);
368
369 /* In our case poly_v=1
370 check(pdYdy[i+j*nx]=(cpl_polynomial_eval(poly_v,sup)-
371 cpl_polynomial_eval(poly_v,inf)));
372
373 */
374/*
375 pcor[i+j*nx]=0.25*fabs(pdXdx[i+j*nx]*pdYdy[i+j*nx]-
376 pdXdy[i+j*nx]*pdYdx[i+j*nx]);
377
378*/
379
380 pcor[i+j*nx]=fabs(pdXdx[i+j*nx]*pdYdy[i+j*nx]-
381 pdXdy[i+j*nx]*pdYdx[i+j*nx]);
382
383 }
384 }
385
386 check(cpl_image_save(warped,"order_warped.fits",CPL_BPP_IEEE_FLOAT,NULL,
387 CPL_IO_DEFAULT));
388 check(cpl_image_save(wone,"wone.fits",CPL_BPP_IEEE_FLOAT,NULL,
389 CPL_IO_DEFAULT));
390 check(cpl_image_save(corr,"corr.fits",CPL_BPP_IEEE_FLOAT,NULL,
391 CPL_IO_DEFAULT));
392 cpl_image_add_scalar(corr,add);
393 check(cpl_image_divide(warped,corr));
394 f_cor=cpl_image_get_flux_window(corr,1,140,nx,216);
395
396 f_add=add*nx*ny;
397 xsh_msg("Flux add frame: %g",f_add);
398 f_end=cpl_image_get_flux_window(warped,1,140,nx,216);
399
400
401 xsh_msg("Flux corrected frame: %g",f_end);
402 xsh_msg("Flux predicted frame: %g",f_end*(f_add+f_cor)/f_cor);
403
404
405 check(cpl_image_save(warped,"corrected.fits",CPL_BPP_IEEE_FLOAT,NULL,
406 CPL_IO_DEFAULT));
407
408 /* Now detect continuum */
409 dcn_clipping.sigma = 2.5 ;
410 dcn_clipping.niter = 5 ;
411 dcn_clipping.frac = 0.7 ;
412 //The following value is crucial to the success of the test
413 //we use the min allowed to make the test pass
414 dcn_clipping.res_max = 0.4 ;
415
416 detect_param.search_window = 30;
417 detect_param.running_window = 7;
418 detect_param.fit_window = 10;
419 detect_param.poly_degree = 2;
420 detect_param.poly_step = 2;
421 detect_param.fit_threshold = 1.0;
422
424 // cpl_msg_set_level( CPL_MSG_DEBUG ) ;
425 check (result_frame = xsh_detect_continuum( dtc_frame, tbl_frame, NULL,
426 &detect_param,
427 &dcn_clipping,
428 instrument,&resid_frame) ) ;
429
430 /* Now Verify order tables */
431 check( verify_order_table( result_frame ) ) ;
432
433 cleanup:
434 xsh_free_frame(&resid_frame);
435 xsh_free_propertylist(&img_header);
436 xsh_free_polynomial(&poly0);
437 xsh_free_polynomial(&poly1);
438 xsh_free_polynomial(&poly2);
439 xsh_free_polynomial(&poly_u);
440 xsh_free_polynomial(&poly_v);
441
442 xsh_free_frame(&img_frame);
443 xsh_free_frame(&dtc_frame);
444 xsh_free_frame(&tbl_frame);
445 xsh_free_frame(&result_frame);
446 xsh_order_list_free(&list);
447 xsh_free_image(&image);
448 xsh_free_image(&bias);
449 xsh_free_image(&warped);
450 xsh_free_image(&wone);
451 xsh_free_image(&one);
452
453 xsh_free_image(&dXdx);
454 xsh_free_image(&dYdy);
455 xsh_free_image(&dXdy);
456 xsh_free_image(&dYdx);
457 xsh_free_image(&corr);
458
459
460 xsh_free_vector(&sup);
461 xsh_free_vector(&inf);
462 xsh_pre_free(&img_pre);
463 xsh_free_vector(&xprofile);
464 xsh_free_vector(&yprofile);
467 if (cpl_error_get_code() != CPL_ERROR_NONE) {
468 xsh_error_dump(CPL_MSG_ERROR);
469 return 1;
470 }
471 else {
472 return 0;
473 }
474
475}
476
static int nx
static const char * tbl_name
static double exptime
static int starty
static int dimension
static int width
static int endy
static double derivative_x(const double a1, const double a2, const double x)
static int degree
static int norder
static void verify_order_table(cpl_frame *result)
int main(void)
static const double step
static int ny
#define MODULE_ID
static double derivative_y(const double a1, const double a2, const double y)
static const char * dtc_pre_name
static const double poly0_coeff[]
Unit test of XSH_DETECT_CONTINUUM.
static const char * img_name
static xsh_instrument * instrument
xsh_order_list * create_order_list(int norder, xsh_instrument *instrument)
Definition: tests.c:410
void add_to_order_list(xsh_order_list *list, int order, int absorder, cpl_polynomial *poly, int xdelta, int starty, int endy)
Definition: tests.c:432
cpl_image * xsh_test_create_bias_image(const char *name, int nx, int ny, xsh_instrument *instrument)
Definition: tests.c:89
cpl_image * create_order_image(xsh_order_list *list, int nx, int ny)
Definition: tests.c:361
cpl_propertylist * mkHeader(XSH_INSTRCONFIG *iconfig, int nx, int ny, double exptime)
Definition: tests.c:221
cpl_frame * xsh_order_list_save(xsh_order_list *order_list, xsh_instrument *instrument, const char *filename, const char *tag, const int ny)
Save an order list to a frame.
void xsh_order_list_dump(xsh_order_list *list, const char *fname)
void xsh_order_list_free(xsh_order_list **list)
free memory associated to an order_list
void xsh_pre_free(xsh_pre **pre)
Free a xsh_pre structure.
Definition: xsh_data_pre.c:823
xsh_pre * xsh_pre_create(cpl_frame *raw, cpl_frame *bpmap, cpl_image *bias_data, xsh_instrument *instr, const int pre_overscan_corr, const bool flag_neg_and_thresh_pix)
Create a XSH_PRE from a raw frame.
Definition: xsh_data_pre.c:450
cpl_frame * xsh_pre_save(const xsh_pre *pre, const char *filename, const char *tag, int temp)
Save PRE on disk.
cpl_frame * xsh_detect_continuum(cpl_frame *frame, cpl_frame *order_table, cpl_frame *spectral_frame, xsh_detect_continuum_param *detect_param, xsh_clipping_param *dcn_clipping, xsh_instrument *instr, cpl_frame **resid_frame)
Detect order and compute polynomial description of ordermin and order max. Uses a guess order table i...
#define assure(CONDITION, ERROR_CODE,...)
Definition: xsh_error.h:54
#define check(COMMAND)
Definition: xsh_error.h:71
#define xsh_error_dump(level)
Definition: xsh_error.h:92
#define check_msg(COMMAND,...)
Definition: xsh_error.h:62
void xsh_instrument_set_mode(xsh_instrument *i, XSH_MODE mode)
Set a mode on instrument structure.
void xsh_instrument_set_recipe_id(xsh_instrument *instrument, const char *recipe_id)
Set the recipe_id into the instrument structure.
void xsh_instrument_set_arm(xsh_instrument *i, XSH_ARM arm)
Set an arm on instrument structure.
XSH_INSTRCONFIG * xsh_instrument_get_config(xsh_instrument *i)
Get the instrument default set of keywords.
void xsh_instrument_set_lamp(xsh_instrument *i, XSH_LAMP lamp)
Set a lamp on instrument structure.
void xsh_instrument_free(xsh_instrument **instrument)
free an instrument structure
xsh_instrument * xsh_instrument_new(void)
create new instrument structure
int * y
int * x
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
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
cpl_error_code xsh_get_property_value(const cpl_propertylist *plist, const char *keyword, cpl_type keywordtype, void *result)
Read a property value from a property list.
Definition: xsh_utils.c:1600
void xsh_free_frame(cpl_frame **f)
Deallocate a frame and set the pointer to NULL.
Definition: xsh_utils.c:2269
int xsh_debug_level_set(int level)
set debug level
Definition: xsh_utils.c:3125
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
Definition: xsh_utils.c:2179
const char * recipe_id
cpl_image * data
Definition: xsh_data_pre.h:65
#define TESTS_CLEAN_WORKSPACE(DRL_ID)
Definition: tests.h:139
#define TESTS_INIT_WORKSPACE(DRL_ID)
Definition: tests.h:133
#define TESTS_INIT(DRL_ID)
Definition: tests.h:105
@ XSH_LAMP_UNDEFINED
@ XSH_ARM_VIS
@ XSH_MODE_SLIT
#define QC_ORD_ORDERPOS_RESIDAVG
Definition: xsh_pfits_qc.h:176
@ XSH_DEBUG_LEVEL_LOW
Definition: xsh_utils.h:137
cpl_image * xsh_warp_image_generic(cpl_image *image_in, char *kernel_type, cpl_polynomial *poly_u, cpl_polynomial *poly_v)