CR2RE Pipeline Reference Manual 1.6.8
cr2res_qc-test.c
1/*
2 * This file is part of the CR2RES Pipeline
3 * Copyright (C) 2002,2003 European Southern Observatory
4 *
5 * This program 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, Inc., 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 Includes
26 -----------------------------------------------------------------------------*/
27
28#include <stdlib.h>
29#include <string.h>
30#include <cpl.h>
31#include <cr2res_qc.h>
32
33#include "cr2res_trace.h"
34#include "cr2res_dfs.h"
35#include "cr2res_pfits.h"
36#include "cr2res_io.h"
37
38
39#define WLEN_BEGIN(i) ({char s[20]; sprintf(s, CR2RES_HEADER_WLEN_BEGIN, i); s;})
40#define WLEN_END(i) ({char s[20]; sprintf(s, CR2RES_HEADER_WLEN_END, i); s;})
41#define WLEN_CENY(i) ({char s[20]; sprintf(s, CR2RES_HEADER_WLEN_CENY, i); s;})
42
43/*-----------------------------------------------------------------------------
44 Functions prototypes
45 -----------------------------------------------------------------------------*/
46
47static void test_cr2res_dark_qc_ron(void);
48static void test_cr2res_qc_obs_nodding_slit_psf(void);
49
50/*----------------------------------------------------------------------------*/
55/*----------------------------------------------------------------------------*/
56
58#ifdef CR2RES_UNUSED_TESTS
59/*----------------------------------------------------------------------------*/
65/*----------------------------------------------------------------------------*/
66static cpl_table *create_test_table()
67{
68 cpl_table *traces;
69 cpl_array *array, *slit_fraction, *wave, *wave_err, *slit_a, *slit_b,
70 *slit_c;
71 int poly_order, norders;
72 cpl_propertylist *hdr = cpl_propertylist_new();
73 cpl_propertylist *main_header = cpl_propertylist_new();
74 char * extname;
75
76 /* Initialise */
77 poly_order = 2;
78 norders = 9;
79
80 /* NULL Input */
81 traces = cpl_table_new(norders);
82 cpl_table_new_column_array(traces, CR2RES_COL_ALL, CPL_TYPE_DOUBLE,
83 poly_order);
84 cpl_table_new_column_array(traces, CR2RES_COL_UPPER, CPL_TYPE_DOUBLE,
85 poly_order);
86 cpl_table_new_column_array(traces, CR2RES_COL_LOWER, CPL_TYPE_DOUBLE,
87 poly_order);
88 cpl_table_new_column(traces, CR2RES_COL_ORDER, CPL_TYPE_INT);
89 cpl_table_new_column(traces, CR2RES_COL_TRACENB, CPL_TYPE_INT);
90
91 cpl_table_new_column_array(traces, CR2RES_COL_WAVELENGTH, CPL_TYPE_DOUBLE,
92 2);
93 cpl_table_new_column_array(traces, CR2RES_COL_WAVELENGTH_ERROR,
94 CPL_TYPE_DOUBLE, 2);
95 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_CURV_A, CPL_TYPE_DOUBLE,
96 3);
97 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_CURV_B, CPL_TYPE_DOUBLE,
98 3);
99 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_CURV_C, CPL_TYPE_DOUBLE,
100 3);
101 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_FRACTION,
102 CPL_TYPE_DOUBLE, 3);
103
104 /*
105 All| Upper| Lower| Order
106 54.3148, 0.00738623| 110.379, 0.0159501|1.63328, -8.95809e-05| 1
107 226.289, 0.0169145| 311.885, 0.0167957| 139.106, 0.017396| 2
108 437.881, 0.0172448| 524.126, 0.0171958| 350.398, 0.0170009| 3
109 660.954, 0.0178211| 747.931, 0.0179547| 572.986, 0.0177137| 4
110 897.266, 0.0185319| 985.06, 0.0186544| 808.823, 0.0185517| 5
111 1148.31, 0.019388| 1237.01, 0.0193813| 1059.39, 0.0194215| 6
112 1415.88, 0.0202877| 1505.34, 0.0202763| 1326.43, 0.0202534| 7
113 1701.85, 0.021292| 1792.03, 0.0213662| 1611.65, 0.0212178| 8
114 1982.59, 0.0111388|2047.88, 8.66878e-05| 1917.3, 0.0221835| 9
115
116 */
117 double all_1[] = {54.3148, 226.289, 437.881, 660.954, 897.266,
118 1148.31, 1415.88, 1701.85, 1982.59};
119 double all_2[] = {0.00738623, 0.0169145, 0.0172448, 0.0178211,
120 0.0185319, 0.019388, 0.0202877, 0.021292, 0.0111388};
121 double upper_1[] = {110.379, 311.885, 524.126, 747.931, 985.06,
122 1237.01, 1505.34, 1792.03, 2047.88};
123 double upper_2[] = {0.0159501, 0.0167957, 0.0171958, 0.0179547,
124 0.0186544, 0.0193813, 0.0202763, 0.0213662, 8.66878e-05};
125 double lower_1[] = {1.63328, 139.106, 350.398, 572.986, 808.823,
126 1059.39, 1326.43, 1611.65, 1917.3};
127 double lower_2[] = {-8.95809e-05, 0.017396, 0.0170009, 0.0177137,
128 0.0185517, 0.0194215, 0.0202534, 0.0212178, 0.0221835};
129 array = cpl_array_new(poly_order, CPL_TYPE_DOUBLE);
130 slit_fraction = cpl_array_new(3, CPL_TYPE_DOUBLE);
131 cpl_array_set_double(slit_fraction, 0, 0);
132 cpl_array_set_double(slit_fraction, 1, 0.5);
133 cpl_array_set_double(slit_fraction, 2, 1);
134 wave = cpl_array_new(2, CPL_TYPE_DOUBLE);
135 cpl_array_set_double(wave, 0, 9.45e2);
136 cpl_array_set_double(wave, 1, 3.13e-3);
137 wave_err = cpl_array_new(2, CPL_TYPE_DOUBLE);
138 cpl_array_set_double(wave_err, 0, 5e-2);
139 cpl_array_set_double(wave_err, 1, 5e-2);
140
141 slit_a = cpl_array_new(3, CPL_TYPE_DOUBLE);
142 cpl_array_set(slit_a, 0, 0);
143 cpl_array_set(slit_a, 1, 1);
144 cpl_array_set(slit_a, 2, 0);
145 slit_b = cpl_array_new(3, CPL_TYPE_DOUBLE);
146 cpl_array_set(slit_b, 0, 0);
147 cpl_array_set(slit_b, 1, 0);
148 cpl_array_set(slit_b, 2, 0);
149 slit_c = cpl_array_new(3, CPL_TYPE_DOUBLE);
150 cpl_array_set(slit_c, 0, 0);
151 cpl_array_set(slit_c, 1, 0);
152 cpl_array_set(slit_c, 2, 0);
153
154 for (int i = 0; i < norders; i++)
155 {
156 cpl_array_set(array, 0, all_1[i]);
157 cpl_array_set(array, 1, all_2[i]);
158 cpl_table_set_array(traces, CR2RES_COL_ALL, i, array);
159 cpl_array_set(array, 0, upper_1[i]);
160 cpl_array_set(array, 1, upper_2[i]);
161 cpl_table_set_array(traces, CR2RES_COL_UPPER, i, array);
162 cpl_array_set(array, 0, lower_1[i]);
163 cpl_array_set(array, 1, lower_2[i]);
164 cpl_table_set_array(traces, CR2RES_COL_LOWER, i, array);
165 cpl_table_set(traces, CR2RES_COL_ORDER, i,
167 cpl_table_set(traces, CR2RES_COL_TRACENB, i, 1);
168
169 cpl_table_set_array(traces, CR2RES_COL_SLIT_FRACTION, i, slit_fraction);
170 cpl_table_set_array(traces, CR2RES_COL_WAVELENGTH, i, wave);
171 cpl_table_set_array(traces, CR2RES_COL_WAVELENGTH_ERROR, i, wave_err);
172 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_A, i, slit_a);
173 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_B, i, slit_b);
174 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_C, i, slit_c);
175 }
176
177 extname = cr2res_io_create_extname(1, 1);
178 cpl_propertylist_append_string(hdr, CR2RES_HEADER_EXTNAME, extname);
179
180 double ceny[] = {1994.0945859223, 1723.67027599362, 1436.61298619847,
181 1168.0222016174, 915.8934665223831, 678.542785839296,
182 454.468576982434, 242.388497032926, 63.5899165277783};
183 double begin[] = {1756.78720770673, 1703.55123171562, 1653.44678372399,
184 1606.20544704616, 1561.58862907265, 1519.38353098961,
185 1479.3997538583, 1441.46642683629, -1};
186 double end[] = {1768.81709603003, 1715.21657796851, 1664.76903155768,
187 1617.2042020846, 1572.2818631378, 1529.78775872867,
188 1489.53018613055, 1451.3371044349, -1};
189
190 for (int i = 0; i < 9; i++)
191 {
192 cpl_propertylist_append_double(hdr, WLEN_CENY(i), ceny[i]);
193 cpl_propertylist_append_double(hdr, WLEN_BEGIN(i), begin[i]);
194 cpl_propertylist_append_double(hdr, WLEN_END(i), end[i]);
195 }
196
197
198 cpl_propertylist_append_int(main_header, CR2RES_HEADER_DECKER_POS, CR2RES_DECKER_2_4);
199
200 cpl_table_save(traces, main_header, hdr, "TEST_table.fits", CPL_IO_CREATE);
201
202 cpl_array_delete(array);
203 cpl_array_delete(slit_fraction);
204 cpl_array_delete(wave);
205 cpl_array_delete(wave_err);
206 cpl_array_delete(slit_a);
207 cpl_array_delete(slit_b);
208 cpl_array_delete(slit_c);
209
210 cpl_propertylist_delete(hdr);
211 cpl_propertylist_delete(main_header);
212 cpl_free(extname);
213 return traces;
214}
215#endif
216
217#ifdef CR2RES_UNUSED_TESTS
218/*----------------------------------------------------------------------------*/
224/*----------------------------------------------------------------------------*/
225static cpl_image *create_test_image(void)
226{
227 cpl_table *traces;
228 cpl_image *trace_ima;
229 //cpl_image *extract;
230
231 traces = create_test_table();
232 trace_ima = cr2res_trace_gen_image(traces, 2048, 2048);
233 cpl_table_delete(traces);
234
235 return trace_ima;
236}
237#endif
238
239static void test_cr2res_dark_qc_ron(void)
240{
241 cpl_image *ima1, *ima2;
242 int hsize, nsamples, ndit;
243
244 ima1 = cpl_image_new(100, 100, CPL_TYPE_DOUBLE);
245 ima2 = cpl_image_new(100, 100, CPL_TYPE_DOUBLE);
246
247 hsize = -1;
248 nsamples = -1;
249 ndit = 2;
250
251 for(cpl_size x = 1; x <= 100; x++)
252 {
253 for(cpl_size y = 1; y <= 100; y++)
254 {
255 cpl_image_set(ima1, x, y, 1);
256 cpl_image_set(ima2, x, y, 1);
257 }
258 }
259
260 cr2res_dark_qc_ron(ima1, ima2, hsize, nsamples, ndit);
261 cpl_test_error(CPL_ERROR_NONE);
262
263 cpl_image_delete(ima1);
264 cpl_image_delete(ima2);
265}
266
267static void test_cr2res_qc_obs_nodding_slit_psf()
268{
269 int nrow = 100;
270 // values for creating the default data
271 double x0 = nrow / 2;
272 double A = 1; // total area of the slitfunc should always be 1
273 double offset = 0;
274 double sigma = nrow / 20;
275 double fwhm = -1;
276
277 char col1[] = "01_01_SLIT_FUNC";
278 char col2[] = "02_01_SLIT_FUNC";
279
280 cpl_table * slitfu = cpl_table_new(nrow);
281 cpl_table_new_column(slitfu, col1, CPL_TYPE_DOUBLE);
282 cpl_table_new_column(slitfu, col2, CPL_TYPE_DOUBLE);
283
284 for (cpl_size i = 0; i < nrow; i++)
285 {
286 double value;
287 // area / sqrt(2 pi sigma^2) * exp( -(x - x0)^2/(2 sigma^2)) + offset
288 value = A / sqrt(CPL_MATH_2_PI * sigma * sigma) * exp( -(i - x0) *
289 (i - x0) / (2. * sigma * sigma)) + offset;
290 cpl_table_set_double(slitfu, col1, i, value);
291 cpl_table_set_double(slitfu, col2, i, value);
292 }
293
294 cpl_test_abs(-1, cr2res_qc_obs_slit_psf(NULL,1,1), DBL_EPSILON);
295 cpl_test(fwhm = cr2res_qc_obs_slit_psf(slitfu,2,1));
296 // oversample correction: 102/100
297 cpl_test_abs(fwhm, 2.355 * sigma / 1.02, 0.01);
298
299 cpl_table_delete(slitfu);
300}
301
302/*----------------------------------------------------------------------------*/
306/*----------------------------------------------------------------------------*/
307int main(void)
308{
309 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_DEBUG);
310
311 test_cr2res_dark_qc_ron();
312 test_cr2res_qc_obs_nodding_slit_psf();
313
314 return cpl_test_end(0);
315}
316
char * cr2res_io_create_extname(int detector, int data)
Create Extname.
Definition: cr2res_io.c:618
int cr2res_io_convert_order_idx_to_idxp(int order_idx)
Convert the order_idx to the order_idxp.
Definition: cr2res_io.c:583
int main(void)
Run the Unit tests.
double cr2res_dark_qc_ron(const cpl_image *ima1, const cpl_image *ima2, int hsize, int nsamples, int ndit)
The Read Out Noise computation.
Definition: cr2res_qc.c:74
double cr2res_qc_obs_slit_psf(const cpl_table *slitfu, int order_idxp, int oversample)
Computes the FWHM of the PSF along the slit for a given order.
Definition: cr2res_qc.c:1208
cpl_image * cr2res_trace_gen_image(cpl_table *trace, int nx, int ny)
Make an image out of the trace solution.
Definition: cr2res_trace.c:362