31#include <cr2res_dfs.h>
32#include <cr2res_pfits.h>
33#include <cr2res_trace.h>
34#include <cr2res_trace.c>
44static void test_cr2res_trace(
void);
45static void test_cr2res_trace_clean(
void);
46static void test_cr2res_trace_gen_image(
void);
47static void test_cr2res_trace_get_order_idx_values(
void);
48static void test_cr2res_trace_get_ycen(
void);
49static void test_cr2res_trace_get_height(
void);
50static void test_cr2res_trace_compute_middle(
void);
51static void test_cr2res_trace_compute_height(
void);
52static void test_cr2res_trace_get_trace_ypos(
void);
53static void test_cr2res_trace_signal_detect(
void);
54static void test_cr2res_trace_fit_traces(
void);
55static void test_cr2res_trace_fit_trace(
void);
57static void test_cr2res_trace_convert_labels_to_cluster(
void);
58static void test_cr2res_trace_clean_blobs(
void);
59static void test_cr2res_trace_extract_edges(
void);
60static void test_cr2res_trace_new_slit_fraction(
void);
61static void test_cr2res_trace_add_extra_columns(
void);
62static void test_cr2res_get_trace_table_index(
void);
63static void test_cr2res_get_trace_wave_poly(
void);
73#define WLEN_BEGIN(buffer, i) (sprintf(buffer, CR2RES_HEADER_WLEN_BEGIN, i), buffer)
74#define WLEN_END(buffer, i) (sprintf(buffer, CR2RES_HEADER_WLEN_END, i), buffer)
75#define WLEN_CENY(buffer, i) (sprintf(buffer, CR2RES_HEADER_WLEN_CENY, i), buffer)
85static cpl_table *create_test_table()
88 cpl_array *array, *slit_fraction, *wave, *wave_err, *slit_a, *slit_b,
90 int poly_order, norders;
91 cpl_propertylist *hdr = cpl_propertylist_new();
92 cpl_propertylist *main_header = cpl_propertylist_new();
100 traces = cpl_table_new(norders);
101 cpl_table_new_column_array(traces, CR2RES_COL_ALL, CPL_TYPE_DOUBLE,
103 cpl_table_new_column_array(traces, CR2RES_COL_UPPER, CPL_TYPE_DOUBLE,
105 cpl_table_new_column_array(traces, CR2RES_COL_LOWER, CPL_TYPE_DOUBLE,
107 cpl_table_new_column(traces, CR2RES_COL_ORDER, CPL_TYPE_INT);
108 cpl_table_new_column(traces, CR2RES_COL_TRACENB, CPL_TYPE_INT);
110 cpl_table_new_column_array(traces, CR2RES_COL_WAVELENGTH, CPL_TYPE_DOUBLE,
112 cpl_table_new_column_array(traces, CR2RES_COL_WAVELENGTH_ERROR,
114 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_CURV_A, CPL_TYPE_DOUBLE,
116 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_CURV_B, CPL_TYPE_DOUBLE,
118 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_CURV_C, CPL_TYPE_DOUBLE,
120 cpl_table_new_column_array(traces, CR2RES_COL_SLIT_FRACTION,
136 double all_1[] = {54.3148, 226.289, 437.881, 660.954, 897.266,
137 1148.31, 1415.88, 1701.85, 1982.59};
138 double all_2[] = {0.00738623, 0.0169145, 0.0172448, 0.0178211,
139 0.0185319, 0.019388, 0.0202877, 0.021292, 0.0111388};
140 double upper_1[] = {110.379, 311.885, 524.126, 747.931, 985.06,
141 1237.01, 1505.34, 1792.03, 2047.88};
142 double upper_2[] = {0.0159501, 0.0167957, 0.0171958, 0.0179547,
143 0.0186544, 0.0193813, 0.0202763, 0.0213662, 8.66878e-05};
144 double lower_1[] = {1.63328, 139.106, 350.398, 572.986, 808.823,
145 1059.39, 1326.43, 1611.65, 1917.3};
146 double lower_2[] = {-8.95809e-05, 0.017396, 0.0170009, 0.0177137,
147 0.0185517, 0.0194215, 0.0202534, 0.0212178, 0.0221835};
148 array = cpl_array_new(poly_order, CPL_TYPE_DOUBLE);
149 slit_fraction = cpl_array_new(3, CPL_TYPE_DOUBLE);
150 cpl_array_set_double(slit_fraction, 0, 0);
151 cpl_array_set_double(slit_fraction, 1, 0.5);
152 cpl_array_set_double(slit_fraction, 2, 1);
153 wave = cpl_array_new(2, CPL_TYPE_DOUBLE);
154 cpl_array_set_double(wave, 0, 9.45e2);
155 cpl_array_set_double(wave, 1, 3.13e-3);
156 wave_err = cpl_array_new(2, CPL_TYPE_DOUBLE);
157 cpl_array_set_double(wave_err, 0, 5e-2);
158 cpl_array_set_double(wave_err, 1, 5e-2);
160 slit_a = cpl_array_new(3, CPL_TYPE_DOUBLE);
161 cpl_array_set(slit_a, 0, 0);
162 cpl_array_set(slit_a, 1, 1);
163 cpl_array_set(slit_a, 2, 0);
164 slit_b = cpl_array_new(3, CPL_TYPE_DOUBLE);
165 cpl_array_set(slit_b, 0, 0);
166 cpl_array_set(slit_b, 1, 0);
167 cpl_array_set(slit_b, 2, 0);
168 slit_c = cpl_array_new(3, CPL_TYPE_DOUBLE);
169 cpl_array_set(slit_c, 0, 0);
170 cpl_array_set(slit_c, 1, 0);
171 cpl_array_set(slit_c, 2, 0);
173 for (
int i = 0; i < norders; i++)
175 cpl_array_set(array, 0, all_1[i]);
176 cpl_array_set(array, 1, all_2[i]);
177 cpl_table_set_array(traces, CR2RES_COL_ALL, i, array);
178 cpl_array_set(array, 0, upper_1[i]);
179 cpl_array_set(array, 1, upper_2[i]);
180 cpl_table_set_array(traces, CR2RES_COL_UPPER, i, array);
181 cpl_array_set(array, 0, lower_1[i]);
182 cpl_array_set(array, 1, lower_2[i]);
183 cpl_table_set_array(traces, CR2RES_COL_LOWER, i, array);
184 cpl_table_set(traces, CR2RES_COL_ORDER, i,
186 cpl_table_set(traces, CR2RES_COL_TRACENB, i, 1);
188 cpl_table_set_array(traces, CR2RES_COL_SLIT_FRACTION, i, slit_fraction);
189 cpl_table_set_array(traces, CR2RES_COL_WAVELENGTH, i, wave);
190 cpl_table_set_array(traces, CR2RES_COL_WAVELENGTH_ERROR, i, wave_err);
191 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_A, i, slit_a);
192 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_B, i, slit_b);
193 cpl_table_set_array(traces, CR2RES_COL_SLIT_CURV_C, i, slit_c);
197 cpl_propertylist_append_string(hdr, CR2RES_HEADER_EXTNAME, extname);
199 double ceny[] = {1994.0945859223, 1723.67027599362, 1436.61298619847,
200 1168.0222016174, 915.8934665223831, 678.542785839296,
201 454.468576982434, 242.388497032926, 63.5899165277783};
202 double begin[] = {1756.78720770673, 1703.55123171562, 1653.44678372399,
203 1606.20544704616, 1561.58862907265, 1519.38353098961,
204 1479.3997538583, 1441.46642683629, -1};
205 double end[] = {1768.81709603003, 1715.21657796851, 1664.76903155768,
206 1617.2042020846, 1572.2818631378, 1529.78775872867,
207 1489.53018613055, 1451.3371044349, -1};
211 for (
int i = 0; i < 9; i++)
213 cpl_propertylist_append_double(hdr, WLEN_CENY(buffer, i), ceny[i]);
214 cpl_propertylist_append_double(hdr, WLEN_BEGIN(buffer, i), begin[i]);
215 cpl_propertylist_append_double(hdr, WLEN_END(buffer, i), end[i]);
219 cpl_propertylist_append_int(main_header, CR2RES_HEADER_DECKER_POS, CR2RES_DECKER_2_4);
221 cpl_table_save(traces, main_header, hdr,
"TEST_table.fits", CPL_IO_CREATE);
223 cpl_array_delete(array);
224 cpl_array_delete(slit_fraction);
225 cpl_array_delete(wave);
226 cpl_array_delete(wave_err);
227 cpl_array_delete(slit_a);
228 cpl_array_delete(slit_b);
229 cpl_array_delete(slit_c);
231 cpl_propertylist_delete(hdr);
232 cpl_propertylist_delete(main_header);
244static cpl_image *create_test_image(
void)
247 cpl_image *trace_ima;
248 traces = create_test_table();
250 cpl_image_add_scalar(trace_ima, 1.);
251 cpl_image_multiply_scalar(trace_ima, 10.);
252 cpl_table_delete(traces);
253 cpl_image_save(trace_ima,
"TEST_trace.fits", CPL_TYPE_INT, NULL, CPL_IO_CREATE);
256#ifdef CR2RES_UNUSED_TESTS
257static cpl_table *create_cluster_table(
void)
274 int xs[] = {4, 5, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 1, 2};
275 int ys[] = {4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 5};
276 int clusters[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
278 cpl_table *cluster = cpl_table_new(17);
279 cpl_table_wrap_int(cluster, xs, CR2RES_COL_XS);
280 cpl_table_wrap_int(cluster, ys, CR2RES_COL_YS);
281 cpl_table_wrap_int(cluster, clusters, CR2RES_COL_CLUSTERS);
299static void test_cr2res_trace(
void)
301 cpl_image *int_ima = create_test_image();
302 cpl_image *trace_ima = cpl_image_cast(int_ima, CPL_TYPE_DOUBLE);
303 cpl_image_delete(int_ima);
307 double threshold = 5;
309 cpl_test_null(
cr2res_trace(NULL, 1.0, 1.0, threshold, 1, 2, 10));
310 cpl_test_null(
cr2res_trace(trace_ima, -1.0, 1.0, threshold, 1, 2, 10));
311 cpl_test_null(
cr2res_trace(trace_ima, 1.0, 1.0, threshold, -1, 2, 10));
312 cpl_test_null(
cr2res_trace(trace_ima, 1.0, 1.0, threshold, 1, 2, -10));
314 cpl_test(out =
cr2res_trace(trace_ima, 1.0, 5.0, threshold, 1, 2, 10));
316 cpl_table_get_array(out, CR2RES_COL_ALL, 0);
318 cpl_table_save(out, NULL, NULL,
"TEST_table2.fits", CPL_IO_CREATE);
319 cpl_table_delete(out);
320 cpl_image_delete(trace_ima);
329static void test_cr2res_trace_clean(
void)
334 cpl_binary data[] = {1, 1, 0, 0, 0, 0,
340 cpl_mask *mask = cpl_mask_wrap(6, 6, data);
345 cpl_binary data_cmp[] = {1, 1, 0, 0, 0, 0,
359 cpl_mask *cmp = cpl_mask_wrap(6, 6, data_cmp);
363 cpl_mask_save(res,
"TEST_res.fits", NULL, CPL_IO_CREATE);
364 cpl_test_eq_mask(cmp, res);
365 cpl_mask_unwrap(mask);
366 cpl_mask_unwrap(cmp);
367 cpl_mask_delete(res);
373static void test_cr2res_trace_gen_image(
void)
381 int data[10 * 10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
382 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
383 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
384 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
385 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
386 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
387 -1, -1, -1, -1, -1, -1, -1, 1, 1, 1,
388 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
389 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
390 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
392 cpl_image *cmp = cpl_image_wrap(10, 10, CPL_TYPE_INT, data);
393 cpl_table *trace = create_test_table();
404 extract = cpl_image_extract(res, 32, 105, 41, 114);
405 cpl_test_image_abs(extract, cmp, DBL_EPSILON);
408 cpl_image_delete(res);
409 cpl_image_delete(extract);
410 cpl_image_unwrap(cmp);
411 cpl_table_delete(trace);
419static void test_cr2res_trace_get_order_idx_values(
void)
422 cpl_table *trace = create_test_table();
430 cpl_test_eq(nb_orders, 9);
431 for (
int i = 0; i < 9; i++)
433 cpl_test_eq(res[i], i + 1);
436 cpl_table_delete(trace);
445static void test_cr2res_trace_get_ycen(
void)
448 cpl_table *trace = create_test_table();
449 cpl_size order_nb = 3;
450 cpl_size trace_nb = 1;
451 int size = CR2RES_DETECTOR_SIZE;
462 for (
int i = 0; i < size; i++)
465 data[i] = 437.881 + (i + 1) * 0.0172448;
467 cmp = cpl_vector_wrap(size, data);
471 cpl_test_vector_abs(cmp, res, size * DBL_EPSILON);
474 cpl_vector_delete(res);
475 cpl_vector_unwrap(cmp);
477 cpl_table_delete(trace);
485static void test_cr2res_trace_get_height(
void)
488 cpl_table *trace = create_test_table();
489 cpl_size order_nb = 3;
490 cpl_size trace_nb = 1;
500 cpl_test_eq(res, (
int) 174.1271552);
503 cpl_table_delete(trace);
511static void test_cr2res_trace_compute_middle(
void)
514 cpl_polynomial *trace1 = cpl_polynomial_new(1);
515 cpl_polynomial *trace2 = cpl_polynomial_new(1);
518 cpl_polynomial_set_coeff(trace1, &power, 10.);
519 cpl_polynomial_set_coeff(trace2, &power, 20.);
522 cpl_polynomial_set_coeff(trace1, &power, 1.);
523 cpl_polynomial_set_coeff(trace2, &power, 3.);
525 int vector_size = 10;
527 double data[] = {17., 19., 21., 23., 25., 27., 29., 31., 33., 35.};
528 cpl_vector *cmp = cpl_vector_wrap(10, data);
537 cpl_test_vector_abs(res, cmp, DBL_EPSILON);
540 cpl_vector_unwrap(cmp);
541 cpl_vector_delete(res);
542 cpl_polynomial_delete(trace1);
543 cpl_polynomial_delete(trace2);
551static void test_cr2res_trace_compute_height(
void)
554 cpl_polynomial *trace1 = cpl_polynomial_new(1);
555 cpl_polynomial *trace2 = cpl_polynomial_new(1);
558 cpl_polynomial_set_coeff(trace1, &power, 10.);
559 cpl_polynomial_set_coeff(trace2, &power, 20.);
562 cpl_polynomial_set_coeff(trace1, &power, 1.);
563 cpl_polynomial_set_coeff(trace2, &power, 3.);
565 int vector_size = 10;
576 cpl_test_eq(res, cmp);
579 cpl_polynomial_delete(trace1);
580 cpl_polynomial_delete(trace2);
588static void test_cr2res_trace_get_trace_ypos(
void)
591 cpl_table *traces = create_test_table();
603 cpl_test_abs(res, 243.609448, DBL_EPSILON);
605 cpl_table_delete(traces);
617static void test_cr2res_trace_add_extra_columns(
void)
620 cpl_table *traces = create_test_table();
622 cpl_table_erase_column(traces, CR2RES_COL_ORDER);
623 cpl_table_erase_column(traces, CR2RES_COL_TRACENB);
624 cpl_table_erase_column(traces, CR2RES_COL_WAVELENGTH);
625 cpl_table_erase_column(traces, CR2RES_COL_WAVELENGTH_ERROR);
626 cpl_table_erase_column(traces, CR2RES_COL_SLIT_FRACTION);
627 cpl_table_erase_column(traces, CR2RES_COL_SLIT_CURV_A);
628 cpl_table_erase_column(traces, CR2RES_COL_SLIT_CURV_B);
629 cpl_table_erase_column(traces, CR2RES_COL_SLIT_CURV_C);
631 cpl_table *tmp = cpl_table_duplicate(traces);
632 char *file_for_wl =
"TEST_table.fits";
634 double cmp1[] = {-1, 1441.46160481499, 1479.3948049417, 1519.37844831851, 1561.58340521624, 1606.20007393671, 1653.44125258191, 1703.54553296318, 1756.78133086827};
635 double cmp2[] = {0, 0.00482202129878357, 0.00494891659611621, 0.00508267109871028, 0.00522385640701021, 0.00537310944721049, 0.00553114207801171, 0.00569875244401075, 0.00587683845788956};
641 cpl_table_delete(tmp);
642 tmp = cpl_table_duplicate(traces);
645 cpl_table_delete(tmp);
646 tmp = cpl_table_duplicate(traces);
649 cpl_table_delete(tmp);
650 tmp = cpl_table_duplicate(traces);
654 cpl_table_save(tmp, NULL, NULL,
"TEST_new_table.fits", CPL_IO_CREATE);
657 cpl_test(cpl_table_has_column(tmp, CR2RES_COL_ORDER));
658 cpl_test(cpl_table_has_column(tmp, CR2RES_COL_TRACENB));
659 cpl_test(cpl_table_has_column(tmp, CR2RES_COL_WAVELENGTH));
660 cpl_test(cpl_table_has_column(tmp, CR2RES_COL_WAVELENGTH_ERROR));
661 cpl_test(cpl_table_has_column(tmp, CR2RES_COL_SLIT_FRACTION));
662 cpl_test(cpl_table_has_column(tmp, CR2RES_COL_SLIT_CURV_A));
663 cpl_test(cpl_table_has_column(tmp, CR2RES_COL_SLIT_CURV_B));
664 cpl_test(cpl_table_has_column(tmp, CR2RES_COL_SLIT_CURV_C));
667 for (
int i = 0; i < 9; i++)
670 wl = cpl_table_get_array(tmp, CR2RES_COL_WAVELENGTH, i);
671 cpl_test_abs(cpl_array_get(wl, 0, 0), cmp1[i], FLT_EPSILON);
672 cpl_test_abs(cpl_array_get(wl, 1, 0), cmp2[i], FLT_EPSILON);
679 cpl_table_delete(traces);
680 cpl_table_delete(tmp);
688static void test_cr2res_trace_new_slit_fraction(
void)
691 cpl_table *trace_table = create_test_table();
692 int norder = cpl_table_get_nrow(trace_table);
693 cpl_array * new_slit_fraction;
696 const cpl_array *carray;
702 new_slit_fraction = cpl_array_new(1, CPL_TYPE_DOUBLE);
705 cpl_array_delete(new_slit_fraction);
709 new_slit_fraction = cpl_array_new(3, CPL_TYPE_DOUBLE);
710 cpl_array_set_double(new_slit_fraction, 0, 0);
711 cpl_array_set_double(new_slit_fraction, 1, 0.5);
712 cpl_array_set_double(new_slit_fraction, 2, 1);
715 cpl_test_eq(cpl_table_get_nrow(res), norder);
716 for(cpl_size i = 0; i < norder; i++)
718 cpl_test_array_abs(cpl_table_get_array(res, CR2RES_COL_SLIT_FRACTION, i),
719 cpl_table_get_array(trace_table, CR2RES_COL_SLIT_FRACTION, i), FLT_EPSILON);
721 cpl_test_array_abs(cpl_table_get_array(res, CR2RES_COL_UPPER, i),
722 cpl_table_get_array(trace_table, CR2RES_COL_UPPER, i), FLT_EPSILON);
724 cpl_test_array_abs(cpl_table_get_array(res, CR2RES_COL_ALL, i),
725 cpl_table_get_array(trace_table, CR2RES_COL_ALL, i), FLT_EPSILON);
727 cpl_test_array_abs(cpl_table_get_array(res, CR2RES_COL_LOWER, i),
728 cpl_table_get_array(trace_table, CR2RES_COL_LOWER, i), FLT_EPSILON);
730 cpl_test_array_abs(cpl_table_get_array(res, CR2RES_COL_WAVELENGTH, i),
731 cpl_table_get_array(trace_table, CR2RES_COL_WAVELENGTH, i), FLT_EPSILON);
733 cpl_test_array_abs(cpl_table_get_array(res, CR2RES_COL_SLIT_CURV_A, i),
734 cpl_table_get_array(trace_table, CR2RES_COL_SLIT_CURV_A, i), FLT_EPSILON);
736 cpl_test_array_abs(cpl_table_get_array(res, CR2RES_COL_SLIT_CURV_B, i),
737 cpl_table_get_array(trace_table, CR2RES_COL_SLIT_CURV_B, i), FLT_EPSILON);
740 cpl_test_array_abs(cpl_table_get_array(res, CR2RES_COL_SLIT_CURV_C, i),
741 cpl_table_get_array(trace_table, CR2RES_COL_SLIT_CURV_C, i), FLT_EPSILON);
743 cpl_array_delete(new_slit_fraction);
747 new_slit_fraction = cpl_array_new(3, CPL_TYPE_DOUBLE);
748 cpl_array_set_double(new_slit_fraction, 0, 0.2);
749 cpl_array_set_double(new_slit_fraction, 1, 0.4);
750 cpl_array_set_double(new_slit_fraction, 2, 0.6);
753 array = cpl_array_new(2, CPL_TYPE_DOUBLE);
754 cpl_array_set_double(array, 0, 3);
755 cpl_table_set_array(trace_table, CR2RES_COL_UPPER, 0, array);
756 cpl_array_set_double(array, 0, 2);
757 cpl_table_set_array(trace_table, CR2RES_COL_ALL, 0, array);
758 cpl_array_set_double(array, 0, 1);
759 cpl_table_set_array(trace_table, CR2RES_COL_LOWER, 0, array);
760 cpl_array_delete(array);
762 cpl_table_delete(res);
765 carray = cpl_table_get_array(res, CR2RES_COL_UPPER, 0);
766 cpl_test_abs(cpl_array_get_double(carray, 0, NULL), 2.2, FLT_EPSILON);
767 cpl_test_abs(cpl_array_get_double(carray, 1, NULL), 0, FLT_EPSILON);
768 carray = cpl_table_get_array(res, CR2RES_COL_ALL, 0);
769 cpl_test_abs(cpl_array_get_double(carray, 0, NULL), 1.8, FLT_EPSILON);
770 cpl_test_abs(cpl_array_get_double(carray, 1, NULL), 0, FLT_EPSILON);
771 carray = cpl_table_get_array(res, CR2RES_COL_LOWER, 0);
772 cpl_test_abs(cpl_array_get_double(carray, 0, NULL), 1.4, FLT_EPSILON);
773 cpl_test_abs(cpl_array_get_double(carray, 1, NULL), 0, FLT_EPSILON);
776 cpl_table_delete(res);
777 cpl_table_delete(trace_table);
778 cpl_array_delete(new_slit_fraction);
788static void test_cr2res_trace_signal_detect(
void)
791 cpl_image *int_image = create_test_image();
792 cpl_image *image = cpl_image_cast(int_image, CPL_TYPE_DOUBLE);
793 cpl_image_delete(int_image);
795 double smoothfactor = 1;
799 cpl_binary data2[10 * 10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
800 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
801 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
802 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
803 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
804 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
805 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
806 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
807 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
808 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
810 cpl_mask *cmp = cpl_mask_wrap(10, 10, data2);
815 cpl_test_null(cr2res_trace_signal_detect(NULL, trace_sep, smoothfactor, thresh));
816 cpl_test_null(cr2res_trace_signal_detect(image, -10, smoothfactor, thresh));
817 cpl_test_null(cr2res_trace_signal_detect(image, trace_sep, -1, thresh));
820 cpl_test(res = cr2res_trace_signal_detect(image, trace_sep, smoothfactor, thresh));
822 sub = cpl_mask_extract(res, 32, 105, 41, 114);
829 cpl_image_delete(image);
830 cpl_mask_delete(res);
831 cpl_mask_unwrap(cmp);
832 cpl_mask_delete(sub);
840static void test_cr2res_trace_fit_traces(
void)
843 int xs[] = {4, 5, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 1, 2};
844 int ys[] = {4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 5};
845 int clusters[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
847 cpl_table *cluster = cpl_table_new(17);
848 cpl_table_wrap_int(cluster, xs, CR2RES_COL_XS);
849 cpl_table_wrap_int(cluster, ys, CR2RES_COL_YS);
850 cpl_table_wrap_int(cluster, clusters, CR2RES_COL_CLUSTERS);
854 const cpl_array *arr;
857 cpl_test_null(cr2res_trace_fit_traces(NULL, degree));
858 cpl_test_null(cr2res_trace_fit_traces(cluster, -5));
860 cpl_test(res = cr2res_trace_fit_traces(cluster, degree));
864 arr = cpl_table_get_array(res, CR2RES_COL_UPPER, 0);
865 cpl_test_abs(1.7, cpl_array_get(arr, 0, NULL), DBL_EPSILON * 10);
866 cpl_test_abs(0.5, cpl_array_get(arr, 1, NULL), DBL_EPSILON * 10);
867 arr = cpl_table_get_array(res, CR2RES_COL_UPPER, 1);
868 cpl_test_abs(5, cpl_array_get(arr, 0, NULL), DBL_EPSILON * 10);
869 cpl_test_abs(0, cpl_array_get(arr, 1, NULL), DBL_EPSILON * 10);
871 arr = cpl_table_get_array(res, CR2RES_COL_LOWER, 0);
872 cpl_test_abs(0.6, cpl_array_get(arr, 0, NULL), DBL_EPSILON * 10);
873 cpl_test_abs(0.2, cpl_array_get(arr, 1, NULL), DBL_EPSILON * 10);
874 arr = cpl_table_get_array(res, CR2RES_COL_LOWER, 1);
875 cpl_test_abs(5, cpl_array_get(arr, 0, NULL), DBL_EPSILON * 10);
876 cpl_test_abs(0, cpl_array_get(arr, 1, NULL), DBL_EPSILON * 10);
878 arr = cpl_table_get_array(res, CR2RES_COL_ALL, 0);
879 cpl_test_abs(1.15151515151515, cpl_array_get(arr, 0, NULL), DBL_EPSILON * 10);
880 cpl_test_abs(0.348484848484849, cpl_array_get(arr, 1, NULL), DBL_EPSILON * 10);
881 arr = cpl_table_get_array(res, CR2RES_COL_ALL, 1);
882 cpl_test_abs(5, cpl_array_get(arr, 0, NULL), DBL_EPSILON * 10);
883 cpl_test_abs(0, cpl_array_get(arr, 1, NULL), DBL_EPSILON * 10);
886 cpl_table_unwrap(cluster, CR2RES_COL_XS);
887 cpl_table_unwrap(cluster, CR2RES_COL_YS);
888 cpl_table_unwrap(cluster, CR2RES_COL_CLUSTERS);
889 cpl_table_delete(cluster);
890 cpl_table_delete(res);
898static void test_cr2res_trace_fit_trace(
void)
902 cpl_image *test_image = create_test_image();
903 cpl_table *all = cr2res_trace_convert_labels_to_cluster(test_image);
904 cpl_table_and_selected_int(all, CR2RES_COL_CLUSTERS, CPL_EQUAL_TO, 30);
905 cpl_table *table = cpl_table_extract_selected(all);
911 cpl_test_null(cr2res_trace_fit_trace(NULL, degree));
912 cpl_test_null(cr2res_trace_fit_trace(table, -10));
914 cpl_test(res = cr2res_trace_fit_trace(table, degree));
916 cpl_array_dump(res, 0, 2, NULL);
918 cpl_test_abs(cpl_array_get(res, 0, NULL), 225.007, 1.2);
919 cpl_test_abs(cpl_array_get(res, 1, NULL), 0.0172448, 0.0002);
922 cpl_image_delete(test_image);
923 cpl_table_delete(all);
924 cpl_table_delete(table);
925 cpl_array_delete(res);
983static void test_cr2res_trace_convert_labels_to_cluster(
void)
986 int data_inverse[] = {1, 1, 1, 1, 0,
991 cpl_image *labels = cpl_image_wrap(5, 5, CPL_TYPE_INT, data_inverse);
994 int xs[] = {1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4, 5, 4, 5, 1, 2};
995 int ys[] = {1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5};
996 int clusters[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
999 cpl_test_null(cr2res_trace_convert_labels_to_cluster(NULL));
1000 cpl_test(res = cr2res_trace_convert_labels_to_cluster(labels));
1004 for (
int i = 0; i < 17; i++)
1006 cpl_test_eq(xs[i], cpl_table_get(res, CR2RES_COL_XS, i, NULL));
1007 cpl_test_eq(ys[i], cpl_table_get(res, CR2RES_COL_YS, i, NULL));
1008 cpl_test_eq(clusters[i], cpl_table_get(res, CR2RES_COL_CLUSTERS, i, NULL));
1012 cpl_image_unwrap(labels);
1013 cpl_table_delete(res);
1022static void test_cr2res_trace_clean_blobs(
void)
1025 cpl_binary data[] = {1, 1, 0, 0,
1029 cpl_mask *mask = cpl_mask_wrap(4, 4, data);
1030 int min_cluster = 3;
1031 cpl_binary data2[] = {1, 1, 0, 0,
1035 cpl_mask *cmp = cpl_mask_wrap(4, 4, data2);
1039 cpl_test_null(cr2res_trace_clean_blobs(NULL, min_cluster));
1040 cpl_test_null(cr2res_trace_clean_blobs(mask, -1));
1043 cpl_test(res = cr2res_trace_clean_blobs(mask, 0));
1044 cpl_test_eq_mask(res, mask);
1045 cpl_mask_delete(res);
1047 cpl_test(res = cr2res_trace_clean_blobs(mask, min_cluster));
1050 cpl_test_eq_mask(res, cmp);
1053 cpl_mask_unwrap(mask);
1054 cpl_mask_unwrap(cmp);
1055 cpl_mask_delete(res);
1063static void test_cr2res_trace_extract_edges(
void)
1066 int xs[] = {4, 5, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4};
1067 int ys[] = {4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1};
1068 int clusters[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
1070 cpl_table *pixels_table = cpl_table_new(15);
1071 cpl_table_wrap_int(pixels_table, xs, CR2RES_COL_XS);
1072 cpl_table_wrap_int(pixels_table, ys, CR2RES_COL_YS);
1073 cpl_table_wrap_int(pixels_table, clusters, CR2RES_COL_CLUSTERS);
1075 cpl_table *edge_lower_table;
1076 cpl_table *edge_upper_table;
1078 int cmp_xs_lower[] = {5, 1, 2, 3, 4};
1079 int cmp_ys_lower[] = {2, 1, 1, 1, 1};
1080 int cmp_cluster_lower[] = {1, 1, 1, 1, 1};
1082 int cmp_xs_upper[] = {4, 5, 2, 3, 1};
1083 int cmp_ys_upper[] = {4, 4, 3, 3, 2};
1084 int cmp_cluster_upper[] = {1, 1, 1, 1, 1};
1087 cpl_test_eq(-1, cr2res_trace_extract_edges(NULL, &edge_lower_table, &edge_upper_table));
1088 cpl_test_eq(-1, cr2res_trace_extract_edges(pixels_table, NULL, &edge_upper_table));
1089 cpl_test_eq(-1, cr2res_trace_extract_edges(pixels_table, &edge_lower_table, NULL));
1091 cpl_test_eq(0, cr2res_trace_extract_edges(pixels_table, &edge_lower_table, &edge_upper_table));
1093 for (
int i = 0; i < 5; i++)
1095 cpl_test_eq(cpl_table_get(edge_lower_table, CR2RES_COL_XS, i, NULL), cmp_xs_lower[i]);
1096 cpl_test_eq(cpl_table_get(edge_lower_table, CR2RES_COL_YS, i, NULL), cmp_ys_lower[i]);
1097 cpl_test_eq(cpl_table_get(edge_lower_table, CR2RES_COL_CLUSTERS, i, NULL), cmp_cluster_lower[i]);
1098 cpl_test_eq(cpl_table_get(edge_upper_table, CR2RES_COL_XS, i, NULL), cmp_xs_upper[i]);
1099 cpl_test_eq(cpl_table_get(edge_upper_table, CR2RES_COL_YS, i, NULL), cmp_ys_upper[i]);
1100 cpl_test_eq(cpl_table_get(edge_upper_table, CR2RES_COL_CLUSTERS, i, NULL), cmp_cluster_upper[i]);
1104 cpl_table_unwrap(pixels_table, CR2RES_COL_XS);
1105 cpl_table_unwrap(pixels_table, CR2RES_COL_YS);
1106 cpl_table_unwrap(pixels_table, CR2RES_COL_CLUSTERS);
1107 cpl_table_delete(pixels_table);
1109 cpl_table_delete(edge_lower_table);
1110 cpl_table_delete(edge_upper_table);
1118static void test_cr2res_get_trace_table_index(
void)
1122 int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1123 int data2[] = {1, 1, 1, 1, 1, 1, 2, 1, 1, 1};
1124 cpl_table *trace_wave = cpl_table_new(n);
1125 cpl_table_wrap_int(trace_wave, data, CR2RES_COL_ORDER);
1126 cpl_table_wrap_int(trace_wave, data2, CR2RES_COL_TRACENB);
1139 cpl_test_eq(res, 4);
1146 cpl_test_eq(res, -1);
1153 cpl_test_eq(res, -1);
1156 cpl_table_unwrap(trace_wave, CR2RES_COL_ORDER);
1157 cpl_table_unwrap(trace_wave, CR2RES_COL_TRACENB);
1158 cpl_table_delete(trace_wave);
1166static void test_cr2res_get_trace_wave_poly(
void)
1168 cpl_table *trace_wave = cpl_table_new(1);
1169 cpl_table_new_column_array(trace_wave, CR2RES_COL_WAVELENGTH, CPL_TYPE_DOUBLE, 3);
1170 cpl_table_new_column(trace_wave, CR2RES_COL_ORDER, CPL_TYPE_INT);
1171 cpl_table_new_column(trace_wave, CR2RES_COL_TRACENB, CPL_TYPE_INT);
1172 cpl_table_set(trace_wave, CR2RES_COL_ORDER, 0, 1);
1173 cpl_table_set(trace_wave, CR2RES_COL_TRACENB, 0, 1);
1174 double pdata[] = {1.1, 2.2, 3.3};
1175 cpl_array *parr = cpl_array_wrap_double(pdata, 3);
1176 cpl_table_set_array(trace_wave, CR2RES_COL_WAVELENGTH, 0, parr);
1179 cpl_polynomial *res_poly;
1188 cpl_test_abs(1.1, cpl_polynomial_get_coeff(res_poly, &power), DBL_EPSILON);
1190 cpl_test_abs(2.2, cpl_polynomial_get_coeff(res_poly, &power), DBL_EPSILON);
1192 cpl_test_abs(3.3, cpl_polynomial_get_coeff(res_poly, &power), DBL_EPSILON);
1194 cpl_array_unwrap(parr);
1195 cpl_table_delete(trace_wave);
1196 cpl_polynomial_delete(res_poly);
1206 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_DEBUG);
1208 test_cr2res_trace();
1209 test_cr2res_trace_clean();
1210 test_cr2res_trace_gen_image();
1211 test_cr2res_trace_get_order_idx_values();
1212 test_cr2res_trace_get_ycen();
1213 test_cr2res_trace_get_height();
1214 test_cr2res_trace_compute_middle();
1215 test_cr2res_trace_compute_height();
1216 test_cr2res_trace_get_trace_ypos();
1217 test_cr2res_trace_add_extra_columns();
1218 test_cr2res_trace_signal_detect();
1219 test_cr2res_trace_fit_traces();
1220 test_cr2res_trace_fit_trace();
1221 test_cr2res_trace_convert_labels_to_cluster();
1222 test_cr2res_trace_clean_blobs();
1223 test_cr2res_trace_extract_edges();
1224 test_cr2res_trace_new_slit_fraction();
1225 test_cr2res_get_trace_table_index();
1226 test_cr2res_get_trace_wave_poly();
1227 return cpl_test_end(0);
char * cr2res_io_create_extname(int detector, int data)
Create Extname.
int cr2res_io_convert_order_idx_to_idxp(int order_idx)
Convert the order_idx to the order_idxp.
int main(void)
Run the Unit tests.
cpl_vector * cr2res_trace_get_ycen(const cpl_table *trace, int order_idx, int trace_nb, int size)
Retrieves the middle (All) polynomial from trace table and evaluates.
cpl_vector * cr2res_trace_compute_middle(cpl_polynomial *trace1, cpl_polynomial *trace2, int vector_size)
Computes the positions between 2 trace polynomials.
cpl_image * cr2res_trace_gen_image(cpl_table *trace, int nx, int ny)
Make an image out of the trace solution.
double cr2res_trace_get_trace_ypos(const cpl_table *traces, int idx)
Compute the y position of the trace.
int cr2res_trace_get_height(const cpl_table *trace, cpl_size order_idx, cpl_size trace_nb)
Computes the average height (pix) of an order, from trace polys.
cpl_table * cr2res_trace(cpl_image *ima, int smooth_x, int smooth_y, double threshold, int opening, int degree, int min_cluster)
Main function for running all parts of the trace algorithm.
cpl_size cr2res_get_trace_table_index(const cpl_table *trace_wave, int order_idx, int trace_nb)
Get the index in a TRACE_WAVE table.
cpl_table * cr2res_trace_new_slit_fraction(const cpl_table *traces, const cpl_array *new_slit_fraction)
Recompute the traces at a newly specified slit fraction.
int cr2res_trace_compute_height(cpl_polynomial *trace1, cpl_polynomial *trace2, int vector_size)
Computes extraction height between 2 trace polynomials.
cpl_polynomial * cr2res_get_trace_wave_poly(const cpl_table *trace_wave, const char *poly_column, int order_idx, int trace_nb)
Get a polynomial from a TRACE_WAVE table.
cpl_mask * cr2res_trace_clean(cpl_mask *mask, int opening, int min_cluster)
Clean small blobs.
int cr2res_trace_add_extra_columns(cpl_table *traces, const char *infile, int det_nr)
Add extra columns to the plain trace table.
int * cr2res_trace_get_order_idx_values(const cpl_table *trace, int *nb_order_idx_values)
Count and return the different order_idx values from a TW table.