CR2RE Pipeline Reference Manual 1.6.2
cr2res_extract-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
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
25/*-----------------------------------------------------------------------------
26 Includes
27 -----------------------------------------------------------------------------*/
28
29#include <stdlib.h>
30#include <string.h>
31#include <math.h>
32#include <cpl.h>
33#include <hdrl.h>
34#include <cr2res_dfs.h>
35#include <cr2res_extract.h>
36#include <cr2res_trace.h>
37#include <cr2res_slit_curv.h>
38
39static void test_cr2res_extract_sum(void);
40static void test_cr2res_extract_median(void);
41static void test_cr2res_extract_sum_tilt(void);
42//static void test_cr2res_slitdec_vert_regression(void);
43//static void test_cr2res_slitdec_vert_edge_cases(void);
44//static void test_cr2res_slitdec_curved(void);
45static void test_cr2res_slitdec_errors(void);
46//static void test_cr2res_slitdec_input_slitfunc(void);
47
48
49#ifdef CR2RES_UNUSED_TESTS
50static cpl_table *create_test_table()
51{
52 int poly_order = 2;
53 int n_orders = 2;
54 cpl_table * traces = cpl_table_new(n_orders);
55 cpl_table_new_column_array(traces, CR2RES_COL_ALL, CPL_TYPE_DOUBLE, poly_order);
56 cpl_table_new_column_array(traces, CR2RES_COL_UPPER, CPL_TYPE_DOUBLE, poly_order);
57 cpl_table_new_column_array(traces, CR2RES_COL_LOWER, CPL_TYPE_DOUBLE, poly_order);
58 cpl_table_new_column(traces, CR2RES_COL_ORDER, CPL_TYPE_INT);
59 cpl_table_new_column(traces, CR2RES_COL_TRACENB, CPL_TYPE_INT);
60
61 double all_1[] = {86.6279, 175.5738};
62 double all_2[] = {0.01699, 0.07512};
63 double upper_1[] = {108.5065, 197.3485};
64 double upper_2[] = {0.016601, 0.0184364};
65 double lower_1[] = {64.05477, 153.7987};
66 double lower_2[] = {0.017355, 0.01659297};
67
68 cpl_array * array = cpl_array_new(poly_order, CPL_TYPE_DOUBLE);
69 for (int i = 0; i < n_orders; i++) {
70 cpl_array_set(array, 0, all_1[i]);
71 cpl_array_set(array, 1, all_2[i]);
72 cpl_table_set_array(traces, CR2RES_COL_ALL, i, array);
73 cpl_array_set(array, 0, upper_1[i]);
74 cpl_array_set(array, 1, upper_2[i]);
75 cpl_table_set_array(traces, CR2RES_COL_UPPER, i, array);
76 cpl_array_set(array, 0, lower_1[i]);
77 cpl_array_set(array, 1, lower_2[i]);
78 cpl_table_set_array(traces, CR2RES_COL_LOWER, i, array);
79 cpl_table_set(traces, CR2RES_COL_ORDER, i, 7);
80 cpl_table_set(traces, CR2RES_COL_TRACENB, i, i + 1);
81 }
82
83 cpl_array_delete(array);
84 return traces;
85}
86
87static cpl_image *create_test_image()
88{
89 cpl_image *img;
90
91 // The debugger runs in a different directory than make check
92 // to get the right file in either case check if it exists or not
93 if (access("./tests/cr2res_utils_test_image.fits", F_OK) != -1){
94 img = cpl_image_load("./tests/cr2res_utils_test_image.fits", CPL_TYPE_INT, 0, 1);
95 }
96 else{
97 img = cpl_image_load("./cr2res_utils_test_image.fits", CPL_TYPE_INT, 0, 1);
98 }
99 return img;
100}
101#endif
102
103static cpl_image *create_image_linear_increase(int width, int height, double spec_in[width])
104{
105 double min = 5;
106 double step = 0.1;
107 double slitf;
108 double sigma = height/16.;
109 double mu = height/2.;
110 cpl_image * img = cpl_image_new(width, height, CPL_TYPE_DOUBLE);
111
112 for(int i = 1; i <= width; i++) {
113 double spec;
114 spec = i * step + min;
115 if (i > width/2 - 5 && i < width/2 + 5)
116 spec -= 2 * min * exp(- (i - width/2) * (i - width/2) / (2. * 1 * 1));
117
118 spec_in[i-1] = spec;
119 for(int j = 1; j <= height; j++) {
120 slitf = exp(- (j - mu) * (j - mu) / (2. * sigma * sigma));
121 cpl_image_set(img, i, j, spec * slitf);
122 }
123 }
124
125 return img;
126}
127
128static cpl_image * create_image_sinusoidal(
129 int width,
130 int height,
131 double spec_in[width])
132{
133 double min = 5.0;
134 double sigma = height/8.;
135 double mu = height/2.;
136 double slitf;
137
138 cpl_image * img = cpl_image_new(width, height, CPL_TYPE_DOUBLE);
139
140 for(int i = 1; i <= width; i++) {
141 double spec;
142 // Sinusoidal spectrum
143 spec = 3 * sin(CPL_MATH_2PI * (i-1.)/(0.2 * width)) + min;
144 spec_in[i-1] = spec;
145
146 for(int j = 1; j <= height; j++) {
147 // Normal distribution as slitfunction
148 slitf = exp(- (j - mu) * (j - mu) / (2. * sigma * sigma));
149 cpl_image_set(img, i, j, spec * slitf);
150 }
151 }
152 return img;
153}
154
155cpl_image * apply_shear(cpl_image * img, int width, int height, double shear){
156 int k;
157 double mu = height * 0.5;
158 double spec;
159
160 cpl_image * img_tilt = cpl_image_new(width, height, CPL_TYPE_DOUBLE);
161
162 for(int i = 1; i <= width; i++) {
163 for(int j = 1; j <= height; j++) {
164 k = (int)(i - (j - mu) * shear);
165 // periodic boundary conditions
166 if (k < 1) k = k + width;
167 if (k > width) k = k - width;
168
169 spec = cpl_image_get(img, k, j, &k);
170 cpl_image_set(img_tilt, i, j, spec);
171 }
172 }
173 cpl_image_delete(img);
174
175 return img_tilt;
176}
177
178static cpl_table * create_table_linear_increase(
179 int height,
180 double shear)
181{
182 int poly_order = 1;
183 cpl_table * traces = cpl_table_new(2);
184 cpl_array * array = cpl_array_new(poly_order, CPL_TYPE_DOUBLE);
185 cpl_array * wl = cpl_array_new(2, CPL_TYPE_DOUBLE);
186 cpl_array_set(wl, 0, 10);
187 cpl_array_set(wl, 1, 1);
188
189 cpl_table_new_column_array(traces, CR2RES_COL_ALL, CPL_TYPE_DOUBLE, poly_order);
190 cpl_table_new_column_array(traces, CR2RES_COL_UPPER, CPL_TYPE_DOUBLE, poly_order);
191 cpl_table_new_column_array(traces, CR2RES_COL_LOWER, CPL_TYPE_DOUBLE, poly_order);
192 cpl_table_new_column_array(traces, CR2RES_COL_WAVELENGTH, CPL_TYPE_DOUBLE, 2);
193 cpl_table_new_column(traces, CR2RES_COL_ORDER, CPL_TYPE_INT);
194 cpl_table_new_column(traces, CR2RES_COL_TRACENB, CPL_TYPE_INT);
195 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_CURV_A, CPL_TYPE_DOUBLE, 2);
196 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_CURV_B, CPL_TYPE_DOUBLE, 2);
197 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_CURV_C, CPL_TYPE_DOUBLE, 2);
198
199 height += 1;
200
201
202 cpl_array_set(array, 0, height * 0.5);
203 cpl_table_set_array(traces, CR2RES_COL_ALL, 0, array);
204 cpl_array_set(array, 0, height * 0.8);
205 cpl_table_set_array(traces, CR2RES_COL_UPPER, 0, array);
206 cpl_array_set(array, 0, height * 0.2);
207 cpl_table_set_array(traces, CR2RES_COL_LOWER, 0, array);
208 cpl_table_set_array(traces, CR2RES_COL_WAVELENGTH, 0, wl);
209 cpl_table_set(traces, CR2RES_COL_ORDER, 0, 1);
210 cpl_table_set(traces, CR2RES_COL_TRACENB, 0, 1);
211
212 cpl_array_set(array, 0, height * 0.5);
213 cpl_table_set_array(traces, CR2RES_COL_ALL, 1, array);
214 cpl_array_set(array, 0, height * 0.8);
215 cpl_table_set_array(traces, CR2RES_COL_UPPER, 1, array);
216 cpl_array_set(array, 0, height * 0.2);
217 cpl_table_set_array(traces, CR2RES_COL_LOWER, 1, array);
218 cpl_table_set_array(traces, CR2RES_COL_WAVELENGTH, 1, wl);
219 cpl_table_set(traces, CR2RES_COL_ORDER, 1, 1);
220 cpl_table_set(traces, CR2RES_COL_TRACENB, 1, 2);
221
222 double yc = height * 0.5;
223
224 cpl_array_set(wl, 0, - yc * shear);
225 cpl_array_set(wl, 1, 1);
226 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_A, 0, wl);
227 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_A, 1, wl);
228
229 cpl_array_set(wl, 0, shear);
230 cpl_array_set(wl, 1, 0);
231 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_B, 0, wl);
232 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_B, 1, wl);
233
234 cpl_array_set(wl, 0, 0);
235 cpl_array_set(wl, 1, 0);
236 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_C, 0, wl);
237 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_C, 1, wl);
238
239
240 cpl_array_delete(array);
241 cpl_array_delete(wl);
242 return traces;
243}
244
245/*----------------------------------------------------------------------------*/
268/*----------------------------------------------------------------------------*/
269static void test_cr2res_extract_sum(void)
270{
271 int width = 2000;
272 int height = 50;
273 double spec_in[width];
274 cpl_image * img_in = create_image_linear_increase(width, height, spec_in);
275 hdrl_image * img_hdrl = hdrl_image_create(img_in, NULL);
276 cpl_table * trace_table = create_table_linear_increase(height, 0);
277 int order = 1;
278 int trace = 1;
279
280 cpl_vector * slit_func;
281 cpl_bivector * spec;
282 hdrl_image * model;
283
284 cpl_test_eq( 0, cr2res_extract_sum_vert(img_hdrl, trace_table, order, trace, height, &slit_func, &spec, &model));
285
286 // check results
287 double ratio0 = cpl_bivector_get_x_data(spec)[0] / spec_in[0];
288 for(int i = 0; i < width; i++)
289 {
290 double ratio;
291 //spectrum, with linear increase
292 ratio = cpl_bivector_get_x_data(spec)[i] / spec_in[i];
293 cpl_test_abs(ratio, ratio0, FLT_EPSILON);
294
295 //relative error
296 ratio = cpl_bivector_get_y_data(spec)[i] / cpl_bivector_get_x_data(spec)[i];
297 cpl_test_abs(ratio, 0, DBL_EPSILON);
298 }
299
300 cpl_test_abs(cpl_vector_get_sum(slit_func), 1, DBL_EPSILON);
301
302
303 cpl_vector_save(cpl_bivector_get_x(spec), "TEST_spec.fits", CPL_TYPE_DOUBLE, NULL,
304 CPL_IO_CREATE);
305 cpl_vector_save(cpl_bivector_get_y(spec), "TEST_err.fits", CPL_TYPE_DOUBLE, NULL,
306 CPL_IO_CREATE);
307 cpl_vector_save(slit_func, "TEST_slitfunc.fits", CPL_TYPE_DOUBLE,
308 NULL, CPL_IO_CREATE);
309 cpl_image_save(hdrl_image_get_image(model), "TEST_model.fits", CPL_TYPE_FLOAT,
310 NULL, CPL_IO_CREATE);
311
312 // Free memory
313 cpl_vector_delete(slit_func);
314 cpl_bivector_delete(spec);
315 hdrl_image_delete(model);
316 cpl_image_delete(img_in);
317 cpl_table_delete(trace_table);
318 hdrl_image_delete(img_hdrl);
319}
320
321/*----------------------------------------------------------------------------*/
344/*----------------------------------------------------------------------------*/
345static void test_cr2res_extract_median(void)
346{
347 int width = 2000;
348 int height = 50;
349 double spec_in[width];
350 cpl_image * img_in = create_image_linear_increase(width, height, spec_in);
351 hdrl_image * img_hdrl = hdrl_image_create(img_in, NULL);
352 cpl_table * trace_table = create_table_linear_increase(height, 0);
353 int order = 1;
354 int trace = 1;
355
356 cpl_vector * slit_func;
357 cpl_bivector * spec;
358 hdrl_image * model;
359
360 cpl_test_eq( 0, cr2res_extract_median(img_hdrl, trace_table, order, trace, height, &slit_func, &spec, &model));
361
362 // check results
363 double ratio0 = cpl_bivector_get_x_data(spec)[0] / spec_in[0];
364 for(int i = 0; i < width; i++)
365 {
366
367 double ratio;
368 //spectrum, with linear increase
369 ratio = cpl_bivector_get_x_data(spec)[i] / spec_in[i];
370 cpl_test_abs(ratio, ratio0, FLT_EPSILON);
371
372 //relative error
373 ratio = cpl_bivector_get_y_data(spec)[i] / cpl_bivector_get_x_data(spec)[i];
374 cpl_test_abs(ratio, 0, DBL_EPSILON);
375 }
376
377 cpl_test_abs(cpl_vector_get_sum(slit_func), 1, DBL_EPSILON);
378
379
380 cpl_vector_save(cpl_bivector_get_x(spec), "TEST_spec.fits", CPL_TYPE_DOUBLE, NULL,
381 CPL_IO_CREATE);
382 cpl_vector_save(cpl_bivector_get_y(spec), "TEST_err.fits", CPL_TYPE_DOUBLE, NULL,
383 CPL_IO_CREATE);
384 cpl_vector_save(slit_func, "TEST_slitfunc.fits", CPL_TYPE_DOUBLE,
385 NULL, CPL_IO_CREATE);
386 cpl_image_save(hdrl_image_get_image(model), "TEST_model.fits", CPL_TYPE_FLOAT,
387 NULL, CPL_IO_CREATE);
388
389 // Free memory
390 cpl_vector_delete(slit_func);
391 cpl_bivector_delete(spec);
392 hdrl_image_delete(model);
393 cpl_image_delete(img_in);
394 cpl_table_delete(trace_table);
395 hdrl_image_delete(img_hdrl);
396}
397
398/*----------------------------------------------------------------------------*/
421/*----------------------------------------------------------------------------*/
422static void test_cr2res_extract_sum_tilt(void)
423{
424 int width = 2000;
425 int height = 50;
426 double spec_in[width];
427 cpl_image * img_in = create_image_sinusoidal(width, height, spec_in);
428 img_in = apply_shear(img_in, width, height, 1);
429 hdrl_image * img_hdrl = hdrl_image_create(img_in, NULL);
430 cpl_table * trace_table = create_table_linear_increase(height, 1);
431 int order = 1;
432 int trace = 1;
433
434 cpl_vector * slit_func;
435 cpl_bivector * spec;
436 hdrl_image * model;
437
438 cpl_test_eq( 0, cr2res_extract_sum_tilt(img_hdrl, trace_table, order, trace, height, &slit_func, &spec, &model));
439
440 // check results
441 int delta_x = height / 2 + 1;
442 double ratio0 = cpl_bivector_get_x_data(spec)[delta_x] / spec_in[delta_x];
443 for(int i = delta_x; i < width - delta_x; i++)
444 {
445
446 double ratio;
447 //spectrum, with linear increase
448 ratio = cpl_bivector_get_x_data(spec)[i] / spec_in[i];
449 cpl_test_abs(ratio, ratio0, 1);
450
451 //relative error
452 ratio = cpl_bivector_get_y_data(spec)[i] / cpl_bivector_get_x_data(spec)[i];
453 cpl_test_abs(ratio, 0, 0.1);
454 }
455
456 cpl_test_abs(cpl_vector_get_sum(slit_func), 1, 2 * DBL_EPSILON);
457
458 cpl_image_save(img_in, "TEST_image.fits", CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
459 cpl_vector_save(cpl_bivector_get_x(spec), "TEST_spec.fits", CPL_TYPE_DOUBLE, NULL,
460 CPL_IO_CREATE);
461 cpl_vector_save(cpl_bivector_get_y(spec), "TEST_err.fits", CPL_TYPE_DOUBLE, NULL,
462 CPL_IO_CREATE);
463 cpl_vector_save(slit_func, "TEST_slitfunc.fits", CPL_TYPE_DOUBLE,
464 NULL, CPL_IO_CREATE);
465 cpl_image_save(hdrl_image_get_image(model), "TEST_model.fits", CPL_TYPE_FLOAT,
466 NULL, CPL_IO_CREATE);
467
468 // Free memory
469 cpl_vector_delete(slit_func);
470 cpl_bivector_delete(spec);
471 hdrl_image_delete(model);
472 cpl_image_delete(img_in);
473 cpl_table_delete(trace_table);
474 hdrl_image_delete(img_hdrl);
475}
476#ifdef CR2RES_UNUSED_TESTS
477static void test_cr2res_slitdec_vert_regression(void)
478{
479 cpl_image * img_in = create_test_image();
480 hdrl_image * img_hdrl = hdrl_image_create(img_in, NULL);
481 cpl_table * trace_table = create_test_table();
482 int order = 7;
483 int trace = 1;
484 int height = 70;
485 int swath = 50;
486 int oversample = 3;
487 double smooth_slit = 0.1;
488 int niter = 10;
489 double kappa = 10;
490
491 int width = cpl_image_get_size_x(img_in);
492
493 cpl_vector * slit_func;
494 cpl_bivector * spec;
495 hdrl_image * model;
496 int res;
497
498 // Load Expected results
499 static double data_slitfunc[143] = {0.000115859, 7.43396e-05, 7.10328e-05, 7.62753e-05, 7.10487e-05, 8.11558e-05, 7.85971e-05, 6.83344e-05, 7.17496e-05, 7.96937e-05, 7.35047e-05, 5.22185e-05, 7.33561e-05, 7.43463e-05, 0.000144974, 0.000102243, 0.000359142, 0.000521881, 0.00104286, 0.00146012, 0.00226715, 0.00301241, 0.00413671, 0.00509677, 0.00643321, 0.00773337, 0.00897916, 0.0104182, 0.0117634, 0.0131721, 0.0144836, 0.0158845, 0.0169486, 0.0181268, 0.0189894, 0.020072, 0.0205192, 0.0213352, 0.021635, 0.0220201, 0.0221268, 0.0223179, 0.0223631, 0.0223449, 0.0224997, 0.0223255, 0.0224773, 0.0224355, 0.0225178, 0.0224838, 0.0224948, 0.0226417, 0.0224643, 0.0228002, 0.0226002, 0.0228257, 0.0225603, 0.0226531, 0.0226004, 0.0224983, 0.0225823, 0.0224062, 0.0225994, 0.0223767, 0.0226528, 0.0224482, 0.0227148, 0.0224825, 0.0226146, 0.0225114, 0.022532, 0.022325, 0.022366, 0.0221547, 0.0222041, 0.0220273, 0.0221068, 0.0220118, 0.022042, 0.0220703, 0.0221329, 0.0221981, 0.0222083, 0.0223475, 0.0221351, 0.0224142, 0.0221839, 0.0224193, 0.0221855, 0.0223566, 0.0221801, 0.0223412, 0.022238, 0.0222933, 0.0222503, 0.0223179, 0.0223925, 0.0223932, 0.0224435, 0.0223841, 0.0225682, 0.0223857, 0.0224443, 0.0224466, 0.0223342, 0.0222627, 0.0218657, 0.0217104, 0.021, 0.0205833, 0.0196169, 0.0188126, 0.017692, 0.0164563, 0.0152199, 0.0138034, 0.012523, 0.0108846, 0.00956393, 0.00814578, 0.00676929, 0.00544948, 0.00429528, 0.00323442, 0.0024136, 0.00157264, 0.00111565, 0.000598061, 0.000371827, 0.000139823, 0.000121443, 5.84376e-05, 8.41633e-05, 7.4026e-05, 5.50628e-05, 7.25114e-05, 6.36848e-05, 6.18246e-05, 7.54592e-05, 7.05881e-05, 6.02867e-05, 6.36684e-05, 6.36684e-05 };
500 cpl_vector *cmp_slitfunc = cpl_vector_wrap(143, data_slitfunc);
501
502 static double data_spec[] = {52427.1, 56057, 61339.8, 65980.5, 68602.9, 68408.7, 67261.7, 65948, 64419.7, 63188.3, 61880.6, 60079.3, 58767.2, 56827.8, 55461.9, 54276.3, 53239.5, 52180.1, 51012.6, 49862.9, 49346.3, 49106.3, 49512, 50059.1, 50739.6, 51833, 52867.8, 56163, 58267.9, 59918.2, 61755.8, 63357.5, 64534.8, 66216.8, 67155.8, 68099.7, 69762.6, 71421.4, 72797.3, 74520.5, 75136.2, 75822.4, 75580.1, 74968.4, 73947.4, 72564.9, 71471.5, 70254.3, 69114.7, 67435.2, 66039.3, 64097.1, 62459.1, 61809.6, 60585.5, 59886.6, 56380, 54752.9, 53538.5, 52106.8, 51201.9, 50227.7, 50485.6, 50145.1, 50502.5, 51539.1, 52777.9, 54718.5, 56431.5, 58163.9, 59658.8, 60643.3, 61944.8, 63230.7, 64646.9, 66172.3, 67801.6, 68887.1, 70113.4, 71368.6, 73070.2, 74478.4, 77749.9, 77479.8, 76418.1, 74976.4, 73924.9, 73339.2, 72656.8, 71766, 70424.5, 69250, 68089.5, 67069, 65597.9, 64096.4, 62310.3, 60617.4, 59116.6, 57845.2, 56924, 56161.2, 55271.3, 54702.6, 54136.6, 54096.7, 54553.9, 55668.1, 57046.9, 57986, 59175.6, 58235.6, 59366.1, 61054.1, 62524.4, 64416.5, 66584, 68586.2, 71234.8, 73330.2, 74696.1, 75223.8, 75189.4, 75280.4, 75444.3, 75874.5, 75904, 75838.2, 74891, 74023.9, 72514.4, 70963.7, 69558.8, 67629.4, 66282, 64630.2, 62758.7, 63849.1, 62848.7, 61904.3, 60854.6, 59230, 57784.9, 56456.6, 55437.3, 55184.8, 56000.7, 57246.1, 58924.6, 60388.7, 61565.1, 62219.3, 62859.2, 63542.2, 64846.9, 66776.1, 68786.9, 70464.1, 72447.6, 73847.4, 75108.2, 76561.9, 77626.4, 78978.3, 82490.1, 83193.5, 81041.9, 81479.2, 81559.7, 80826.1, 79666.5, 77906, 76351.9, 75025.8, 73588.5, 72518.2, 71188.3, 69730.8, 68496.9, 66752.2, 64862.7, 63344.7, 61420, 60027.9, 59126.9, 58096, 57417.4, 57173, 57299.7, 58309.4, 59106.8, 60063.1, 61092.4, 60288.4, 61546.3, 63153.4, 65249.9, 67532.7, 70186.9, 72424.3, 74198.5, 75317.4, 75786.2, 75659.8, 76542, 77153.9, 78396.8, 79690.9, 80568.9, 80859.1, 80186.7, 79281.6, 78150.2, 76752.7, 75368, 73920.9, 71622.6, 70165, 68956.5, 67348.3 };
503 cpl_vector * cmp_spec = cpl_vector_wrap(width, data_spec);
504
505 static double data_err[] = {523.439, 499.701, 473.877, 445.496, 387.684, 342.322, 329.536, 333.608, 322.94, 304.494, 343.882, 361.009, 302.392, 307.149, 332.682, 323.992, 362.454, 340.802, 359.662, 340.305, 357.704, 383.636, 364.937, 362.076, 365.54, 352.365, 404.616, 386.916, 364.15, 340.36, 326.278, 354.856, 428.537, 436.106, 429.022, 449.069, 413.98, 416.991, 358.546, 288.909, 305.632, 328.581, 416.744, 466.815, 541.072, 511.904, 405.265, 361.332, 385.985, 403.975, 347.848, 490.804, 469.661, 414.215, 378.947, 372.721, 377.953, 395.166, 419.834, 417.746, 435.44, 433.026, 405.965, 355.437, 374.395, 397.416, 363.972, 388.46, 337.569, 314.348, 269.74, 251.195, 262.08, 312.284, 343.845, 339.1, 332.913, 298.026, 248.648, 281.622, 355.802, 352.142, 346.707, 307.605, 344.607, 458.379, 503.564, 575.246, 589.224, 566.922, 444.094, 374.106, 392.472, 429.108, 462.171, 452.507, 402.114, 336.127, 323.267, 274.167, 258.247, 239.089, 255.083, 341.934, 327.816, 356.862, 376.879, 403.153, 391.552, 369.626, 548.004, 534.1, 551.036, 483.023, 407.938, 367.108, 421.151, 424.767, 455.302, 493.192, 477.779, 471.41, 465.075, 474.877, 379.919, 337.061, 418.257, 508.22, 514.854, 504.106, 458.198, 459.895, 387.318, 290.826, 291.78, 269.617, 270.05, 255.638, 300.431, 329.948, 337.552, 365.143, 374.223, 405.786, 402.211, 377.809, 358.27, 345.365, 342.418, 301.744, 340.773, 347.53, 484.977, 568.101, 600.923, 584.527, 555.079, 468.593, 383.9, 329.843, 444.453, 591.095, 623.873, 590.857, 464.361, 399.636, 366.96, 415.829, 422.989, 425.515, 497.843, 520.913, 585.245, 559.485, 455.038, 428.321, 417.609, 423.205, 410.085, 380.559, 458.3, 498.045, 444.246, 343.187, 325.428, 343.338, 374.162, 317.982, 256.119, 262.269, 335.95, 402.572, 393.778, 395.558, 364.628, 270.383, 256.734, 313.647, 396.637, 381.443, 425.537, 384.808, 448.483, 484.637, 479.905, 489.266, 422.141, 335.441, 319.878, 303.223, 327.866, 369.895, 407.826, 433.113, 539.369, 578.454, 574.983, 440.167, 386.225, 382.11};
506 cpl_vector * cmp_err = cpl_vector_wrap(width, data_err);
507
508 res = cr2res_extract_slitdec_curved(img_hdrl, trace_table, NULL,
509 order, trace, height, swath, oversample, smooth_slit, 0,
510 niter, kappa, CR2RES_GAIN_CHIP1, &slit_func, &spec, &model);
511
512 // Tests compare with expected results
513 cpl_test_eq(res, 0);
514 cpl_test_vector_abs(slit_func, cmp_slitfunc, FLT_EPSILON);
515 cpl_test_vector_abs(cpl_bivector_get_x(spec), cmp_spec, 1e-1);
516 cpl_test_vector_abs(cpl_bivector_get_y(spec), cmp_err, 1e-3);
517 // cpl_test_image_abs(hdrl_image_get_image(model), cmp_model, 1e-4);
518
519 // // in case the files are needed again (e.g. when the input is changed)
520 // cpl_vector_save(cpl_bivector_get_x(spec), "TEST_spec.fits", CPL_TYPE_DOUBLE, NULL,
521 // CPL_IO_CREATE);
522 // cpl_vector_save(cpl_bivector_get_y(spec), "TEST_err.fits", CPL_TYPE_DOUBLE, NULL,
523 // CPL_IO_CREATE);
524 // cpl_vector_save(slit_func, "TEST_slitfunc.fits", CPL_TYPE_DOUBLE,
525 // NULL, CPL_IO_CREATE);
526 // cpl_image_save(hdrl_image_get_image(model), "TEST_model.fits", CPL_TYPE_FLOAT,
527 // NULL, CPL_IO_CREATE);
528
529 // Free memory
530 cpl_vector_unwrap(cmp_slitfunc);
531 cpl_vector_unwrap(cmp_spec);
532 cpl_vector_unwrap(cmp_err);
533 // cpl_image_delete(cmp_model);
534
535 cpl_image_delete(img_in);
536 cpl_table_delete(trace_table);
537 cpl_vector_delete(slit_func);
538 cpl_bivector_delete(spec);
539 hdrl_image_delete(model);
540 hdrl_image_delete(img_hdrl);
541}
542
543static void test_cr2res_slitdec_vert_edge_cases(void)
544{
545 int width = 2000;
546 int height = 50;
547 double spec_in[width];
548 cpl_image * img_in = create_image_linear_increase(width, height, spec_in);
549 hdrl_image * img_hdrl = hdrl_image_create(img_in, NULL);
550 cpl_table * trace_table = create_table_linear_increase(height, 0);
551 int order = 1;
552 int trace = 1;
553 int swath = 15;
554 int oversample = 3;
555 double smooth_slit = 0.1;
556 int niter = 10;
557 double kappa = 10;
558
559 cpl_vector * slit_func;
560 cpl_bivector * spec;
561 hdrl_image * model;
562
563 // Test Edge cases
564 cpl_test_eq(-1, cr2res_extract_slitdec_curved(NULL, trace_table, NULL,
565 order, trace, height, swath,
566 oversample, smooth_slit, 0, niter, kappa,
567 CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
568 cpl_test_eq(-1, cr2res_extract_slitdec_curved(img_hdrl, NULL, NULL,
569 order, trace, height, swath,
570 oversample, smooth_slit, 0, niter, kappa,
571 CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
572 cpl_test_eq(-1, cr2res_extract_slitdec_curved(img_hdrl, trace_table,
573 NULL, -10, trace, height, swath,
574 oversample, smooth_slit, 0, niter, kappa,
575 CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
576 cpl_test_eq(-1, cr2res_extract_slitdec_curved(img_hdrl, trace_table,
577 NULL, order, -3, height, swath,
578 oversample, smooth_slit, 0, niter, kappa,
579 CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
580
581 cpl_test_eq( 0, cr2res_extract_slitdec_curved(img_hdrl, trace_table,
582 NULL, order, trace, 0, swath,
583 oversample, smooth_slit, 0, niter, kappa,
584 CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
585 cpl_vector_delete(slit_func);
586 cpl_bivector_delete(spec);
587 hdrl_image_delete(model);
588
589 cpl_test_eq( 0, cr2res_extract_slitdec_curved(img_hdrl, trace_table,
590 NULL, order, trace, 10000, swath,
591 oversample, smooth_slit, 0, niter, kappa,
592 CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
593 cpl_vector_delete(slit_func);
594 cpl_bivector_delete(spec);
595 hdrl_image_delete(model);
596
597 cpl_test_eq(-1, cr2res_extract_slitdec_curved(img_hdrl, trace_table,
598 NULL, order, trace, height, 0,
599 oversample, smooth_slit, 0, niter, kappa,
600 CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
601 cpl_test_eq(-1, cr2res_extract_slitdec_curved(img_hdrl, trace_table,
602 NULL, order, trace, height, -1,
603 oversample, smooth_slit, 0, niter, kappa,
604 CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
605
606 cpl_test_eq( 0, cr2res_extract_slitdec_curved(img_hdrl, trace_table,
607 NULL, order, trace, height, 10000,
608 oversample, smooth_slit, 0, niter, kappa,
609 CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
610 cpl_vector_delete(slit_func);
611 cpl_bivector_delete(spec);
612 hdrl_image_delete(model);
613
614 cpl_test_eq( 0, cr2res_extract_slitdec_curved(img_hdrl, trace_table,
615 NULL, order, trace, height, swath,
616 0, smooth_slit, 0, niter, kappa, CR2RES_GAIN_CHIP1,
617 &slit_func, &spec, &model));
618 cpl_vector_delete(slit_func);
619 cpl_bivector_delete(spec);
620 hdrl_image_delete(model);
621
622 cpl_test_eq( 0, cr2res_extract_slitdec_curved(img_hdrl, trace_table,
623 NULL, order, trace, height, swath,
624 -1, smooth_slit, 0, niter, kappa, CR2RES_GAIN_CHIP1,
625 &slit_func, &spec, &model));
626 cpl_vector_delete(slit_func);
627 cpl_bivector_delete(spec);
628 hdrl_image_delete(model);
629
630 // Free memory
631 cpl_image_delete(img_in);
632 cpl_table_delete(trace_table);
633 hdrl_image_delete(img_hdrl);
634}
635
636
637static void test_cr2res_slitdec_curved(void)
638{
639 int width = 1000;
640 int height = 20;
641 int order = 1;
642 int trace = 1;
643 int swath = 400;
644 int oversample = 3;
645 double smooth_slit = 0.1;
646 int niter = 10;
647 double kappa = 10;
648 double spec_in[width];
649 double const_shear = 1;
650
651 cpl_vector * shear = cpl_vector_new(width);
652 for (int k = 0; k < width; k++) cpl_vector_set(shear, k, const_shear);
653
654 cpl_image * img_in = create_image_sinusoidal(width, height, spec_in);
655 img_in = apply_shear(img_in, width, height, const_shear);
656 //cpl_image * img_in = create_image_linear_increase(width, height, cpl_vector_get_data(shear), spec_in);
657 hdrl_image * img_hdrl = hdrl_image_create(img_in, NULL);
658 cpl_table * trace_table = create_table_linear_increase(height, const_shear);
659
660 cpl_vector * slit_func;
661 cpl_bivector * spec;
662 hdrl_image * model;
663 cpl_vector * cmp = cpl_vector_new(width);
664 cpl_vector * spec_in_vec = cpl_vector_wrap(width, spec_in);
665
666 cpl_test_eq(0,
667 cr2res_extract_slitdec_curved(img_hdrl, trace_table, NULL, order,
668 trace, height, swath, oversample, smooth_slit, 0.0,
669 niter, kappa, CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
670
671 // check results
672 cpl_vector_copy(cmp, cpl_bivector_get_x(spec));
673 cpl_vector_divide(cmp, spec_in_vec);
674 double ratio0 = cpl_vector_get_median(cmp);
675 double ratio = 0;
676 for(int i = 20; i < width-20; i++) {
677 // shape of spectrum
678 ratio = cpl_bivector_get_x_data(spec)[i] / spec_in[i];
679 cpl_test_abs(ratio, ratio0, 2);
680
681 //relative error
682 ratio = cpl_bivector_get_y_data(spec)[i] / cpl_bivector_get_x_data(spec)[i];
683 cpl_test_lt(ratio, 0.2);
684 }
685
686 ratio = cpl_vector_get_sum(slit_func) / oversample;
687 cpl_test_abs(ratio, 1, FLT_EPSILON);
688
689 cpl_vector_save(cpl_bivector_get_x(spec), "TEST_spec.fits", CPL_TYPE_DOUBLE, NULL,
690 CPL_IO_CREATE);
691 cpl_vector_save(cpl_bivector_get_y(spec), "TEST_err.fits", CPL_TYPE_DOUBLE, NULL,
692 CPL_IO_CREATE);
693 cpl_vector_save(slit_func, "TEST_slitfunc.fits", CPL_TYPE_DOUBLE,
694 NULL, CPL_IO_CREATE);
695 cpl_image_save(hdrl_image_get_image(model), "TEST_model.fits", CPL_TYPE_FLOAT,
696 NULL, CPL_IO_CREATE);
697
698 // Free memory
699 cpl_vector_delete(slit_func);
700 cpl_vector_delete(cmp);
701 cpl_vector_unwrap(spec_in_vec);
702 cpl_bivector_delete(spec);
703 cpl_vector_delete(shear);
704 hdrl_image_delete(model);
705 cpl_image_delete(img_in);
706 cpl_table_delete(trace_table);
707 hdrl_image_delete(img_hdrl);
708}
709#endif
710
711static void test_cr2res_slitdec_errors(void){
712 int width = 1000;
713 int height = 21;
714 int order = 1;
715 int trace = 1;
716 int swath = 200;
717 int oversample = 3;
718 int result;
719 double smooth_slit = 0.1;
720 int niter = 10;
721 double kappa = 10;
722 double spec_in[width];
723
724 cpl_vector * slit_func;
725 cpl_bivector * spec;
726 hdrl_image * model;
727
728 cpl_image * img_in = create_image_linear_increase(width, height * 2, spec_in);
729 cpl_image * err_in = cpl_image_new(width, height * 2, CPL_TYPE_DOUBLE);
730 cpl_image_add_scalar(err_in, 1);
731 hdrl_image * img_hdrl = hdrl_image_create(img_in, err_in);
732 cpl_table * trace_table = create_table_linear_increase(height * 2, 0);
733
734 result = cr2res_extract_slitdec_curved(img_hdrl, trace_table, NULL,
735 order, trace, height, swath, oversample, smooth_slit, 0,
736 niter, kappa, CR2RES_GAIN_CHIP1, &slit_func, &spec, &model);
737
738 cpl_test_eq(0, result);
739 if (result == 0){
740 //error = cpl_bivector_get_y(spec);
741 // Free memory
742 cpl_vector_delete(slit_func);
743 cpl_bivector_delete(spec);
744 hdrl_image_delete(model);
745 }
746
747 cpl_table_delete(trace_table);
748 cpl_image_delete(img_in);
749 cpl_image_delete(err_in);
750 hdrl_image_delete(img_hdrl);
751}
752#ifdef CR2RES_UNUSED_TESTS
753static void test_cr2res_slitdec_input_slitfunc(void)
754{
755 int width = 1000;
756 int height = 20;
757 int order = 1;
758 int trace = 1;
759 int swath = 400;
760 int oversample = 3;
761 double smooth_slit = 0.1;
762 int niter = 10;
763 double kappa = 10;
764 double spec_in[width];
765 double const_shear = 1;
766
767 cpl_vector * shear = cpl_vector_new(width);
768 for (int k = 0; k < width; k++) cpl_vector_set(shear, k, const_shear);
769
770 cpl_image * img_in = create_image_sinusoidal(width, height, spec_in);
771 img_in = apply_shear(img_in, width, height, const_shear);
772 //cpl_image * img_in = create_image_linear_increase(width, height, cpl_vector_get_data(shear), spec_in);
773 hdrl_image * img_hdrl = hdrl_image_create(img_in, NULL);
774 cpl_table * trace_table = create_table_linear_increase(height, const_shear);
775
776 cpl_vector * slit_func = NULL;
777 cpl_vector * slit_func_in = NULL;
778 cpl_bivector * spec = NULL;
779 hdrl_image * model = NULL;
780
781 // Test with correct size
782 cpl_size ny_os = oversample*(height+1) + 1;
783 slit_func_in = cpl_vector_new(ny_os);
784 for (cpl_size i = 0; i < ny_os; i++){
785 // Gaussian curve
786 cpl_vector_set(slit_func_in, i,
787 exp(-0.5 * (i-ny_os/2.) * (i-ny_os/2.) / ((ny_os/4) * (ny_os/4)))
788 );
789 }
790 // Normalize
791 cpl_vector_divide_scalar(slit_func_in, cpl_vector_get_sum(slit_func_in));
792 cpl_vector_multiply_scalar(slit_func_in, oversample);
793
794 cpl_test_eq(0,
795 cr2res_extract_slitdec_curved(img_hdrl, trace_table, slit_func_in,
796 order, trace, height, swath, oversample, smooth_slit, 0.0,
797 niter, kappa, CR2RES_GAIN_CHIP1, &slit_func, &spec,
798 &model));
799
800 // Check
801 cpl_test_nonnull(spec);
802 cpl_test_nonnull(slit_func);
803 cpl_test_nonnull(model);
804 // cpl_test_vector_abs(slit_func_in, slit_func, DBL_EPSILON);
805
806 cpl_vector_delete(slit_func_in);
807 cpl_vector_delete(slit_func);
808 cpl_bivector_delete(spec);
809 hdrl_image_delete(model);
810
811
812 // Test with wrong size
813 slit_func_in = cpl_vector_new(ny_os + 1);
814 cpl_test_eq(0,
815 cr2res_extract_slitdec_curved(img_hdrl, trace_table, slit_func_in,
816 order, trace, height, swath, oversample, smooth_slit, 0,
817 niter, kappa, CR2RES_GAIN_CHIP1, &slit_func, &spec, &model));
818
819 cpl_test_nonnull(spec);
820 cpl_test_nonnull(slit_func);
821 cpl_test_nonnull(model);
822 cpl_test_eq(ny_os, cpl_vector_get_size(slit_func));
823
824 // Free memory
825 cpl_vector_delete(slit_func_in);
826 cpl_vector_delete(slit_func);
827 cpl_bivector_delete(spec);
828 hdrl_image_delete(model);
829
830 cpl_vector_delete(shear);
831 cpl_image_delete(img_in);
832 cpl_table_delete(trace_table);
833 hdrl_image_delete(img_hdrl);
834}
835#endif
836
837/*----------------------------------------------------------------------------*/
841/*----------------------------------------------------------------------------*/
842int main(void)
843{
844 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_DEBUG);
845
846 /* TMP */
847 test_cr2res_extract_sum();
848 test_cr2res_extract_median();
849 test_cr2res_extract_sum_tilt();
850 //test_cr2res_slitdec_curved();
851
852 test_cr2res_slitdec_errors();
853 // test_cr2res_slitdec_input_slitfunc();
854
855 return cpl_test_end(0);
856}
int cr2res_extract_median(const hdrl_image *hdrl_in, const cpl_table *trace_tab, int order, int trace_id, int height, cpl_vector **slit_func, cpl_bivector **spec, hdrl_image **model)
Simple extraction function with the median.
int cr2res_extract_slitdec_curved(const hdrl_image *img_hdrl, const cpl_table *trace_tab, const cpl_vector *slit_func_vec_in, int order, int trace_id, int height, int swath, int oversample, double smooth_slit, double smooth_spec, int niter, double kappa, double error_factor, cpl_vector **slit_func, cpl_bivector **spec, hdrl_image **model)
Extract optimally (slit-decomposition) with polynomial slit.
int cr2res_extract_sum_tilt(const hdrl_image *hdrl_in, const cpl_table *trace_tab, int order, int trace_id, int height, cpl_vector **slit_func, cpl_bivector **spec, hdrl_image **model)
Simple extraction function with curvature correction.
int cr2res_extract_sum_vert(const hdrl_image *hdrl_in, const cpl_table *trace_tab, int order, int trace_id, int height, cpl_vector **slit_func, cpl_bivector **spec, hdrl_image **model)
Simple extraction function.
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
Definition: hdrl_image.c:295
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:105
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379