X-shooter Pipeline Reference Manual 3.8.15
test-xsh_dfs_sdp.c
Go to the documentation of this file.
1/* *
2 * This file is part of the ESO X-Shooter package *
3 * Copyright (C) 2014 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#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24
25/*-----------------------------------------------------------------------------
26 Includes
27 -----------------------------------------------------------------------------*/
28
29#include <xsh_utils.h>
30#include <xsh_dfs.h>
31#include <xsh_pfits.h>
32#include <xsh_pfits_qc.h>
33#include <xsh_data_spectrum.h>
34#include <cpl.h>
35#include <cpl_test.h>
36#include <errno.h>
37
38/*-----------------------------------------------------------------------------
39 Defines
40 -----------------------------------------------------------------------------*/
41
42#define TEST_NAME "Test-XSH_DFS_SDP"
43
44/* The following are input values for the dummy data. */
45#define RECIPE_ID "test_recipe"
46#define RAW_FILE_NAME "input_raw_file.fits"
47#define RAW_FRAME_TAG XSH_WAVE_VIS
48#define PRODUCT_FILE_NAME "OBJECT_SLIT_STARE_VIS.fits"
49#define PRODUCT_FRAME_TAG XSH_OBJECT_SLIT_STARE_VIS
50#define OUTPUT_FILE_NAME "SDP_"PRODUCT_FILE_NAME
51#define OUTPUT_FRAME_TAG "SCIENCE.SPECTRUM"
52#define SNR_VALUE 3.5
53#define TARGET_NAME "SUN,centre,P2"
54#define OBJECT_VALUE "STD,TELLURIC"
55#define SLIT_STRING_VALUE "0.9x11"
56#define MJDOBS_VALUE 10.1
57#define DATEOBS_VALUE "2014-01-01T00:00:00.000"
58#define RA_VALUE 60.605358
59#define DEC_VALUE -70.27194
60#define ORIGIN_VALUE "ESO"
61#define TELESCOP_VALUE "ESO-VLT-U2"
62#define EQUINOX_VALUE 2000
63#if defined CPL_VERSION_CODE && CPL_VERSION_CODE <= CPL_VERSION(6, 0, 6)
64#define RADECSYS_VALUE "FK5"
65#endif
66#define INSTRUME_VALUE "XSHOOTER"
67#define EXPTIME_VALUE 15.
68#define PROG_ID_VALUE "abc"
69#define OBS_ID_VALUE 123
70#define PRO_TECH_VALUE "ECHELLE,SLIT,STARE"
71#define CONAD_VALUE 4.0
72#define RON_VALUE 2.6
73#define CSYER1_VALUE 1.2
74#define BUINT_VALUE "ADU"
75
76/* The following are expected values used by the check_output_file() function
77 * to check the generated output. */
78#define EXPECTED_ORIGIN ORIGIN_VALUE
79#define EXPECTED_DISPELEM "VIS"
80#define EXPECTED_OBJECT TARGET_NAME
81#if defined CPL_VERSION_CODE && CPL_VERSION_CODE <= CPL_VERSION(6, 0, 6)
82#define EXPECTED_RADECSYS RADECSYS_VALUE
83#endif
84#define EXPECTED_EQUINOX EQUINOX_VALUE
85#define EXPECTED_RA RA_VALUE
86#define EXPECTED_DEC DEC_VALUE
87#define EXPECTED_EXPTIME EXPTIME_VALUE
88#define EXPECTED_MJDOBS MJDOBS_VALUE
89#define EXPECTED_MJDEND MJDOBS_VALUE + EXPTIME_VALUE/86400.
90#define EXPECTED_PROG_ID PROG_ID_VALUE
91#define EXPECTED_OBS_ID OBS_ID_VALUE
92#define EXPECTED_OBSTECH PRO_TECH_VALUE
93#define EXPECTED_PRODCATG OUTPUT_FRAME_TAG
94#define EXPECTED_PRODLVL 2
95#define EXPECTED_FLUXCAL "UNCALIBRATED"
96#define EXPECTED_WAVELMIN 500.
97#define EXPECTED_WAVELMAX 600.
98#define EXPECTED_SPEC_BIN 10.
99#define EXPECTED_TOT_FLUX CPL_FALSE
100#define EXPECTED_FLUXERR -2
101#define EXPECTED_SNR SNR_VALUE
102#define EXPECTED_DETRON RON_VALUE
103#define EXPECTED_EFFRON RON_VALUE
104#define EXPECTED_PROV1 RAW_FILE_NAME
105#define EXPECTED_NCOMBINE 1
106#define EXPECTED_TITLE "SUN,centre_123_2014-01-01T00:00:00.000"
107#define EXPECTED_APERTURE 0.9/3600.
108#define EXPECTED_TELAPSE EXPTIME_VALUE
109#define EXPECTED_TMID MJDOBS_VALUE + EXPTIME_VALUE/(2.0 * 86400.)
110#define EXPECTED_SPEC_VAL 550.
111#define EXPECTED_SPEC_BW 100.
112#define EXPECTED_TDMIN1 EXPECTED_WAVELMIN
113#define EXPECTED_TDMAX1 EXPECTED_WAVELMAX
114#define EXPECTED_TFIELDS 5
115#define EXPECTED_TFIELDS_UNCAL 7
116#define EXPECTED_NELEM 11
117#define EXPECTED_EXTNAME "SPECTRUM"
118#define EXPECTED_INHERIT CPL_TRUE
119
120/* The following are some additional FITS keyword macros. */
121#define EQUINOX_KEYWORD "EQUINOX"
122#if defined CPL_VERSION_CODE && CPL_VERSION_CODE <= CPL_VERSION(6, 0, 6)
123#define RADECSYS_KEYWORD "RADECSYS"
124#endif
125#define INSTRUME_KEYWORD "INSTRUME"
126#define SIMPLE_KEYWORD "SIMPLE"
127#define BITPIX_KEYWORD "BITPIX"
128#define EXTEND_KEYWORD "EXTEND"
129#define DATE_KEYWORD "DATE"
130#define CHECKSUM_KEYWORD "CHECKSUM"
131#define DATASUM_KEYWORD "DATASUM"
132#define TFIELDS_KEYWORD "TFIELDS"
133
134#define test_success(expr) cpl_test_assert((expr) == EXIT_SUCCESS)
135
136/*----------------------------------------------------------------------------*/
141/*----------------------------------------------------------------------------*/
142
143/*-----------------------------------------------------------------------------
144 Private Function prototypes
145 -----------------------------------------------------------------------------*/
146
147static int getlen(const char* str);
148
149static int create_dummy_raw_frame(cpl_frameset* frames);
150
151static int create_input_product_frame(cpl_frameset* frames,
152 const cpl_parameterlist* params,
154
155static int check_output_file(cpl_boolean expect_uncalib);
156
157/*----------------------------------------------------------------------------*/
161/*----------------------------------------------------------------------------*/
162
163int main(void)
164{
165 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
166 cpl_msg_set_domain(TEST_NAME);
167
168 /* Create a workspace sub directory for this unit test and change to that
169 * directory. */
170 /* Note: dont use the -p option of mkdir since it is less portable. */
171 cpl_test_assert( system("test -d workspace_"TEST_NAME
172 " || mkdir workspace_"TEST_NAME) == 0 );
173 cpl_test_assert( chdir("workspace_"TEST_NAME) == 0 );
174
175 /* Force removal of the test files if any were left over from a previous
176 * test run. */
177 (void) remove(RAW_FILE_NAME);
178 (void) remove(PRODUCT_FILE_NAME);
179 (void) remove(OUTPUT_FILE_NAME);
180 errno = 0;
181
182 printf("I'm inside the main of xsh_dfs_sdp");
183
184 /* Create an empty parameter list. */
185 cpl_parameterlist* params = cpl_parameterlist_new();
186 cpl_test_assert(params != NULL);
187 cpl_parameter* p = cpl_parameter_new_value(
188 "xsh."RECIPE_ID".dummy-association-keys",
189 CPL_TYPE_INT, "test param", RECIPE_ID, 2);
190 cpl_test_assert(p != NULL);
191 cpl_test_assert(cpl_parameterlist_append(params, p) == CPL_ERROR_NONE);
192
193 /* Create a new empty frame set to which we add input and output frames. */
194 cpl_frameset* frames = cpl_frameset_new();
195 cpl_test_assert(frames != NULL);
196
197 /* Create the dummy raw input FITS file and frame. */
199
200 /* Create an X-Shooter instrument structure required for adding the input
201 * product frame and output frames to a frame set. */
203 cpl_test_assert(instrument != NULL);
208
209 /* Create the dummy product spectrum FITS file and frame. */
211 cpl_frame* product_frame = cpl_frameset_find(frames, PRODUCT_FRAME_TAG);
212 cpl_test_assert(product_frame != NULL);
213
214 /* Now test conversion of the product frame from X-Shooter native format to
215 * the Science Data Product format for 1D spectra. */
216 xsh_add_sdp_product_spectrum(NULL, product_frame, frames, frames,
217 params, RECIPE_ID, instrument,NULL);
218 cpl_test_error(CPL_ERROR_NONE);
219
221 cpl_test_assert(cpl_test_get_failed() == 0);
222
223 /* Check the conversion when data is given as flux calibrated. */
224 xsh_add_sdp_product_spectrum(product_frame, NULL, frames, frames,
225 params, RECIPE_ID, instrument,NULL);
226 cpl_test_error(CPL_ERROR_NONE);
227
229 cpl_test_assert(cpl_test_get_failed() == 0);
230
231 /* Check the conversion when data is given as calibrated and uncalibrated. */
232 xsh_add_sdp_product_spectrum(product_frame, product_frame, frames, frames,
233 params, RECIPE_ID, instrument,NULL);
234 cpl_test_error(CPL_ERROR_NONE);
235
237 cpl_test_assert(cpl_test_get_failed() == 0);
238
239 /* Cleanup memory and delete the generated test files if no tests failed. */
241 while (! cpl_frameset_is_empty(frames)) {
242 cpl_frame* frame = cpl_frameset_get_position(frames, 0);
243 cpl_test_assert(frame != NULL);
244 cpl_test_assert(cpl_frameset_erase_frame(frames, frame) == CPL_ERROR_NONE);
245 }
246 cpl_frameset_delete(frames);
247 cpl_parameterlist_delete(params);
250 if (cpl_test_get_failed() == 0) {
251 (void) remove(RAW_FILE_NAME);
252 (void) remove(PRODUCT_FILE_NAME);
253 (void) remove(OUTPUT_FILE_NAME);
254 /* Delete workspace directory if it exists and no errors were discovered. */
255 cpl_test_assert( chdir("..") == 0 );
256 cpl_test_assert( system("test -d workspace_"TEST_NAME
257 "&& rm -r -f workspace_"TEST_NAME) == 0 );
258 }
259
260 return cpl_test_end(0);
261}
262
263
277static int create_dummy_raw_frame(cpl_frameset* frames)
278{
279 /* Create a property list of FITS keywords for the raw file. */
280 cpl_propertylist* props = cpl_propertylist_new();
281 cpl_test_assert(props != NULL);
282 cpl_test_assert(cpl_propertylist_append_string(props, CPL_DFS_PRO_CATG,
284 == CPL_ERROR_NONE);
285 cpl_test_assert(cpl_propertylist_append_string(props, XSH_SDP_KEYWORD_OBJECT,
287 == CPL_ERROR_NONE);
288 cpl_test_assert(cpl_propertylist_append_string(props, XSH_DPR_TYPE,
290 == CPL_ERROR_NONE);
291 cpl_test_assert(cpl_propertylist_append_string(props, XSH_OBS_TARG_NAME,
293 == CPL_ERROR_NONE);
294 cpl_test_assert(cpl_propertylist_append_string(props, XSH_SLIT_VIS,
296 == CPL_ERROR_NONE);
297 cpl_test_assert(cpl_propertylist_append_double(props, XSH_MJDOBS,
299 == CPL_ERROR_NONE);
300 cpl_test_assert(cpl_propertylist_append_string(props, XSH_DATE_OBS,
302 == CPL_ERROR_NONE);
303 cpl_test_assert(cpl_propertylist_append_double(props, XSH_RA, RA_VALUE)
304 == CPL_ERROR_NONE);
305 cpl_test_assert(cpl_propertylist_append_double(props, XSH_DEC, DEC_VALUE)
306 == CPL_ERROR_NONE);
307 cpl_test_assert(cpl_propertylist_append_string(props, XSH_SDP_KEYWORD_ORIGIN,
309 == CPL_ERROR_NONE);
310 cpl_test_assert(cpl_propertylist_append_string(props, XSH_TELESCOP,
312 == CPL_ERROR_NONE);
313 cpl_test_assert(cpl_propertylist_append_string(props, INSTRUME_KEYWORD,
315 == CPL_ERROR_NONE);
316 cpl_test_assert(cpl_propertylist_append_double(props, EQUINOX_KEYWORD,
318 == CPL_ERROR_NONE);
319#if defined CPL_VERSION_CODE && CPL_VERSION_CODE <= CPL_VERSION(6, 0, 6)
320 cpl_test_assert(cpl_propertylist_append_string(props, RADECSYS_KEYWORD,
321 RADECSYS_VALUE)
322 == CPL_ERROR_NONE);
323#endif
324 cpl_test_assert(cpl_propertylist_append_double(props, XSH_EXPTIME,
326 == CPL_ERROR_NONE);
327 cpl_test_assert(cpl_propertylist_append_string(props, XSH_OBS_PROG_ID,
329 == CPL_ERROR_NONE);
330 cpl_test_assert(cpl_propertylist_append_int(props, XSH_OBS_ID, OBS_ID_VALUE)
331 == CPL_ERROR_NONE);
332 cpl_test_assert(cpl_propertylist_append_string(props, XSH_PRO_TECH,
334 == CPL_ERROR_NONE);
335 cpl_test_assert(cpl_propertylist_append_double(props, XSH_CONAD, CONAD_VALUE)
336 == CPL_ERROR_NONE);
337 cpl_test_assert(cpl_propertylist_append_double(props, XSH_RON, RON_VALUE)
338 == CPL_ERROR_NONE);
339
340 /* Create a dummy image and save it to a FITS file. */
341 cpl_image* image = cpl_image_new(10, 10, CPL_TYPE_FLOAT);
342 cpl_test_assert(image != NULL);
343 cpl_test_assert(cpl_image_save(image, RAW_FILE_NAME, CPL_TYPE_FLOAT, props,
344 CPL_IO_CREATE)
345 == CPL_ERROR_NONE);
346
347 /* Create a frame to describe the FITS file and add it to the frame set. */
348 cpl_frame* frame = cpl_frame_new();
349 cpl_test_assert(frame != NULL);
350 cpl_test_assert(cpl_frame_set_filename(frame, RAW_FILE_NAME)
351 == CPL_ERROR_NONE);
352 cpl_test_assert(cpl_frame_set_tag(frame, RAW_FRAME_TAG)
353 == CPL_ERROR_NONE);
354 cpl_test_assert(cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE)
355 == CPL_ERROR_NONE);
356 cpl_test_assert(cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW)
357 == CPL_ERROR_NONE);
358 cpl_test_assert(cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL)
359 == CPL_ERROR_NONE);
360 cpl_test_assert(cpl_frameset_insert(frames, frame) == CPL_ERROR_NONE);
361
362 cpl_image_delete(image);
363 cpl_propertylist_delete(props);
364 return EXIT_SUCCESS;
365}
366
367
385static int create_input_product_frame(cpl_frameset* frames,
386 const cpl_parameterlist* params,
388{
389 /* Create the input FITS file containing a dummy spectrum in X-Shooter native
390 * format. */
391 xsh_spectrum* spectrum = xsh_spectrum_1D_create(500., 600., 10.);
392 cpl_test_assert(spectrum != NULL);
393 cpl_test_assert(cpl_image_set(spectrum->flux, 4, 1, 7) == CPL_ERROR_NONE);
394 cpl_test_assert(cpl_image_set(spectrum->flux, 5, 1, 21) == CPL_ERROR_NONE);
395 cpl_test_assert(cpl_image_set(spectrum->flux, 6, 1, 12) == CPL_ERROR_NONE);
396 cpl_test_assert(cpl_image_set(spectrum->errs, 4, 1, 0.25) == CPL_ERROR_NONE);
397 cpl_test_assert(cpl_image_set(spectrum->errs, 5, 1, 0.5) == CPL_ERROR_NONE);
398 cpl_test_assert(cpl_image_set(spectrum->errs, 6, 1, 0.25) == CPL_ERROR_NONE);
399 cpl_test_assert(cpl_image_set(spectrum->qual, 1, 1, 16) == CPL_ERROR_NONE);
400 cpl_test_assert(cpl_image_set(spectrum->qual, 10, 1, 33) == CPL_ERROR_NONE);
401 cpl_test_assert(cpl_propertylist_append_double(spectrum->flux_header,
403 == CPL_ERROR_NONE);
404 cpl_test_assert(cpl_propertylist_append_double(spectrum->flux_header,
406 == CPL_ERROR_NONE);
407 cpl_test_assert(cpl_propertylist_append_double(spectrum->flux_header,
409 == CPL_ERROR_NONE);
410 cpl_test_assert(cpl_propertylist_append_string(spectrum->flux_header,
412 == CPL_ERROR_NONE);
413 cpl_test_assert(cpl_propertylist_append_string(spectrum->flux_header,
415 == CPL_ERROR_NONE);
416 cpl_test_assert(cpl_propertylist_append_string(spectrum->errs_header,
418 == CPL_ERROR_NONE);
419 cpl_frame* frame = xsh_spectrum_save(spectrum, PRODUCT_FILE_NAME,
421 cpl_test_assert(frame != NULL);
422 cpl_test_error(CPL_ERROR_NONE);
423
424 /* Update some of the frame information. */
425 cpl_test_assert(cpl_frame_set_tag(frame, PRODUCT_FRAME_TAG)
426 == CPL_ERROR_NONE);
427 cpl_test_assert(cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE)
428 == CPL_ERROR_NONE);
429 cpl_test_assert(cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT)
430 == CPL_ERROR_NONE);
431 cpl_test_assert(cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL)
432 == CPL_ERROR_NONE);
433
434 /* Add the input spectrum frame to the list of frames. */
435 xsh_add_product_spectrum(frame, frames, params, RECIPE_ID, instrument, NULL,NULL);
436 cpl_test_error(CPL_ERROR_NONE);
437
438 cpl_frame_delete(frame);
439 xsh_spectrum_free(&spectrum);
440 return EXIT_SUCCESS;
441}
442
443
449static int getlen(const char* str)
450{
451 if (str == NULL) return -1;
452 return strlen(str);
453}
454
455
464static int check_output_file(cpl_boolean expect_uncalib)
465{
466 cpl_size i;
467 int expected_TFIELDS = expect_uncalib ? EXPECTED_TFIELDS_UNCAL
469
470 /* Load the FITS keywords and binary table. */
471 cpl_propertylist* props = cpl_propertylist_load(OUTPUT_FILE_NAME, 0);
472 cpl_test_assert(props != NULL);
473 cpl_table* table = cpl_table_load(OUTPUT_FILE_NAME, 1, CPL_TRUE);
474 cpl_test_assert(table != NULL);
475 cpl_propertylist* tableprops = cpl_propertylist_load(OUTPUT_FILE_NAME, 1);
476 cpl_test_assert(tableprops != NULL);
477
478 /* Check that the required keywords are present and have the expected
479 * values in the primary header. */
480 cpl_test_eq(cpl_propertylist_get_bool(props, SIMPLE_KEYWORD), CPL_TRUE);
481 cpl_test(cpl_propertylist_get_int(props, BITPIX_KEYWORD) > 0);
482 cpl_test_eq(cpl_propertylist_get_int(props, XSH_NAXIS), 0);
483 cpl_test_eq(cpl_propertylist_get_bool(props, EXTEND_KEYWORD), CPL_TRUE);
484 cpl_test_eq_string(cpl_propertylist_get_string(props, XSH_SDP_KEYWORD_ORIGIN),
486 cpl_test(getlen(cpl_propertylist_get_string(props, DATE_KEYWORD)) > 8);
487 cpl_test(getlen(cpl_propertylist_get_string(props, XSH_TELESCOP)) > 1);
488 cpl_test(getlen(cpl_propertylist_get_string(props, INSTRUME_KEYWORD)) > 1);
489 cpl_test_eq_string(cpl_propertylist_get_string(props,
492 cpl_test(getlen(cpl_propertylist_get_string(props,
494 cpl_test_eq_string(cpl_propertylist_get_string(props, XSH_SDP_KEYWORD_OBJECT),
496 cpl_test_abs(cpl_propertylist_get_double(props, EQUINOX_KEYWORD),
497 EXPECTED_EQUINOX, FLT_EPSILON);
498#if defined CPL_VERSION_CODE && CPL_VERSION_CODE <= CPL_VERSION(6, 0, 6)
499 cpl_test_eq_string(cpl_propertylist_get_string(props, RADECSYS_KEYWORD),
500 EXPECTED_RADECSYS);
501#endif
502 cpl_test_abs(cpl_propertylist_get_double(props, XSH_RA), EXPECTED_RA,
503 FLT_EPSILON);
504 cpl_test_abs(cpl_propertylist_get_double(props, XSH_DEC), EXPECTED_DEC,
505 FLT_EPSILON);
506 cpl_test_abs(cpl_propertylist_get_double(props, XSH_EXPTIME),
507 EXPECTED_EXPTIME, FLT_EPSILON);
508 cpl_test_abs(cpl_propertylist_get_double(props, XSH_MJDOBS), EXPECTED_MJDOBS,
509 FLT_EPSILON);
510 cpl_test_abs(cpl_propertylist_get_double(props, XSH_MJDEND), EXPECTED_MJDEND,
511 FLT_EPSILON);
512 cpl_test(cpl_propertylist_get_double(props, XSH_MJDOBS)
513 < cpl_propertylist_get_double(props, XSH_MJDEND));
514 cpl_test_eq_string(cpl_propertylist_get_string(props,
517 cpl_test_eq(cpl_propertylist_get_int(props, XSH_SDP_KEYWORD_OBID1),
519 cpl_test_eq(cpl_propertylist_get_bool(props, XSH_SDP_KEYWORD_M_EPOCH),
520 CPL_FALSE);
521 cpl_test_eq_string(cpl_propertylist_get_string(props,
524 cpl_test_eq_string(cpl_propertylist_get_string(props,
527 cpl_test_eq(cpl_propertylist_get_int(props, XSH_SDP_KEYWORD_PRODLVL),
529 cpl_test_eq_string(cpl_propertylist_get_string(props,
532 cpl_test_eq(cpl_propertylist_get_bool(props, XSH_SDP_KEYWORD_CONTNORM),
533 CPL_FALSE);
534 cpl_test_abs(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_WAVELMIN),
535 EXPECTED_WAVELMIN, FLT_EPSILON);
536 cpl_test_abs(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_WAVELMAX),
537 EXPECTED_WAVELMAX, FLT_EPSILON);
538 cpl_test_abs(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_SPEC_BIN),
539 EXPECTED_SPEC_BIN, FLT_EPSILON);
540 cpl_test_eq(cpl_propertylist_get_bool(props, XSH_SDP_KEYWORD_TOT_FLUX),
542 cpl_test_abs(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_FLUXERR),
543 EXPECTED_FLUXERR, FLT_EPSILON);
544 cpl_test_eq(getlen(cpl_propertylist_get_string(props,
546 0);
547 cpl_test_abs(cpl_propertylist_get_double(props, XSH_SNR),
548 EXPECTED_SNR, FLT_EPSILON);
549 cpl_test_abs(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_DETRON),
550 EXPECTED_DETRON, FLT_EPSILON);
551 cpl_test_abs(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_EFFRON),
552 EXPECTED_EFFRON, FLT_EPSILON);
553 cpl_test(cpl_propertylist_get_int(props, XSH_SDP_KEYWORD_LAMNLIN) > 1);
554 cpl_test(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_LAMRMS) > 1e-6);
555 cpl_test(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_SPEC_RES) > 1e-6);
556 cpl_test(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_SPEC_ERR) > 1e-6);
557 cpl_test(cpl_propertylist_get_double(props, XSH_SDP_KEYWORD_SPEC_SYE) > 1e-6);
558 cpl_test(getlen(cpl_propertylist_get_string(props, XSH_SDP_KEYWORD_PROCSOFT))
559 > 1);
560 cpl_test_eq_string(cpl_propertylist_get_string(props,
563 cpl_test(cpl_propertylist_has(props, XSH_SDP_KEYWORD_PROV(2)) == CPL_FALSE);
564 cpl_test_eq(cpl_propertylist_get_int(props, XSH_SDP_KEYWORD_NCOMBINE),
566 cpl_test(cpl_propertylist_has(props, "ASSON1"));
567 cpl_test(cpl_propertylist_has(props, "ASSOC1"));
568 cpl_test(cpl_propertylist_has(props, "ASSOM1"));
569 cpl_test(cpl_propertylist_has(props, "ASSON2"));
570 cpl_test(cpl_propertylist_has(props, "ASSOC2"));
571 cpl_test(cpl_propertylist_has(props, "ASSOM2"));
572 cpl_test(! cpl_propertylist_has(props, "ASSON3"));
573 cpl_test(! cpl_propertylist_has(props, "ASSOC3"));
574 cpl_test(! cpl_propertylist_has(props, "ASSOM3"));
575
576 if (cpl_version_get_binary_version() >= CPL_VERSION(6, 4, 2)) {
577 cpl_test(cpl_propertylist_has(props, CHECKSUM_KEYWORD));
578 cpl_test(cpl_propertylist_has(props, DATASUM_KEYWORD));
579 }
580
581 /* Check that the table header keywords are correct. */
582 cpl_test_eq(cpl_propertylist_get_int(tableprops, BITPIX_KEYWORD), 8);
583 cpl_test_eq(cpl_propertylist_get_int(tableprops, XSH_NAXIS), 2);
584 cpl_test_eq_string(cpl_propertylist_get_string(tableprops,
587 cpl_test_eq_string(cpl_propertylist_get_string(tableprops,
590 cpl_test_abs(cpl_propertylist_get_double(tableprops, XSH_RA), EXPECTED_RA,
591 FLT_EPSILON);
592 cpl_test_abs(cpl_propertylist_get_double(tableprops, XSH_DEC), EXPECTED_DEC,
593 FLT_EPSILON);
594 cpl_test_abs(cpl_propertylist_get_double(tableprops,
596 EXPECTED_APERTURE, FLT_EPSILON);
597 cpl_test_abs(cpl_propertylist_get_double(tableprops, XSH_SDP_KEYWORD_TELAPSE),
598 EXPECTED_TELAPSE, FLT_EPSILON);
599 cpl_test_abs(cpl_propertylist_get_double(tableprops, XSH_SDP_KEYWORD_TMID),
600 EXPECTED_TMID, FLT_EPSILON);
601 cpl_test_abs(cpl_propertylist_get_double(tableprops,
603 EXPECTED_SPEC_VAL, FLT_EPSILON);
604 cpl_test_abs(cpl_propertylist_get_double(tableprops, XSH_SDP_KEYWORD_SPEC_BW),
605 EXPECTED_SPEC_BW, FLT_EPSILON);
606 cpl_test_abs(cpl_propertylist_get_double(tableprops,
608 EXPECTED_TDMIN1, FLT_EPSILON);
609 cpl_test_abs(cpl_propertylist_get_double(tableprops,
611 EXPECTED_TDMAX1, FLT_EPSILON);
612 cpl_test_eq(cpl_propertylist_get_int(tableprops, TFIELDS_KEYWORD),
613 expected_TFIELDS);
614 cpl_test_eq(cpl_propertylist_get_int(tableprops, XSH_SDP_KEYWORD_NELEM),
616 cpl_test_eq_string(cpl_propertylist_get_string(tableprops, XSH_EXTNAME),
618 cpl_test_eq(cpl_propertylist_get_bool(tableprops, XSH_SDP_KEYWORD_INHERIT),
620/*FIXME: disabling CHECKSUM generation completely until whe know which version of CPL is fixed.
621 if (cpl_version_get_binary_version() > CPL_VERSION(6, 4, 0)) {
622 cpl_test(cpl_propertylist_has(tableprops, CHECKSUM_KEYWORD));
623 cpl_test(cpl_propertylist_has(tableprops, DATASUM_KEYWORD));
624 }
625*/
626
627 for (i = 1; i <= expected_TFIELDS; ++i) {
628 char* field = cpl_sprintf("TTYPE%"CPL_SIZE_FORMAT, i);
629 cpl_test(getlen(cpl_propertylist_get_string(tableprops, field)) > 1);
630 cpl_free(field);
631 field = cpl_sprintf("TFORM%"CPL_SIZE_FORMAT, i);
632 cpl_test(getlen(cpl_propertylist_get_string(tableprops, field)) > 1);
633 cpl_free(field);
634 field = cpl_sprintf("TUNIT%"CPL_SIZE_FORMAT, i);
635 switch (i) {
636 case 1:
637 cpl_test_eq_string(cpl_propertylist_get_string(tableprops, field),
638 "nm");
639 break;
640 case 2:
641 case 3:
642 case 6:
643 case 7:
644 cpl_test_eq_string(cpl_propertylist_get_string(tableprops, field),
645 "adu");
646 break;
647 case 4:
648 case 5:
649 cpl_test(getlen(cpl_propertylist_get_string(tableprops, field)) == 0);
650 break;
651 default:
652 cpl_test(getlen(cpl_propertylist_get_string(tableprops, field)) > 1);
653 break;
654 }
655 cpl_free(field);
656 field = cpl_sprintf("TUTYP%"CPL_SIZE_FORMAT, i);
657 cpl_test(getlen(cpl_propertylist_get_string(tableprops, field)) > 1);
658 cpl_free(field);
659 field = cpl_sprintf("TUCD%"CPL_SIZE_FORMAT, i);
660 cpl_test(getlen(cpl_propertylist_get_string(tableprops, field)) > 1);
661 cpl_free(field);
662 }
663
664 /* Check that the table values are correct. */
665 cpl_test_eq(cpl_table_get_nrow(table), 1);
666 cpl_test_eq(cpl_table_get_ncol(table), expected_TFIELDS);
667 double expected_wave[] = {
668 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600
669 };
670 double expected_flux[] = { 0, 0, 0, 7 , 21 , 12 , 0, 0, 0, 0, 0};
671 double expected_errs[] = { 0, 0, 0, 0.25, 0.5, 0.25, 0, 0, 0, 0, 0};
672 int expected_qual[] = {16, 0, 0, 0 , 0 , 0 , 0, 0, 0, 33, 0};
673 double expected_snr[] = { 0, 0, 0, 28 , 42 , 48 , 0, 0, 0, 0, 0};
674 const cpl_array * wave_array = cpl_table_get_array(table,
676 cpl_test_nonnull(wave_array);
677 const cpl_array * flux_array = cpl_table_get_array(table,
679 cpl_test_nonnull(flux_array);
680 const cpl_array * errs_array = cpl_table_get_array(table,
682 cpl_test_nonnull(errs_array);
683 const cpl_array * qual_array = cpl_table_get_array(table,
685 cpl_test_nonnull(qual_array);
686 const cpl_array * snr_array = cpl_table_get_array(table,
688 cpl_test_nonnull(snr_array);
689 const double* calculated_wave = NULL;
690 if (wave_array != NULL) {
691 calculated_wave = cpl_array_get_data_double_const(wave_array);
692 cpl_test_nonnull(calculated_wave);
693 }
694 const double* calculated_flux = NULL;
695 if (flux_array != NULL) {
696 calculated_flux = cpl_array_get_data_double_const(flux_array);
697 cpl_test_nonnull(calculated_flux);
698 }
699 const double* calculated_errs = NULL;
700 if (errs_array != NULL) {
701 calculated_errs = cpl_array_get_data_double_const(errs_array);
702 cpl_test_nonnull(calculated_errs);
703 }
704 const int* calculated_qual = NULL;
705 if (qual_array != NULL) {
706 calculated_qual = cpl_array_get_data_int_const(qual_array);
707 cpl_test_nonnull(calculated_qual);
708 }
709 const double* calculated_snr = NULL;
710 if (snr_array != NULL) {
711 calculated_snr = cpl_array_get_data_double_const(snr_array);
712 cpl_test_nonnull(calculated_snr);
713 }
714 if (calculated_wave != NULL && calculated_flux != NULL &&
715 calculated_errs != NULL && calculated_qual != NULL &&
716 calculated_snr != NULL)
717 {
718 for (i = 0; i < 11; ++i) {
719 cpl_test_abs(calculated_wave[i], expected_wave[i], FLT_EPSILON);
720 cpl_test_abs(calculated_flux[i], expected_flux[i], FLT_EPSILON);
721 cpl_test_abs(calculated_errs[i], expected_errs[i], FLT_EPSILON);
722 cpl_test_eq(calculated_qual[i], expected_qual[i]);
723 cpl_test_abs(calculated_snr[i], expected_snr[i], FLT_EPSILON);
724 }
725 }
726
727 /* Check extra columns in table if uncalibrated data is expected. */
728 if (expect_uncalib) {
729 flux_array = cpl_table_get_array(table, XSH_SDP_COLUMN_FLUX_REDUCED, 0);
730 cpl_test_nonnull(flux_array);
731 errs_array = cpl_table_get_array(table, XSH_SDP_COLUMN_ERR_REDUCED, 0);
732 cpl_test_nonnull(errs_array);
733 calculated_flux = NULL;
734 if (flux_array != NULL) {
735 calculated_flux = cpl_array_get_data_double_const(flux_array);
736 cpl_test_nonnull(calculated_flux);
737 }
738 calculated_errs = NULL;
739 if (errs_array != NULL) {
740 calculated_errs = cpl_array_get_data_double_const(errs_array);
741 cpl_test_nonnull(calculated_errs);
742 }
743 if (calculated_flux != NULL && calculated_errs != NULL)
744 {
745 for (i = 0; i < 11; ++i) {
746 cpl_test_abs(calculated_flux[i], expected_flux[i], FLT_EPSILON);
747 cpl_test_abs(calculated_errs[i], expected_errs[i], FLT_EPSILON);
748 }
749 }
750 }
751
752 /* Cleanup memory */
753 cpl_table_delete(table);
754 cpl_propertylist_delete(tableprops);
755 cpl_propertylist_delete(props);
756
757 return EXIT_SUCCESS;
758}
static xsh_instrument * instrument
cpl_frame * xsh_spectrum_save(xsh_spectrum *s, const char *filename, const char *tag)
save a spectrum
xsh_spectrum * xsh_spectrum_1D_create(double lambda_min, double lambda_max, double lambda_step)
Create a 1D spectrum structure.
void xsh_spectrum_free(xsh_spectrum **s)
free memory associated to an 1D spectrum
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.
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
void xsh_free_temporary_files(void)
Free temprary files list.
Definition: xsh_utils.c:1451
void xsh_free_product_files(void)
Free temprary files list.
Definition: xsh_utils.c:1491
cpl_propertylist * errs_header
cpl_propertylist * flux_header
cpl_image * flux
cpl_image * qual
cpl_image * errs
#define DATEOBS_VALUE
#define EXPECTED_FLUXCAL
#define EXPECTED_NCOMBINE
#define EXPECTED_TDMIN1
#define EXPECTED_TOT_FLUX
#define EXPECTED_RA
#define EXPECTED_FLUXERR
#define RAW_FILE_NAME
#define EXPECTED_PRODLVL
#define RAW_FRAME_TAG
#define BITPIX_KEYWORD
#define PRODUCT_FRAME_TAG
#define EXPECTED_EXTNAME
#define PRODUCT_FILE_NAME
#define EXPECTED_PROV1
#define EXPECTED_OBJECT
#define EXPECTED_EFFRON
#define OBJECT_VALUE
#define EXPECTED_DETRON
#define CHECKSUM_KEYWORD
#define EXPECTED_MJDOBS
#define EXPECTED_TFIELDS
#define INSTRUME_VALUE
#define EXTEND_KEYWORD
#define TEST_NAME
#define EXPECTED_TELAPSE
#define EXPECTED_WAVELMAX
#define EXPECTED_WAVELMIN
#define EXPECTED_ORIGIN
#define SNR_VALUE
#define EQUINOX_VALUE
static int check_output_file(cpl_boolean expect_uncalib)
Checks that the generated output file is valid.
#define DATE_KEYWORD
int main(void)
Unit tests of the Science Data Product DFS functions.
static int create_dummy_raw_frame(cpl_frameset *frames)
Creates an input FITS file representing a dummy raw data file.
#define EQUINOX_KEYWORD
#define EXPECTED_MJDEND
#define EXPECTED_PROG_ID
#define EXPECTED_TMID
#define EXPECTED_OBSTECH
#define EXPECTED_TDMAX1
#define OBS_ID_VALUE
#define INSTRUME_KEYWORD
#define CSYER1_VALUE
#define MJDOBS_VALUE
#define DATASUM_KEYWORD
#define SLIT_STRING_VALUE
#define EXPECTED_EQUINOX
#define EXPECTED_SPEC_VAL
#define EXPECTED_NELEM
#define EXPECTED_TFIELDS_UNCAL
#define EXPECTED_PRODCATG
#define ORIGIN_VALUE
static int create_input_product_frame(cpl_frameset *frames, const cpl_parameterlist *params, xsh_instrument *instrument)
Creates a 1D spectrum product FITS file in X-Shooter native format.
#define RON_VALUE
#define PRO_TECH_VALUE
#define OUTPUT_FILE_NAME
#define PROG_ID_VALUE
#define EXPECTED_DISPELEM
#define BUINT_VALUE
#define EXPTIME_VALUE
#define EXPECTED_INHERIT
#define CONAD_VALUE
#define TELESCOP_VALUE
#define EXPECTED_APERTURE
static int getlen(const char *str)
#define RECIPE_ID
#define EXPECTED_OBS_ID
#define EXPECTED_TITLE
#define RA_VALUE
#define TARGET_NAME
#define EXPECTED_DEC
#define DEC_VALUE
#define test_success(expr)
#define TFIELDS_KEYWORD
#define EXPECTED_EXPTIME
#define EXPECTED_SPEC_BIN
#define SIMPLE_KEYWORD
#define EXPECTED_SPEC_BW
#define EXPECTED_SNR
@ XSH_LAMP_QTH
@ XSH_ARM_VIS
@ XSH_MODE_SLIT
void xsh_add_product_spectrum(cpl_frame *frame, cpl_frameset *frameset, const cpl_parameterlist *parameters, const char *recipe_id, xsh_instrument *instr, cpl_frame **result_frame, cpl_propertylist *qclist)
Definition: xsh_dfs.c:2067
void xsh_add_sdp_product_spectrum(const cpl_frame *flux_cal_frame, const cpl_frame *uncal_frame, cpl_frameset *frameset, const cpl_frameset *usedframes, const cpl_parameterlist *parameters, const char *recipe_id, xsh_instrument *instrument, cpl_propertylist *qclist)
Creates a 1D spectrum product in the Science Data Product format.
Definition: xsh_dfs.c:6326
#define XSH_SDP_KEYWORD_NCOMBINE
Definition: xsh_pfits.h:334
#define XSH_SDP_KEYWORD_PRODCATG
Definition: xsh_pfits.h:286
#define XSH_SDP_KEYWORD_TELAPSE
Definition: xsh_pfits.h:298
#define XSH_SDP_KEYWORD_FLUXERR
Definition: xsh_pfits.h:321
#define XSH_SDP_COLUMN_FLUX
Definition: xsh_pfits.h:342
#define XSH_SDP_KEYWORD_INHERIT
Definition: xsh_pfits.h:307
#define XSH_BUNIT
Definition: xsh_pfits.h:113
#define XSH_EXPTIME
Definition: xsh_pfits.h:125
#define XSH_SDP_KEYWORD_LAMNLIN
Definition: xsh_pfits.h:328
#define XSH_SDP_KEYWORD_WAVELMIN
Definition: xsh_pfits.h:317
#define XSH_MJDEND
Definition: xsh_pfits.h:40
#define XSH_SDP_COLUMN_WAVE
Definition: xsh_pfits.h:337
#define XSH_SDP_COLUMN_ERR_REDUCED
Definition: xsh_pfits.h:368
#define XSH_SDP_KEYWORD_LAMRMS
Definition: xsh_pfits.h:329
#define XSH_SLIT_VIS
Definition: xsh_pfits.h:137
#define XSH_RA
Definition: xsh_pfits.h:44
#define XSH_SDP_KEYWORD_OBSTECH
Definition: xsh_pfits.h:314
#define XSH_SDP_KEYWORD_TDMAX(n)
Definition: xsh_pfits.h:303
#define XSH_SDP_KEYWORD_OBJECT
Definition: xsh_pfits.h:285
#define XSH_SDP_KEYWORD_ORIGIN
Definition: xsh_pfits.h:287
#define XSH_SDP_COLUMN_QUAL
Definition: xsh_pfits.h:354
#define XSH_SDP_KEYWORD_WAVELMAX
Definition: xsh_pfits.h:318
#define XSH_SDP_KEYWORD_APERTURE
Definition: xsh_pfits.h:297
#define XSH_SDP_COLUMN_FLUX_REDUCED
Definition: xsh_pfits.h:364
#define XSH_SDP_COLUMN_SNR
Definition: xsh_pfits.h:359
#define XSH_SDP_KEYWORD_SPEC_RES
Definition: xsh_pfits.h:325
#define XSH_SDP_COLUMN_ERR
Definition: xsh_pfits.h:348
#define XSH_EXTNAME
Definition: xsh_pfits.h:124
#define XSH_SDP_KEYWORD_PRODLVL
Definition: xsh_pfits.h:283
#define XSH_SDP_KEYWORD_PROCSOFT
Definition: xsh_pfits.h:282
#define XSH_SDP_KEYWORD_SPEC_ERR
Definition: xsh_pfits.h:326
#define XSH_SDP_KEYWORD_TDMIN(n)
Definition: xsh_pfits.h:302
#define XSH_SDP_KEYWORD_NELEM
Definition: xsh_pfits.h:304
#define XSH_SDP_KEYWORD_M_EPOCH
Definition: xsh_pfits.h:313
#define XSH_DEC
Definition: xsh_pfits.h:45
#define XSH_SDP_KEYWORD_DISPELEM
Definition: xsh_pfits.h:289
#define XSH_MJDOBS
Definition: xsh_pfits.h:39
#define XSH_SDP_KEYWORD_PROV(n)
Definition: xsh_pfits.h:333
#define XSH_SDP_KEYWORD_SPECSYS
Definition: xsh_pfits.h:290
#define XSH_SNR
Definition: xsh_pfits.h:49
#define XSH_OBS_PROG_ID
Definition: xsh_pfits.h:47
#define XSH_SDP_KEYWORD_OBID1
Definition: xsh_pfits.h:312
#define XSH_SDP_KEYWORD_SPEC_BW
Definition: xsh_pfits.h:310
#define XSH_SDP_KEYWORD_DETRON
Definition: xsh_pfits.h:331
#define XSH_SDP_KEYWORD_FLUXCAL
Definition: xsh_pfits.h:315
#define XSH_TELESCOP
Definition: xsh_pfits.h:60
#define XSH_SDP_KEYWORD_TOT_FLUX
Definition: xsh_pfits.h:320
#define XSH_SDP_KEYWORD_REFERENC
Definition: xsh_pfits.h:323
#define XSH_SDP_KEYWORD_TITLE
Definition: xsh_pfits.h:296
#define XSH_RON
Definition: xsh_pfits.h:161
#define XSH_SDP_KEYWORD_SPEC_VAL
Definition: xsh_pfits.h:309
#define XSH_OBS_TARG_NAME
Definition: xsh_pfits.h:128
#define XSH_SDP_KEYWORD_PROG_ID
Definition: xsh_pfits.h:311
#define XSH_DPR_TYPE
Definition: xsh_pfits.h:147
#define XSH_SDP_KEYWORD_TMID
Definition: xsh_pfits.h:299
#define XSH_SDP_KEYWORD_CONTNORM
Definition: xsh_pfits.h:316
#define XSH_SDP_KEYWORD_SPEC_BIN
Definition: xsh_pfits.h:319
#define XSH_PRO_TECH
Definition: xsh_pfits.h:48
#define XSH_DATE_OBS
Definition: xsh_pfits.h:123
#define XSH_CONAD
Definition: xsh_pfits.h:162
#define XSH_SDP_KEYWORD_SPEC_SYE
Definition: xsh_pfits.h:327
#define XSH_SDP_KEYWORD_EFFRON
Definition: xsh_pfits.h:332
#define XSH_OBS_ID
Definition: xsh_pfits.h:127
#define XSH_NAXIS
Definition: xsh_pfits.h:41
#define XSH_QC_FLUX_SN
Definition: xsh_pfits_qc.h:117
#define XSH_CSYER1