UVES Pipeline Reference Manual  5.4.6
uves_extract-test.c
1 /* *
2  * This file is part of the ESO UVES Pipeline *
3  * Copyright (C) 2004,2005 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-08-08 13:36:07 $
23  * $Revision: 1.14 $
24  * $Name: not supported by cvs2svn $
25  * $Log: not supported by cvs2svn $
26  * Revision 1.13 2013/07/02 12:42:17 amodigli
27  * Rename DEBUG to debug_mode to remove compiler error on some platforms (that name is reserved to special compiler options)
28  *
29  * Revision 1.12 2010/04/27 09:55:01 amodigli
30  * fixed call to uves_extract error due to API change
31  *
32  * Revision 1.11 2009/06/05 05:49:02 amodigli
33  * updated init/end to cpl5
34  *
35  * Revision 1.10 2007/08/30 07:56:05 amodigli
36  * fixed some doxygen warnings
37  *
38  * Revision 1.9 2007/06/22 14:50:11 jmlarsen
39  * Expanded, again, interface of uves_save_image()
40  *
41  * Revision 1.8 2007/06/22 09:33:21 jmlarsen
42  * Changed interface of uves_save_image
43  *
44  * Revision 1.7 2007/06/20 15:50:20 jmlarsen
45  * Decrease test images size
46  *
47  * Revision 1.6 2007/05/25 11:50:32 jmlarsen
48  * Re-added ORDER_TRACE_TABLE
49  *
50  * Revision 1.5 2007/05/23 06:43:23 jmlarsen
51  * Removed unused variables
52  *
53  * Revision 1.4 2007/05/22 14:51:02 jmlarsen
54  * Removed unused variables
55  *
56  * Revision 1.3 2007/05/02 13:20:28 jmlarsen
57  * Changed interface of uves_extract_iterate
58  *
59  * Revision 1.2 2007/04/24 12:50:29 jmlarsen
60  * Replaced cpl_propertylist -> uves_propertylist which is much faster
61  *
62  * Revision 1.1 2007/03/15 12:27:18 jmlarsen
63  * Moved unit tests to ./uves/tests and ./flames/tests
64  *
65  * Revision 1.3 2007/02/27 14:04:14 jmlarsen
66  * Move unit test infrastructure to IRPLIB
67  *
68  * Revision 1.2 2007/02/22 15:38:53 jmlarsen
69  * Changed tolerance
70  *
71  * Revision 1.1 2007/02/21 12:37:41 jmlarsen
72  * Added uves_extract test
73  *
74  * Revision 1.2 2007/01/29 12:17:54 jmlarsen
75  * Support setting verbosity from command line
76  *
77  * Revision 1.1 2006/11/28 08:26:35 jmlarsen
78  * Added QC log unit test
79  *
80  */
81 
82 /*-----------------------------------------------------------------------------
83  Includes
84  -----------------------------------------------------------------------------*/
85 
86 #ifdef HAVE_CONFIG_H
87 # include <config.h>
88 #endif
89 
90 #include <uves_extract.h>
91 #include <uves_extract_iterate.h>
92 #include <uves_extract_profile.h>
93 #include <uves_test_simulate.h>
94 #include <uves.h>
95 #include <uves_parameters.h>
96 #include <uves_pfits.h>
97 #include <uves_utils_wrappers.h>
98 #include <uves_utils_polynomial.h>
99 #include <uves_dfs.h>
100 #include <uves_chip.h>
101 #include <uves_error.h>
102 #include <cpl_test.h>
103 
104 #include <cpl.h>
105 /*-----------------------------------------------------------------------------
106  Defines
107  -----------------------------------------------------------------------------*/
108 
109 /*-----------------------------------------------------------------------------
110  Functions prototypes
111  -----------------------------------------------------------------------------*/
112 
113 
114 /*----------------------------------------------------------------------------*/
118 /*----------------------------------------------------------------------------*/
121 /*----------------------------------------------------------------------------*/
125 /*----------------------------------------------------------------------------*/
126 
127 static cpl_image *
128 create_spectrum(int nx, int ny, int minorder, int maxorder, const polynomial *order_locations,
129  slit_geometry sg, cpl_image **sky_spectrum)
130 {
131  int norders = maxorder - minorder + 1;
132  cpl_image *spectrum = cpl_image_new(nx, norders, CPL_TYPE_DOUBLE);
133  cpl_image *dummy = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
134  uves_iterate_position *pos = NULL;
135 
136  cpl_binary *bpm = NULL;
137  bool loop_y = false;
138 
139  double tot_flux = 3000;
140 
141  pos = uves_iterate_new(nx, ny, order_locations, minorder, maxorder, sg);
142  *sky_spectrum = cpl_image_new(nx, norders, CPL_TYPE_DOUBLE);
143 
144  {
145  int x, order;
146  for (x = 1; x <= nx; x++)
147  for (order = 1; order <= norders; order++)
148  {
149  cpl_image_reject(spectrum, x, order);
150  cpl_image_reject(*sky_spectrum, x, order);
151  }
152  }
153 
154  for (uves_iterate_set_first(pos,
155  1, nx,
156  minorder, maxorder,
157  bpm,
158  loop_y);
159  !uves_iterate_finished(pos);
161  {
162  int spectrum_row = pos->order - minorder + 1;
163 
164  double sky = 1000+20000*(pos->order - minorder)*1.0/(maxorder - minorder);
165 
166  check_nomsg( cpl_image_set(spectrum , pos->x, spectrum_row, tot_flux) );
167  check_nomsg( cpl_image_set(*sky_spectrum, pos->x, spectrum_row, sky) );
168 
169  }
170 
171  cleanup:
172  uves_iterate_delete(&pos);
173  uves_free_image(&dummy);
174  return spectrum;
175 }
176 
177 
178 /*----------------------------------------------------------------------------*/
182 /*----------------------------------------------------------------------------*/
183 
184 static void
186 {
187  polynomial *order_locations = NULL;
188  int minorder = 1;
189 // int maxorder = 22;
190 // int nx = 3000;
191 // int ny = 2000;
192  int maxorder = 8;
193  int nx = 500;
194  int ny = 600;
195  slit_geometry sg = {30.0, 0.0};
196  cpl_image *in_spectrum = NULL;
197  cpl_image *in_sky = NULL;
198  cpl_image *image = NULL;
199  cpl_image *image_noise = NULL;
200  uves_propertylist *image_header = NULL;
201  cpl_table *ordertable = NULL;
202  cpl_parameterlist * parameters = NULL;
203  const char *test_id = "uves_extract-test";
204  bool extract_partial = false;
205  bool debug_mode = true;
206  bool blue = true;
207  enum uves_chip chip = uves_chip_get_first(blue);
208  cpl_image *cosmics = NULL;
209  uves_iterate_position *pos = NULL;
210  uves_extract_profile *profile = NULL;
211 
212  /* Output */
213  cpl_image *out_spectrum = NULL;
214  cpl_image *out_sky = NULL;
215  cpl_image *out_sky_noise = NULL;
216 // uves_propertylist *spectrum_header = NULL;
217 // cpl_image *spectrum_noise = NULL;
218  cpl_table *cosmic_mask = NULL;
219  cpl_image *cosmic_image = NULL;
220 // cpl_table *profile_table = NULL;
221  cpl_image *weights = NULL;
222  cpl_table *info_tbl = NULL;
223  cpl_table *order_trace = NULL;
224 
225  /* Build data */
226  check_nomsg( create_order_table(NULL, &order_locations, NULL,
227  minorder, maxorder, nx) );
228 
229  check_nomsg( in_spectrum = create_spectrum(nx, ny,
230  minorder, maxorder,
231  order_locations,
232  sg,
233  &in_sky) );
234 
235  pos = uves_iterate_new(nx, ny, order_locations, minorder, maxorder, sg);
236 
237  profile = uves_extract_profile_new(uves_gauss,
239  4, 0, 0);
240 
241  profile->y0 = uves_polynomial_new_zero(2);
242  profile->sigma = uves_polynomial_new_zero(2);
243  uves_polynomial_shift(profile->sigma, 0, 2.5);
244 
245  check_nomsg( image = uves_create_image(pos,
246  chip,
247  in_spectrum, in_sky,
248  cosmics,
249  profile,
250  &image_noise,
251  &image_header) );
252 
253  uves_save_image(image, "image.fits", NULL, true, true);
254  uves_save_image(image_noise, "noise.fits", NULL, true, true);
255 
256  ordertable = cpl_table_new(2);
257  cpl_table_new_column(ordertable, "Order", CPL_TYPE_INT);
258  cpl_table_set_int(ordertable, "Order", 0, minorder);
259  cpl_table_set_int(ordertable, "Order", 1, maxorder);
260 
261  /* Extract */
262  parameters = cpl_parameterlist_new();
263  check_nomsg( uves_propagate_parameters_step(UVES_EXTRACT_ID,
264  parameters,
265  test_id,
266  NULL));
267 
268  {
269  const char *value = "optimal"; //fixme should test also linear
270  uves_set_parameter(parameters, test_id, UVES_EXTRACT_ID ".method", CPL_TYPE_STRING, &value);
271  }
272 
273  check( out_spectrum =
274  uves_extract(image,
275  image_noise,
276  image_header,
277  ordertable,
278  order_locations,
279  sg.length,
280  sg.offset,
281  parameters,
282  test_id,
283  "",
284  extract_partial,
285  debug_mode,
286  chip,
287  NULL,/* spectrum_header */
288  NULL, /* spectrum_noise */
289  &out_sky,
290  &out_sky_noise,
291  &cosmic_mask,
292  &cosmic_image,
293  NULL, /* profile_table */
294  &weights,
295  &info_tbl,
296  &order_trace),
297  "Error during extraction");
298 
299  uves_save_image(out_spectrum, "spectrum.fits", NULL, true, true);
300 
301  /* Check results */
302  {
303  int x, order;
304 
305  for (order = minorder; order <= maxorder; order++)
306  {
307  int spectrum_row = order - minorder + 1;
308 
309  for (x = 1; x <= nx; x++)
310  {
311  int in_bad, out_bad;
312  double in = cpl_image_get( in_spectrum, x, spectrum_row, &in_bad);
313  double sky = cpl_image_get( in_sky , x, spectrum_row, &in_bad);
314  double out = cpl_image_get(out_spectrum, x, spectrum_row, &out_bad);
315  double osky = cpl_image_get(out_sky , x, spectrum_row, &out_bad);
316 
317 #if 0 /* linear */
318  assure( out_bad || in_bad ||
319  float_equal(out, in + sky, 0.001),
320  CPL_ERROR_ILLEGAL_OUTPUT,
321  "At (x, order) = (%d, %d): In = %f + %f (%d); Out = %f (%d)",
322  x, order, sky, in, in_bad, out, out_bad);
323 
324 #else /* optimal */
325 
326 #if 0
327  assure( out_bad || in_bad ||
328  float_equal(out, in, 0.02),
329  CPL_ERROR_ILLEGAL_OUTPUT,
330  "Object spectrum differs at (x, order) = (%d, %d): In = %f (%d); Out = %f (%d)",
331  x, order, in, in_bad, out, out_bad);
332 
333  assure( out_bad || in_bad ||
334  float_equal(osky, sky, 0.01),
335  CPL_ERROR_ILLEGAL_OUTPUT,
336  "Sky spectrum differs at (x, order) = (%d, %d), sky: In = %f (%d); Out = %f (%d)",
337  x, order, sky, in_bad, osky, out_bad);
338 #endif
339  if (!out_bad && !in_bad)
340  {
341  cpl_test_rel(out, in, 0.02);
342  cpl_test_rel(osky, sky, 0.01);
343  }
344 #endif
345 
346  }
347  }
348  }
349 
350  cleanup:
351  uves_free_image(&in_spectrum);
352  uves_free_image(&in_sky);
353  uves_free_image(&image);
354  uves_free_image(&image_noise);
355  uves_free_propertylist(&image_header);
356  uves_polynomial_delete(&order_locations);
357  uves_free_parameterlist(&parameters);
358  uves_free_table(&ordertable);
359  uves_iterate_delete(&pos);
360  uves_extract_profile_delete(&profile);
361  uves_free_image(&cosmics);
362 
363  uves_free_image(&out_spectrum);
364  uves_free_image(&out_sky);
365  uves_free_image(&out_sky_noise);
366  uves_free_image(&weights);
367  uves_free_table(&cosmic_mask);
368  uves_free_image(&cosmic_image);
369  uves_free_table(&info_tbl);
370  uves_free_table(&order_trace);
371  return;
372 }
373 
374 
375 /*----------------------------------------------------------------------------*/
379 /*----------------------------------------------------------------------------*/
380 
381 static void
383 {
384  polynomial *order_locations;
385  uves_iterate_position *pos = NULL;
386  cpl_binary *bpm = NULL;
387  bool loop_y = true;
388  int nx = 2000;
389  int ny = 1000;
390  cpl_image *image = cpl_image_new(2000, 1000, CPL_TYPE_DOUBLE);
391  int minorder = 3;
392  int maxorder = 15;
393  slit_geometry sg = {30.0, 0.0};
394 
395  check_nomsg( create_order_table(NULL, &order_locations, NULL,
396  minorder, maxorder, nx) );
397 
398 
399  pos = uves_iterate_new(nx, ny,
400  order_locations,
401  minorder,
402  maxorder,
403  sg);
404 
405 
407  1, nx,
408  minorder, maxorder,
409  bpm,
410  loop_y),
411  "Set first position failed");
412 
413  assure( pos->x == 1 && pos->order == minorder,
414  CPL_ERROR_ILLEGAL_OUTPUT,
415  "Set first position failed: x, order, minorder = %d %d %d",
416  pos->x, pos->order, minorder);
417 
418  {
419  int y = pos->y;
420 
421  assure_nomsg( !uves_iterate_finished(pos), CPL_ERROR_ILLEGAL_OUTPUT );
422 
423  check( uves_iterate_increment(pos), "Increment failed");
424  check( uves_iterate_increment(pos), "Increment failed");
425  check( uves_iterate_increment(pos), "Increment failed");
426  check( uves_iterate_increment(pos), "Increment failed");
427 
428  /* Must hold for the polynomial used */
429  assure( pos->x == 1 && pos->y == y+4 &&
430  pos->order == minorder, CPL_ERROR_ILLEGAL_OUTPUT,
431  "Increment failed: x, y, order = %d, %d (%d), %d",
432  pos->x, pos->y, y+1, pos->order);
433  }
434 
435  /* Go to next order */
436  while(pos->x < nx)
437  {
439  }
440  while(pos->x != 1)
441  {
443  }
444 
445  {
446  int y = pos->y;
448 
449  cpl_test_eq( pos->x, 1 );
450  cpl_test_eq( pos->y, y+1 );
451  cpl_test_eq( pos->order, minorder+1 );
452  /* Here was a bug... */
453 
454  }
455 
456 
457 
458  cleanup:
459  uves_free_image(&image);
460  uves_polynomial_delete(&order_locations);
461  uves_iterate_delete(&pos);
462  return;
463 }
464 
465 /*----------------------------------------------------------------------------*/
469 /*----------------------------------------------------------------------------*/
470 
471 int main(void)
472 {
473  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
474 
475 // cpl_msg_set_level(CPL_MSG_DEBUG);
476 
477  test_iterate();
478 
479  test_extract();
480 
481  return cpl_test_end(0);
482 }
483 
484 
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
bool uves_iterate_finished(const uves_iterate_position *p)
Finished iterating?
static void test_extract(void)
test extraction
void create_order_table(cpl_table **ordertable, polynomial **order_locations, cpl_table **tracetable, int minorder, int maxorder, int nx)
Create order table.
void uves_iterate_delete(uves_iterate_position **p)
Deallocate iterator and set pointer to NULL.
#define check_nomsg(CMD)
Definition: uves_error.h:204
uves_iterate_position * uves_iterate_new(int nx, int ny, const polynomial *order_locations, int minorder, int maxorder, slit_geometry sg)
Allocate iterator.
void uves_iterate_set_first(uves_iterate_position *p, int xmin, int xmax, int ordermin, int ordermax, const cpl_binary *bpm, bool loop_y)
Initialize iteration.
int uves_gauss_derivative(const double x[], const double a[], double result[])
Evaluate the derivatives of a gaussian.
Definition: uves_utils.c:4346
static void test_iterate(void)
test iteration
static cpl_image * create_spectrum(int nx, int ny, int minorder, int maxorder, const polynomial *order_locations, slit_geometry sg, cpl_image **sky_spectrum)
test spectrum creation
int uves_gauss(const double x[], const double a[], double *result)
Evaluate a gaussian.
Definition: uves_utils.c:4291
cpl_image * uves_extract(cpl_image *image, cpl_image *image_noise, const uves_propertylist *image_header, const cpl_table *ordertable, const polynomial *order_locations_raw, double slit_length, double offset, const cpl_parameterlist *parameters, const char *context, const char *mode, bool extract_partial, bool debug_mode, enum uves_chip chip, uves_propertylist **header, cpl_image **spectrum_noise, cpl_image **sky_spectrum, cpl_image **sky_spectrum_noise, cpl_table **cosmic_mask, cpl_image **cosmic_image, cpl_table **profile_table, cpl_image **weights, cpl_table **info_tbl, cpl_table **order_trace)
Extract a spectrum.
Definition: uves_extract.c:569
cpl_image * uves_create_image(uves_iterate_position *pos, enum uves_chip chip, const cpl_image *spectrum, const cpl_image *sky, const cpl_image *cosmic_image, const uves_extract_profile *profile, cpl_image **image_noise, uves_propertylist **image_header)
Reconstruct echelle image from spectrum.
Definition: uves_utils.c:4534
enum uves_chip uves_chip_get_first(bool blue)
Get first chip for blue or red arm.
Definition: uves_chip.c:92
cpl_error_code uves_polynomial_shift(polynomial *p, int varno, double shift)
Shift a polynomial.
#define assure_nomsg(BOOL, CODE)
Definition: uves_error.h:177
int main(void)
Test of uves_extract.
#define check(CMD,...)
Definition: uves_error.h:198
polynomial * uves_polynomial_new_zero(int dim)
Create a zero polynomial.
void uves_iterate_increment(uves_iterate_position *p)
Get next position.