CR2RE Pipeline Reference Manual 1.6.10
cr2res_utils-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 <math.h>
31#include <cpl.h>
32#include <hdrl.h>
33#include <cr2res_utils.h>
34#include <cr2res_dfs.h>
35#include <cr2res_trace.h>
36#include <cr2res_wave.h>
37#include <cr2res_io.h>
38#include <cr2res_slit_curv.h>
39
40#ifndef localdir
41#define localdir getenv("srcdir")
42#endif
43
44
45/*-----------------------------------------------------------------------------
46 Functions prototypes
47 -----------------------------------------------------------------------------*/
48
49static void test_cr2res_vector_get_int(void);
50static void test_cr2res_vector_get_rest(void);
51static void test_cr2res_image_cut_rectify(void);
52static void test_cr2res_image_insert_rect(void);
53static void test_cr2res_polynomial_eval_vector(void);
54static void test_cr2res_threshold_spec(void);
55static void test_cr2res_get_base_name(void);
56static void test_cr2res_get_root_name(void);
57//static void test_cr2res_extract_filename(void);
58static void test_cr2res_extract_frameset(void);
59static void test_cr2res_convert_array_to_poly(void);
60static void test_cr2res_convert_poly_to_array(void);
61static void test_cr2res_detector_shotnoise_model(void);
62static void test_cr2res_fit_interorder(void);
63static void test_cr2res_slit_pos(void);
64static void test_cr2res_slit_pos_img(void);
65static void test_cr2res_get_license(void);
66static void test_cr2res_slit_curv_compute_order_trace(void);
67static void test_cr2res_optimal_filter_2d(void);
68static void test_cr2res_polyfit_2d(void);
69
70/*----------------------------------------------------------------------------*/
75/*----------------------------------------------------------------------------*/
76
79static void test_cr2res_vector_get_int(void)
80{
81 int i;
82 int n = 10;
83 cpl_vector *in = cpl_vector_new(n);
84 int *res;
85
86 for (i = 0; i < n; i++)
87 {
88 double d;
89 d = (double)i;
90 cpl_vector_set(in, i, d + (d / (n + 1)));
91 }
92
93 cpl_test_null(cr2res_vector_get_int(NULL));
94
95 cpl_test(res = cr2res_vector_get_int(in));
96
97 for (i = 0; i < n; i++)
98 {
99 cpl_test_eq(i, res[i]);
100 }
101
102 cpl_vector_delete(in);
103 cpl_free(res);
104
105 return;
106}
107static void test_cr2res_vector_get_rest(void)
108{
109 int i;
110 int n = 1000;
111 cpl_vector *in = cpl_vector_new(n);
112 cpl_vector *out = cpl_vector_new(n);
113 double *res;
114
115 for (i = 0; i < n; i++)
116 {
117 double d;
118 d = (double)i;
119 cpl_vector_set(in, i, d + (d / (n + 1)));
120 cpl_vector_set(out, i, (d / (n + 1)));
121 }
122
123 cpl_test_null(cr2res_vector_get_rest(NULL));
124
125 cpl_test(res = cr2res_vector_get_rest(in));
126 cpl_vector_delete(in);
127 in = cpl_vector_wrap(n, res);
128 cpl_test_vector_abs(in, out, DBL_EPSILON * n);
129
130 cpl_vector_delete(in);
131 cpl_vector_delete(out);
132
133 return;
134}
135static void test_cr2res_image_cut_rectify(void)
136{
137 cpl_image *res;
138 int imdata[] = {1, 2, 3, 2, 1,
139 1, 2, 9, 2, 9,
140 1, 9, 3, 9, 1,
141 9, 2, 3, 2, 1};
142 cpl_image *img = cpl_image_wrap_int(5, 4, imdata);
143 cpl_image_flip(img, 0); // so that the image looks as formatted above.
144
145 // What result should be
146 int cmpdata[] = {9, 9, 9, 9, 9};
147 cpl_image *cmp = cpl_image_wrap_int(5, 1, cmpdata);
148
149 double ydata[] = {1.9, 2.1, 3.5, 2.8, 3.99};
150 cpl_vector *ycen = cpl_vector_wrap(5, ydata);
151
152 // Run the main function to be tested
153 cpl_test_null(cr2res_image_cut_rectify(NULL, ycen, 1));
154 cpl_test_null(cr2res_image_cut_rectify(img, NULL, 1));
155 cpl_test_null(cr2res_image_cut_rectify(img, ycen, 0));
156
157 cpl_test(res = cr2res_image_cut_rectify(img, ycen, 1));
158
159 // Compare the two
160 cpl_test_image_abs(res, cmp, 0);
161
162 cpl_image_unwrap(img);
163 cpl_image_unwrap(cmp);
164 cpl_vector_unwrap(ycen);
165 cpl_image_delete(res);
166
167 return;
168}
169static void test_cr2res_image_insert_rect(void)
170{
171 int recdata[] = {1, 2, 3, 2, 1,
172 1, 2, 9, 2, 9,
173 1, 9, 3, 9, 1,
174 9, 2, 3, 2, 1};
175 cpl_image *rect_in = cpl_image_wrap_int(5, 4, recdata);
176 cpl_image_flip(rect_in, 0);
177
178 double ydata[] = {0.5, 1.1, 6.7, 11.9, 12.1};
179 cpl_vector *ycen = cpl_vector_wrap(5, ydata);
180 cpl_image *img_out = cpl_image_new(5, 12, CPL_TYPE_INT);
181 int cmpdata[] = {0, 0, 0, 2, 9,
182 0, 0, 0, 2, 1,
183 0, 0, 0, 9, 1,
184 0, 0, 0, 2, 0,
185 0, 0, 0, 0, 0,
186 0, 0, 3, 0, 0,
187 0, 0, 9, 0, 0,
188 0, 0, 3, 0, 0,
189 0, 0, 3, 0, 0,
190 0, 0, 0, 0, 0,
191 0, 2, 0, 0, 0,
192 1, 2, 0, 0, 0};
193 cpl_image *compare = cpl_image_wrap_int(5, 12, cmpdata);
194 cpl_image_flip(compare, 0);
195
196 cpl_test_eq(-1, cr2res_image_insert_rect(NULL, ycen, img_out));
197 cpl_test_eq(-1, cr2res_image_insert_rect(rect_in, NULL, img_out));
198 cpl_test_eq(-1, cr2res_image_insert_rect(rect_in, ycen, NULL));
199
200 cpl_test_zero(cr2res_image_insert_rect(rect_in, ycen, img_out));
201
202 if (cpl_msg_get_level() == CPL_MSG_DEBUG)
203 {
204 cpl_image_save(img_out, "TEST_out.fits", CPL_TYPE_INT, NULL,
205 CPL_IO_CREATE);
206 cpl_image_save(compare, "TEST_cmp.fits", CPL_TYPE_INT, NULL,
207 CPL_IO_CREATE);
208 }
209
210 // img_out == compare ?
211 cpl_test_image_abs(img_out, compare, 0);
212
213 cpl_image_unwrap(rect_in);
214 cpl_image_unwrap(compare);
215 cpl_vector_unwrap(ycen);
216 cpl_image_delete(img_out);
217
218 return;
219}
220static void test_cr2res_polynomial_eval_vector(void)
221{
222 int i;
223 cpl_size power;
224 double p0 = 1.1, p1 = 2.2, p2 = 3.3;
225 int n = 100;
226 cpl_vector *in = cpl_vector_new(n);
227 cpl_vector *out = cpl_vector_new(n);
228 cpl_vector *res;
229 cpl_polynomial *poly = cpl_polynomial_new(1);
230
231 power = 0;
232 cpl_polynomial_set_coeff(poly, &power, p0);
233 power = 1;
234 cpl_polynomial_set_coeff(poly, &power, p1);
235 power = 2;
236 cpl_polynomial_set_coeff(poly, &power, p2);
237
238 for (i = 0; i < n; i++)
239 {
240 double d, val;
241 d = (double)i;
242 //val = d + (d / (n + 1));
243 cpl_vector_set(in, i, d);
244 val = (p2 * d * d) + (p1 * d) + p0;
245 cpl_vector_set(out, i, val);
246 }
247
248 cpl_test_null(cr2res_polynomial_eval_vector(NULL, in));
249 cpl_test_null(cr2res_polynomial_eval_vector(poly, NULL));
250
251 cpl_test(res = cr2res_polynomial_eval_vector(poly, in));
252
253 cpl_test_vector_abs(res, out, DBL_EPSILON * n * n * 10);
254
255 cpl_vector_delete(in);
256 cpl_vector_delete(out);
257 cpl_vector_delete(res);
258 cpl_polynomial_delete(poly);
259
260 return;
261}
262
263/*----------------------------------------------------------------------------*/
273/*----------------------------------------------------------------------------*/
274static void test_cr2res_threshold_spec(void)
275{
276 //define input
277 int n = 10;
278 double data[] = {1., 2., 1., 5., 3., 1., 15., 2., 0., 1.};
279 cpl_vector *invector = cpl_vector_wrap(n, data);
280 // expected data = data - median of boxcar - thresh
281 // what is the expected behaviour at the borders?
282 // -3, -3, -4, 0, -3, -4, 10, -2, -3, -1
283 double outdata[] = {1 - 1 - 3, 2 - 1 - 3, 1 - 2 - 3, 5 - 3 - 3, 3 - 3 - 3,
284 1 - 3 - 3, 15 - 2 - 3, 2 - 2 - 3, 0 - 1 - 3, 1 - 1 - 3};
285 cpl_vector *outvector = cpl_vector_wrap(n, outdata);
286
287 //boxcar size = smooth + 3, for even values, and smooth + 2 for odd values
288 int smooth = 0; //the documentation isn't really right about what smooth is
289 double thresh = 3;
290 //define output
291 cpl_vector *res;
292
293 //run test
294 cpl_test_null(cr2res_threshold_spec(NULL, smooth, thresh));
295 cpl_test_null(cr2res_threshold_spec(invector, -1, thresh));
296 //cpl_test_null(cr2res_threshold_spec(invector, smooth, 4545));
297
298 cpl_test(res = cr2res_threshold_spec(invector, smooth, thresh));
299
300 //cpl_vector_dump(res, "test.log");
301 //check output
302 cpl_test_vector_abs(outvector, res, DBL_EPSILON * n * n * 10);
303
304 //deallocate memory
305 cpl_vector_unwrap(outvector);
306 cpl_vector_unwrap(invector);
307 cpl_vector_delete(res);
308
309 return;
310}
311
312/*----------------------------------------------------------------------------*/
318/*----------------------------------------------------------------------------*/
319static void test_cr2res_get_base_name(void)
320{
321 //define input
322 char *filename = "./../tests/cr2res_trace-test.log";
323 char *res;
324
325 //run test
326 cpl_test_null(cr2res_get_base_name(NULL));
327
328 cpl_test(res = cr2res_get_base_name(filename));
329 //test output
330 cpl_test_eq_string(res, "cr2res_trace-test.log");
331}
332
333/*----------------------------------------------------------------------------*/
339/*----------------------------------------------------------------------------*/
340static void test_cr2res_get_root_name(void)
341{
342 //define input
343 //it only removes the extension for fits, dat, paf, txt, and ascii files
344 char *filename = "cr2res_trace-test.fits";
345 char *res;
346
347 //run test
348 cpl_test_null(cr2res_get_root_name(NULL));
349
350 cpl_test(res = cr2res_get_root_name(filename));
351 //test output
352 cpl_test_eq_string(res, "cr2res_trace-test");
353}
354#ifdef CR2RES_UNUSED_TESTS
355/*----------------------------------------------------------------------------*/
360/*----------------------------------------------------------------------------*/
361static void test_cr2res_extract_filename(void)
362{
363 //define input
364 cpl_frame *frame = cpl_frame_new();
365 cpl_frame_set_filename(frame, "bla-test.log");
366 cpl_frame_set_tag(frame, "test_correct");
367
368 cpl_frame *other = cpl_frame_new();
369 cpl_frame_set_filename(other, "blub-test.log");
370 cpl_frame_set_tag(other, "test_wrong");
371
372 cpl_frameset *in = cpl_frameset_new();
373 cpl_frameset_insert(in, other);
374 cpl_frameset_insert(in, frame);
375
376 char *tag = "test_correct";
377 const char *res;
378
379 //run test
380 cpl_test_null(cr2res_extract_filename(NULL, tag));
381 cpl_test_null(cr2res_extract_filename(in, NULL));
382
383 cpl_test(res = cr2res_extract_filename(in, tag));
384 //test output
385 cpl_test_eq_string(res, "bla-test.log");
386
387 //deallocate memory
388 cpl_frameset_delete(in); //this should also delete the frames
389}
390#endif
391
392/*----------------------------------------------------------------------------*/
401/*----------------------------------------------------------------------------*/
402static void test_cr2res_extract_frameset(void)
403{
404 //define input
405 cpl_frame *frame = cpl_frame_new();
406 cpl_frame_set_filename(frame, "bla-test.log");
407 cpl_frame_set_tag(frame, "test_correct");
408
409 cpl_frame *other = cpl_frame_new();
410 cpl_frame_set_filename(other, "blub-test.log");
411 cpl_frame_set_tag(other, "test_wrong");
412
413 cpl_frameset *in = cpl_frameset_new();
414 cpl_frameset_insert(in, frame);
415 cpl_frameset_insert(in, other);
416
417 char *tag = "test_correct";
418 cpl_frameset *res;
419
420 //run test
421 cpl_test_null(cr2res_extract_frameset(NULL, tag));
422 cpl_test_null(cr2res_extract_frameset(in, NULL));
423
424 cpl_test(res = cr2res_extract_frameset(in, tag));
425 //test output
426 //test size
427 cpl_test_eq(1, cpl_frameset_get_size(res));
428 //check if filenames fit
429 const char *fname1 = "bla-test.log";
430 const char *fname2 = cpl_frame_get_filename(
431 cpl_frameset_get_position(res, 0));
432 cpl_test_eq_string(fname1, fname2); //Is that the right comparison?
433 //check that the reference was copied as it is supposed to
434 cpl_test_noneq_ptr(cpl_frameset_get_position(res, 0), frame);
435
436 //deallocate memory
437 //this also deletes the frames
438 cpl_frameset_delete(res);
439 cpl_frameset_delete(in);
440}
441/*----------------------------------------------------------------------------*/
445/*----------------------------------------------------------------------------*/
446static void test_cr2res_convert_array_to_poly(void)
447{
448 //define input
449 int n = 10;
450 double data[] = {0.9, 1.5, 219.1, 123.8, 18, 123.3, 0.623, 0., 0.9, 1};
451 cpl_array *arr = cpl_array_wrap_double(data, n);
452 cpl_polynomial *res;
453
454 //run test
455 cpl_test_null(cr2res_convert_array_to_poly(NULL));
456
457 cpl_test(res = cr2res_convert_array_to_poly(arr));
458
459 //test output
460 for (int i = 0; i < n; i++) {
461 cpl_size power;
462 double poly;
463 power = i;
464 poly = cpl_polynomial_get_coeff(res, &power);
465 cpl_test_eq(data[i], poly);
466 }
467
468 //deallocate memory
469 cpl_polynomial_delete(res);
470 cpl_array_unwrap(arr);
471}
472
473/*----------------------------------------------------------------------------*/
477/*----------------------------------------------------------------------------*/
478static void test_cr2res_convert_poly_to_array(void)
479{
480 //define input
481 int n = 10;
482 cpl_array *res;
483 double data[] = {0.9, 1.5, 219.1, 123.8, 18, 123.3, 0.623, 0., 0.9, 1};
484 cpl_polynomial *poly = cpl_polynomial_new(1);
485 for (cpl_size i = 0; i < n; i++)
486 cpl_polynomial_set_coeff(poly, &i, data[i]);
487
488 //also if size = NULL, no error is raised. Problem?
489
490 //run test
491 cpl_test_null(cr2res_convert_poly_to_array(NULL, n));
492 cpl_test_null(cr2res_convert_poly_to_array(poly, 0));
493
494 cpl_test(res = cr2res_convert_poly_to_array(poly, n));
495 //test output
496 for (int j = 0; j < n; j++)
497 cpl_test_eq(cpl_array_get(res, j, NULL), data[j]);
498
499 //deallocate memory
500 cpl_polynomial_delete(poly);
501 cpl_array_delete(res);
502}
503
504/*----------------------------------------------------------------------------*/
508/*----------------------------------------------------------------------------*/
509static void test_cr2res_detector_shotnoise_model(void)
510{
511 //define input
512 const double count = 1;
513 const double gain = 7;
514 const double ron = 3;
515 const double err = sqrt(count/gain + ron * ron);
516 int width = 5;
517 int height = 12;
518
519 cpl_image *ima_data = cpl_image_new(width, height, CPL_TYPE_INT);
520 cpl_image_add_scalar(ima_data, count);
521 // set first pixel to negative to check behaviour
522 cpl_image_set(ima_data, 1, 1, -1);
523
524 cpl_image *ima_errs;
525
526 cpl_image * compare = cpl_image_new(width, height, CPL_TYPE_INT);
527 cpl_image_add_scalar(compare, err);
528 cpl_image_set(compare, 1, 1, ron);
529
530 //run test
531 cpl_test_eq(CPL_ERROR_NULL_INPUT,
532 cr2res_detector_shotnoise_model(NULL, gain, ron, &ima_errs));
533 cpl_test_error(CPL_ERROR_NULL_INPUT);
534 cpl_test_eq(CPL_ERROR_ILLEGAL_INPUT,
535 cr2res_detector_shotnoise_model(ima_data, 0, ron, &ima_errs));
536 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
537 cpl_test_eq(CPL_ERROR_ILLEGAL_INPUT,
538 cr2res_detector_shotnoise_model(ima_data, gain, -1, &ima_errs));
539 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
540 cpl_test_eq(CPL_ERROR_NULL_INPUT, cr2res_detector_shotnoise_model(ima_data,
541 gain, ron, NULL));
542 cpl_test_error(CPL_ERROR_NULL_INPUT);
543
544 cpl_test_eq(CPL_ERROR_NONE, cr2res_detector_shotnoise_model(ima_data, gain,
545 ron, &ima_errs));
546 //test output
547 cpl_test_image_abs(ima_errs, compare, 0);
548
549 //deallocate memory
550 cpl_image_delete(ima_data);
551 cpl_image_delete(ima_errs);
552 cpl_image_delete(compare);
553}
554
555static cpl_table *create_test_table()
556{
557 int poly_order = 2;
558 int n_orders = 2;
559 cpl_table * traces = cpl_table_new(n_orders);
560 cpl_table_new_column_array(traces, CR2RES_COL_ALL,
561 CPL_TYPE_DOUBLE, poly_order);
562 cpl_table_new_column_array(traces, CR2RES_COL_UPPER,
563 CPL_TYPE_DOUBLE, poly_order);
564 cpl_table_new_column_array(traces, CR2RES_COL_LOWER,
565 CPL_TYPE_DOUBLE, poly_order);
566 cpl_table_new_column(traces, CR2RES_COL_ORDER, CPL_TYPE_INT);
567 cpl_table_new_column(traces, CR2RES_COL_TRACENB, CPL_TYPE_INT);
568
569 double all_1[] = {86.6279, 175.5738};
570 double all_2[] = {0.01699, 0.07512};
571 double upper_1[] = {108.5065, 197.3485};
572 double upper_2[] = {0.016601, 0.0184364};
573 double lower_1[] = {64.05477, 153.7987};
574 double lower_2[] = {0.017355, 0.01659297};
575
576 cpl_array * array = cpl_array_new(poly_order, CPL_TYPE_DOUBLE);
577 for (int i = 0; i < n_orders; i++)
578 {
579 cpl_array_set(array, 0, all_1[i]);
580 cpl_array_set(array, 1, all_2[i]);
581 cpl_table_set_array(traces, CR2RES_COL_ALL, i, array);
582 cpl_array_set(array, 0, upper_1[i]);
583 cpl_array_set(array, 1, upper_2[i]);
584 cpl_table_set_array(traces, CR2RES_COL_UPPER, i, array);
585 cpl_array_set(array, 0, lower_1[i]);
586 cpl_array_set(array, 1, lower_2[i]);
587 cpl_table_set_array(traces, CR2RES_COL_LOWER, i, array);
588 cpl_table_set(traces, CR2RES_COL_ORDER, i, 7);
589 cpl_table_set(traces, CR2RES_COL_TRACENB, i, i + 1);
590 }
591
592 cpl_array_delete(array);
593 return traces;
594}
595
596static cpl_image *create_test_image()
597{
598 char *my_path = cpl_sprintf("%s/cr2res_utils_test_image.fits",
599 localdir);
600 cpl_image *img = cpl_image_load(my_path, CPL_TYPE_INT, 0, 1);
601 cpl_free(my_path) ;
602 return img;
603}
604
605/*----------------------------------------------------------------------------*/
609/*----------------------------------------------------------------------------*/
610static void test_cr2res_fit_interorder(void)
611{
612 // Define all variables
613 cpl_image *img = create_test_image();
614
615 // for(int i = 1; i < 100; i++)
616 // {
617 // for(int j = 1; j < 100; j++)
618 // {
619 // cpl_image_set(img, i, j, 10000);
620 // }
621 // }
622
623 cpl_table *trace_wave = create_test_table();
624 cpl_polynomial * res;
625 cpl_polynomial *cmp = cpl_polynomial_new(2);
626 cpl_size power[] = {0,0};
627
628 // Define comparison polynomial, values from previous run
629 // 1.dim.power 2.dim.power coefficient
630 // 0 0 25.1533
631 // 1 0 0.245861
632 // 0 1 0.519612
633 // 1 1 -0.000952474
634 cpl_polynomial_set_coeff(cmp, power, 25.1533);
635 power[0] = 1;
636 cpl_polynomial_set_coeff(cmp, power, 0.245861);
637 power[1] = 1;
638 cpl_polynomial_set_coeff(cmp, power, -0.000952474);
639 power[0] = 0;
640 power[1] = 1;
641 cpl_polynomial_set_coeff(cmp, power, 0.519612);
642
643 // Run function
644 cpl_test(res = cr2res_fit_interorder(img, trace_wave, 1, 1));
645
646 // Compare output
647 // thats as precise as it gets, from the polynomial dump
648 cpl_test_polynomial_abs(res, cmp, 1e-4);
649
650 // delete cpl objects
651 cpl_table_delete(trace_wave);
652 cpl_polynomial_delete(res);
653 cpl_polynomial_delete(cmp);
654 cpl_image_delete(img);
655 return;
656}
657
658/*----------------------------------------------------------------------------*/
662/*----------------------------------------------------------------------------*/
663static void test_cr2res_slit_pos()
664{
665 int chip = 2;
666
667 char *my_path = cpl_sprintf("%s/cr2res_util_calib_calibrated_collapsed_extr1D_tw.fits",
668 localdir);
669 cpl_table *tw_decker1 = cpl_table_load(my_path, chip, 0);
670 cpl_free(my_path) ;
671
672 int nb_orders = 0;
673 cpl_polynomial ** coef_slit = NULL;
674 cpl_polynomial ** coef_wave = NULL;
675
676 // test NULL input
677 cpl_test_eq(-1, cr2res_slit_pos(NULL, &coef_slit, &coef_wave, &nb_orders));
678 cpl_test_eq(-1, cr2res_slit_pos(tw_decker1, NULL, &coef_wave, &nb_orders));
679 cpl_test_eq(-1, cr2res_slit_pos(tw_decker1, &coef_slit, NULL, &nb_orders));
680 cpl_test_eq(-1, cr2res_slit_pos(tw_decker1, &coef_slit, &coef_wave, NULL));
681
682 // normal run
683 cpl_test_eq(0, cr2res_slit_pos(tw_decker1, &coef_slit, &coef_wave, &nb_orders));
684
685 // Test results
686 cpl_test_nonnull(coef_slit);
687 cpl_test_nonnull(coef_wave);
688 cpl_test_noneq(0, nb_orders);
689
690 for (int i = 0; i < nb_orders; i++){
691 cpl_test_nonnull(coef_slit[i]);
692 cpl_test_nonnull(coef_wave[i]);
693 }
694
695 // Cleanup
696 cpl_table_delete(tw_decker1);
697 if (coef_wave != NULL){
698 for (int i=0; i < nb_orders; i++){
699 cpl_polynomial_delete(coef_wave[i]);
700 }
701 cpl_free(coef_wave);
702 }
703 if (coef_slit != NULL){
704 for (int i=0; i < nb_orders; i++){
705 cpl_polynomial_delete(coef_slit[i]);
706 }
707 cpl_free(coef_slit);
708 }
709}
710
711/*----------------------------------------------------------------------------*/
715/*----------------------------------------------------------------------------*/
716static void test_cr2res_slit_pos_img()
717{
718 int chip = 2;
719 char *my_path =
720 cpl_sprintf("%s/cr2res_util_calib_calibrated_collapsed_extr1D_tw.fits",
721 localdir);
722 cpl_table *tw_decker1 = cpl_table_load(my_path, chip, 0);
723 cpl_free(my_path) ;
724 cpl_image * slitpos = NULL;
725 cpl_image * wavelength = NULL;
726
727 // Test null input
728 cpl_test_eq(-1, cr2res_slit_pos_image(NULL, &slitpos, &wavelength));
729 cpl_test_eq(-1, cr2res_slit_pos_image(tw_decker1, NULL, &wavelength));
730 cpl_test_eq(-1, cr2res_slit_pos_image(tw_decker1, &slitpos, NULL));
731
732 // Test normal run
733 cpl_test_eq(0, cr2res_slit_pos_image(tw_decker1, &slitpos, &wavelength));
734
735 // Test results
736 cpl_test_nonnull(slitpos);
737 cpl_test_nonnull(wavelength);
738 // check that they are the same size
739 cpl_test_eq(cpl_image_get_size_x(slitpos), cpl_image_get_size_x(wavelength));
740 cpl_test_eq(cpl_image_get_size_y(slitpos), cpl_image_get_size_y(wavelength));
741 // check that slitpos is between 0 and 1
742 cpl_test_leq(cpl_image_get_max(slitpos), 1);
743 cpl_test_leq(-cpl_image_get_min(slitpos), 0);
744 // check the wavelength values (the upper value depends on the test input)
745 cpl_test_leq(-cpl_image_get_min(wavelength), 0);
746 cpl_test_leq(cpl_image_get_max(wavelength), 1500);
747
748 // Debug output
749 if (slitpos != NULL)
750 cpl_image_save(slitpos, "TEST_slit.fits", CPL_TYPE_DOUBLE,
751 NULL, CPL_IO_CREATE);
752 if (wavelength != NULL)
753 cpl_image_save(wavelength, "TEST_wave.fits", CPL_TYPE_DOUBLE,
754 NULL, CPL_IO_CREATE);
755
756 // Cleanup
757 cpl_table_delete(tw_decker1);
758 if (slitpos != NULL) cpl_image_delete(slitpos);
759 if (wavelength != NULL) cpl_image_delete(wavelength);
760}
761
762static cpl_image * load_etalon_image(){
763 char * path = cpl_sprintf("%s/cr2res_slit_curv_test.fits",
764 localdir);
765 cpl_image * img = cpl_image_load(path, CPL_TYPE_INT, 0, 1);
766 cpl_free(path) ;
767 return img;
768}
769
770static cpl_table * load_etalon_table(){
771 char * path = cpl_sprintf("%s/cr2res_slit_curv_test_tw.fits",
772 localdir);
773 cpl_table * trace_wave = cpl_table_load(path, 1, 0);
774 cpl_free(path);
775 return trace_wave;
776}
777
778static void test_cr2res_slit_curv_compute_order_trace(){
779
780 hdrl_image * img_hdrl;
781 cpl_image * img_in = load_etalon_image();
782 cpl_table * trace_wave = load_etalon_table();
783
784 cpl_polynomial * poly_a = NULL;
785 cpl_polynomial * poly_b = NULL;
786 cpl_polynomial * poly_c = NULL;
787
788 int order = 1;
789 int trace = 1;
790 int height = 100; // The height of the order
791 int window = 15; // The spacing between peaks
792 int degree = 2; // That is the default format
793 int fit_c = 1; // Thats what we want most of the time
794 int result;
795
796 // cpl_table_save(trace_wave, NULL, NULL, "debug_tw.fits", CPL_IO_CREATE);
797
798 img_hdrl = hdrl_image_create(img_in, NULL);
799
800 result = cr2res_slit_curv_compute_order_trace(img_hdrl, trace_wave,
801 order, trace, height, window, degree, fit_c,
802 &poly_a, &poly_b, &poly_c);
803 cpl_test_eq(0, result);
804
805 if (result == 0){
806 cpl_polynomial_dump(poly_a, stderr);
807 cpl_polynomial_dump(poly_b, stderr);
808 cpl_polynomial_dump(poly_c, stderr);
809 }
810
811 cpl_image_delete(img_in);
812 hdrl_image_delete(img_hdrl);
813 cpl_table_delete(trace_wave);
814
815 cpl_polynomial_delete(poly_a);
816 cpl_polynomial_delete(poly_b);
817 cpl_polynomial_delete(poly_c);
818}
819
820static void test_cr2res_optimal_filter_2d(void)
821{
822 cpl_image * img;
823 cpl_image * weight;
824 cpl_image * model;
825 double lam_x = 1, lam_y = 1;
826
827 int nx = 100;
828 int ny = 50;
829
830 img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
831 weight = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
832
833 for (cpl_size i = 1; i <= nx; i++)
834 {
835 for (cpl_size j = 1; j <= ny; j++)
836 {
837 cpl_image_set(img, i, j, 10);
838 cpl_image_set(weight, i, j, 1);
839 }
840 }
841
842 cpl_test_nonnull(
843 model = cr2res_util_optimal_filter_2d(img, weight, lam_x, lam_y));
844
845 cpl_image_save(model, "TEST_optimal_filter.fits",
846 CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
847
848 cpl_image_delete(img);
849 cpl_image_delete(weight);
850 cpl_image_delete(model);
851}
852
853/*----------------------------------------------------------------------------*/
867/*----------------------------------------------------------------------------*/
868static void test_cr2res_polyfit_2d(void)
869{
870 cpl_vector *x, *y, *z;
871 cpl_polynomial * poly;
872
873 cpl_size npoints = 5 * 5;
874 cpl_size ngrid = npoints * npoints;
875 cpl_size i, j, k;
876 cpl_size power[2];
877 cpl_size degree[2];
878
879 x = cpl_vector_new(ngrid);
880 y = cpl_vector_new(ngrid);
881 z = cpl_vector_new(ngrid);
882
883 // f(x, y) = 1 + x + 2 * x y^2
884 k = 0;
885 for (i = 0; i < npoints ; i++){
886 for (j = 0; j < npoints; j++){
887 cpl_vector_set(x, k, i);
888 cpl_vector_set(y, k, j);
889 cpl_vector_set(z, k, 1 + i + 2 * i * j * j);
890 k++;
891 }
892 }
893
894 // Define the degrees that should be fitted
895 // These are always one larger than the actual degree
896 // since it includes degree 0
897 degree[0] = 2;
898 degree[1] = 3;
899
900 // Do the fit
901 cpl_test_nonnull(poly = cr2res_polyfit_2d(x, y, z, degree));
902
903 // Check results
904 cpl_test_eq(cpl_polynomial_get_dimension(poly), 2);
905
906 power[0] = 0;
907 power[1] = 0;
908 cpl_test_abs(cpl_polynomial_get_coeff(poly, power), 1, 0.00001);
909
910 power[0] = 1;
911 power[1] = 0;
912 cpl_test_abs(cpl_polynomial_get_coeff(poly, power), 1, 0.00001);
913
914 power[0] = 1;
915 power[1] = 2;
916 cpl_test_abs(cpl_polynomial_get_coeff(poly, power), 2, 0.00001);
917
918 // Clean up
919 cpl_vector_delete(x);
920 cpl_vector_delete(y);
921 cpl_vector_delete(z);
922 cpl_polynomial_delete(poly);
923}
924
925/*----------------------------------------------------------------------------*/
933/*----------------------------------------------------------------------------*/
934static void test_cr2res_get_license(void)
935{
936 const char *license;
937 cpl_test(license = cr2res_get_license());
938 return;
939}
940
941/*----------------------------------------------------------------------------*/
945/*----------------------------------------------------------------------------*/
946int main(void)
947{
948 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_DEBUG);
949
950 test_cr2res_vector_get_rest();
951 test_cr2res_vector_get_int();
952 test_cr2res_polynomial_eval_vector();
953 test_cr2res_image_cut_rectify();
954 test_cr2res_image_insert_rect();
955 test_cr2res_threshold_spec();
956 test_cr2res_get_base_name();
957 test_cr2res_get_root_name();
958 test_cr2res_extract_frameset();
959 test_cr2res_convert_array_to_poly();
960 test_cr2res_convert_poly_to_array();
961 test_cr2res_detector_shotnoise_model();
962 test_cr2res_get_license();
963 test_cr2res_fit_interorder();
964 test_cr2res_slit_pos();
965 test_cr2res_slit_pos_img();
966 test_cr2res_slit_curv_compute_order_trace();
967 test_cr2res_optimal_filter_2d();
968 test_cr2res_polyfit_2d();
969
970 return cpl_test_end(0);
971}
972
int cr2res_slit_curv_compute_order_trace(const hdrl_image *img, const cpl_table *trace_wave, const int order, const int trace, const int height, const int window, const cpl_size change_degree, const int slit_degree, cpl_polynomial **slit_poly_a, cpl_polynomial **slit_poly_b, cpl_polynomial **slit_poly_c)
Get the slit curvature directly from the image.
int main(void)
Run the Unit tests.
cpl_image * cr2res_image_cut_rectify(const cpl_image *img_in, const cpl_vector *ycen, int height)
Cut a bent order into a rectangle, shifting columns.
Definition: cr2res_utils.c:907
int * cr2res_vector_get_int(const cpl_vector *ycen)
Definition: cr2res_utils.c:230
cpl_error_code cr2res_detector_shotnoise_model(const cpl_image *ima_data, const double gain, const double ron, cpl_image **ima_errs)
compute photon count error in [ADU]
cpl_polynomial * cr2res_fit_interorder(cpl_image *img, cpl_table *trace_wave, cpl_size order_x, cpl_size order_y)
Fit a 2D Polynomial to the interorder regions.
Definition: cr2res_utils.c:461
cpl_polynomial * cr2res_convert_array_to_poly(const cpl_array *arr)
Convert an array to polynomial.
cpl_vector * cr2res_threshold_spec(const cpl_vector *invector, int smooth, double thresh)
Find the regions with over-average values in a vector.
double * cr2res_vector_get_rest(const cpl_vector *ycen)
Definition: cr2res_utils.c:253
cpl_vector * cr2res_polynomial_eval_vector(const cpl_polynomial *poly, const cpl_vector *vec)
Evaluate a polynomial on a vector.
cpl_array * cr2res_convert_poly_to_array(const cpl_polynomial *poly, int size)
Convert a polynomial to array.
cpl_image * cr2res_util_optimal_filter_2d(const cpl_image *img, const cpl_image *weight, double lam_x, double lam_y)
Apply the optimal filter in the 2D case.
char * cr2res_get_root_name(const char *filename)
Find out the root part of a basename (name without extension).
int cr2res_slit_pos_image(const cpl_table *trace_wave, cpl_image **slitpos, cpl_image **wavelength)
get a image of the slitposition (and wavelength) along the slit
Definition: cr2res_utils.c:841
int cr2res_slit_pos(const cpl_table *trace_wave, cpl_polynomial ***coef_slit, cpl_polynomial ***coef_wave, int *size)
Create the polynomials needed to calculate the slit pos and wavelength at any point x,...
Definition: cr2res_utils.c:627
cpl_frameset * cr2res_extract_frameset(const cpl_frameset *in, const char *tag)
Extract the frames with the given tag from a frameset.
int cr2res_image_insert_rect(const cpl_image *rect_in, const cpl_vector *ycen, cpl_image *img_out)
Re-insert a rectangular cut-out of an order into the full frame.
Definition: cr2res_utils.c:984
char * cr2res_get_base_name(const char *filename)
Find out the base name of a file (i.e. without prefix path)
const char * cr2res_get_license(void)
Get the pipeline copyright and license.
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
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379