X-shooter Pipeline Reference Manual 3.8.15
xsh_blaze.c
Go to the documentation of this file.
1/* a
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/*
22 * $Author: amodigli $
23 * $Date: 2012-08-09 15:08:55 $
24 * $Revision: 1.4 $
25 * $Name: not supported by cvs2svn $
26 */
27/*----------------------------------------------------------------------------
28 Includes
29 ----------------------------------------------------------------------------*/
30#include <math.h>
31#include <string.h>
32#include <xsh_error.h>
33#include <xsh_utils_ifu.h>
34#include <xsh_utils_image.h>
35#include <xsh_utils_wrappers.h>
36#include <xsh_utils_table.h>
37#include <xsh_pfits.h>
38#include <xsh_model_io.h>
39#include <xsh_data_rec.h>
40#include <xsh_data_spectrum.h>
41#include <xsh_dfs.h>
42#include <xsh_drl.h>
43#include <xsh_blaze.h>
44
45/*----------------------------------------------------------------------------*/
51/*----------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
56/*****************************************************************************/
70/*****************************************************************************/
71cpl_frame *xsh_divide_by_blaze( cpl_frame *pre_frame, cpl_frame *blaze_frame,
73{
74 xsh_pre *pre = NULL;
75 const char* blaze_name = NULL;
76 cpl_image *blaze_img = NULL;
77 cpl_frame *result_frame = NULL;
78 float *data1 = NULL;
79 float *data2 = NULL;
80 float *errs1 = NULL;
81 int i;
82 const char* tag = NULL;
83
84 XSH_ASSURE_NOT_NULL( pre_frame);
85 XSH_ASSURE_NOT_NULL( blaze_frame);
87
88 check( pre = xsh_pre_load( pre_frame, instrument));
89 check( tag = cpl_frame_get_tag( pre_frame));
90 check( blaze_name = cpl_frame_get_filename( blaze_frame));
91 check( blaze_img = cpl_image_load( blaze_name, CPL_TYPE_FLOAT,0,0));
92
93 check( data1 = cpl_image_get_data_float( pre->data));
94 check( errs1 = cpl_image_get_data_float( pre->errs));
95 check( data2 = cpl_image_get_data_float( blaze_img));
96
97 for(i=0;i< pre->nx*pre->ny; i++){
98
99 if ( data2[i] == 0){
100 data1[i] = 0;
101 }
102 else {
103 double d1 = 0.0, d2 = 0.0;
104 double e1 = 0.0;
105 d1 = data1[i];
106 d2 = data2[i];
107 e1 = errs1[i];
108 data1[i] = (float)(d1/d2);
109 errs1[i] = (float)(e1/d2);
110 }
111 }
112
113 check( result_frame = xsh_pre_save ( pre, "DIV_BY_BLAZE.fits", tag, 1));
114 check( cpl_frame_set_tag ( result_frame, tag));
115
116 cleanup:
117 xsh_free_image( &blaze_img);
118 xsh_pre_free( &pre);
119
120 if ( cpl_error_get_code() != CPL_ERROR_NONE){
121 xsh_free_frame( &result_frame);
122 }
123 return result_frame;
124}
125/*****************************************************************************/
126
127/*****************************************************************************/
141/*****************************************************************************/
142
143cpl_frame *xsh_blaze_image( cpl_frame* masterflat_frame,
144 cpl_frame *order_frame, xsh_instrument *instrument)
145{
146 cpl_image *result_img = NULL;
147 cpl_frame *result_frame = NULL;
148 xsh_order_list *order_list = NULL;
149 char blaze_name[256];
150 char blaze_tag[16];
151
152 XSH_ASSURE_NOT_NULL( masterflat_frame);
153 XSH_ASSURE_NOT_NULL( order_frame);
155
156
157 sprintf( blaze_name, "%s", "BLAZE_IMAGE.fits");
158 sprintf(blaze_tag, "%s", "BLAZE");
159
160 check( order_list = xsh_order_list_load( order_frame, instrument));
161 check( result_img = xsh_create_blaze( masterflat_frame, order_list,
162 instrument));
163
164 check( cpl_image_save( result_img, blaze_name,
165 CPL_BPP_IEEE_FLOAT, NULL,CPL_IO_DEFAULT));
166
167 check( result_frame = cpl_frame_new());
168 check( cpl_frame_set_filename( result_frame, blaze_name));
169 check( cpl_frame_set_tag( result_frame, blaze_tag));
170
171 cleanup:
172 xsh_free_image( &result_img);
173 xsh_order_list_free( &order_list);
174
175 if ( cpl_error_get_code() != CPL_ERROR_NONE){
176 xsh_free_frame( &result_frame);
177 }
178 return result_frame;
179}
180/*****************************************************************************/
181
182
183/*****************************************************************************/
196/*****************************************************************************/
197cpl_image* xsh_create_blaze( cpl_frame* masterflat_frame,
199{
200 xsh_pre *masterflat_pre = NULL;
201 float *masterflat_data = NULL;
202 cpl_image *result = NULL;
203 float *result_data = NULL;
204 int i, iorder, y, nx, ny;
205 cpl_vector *cen_flux_vect = NULL, *cen_flux_pos_vect = NULL;
206 double *cen_flux_pos = NULL, *cen_flux = NULL;
207 int deg_poly = 18;
208 double mse =0.0;
209
210 XSH_ASSURE_NOT_NULL( masterflat_frame);
211 XSH_ASSURE_NOT_NULL( order_list);
213
214
215 check( masterflat_pre = xsh_pre_load( masterflat_frame, instrument));
216 XSH_CMP_INT( order_list->bin_x, ==, masterflat_pre->binx, "binning in x",);
217 XSH_CMP_INT( order_list->bin_y, ==, masterflat_pre->biny, "binning in y",);
218
219 check( nx = cpl_image_get_size_x( masterflat_pre->data));
220 check( ny = cpl_image_get_size_y( masterflat_pre->data));
221 check( masterflat_data = cpl_image_get_data_float( masterflat_pre->data));
222 XSH_MALLOC( cen_flux, double, ny);
223 XSH_MALLOC( cen_flux_pos, double, ny);
224
225 check( result = cpl_image_new( nx,ny, CPL_TYPE_FLOAT));
226 check( result_data = cpl_image_get_data_float( result));
227
228 /* fit the central flux */
229 for( iorder= 0; iorder < order_list->size; iorder++) {
230 int x_cen;
231 int start_y, end_y;
232 int size_y=0;
233 int absorder;
234
235 check( start_y = xsh_order_list_get_starty( order_list, iorder));
236 check( end_y = xsh_order_list_get_endy( order_list, iorder));
237 absorder = order_list->list[iorder].absorder;
238
239 for(y=start_y; y <= end_y; y++){
240 check( x_cen = xsh_order_list_eval_int( order_list,
241 order_list->list[iorder].cenpoly, y));
242 cen_flux[y-start_y] = masterflat_data[(x_cen-1)+(y-1)*nx];
243 cen_flux_pos[y-start_y] = (double)y;
244 size_y++;
245 }
246
247 check( cen_flux_vect = cpl_vector_wrap( size_y, cen_flux));
248 check( cen_flux_pos_vect = cpl_vector_wrap( size_y, cen_flux_pos));
249
250 check( order_list->list[iorder].blazepoly =
251 xsh_polynomial_fit_1d_create( cen_flux_pos_vect,
252 cen_flux_vect, deg_poly, &mse));
253 xsh_msg_dbg_medium("Polynomial blaze fitting for order %d with mse %f", absorder, mse);
254
255 while( mse >= MSE_LIMIT){
256 deg_poly--;
257 xsh_msg( "Not good mse %f Decrease deg poly to %d",mse, deg_poly);
258 xsh_free_polynomial( &(order_list->list[iorder].blazepoly));
259 check( order_list->list[iorder].blazepoly = xsh_polynomial_fit_1d_create(
260 cen_flux_pos_vect,
261 cen_flux_vect, deg_poly, &mse));
262 }
263#if REGDEBUG_BLAZE
264 /* REGDEBUG */
265 {
266 FILE* regdebug = NULL;
267 char filename[256];
268
269 sprintf(filename, "blaze_%d.dat",absorder);
270 regdebug = fopen(filename,"w");
271
272 fprintf( regdebug, "# y flux poly\n");
273
274 for( y=0; y< size_y; y++){
275 double flux_cen_val;
276
277 check( flux_cen_val = cpl_polynomial_eval_1d(
278 order_list->list[iorder].blazepoly, cen_flux_pos[y], NULL));
279 fprintf(regdebug, "%f %f %f\n", cen_flux_pos[y], cen_flux[y], flux_cen_val);
280 }
281 fclose(regdebug);
282 }
283#endif
284
285 /* normalize the order */
286 for(y=start_y; y <= end_y; y++){
287 double flux_cen_val;
288 int x_min, x_max;
289
290 check( x_min = xsh_order_list_eval_int( order_list,
291 order_list->list[iorder].edglopoly, y));
292 check( x_max = xsh_order_list_eval_int( order_list,
293 order_list->list[iorder].edguppoly, y));
294 check( flux_cen_val = cpl_polynomial_eval_1d(
295 order_list->list[iorder].blazepoly, y, NULL));
296
297 for( i=x_min; i<= x_max; i++){
298 result_data[i-1+(y-1)*nx] = flux_cen_val;
299 }
300 }
301 xsh_unwrap_vector( &cen_flux_vect);
302 xsh_unwrap_vector( &cen_flux_pos_vect);
303 } /* end loop over orders */
304
305#if REGDEBUG_BLAZE
306 {
307
308 check( cpl_image_save( result, "BLAZE_IMAGE.fits",
309 CPL_BPP_IEEE_FLOAT, NULL,CPL_IO_DEFAULT));
310 }
311#endif
312
313 cleanup:
314 if ( cpl_error_get_code() != CPL_ERROR_NONE){
315 xsh_unwrap_vector( &cen_flux_vect);
316 xsh_unwrap_vector( &cen_flux_pos_vect);
317 xsh_free_image( &result);
318 }
319 xsh_pre_free( &masterflat_pre);
320 XSH_FREE( cen_flux);
321 XSH_FREE( cen_flux_pos);
322 return result;
323}
324/*****************************************************************************/
325
static xsh_instrument * instrument
cpl_frame * xsh_divide_by_blaze(cpl_frame *pre_frame, cpl_frame *blaze_frame, xsh_instrument *instrument)
Divide a pre image by the blaze image.
Definition: xsh_blaze.c:71
cpl_image * xsh_create_blaze(cpl_frame *masterflat_frame, xsh_order_list *order_list, xsh_instrument *instrument)
Normalize a master flat frame order by order.
Definition: xsh_blaze.c:197
cpl_frame * xsh_blaze_image(cpl_frame *masterflat_frame, cpl_frame *order_frame, xsh_instrument *instrument)
Normalize a master flat frame order by order.
Definition: xsh_blaze.c:143
int xsh_order_list_eval_int(xsh_order_list *list, cpl_polynomial *poly, double y)
Evaluate an order list poly but return the central pixel position rounding the polynomial.
xsh_order_list * xsh_order_list_load(cpl_frame *frame, xsh_instrument *instr)
load an order list from a frame
int xsh_order_list_get_starty(xsh_order_list *list, int i)
get position on Y axis of first pixel detected on order
int xsh_order_list_get_endy(xsh_order_list *list, int i)
get position on Y axis of last pixel detected on order
void xsh_order_list_free(xsh_order_list **list)
free memory associated to an order_list
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
cpl_frame * xsh_pre_save(const xsh_pre *pre, const char *filename, const char *tag, int temp)
Save PRE on disk.
#define check(COMMAND)
Definition: xsh_error.h:71
#define XSH_CMP_INT(A, OPERATOR, B, SUFFIX,...)
Definition: xsh_error.h:119
#define XSH_ASSURE_NOT_NULL(pointer)
Definition: xsh_error.h:99
int * y
#define xsh_msg_dbg_medium(...)
Definition: xsh_msg.h:44
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
void xsh_unwrap_vector(cpl_vector **v)
Unwrap a vector and set the pointer to NULL.
Definition: xsh_utils.c:2345
void xsh_free_polynomial(cpl_polynomial **p)
Deallocate a polynomial and set the pointer to NULL.
Definition: xsh_utils.c:2194
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
xsh_order * list
cpl_polynomial * edguppoly
cpl_polynomial * blazepoly
cpl_polynomial * edglopoly
cpl_polynomial * cenpoly
cpl_image * data
Definition: xsh_data_pre.h:65
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 MSE_LIMIT
Definition: xsh_blaze.h:57
int nx
int ny
#define XSH_FREE(POINTER)
Definition: xsh_utils.h:92
#define XSH_MALLOC(POINTER, TYPE, SIZE)
Definition: xsh_utils.h:49
cpl_polynomial * xsh_polynomial_fit_1d_create(const cpl_vector *x_pos, const cpl_vector *values, int degree, double *mse)