33#include <cr2res_utils.h>
34#include <cr2res_dfs.h>
35#include <cr2res_trace.h>
36#include <cr2res_wave.h>
38#include <cr2res_slit_curv.h>
41#define localdir getenv("srcdir")
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);
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);
79static void test_cr2res_vector_get_int(
void)
83 cpl_vector *in = cpl_vector_new(n);
86 for (i = 0; i < n; i++)
90 cpl_vector_set(in, i, d + (d / (n + 1)));
97 for (i = 0; i < n; i++)
99 cpl_test_eq(i, res[i]);
102 cpl_vector_delete(in);
107static void test_cr2res_vector_get_rest(
void)
111 cpl_vector *in = cpl_vector_new(n);
112 cpl_vector *out = cpl_vector_new(n);
115 for (i = 0; i < n; i++)
119 cpl_vector_set(in, i, d + (d / (n + 1)));
120 cpl_vector_set(out, i, (d / (n + 1)));
126 cpl_vector_delete(in);
127 in = cpl_vector_wrap(n, res);
128 cpl_test_vector_abs(in, out, DBL_EPSILON * n);
130 cpl_vector_delete(in);
131 cpl_vector_delete(out);
135static void test_cr2res_image_cut_rectify(
void)
138 int imdata[] = {1, 2, 3, 2, 1,
142 cpl_image *img = cpl_image_wrap_int(5, 4, imdata);
143 cpl_image_flip(img, 0);
146 int cmpdata[] = {9, 9, 9, 9, 9};
147 cpl_image *cmp = cpl_image_wrap_int(5, 1, cmpdata);
149 double ydata[] = {1.9, 2.1, 3.5, 2.8, 3.99};
150 cpl_vector *ycen = cpl_vector_wrap(5, ydata);
160 cpl_test_image_abs(res, cmp, 0);
162 cpl_image_unwrap(img);
163 cpl_image_unwrap(cmp);
164 cpl_vector_unwrap(ycen);
165 cpl_image_delete(res);
169static void test_cr2res_image_insert_rect(
void)
171 int recdata[] = {1, 2, 3, 2, 1,
175 cpl_image *rect_in = cpl_image_wrap_int(5, 4, recdata);
176 cpl_image_flip(rect_in, 0);
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,
193 cpl_image *compare = cpl_image_wrap_int(5, 12, cmpdata);
194 cpl_image_flip(compare, 0);
202 if (cpl_msg_get_level() == CPL_MSG_DEBUG)
204 cpl_image_save(img_out,
"TEST_out.fits", CPL_TYPE_INT, NULL,
206 cpl_image_save(compare,
"TEST_cmp.fits", CPL_TYPE_INT, NULL,
211 cpl_test_image_abs(img_out, compare, 0);
213 cpl_image_unwrap(rect_in);
214 cpl_image_unwrap(compare);
215 cpl_vector_unwrap(ycen);
216 cpl_image_delete(img_out);
220static void test_cr2res_polynomial_eval_vector(
void)
224 double p0 = 1.1, p1 = 2.2, p2 = 3.3;
226 cpl_vector *in = cpl_vector_new(n);
227 cpl_vector *out = cpl_vector_new(n);
229 cpl_polynomial *poly = cpl_polynomial_new(1);
232 cpl_polynomial_set_coeff(poly, &power, p0);
234 cpl_polynomial_set_coeff(poly, &power, p1);
236 cpl_polynomial_set_coeff(poly, &power, p2);
238 for (i = 0; i < n; i++)
243 cpl_vector_set(in, i, d);
244 val = (p2 * d * d) + (p1 * d) + p0;
245 cpl_vector_set(out, i, val);
253 cpl_test_vector_abs(res, out, DBL_EPSILON * n * n * 10);
255 cpl_vector_delete(in);
256 cpl_vector_delete(out);
257 cpl_vector_delete(res);
258 cpl_polynomial_delete(poly);
274static void test_cr2res_threshold_spec(
void)
278 double data[] = {1., 2., 1., 5., 3., 1., 15., 2., 0., 1.};
279 cpl_vector *invector = cpl_vector_wrap(n, data);
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);
302 cpl_test_vector_abs(outvector, res, DBL_EPSILON * n * n * 10);
305 cpl_vector_unwrap(outvector);
306 cpl_vector_unwrap(invector);
307 cpl_vector_delete(res);
319static void test_cr2res_get_base_name(
void)
322 char *filename =
"./../tests/cr2res_trace-test.log";
330 cpl_test_eq_string(res,
"cr2res_trace-test.log");
340static void test_cr2res_get_root_name(
void)
344 char *filename =
"cr2res_trace-test.fits";
352 cpl_test_eq_string(res,
"cr2res_trace-test");
354#ifdef CR2RES_UNUSED_TESTS
361static void test_cr2res_extract_filename(
void)
364 cpl_frame *frame = cpl_frame_new();
365 cpl_frame_set_filename(frame,
"bla-test.log");
366 cpl_frame_set_tag(frame,
"test_correct");
368 cpl_frame *other = cpl_frame_new();
369 cpl_frame_set_filename(other,
"blub-test.log");
370 cpl_frame_set_tag(other,
"test_wrong");
372 cpl_frameset *in = cpl_frameset_new();
373 cpl_frameset_insert(in, other);
374 cpl_frameset_insert(in, frame);
376 char *tag =
"test_correct";
380 cpl_test_null(cr2res_extract_filename(NULL, tag));
381 cpl_test_null(cr2res_extract_filename(in, NULL));
383 cpl_test(res = cr2res_extract_filename(in, tag));
385 cpl_test_eq_string(res,
"bla-test.log");
388 cpl_frameset_delete(in);
402static void test_cr2res_extract_frameset(
void)
405 cpl_frame *frame = cpl_frame_new();
406 cpl_frame_set_filename(frame,
"bla-test.log");
407 cpl_frame_set_tag(frame,
"test_correct");
409 cpl_frame *other = cpl_frame_new();
410 cpl_frame_set_filename(other,
"blub-test.log");
411 cpl_frame_set_tag(other,
"test_wrong");
413 cpl_frameset *in = cpl_frameset_new();
414 cpl_frameset_insert(in, frame);
415 cpl_frameset_insert(in, other);
417 char *tag =
"test_correct";
427 cpl_test_eq(1, cpl_frameset_get_size(res));
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);
434 cpl_test_noneq_ptr(cpl_frameset_get_position(res, 0), frame);
438 cpl_frameset_delete(res);
439 cpl_frameset_delete(in);
446static void test_cr2res_convert_array_to_poly(
void)
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);
460 for (
int i = 0; i < n; i++) {
464 poly = cpl_polynomial_get_coeff(res, &power);
465 cpl_test_eq(data[i], poly);
469 cpl_polynomial_delete(res);
470 cpl_array_unwrap(arr);
478static void test_cr2res_convert_poly_to_array(
void)
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]);
496 for (
int j = 0; j < n; j++)
497 cpl_test_eq(cpl_array_get(res, j, NULL), data[j]);
500 cpl_polynomial_delete(poly);
501 cpl_array_delete(res);
509static void test_cr2res_detector_shotnoise_model(
void)
512 const double count = 1;
513 const double gain = 7;
514 const double ron = 3;
515 const double err = sqrt(count/gain + ron * ron);
519 cpl_image *ima_data = cpl_image_new(width, height, CPL_TYPE_INT);
520 cpl_image_add_scalar(ima_data, count);
522 cpl_image_set(ima_data, 1, 1, -1);
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);
531 cpl_test_eq(CPL_ERROR_NULL_INPUT,
533 cpl_test_error(CPL_ERROR_NULL_INPUT);
534 cpl_test_eq(CPL_ERROR_ILLEGAL_INPUT,
536 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
537 cpl_test_eq(CPL_ERROR_ILLEGAL_INPUT,
539 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
542 cpl_test_error(CPL_ERROR_NULL_INPUT);
547 cpl_test_image_abs(ima_errs, compare, 0);
550 cpl_image_delete(ima_data);
551 cpl_image_delete(ima_errs);
552 cpl_image_delete(compare);
555static cpl_table *create_test_table()
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);
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};
576 cpl_array * array = cpl_array_new(poly_order, CPL_TYPE_DOUBLE);
577 for (
int i = 0; i < n_orders; i++)
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);
592 cpl_array_delete(array);
596static cpl_image *create_test_image()
598 char *my_path = cpl_sprintf(
"%s/cr2res_utils_test_image.fits",
600 cpl_image *img = cpl_image_load(my_path, CPL_TYPE_INT, 0, 1);
610static void test_cr2res_fit_interorder(
void)
613 cpl_image *img = create_test_image();
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};
634 cpl_polynomial_set_coeff(cmp, power, 25.1533);
636 cpl_polynomial_set_coeff(cmp, power, 0.245861);
638 cpl_polynomial_set_coeff(cmp, power, -0.000952474);
641 cpl_polynomial_set_coeff(cmp, power, 0.519612);
648 cpl_test_polynomial_abs(res, cmp, 1e-4);
651 cpl_table_delete(trace_wave);
652 cpl_polynomial_delete(res);
653 cpl_polynomial_delete(cmp);
654 cpl_image_delete(img);
663static void test_cr2res_slit_pos()
667 char *my_path = cpl_sprintf(
"%s/cr2res_util_calib_calibrated_collapsed_extr1D_tw.fits",
669 cpl_table *tw_decker1 = cpl_table_load(my_path, chip, 0);
673 cpl_polynomial ** coef_slit = NULL;
674 cpl_polynomial ** coef_wave = NULL;
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));
683 cpl_test_eq(0,
cr2res_slit_pos(tw_decker1, &coef_slit, &coef_wave, &nb_orders));
686 cpl_test_nonnull(coef_slit);
687 cpl_test_nonnull(coef_wave);
688 cpl_test_noneq(0, nb_orders);
690 for (
int i = 0; i < nb_orders; i++){
691 cpl_test_nonnull(coef_slit[i]);
692 cpl_test_nonnull(coef_wave[i]);
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]);
703 if (coef_slit != NULL){
704 for (
int i=0; i < nb_orders; i++){
705 cpl_polynomial_delete(coef_slit[i]);
716static void test_cr2res_slit_pos_img()
720 cpl_sprintf(
"%s/cr2res_util_calib_calibrated_collapsed_extr1D_tw.fits",
722 cpl_table *tw_decker1 = cpl_table_load(my_path, chip, 0);
724 cpl_image * slitpos = NULL;
725 cpl_image * wavelength = NULL;
736 cpl_test_nonnull(slitpos);
737 cpl_test_nonnull(wavelength);
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));
742 cpl_test_leq(cpl_image_get_max(slitpos), 1);
743 cpl_test_leq(-cpl_image_get_min(slitpos), 0);
745 cpl_test_leq(-cpl_image_get_min(wavelength), 0);
746 cpl_test_leq(cpl_image_get_max(wavelength), 1500);
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);
757 cpl_table_delete(tw_decker1);
758 if (slitpos != NULL) cpl_image_delete(slitpos);
759 if (wavelength != NULL) cpl_image_delete(wavelength);
762static cpl_image * load_etalon_image(){
763 char * path = cpl_sprintf(
"%s/cr2res_slit_curv_test.fits",
765 cpl_image * img = cpl_image_load(path, CPL_TYPE_INT, 0, 1);
770static cpl_table * load_etalon_table(){
771 char * path = cpl_sprintf(
"%s/cr2res_slit_curv_test_tw.fits",
773 cpl_table * trace_wave = cpl_table_load(path, 1, 0);
778static void test_cr2res_slit_curv_compute_order_trace(){
780 hdrl_image * img_hdrl;
781 cpl_image * img_in = load_etalon_image();
782 cpl_table * trace_wave = load_etalon_table();
784 cpl_polynomial * poly_a = NULL;
785 cpl_polynomial * poly_b = NULL;
786 cpl_polynomial * poly_c = NULL;
801 order, trace, height, window, degree, fit_c,
802 &poly_a, &poly_b, &poly_c);
803 cpl_test_eq(0, result);
806 cpl_polynomial_dump(poly_a, stderr);
807 cpl_polynomial_dump(poly_b, stderr);
808 cpl_polynomial_dump(poly_c, stderr);
811 cpl_image_delete(img_in);
813 cpl_table_delete(trace_wave);
815 cpl_polynomial_delete(poly_a);
816 cpl_polynomial_delete(poly_b);
817 cpl_polynomial_delete(poly_c);
820static void test_cr2res_optimal_filter_2d(
void)
825 double lam_x = 1, lam_y = 1;
830 img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
831 weight = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
833 for (cpl_size i = 1; i <= nx; i++)
835 for (cpl_size j = 1; j <= ny; j++)
837 cpl_image_set(img, i, j, 10);
838 cpl_image_set(weight, i, j, 1);
845 cpl_image_save(model,
"TEST_optimal_filter.fits",
846 CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
848 cpl_image_delete(img);
849 cpl_image_delete(weight);
850 cpl_image_delete(model);
868static void test_cr2res_polyfit_2d(
void)
870 cpl_vector *x, *y, *z;
871 cpl_polynomial * poly;
873 cpl_size npoints = 5 * 5;
874 cpl_size ngrid = npoints * npoints;
879 x = cpl_vector_new(ngrid);
880 y = cpl_vector_new(ngrid);
881 z = cpl_vector_new(ngrid);
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);
901 cpl_test_nonnull(poly = cr2res_polyfit_2d(x, y, z, degree));
904 cpl_test_eq(cpl_polynomial_get_dimension(poly), 2);
908 cpl_test_abs(cpl_polynomial_get_coeff(poly, power), 1, 0.00001);
912 cpl_test_abs(cpl_polynomial_get_coeff(poly, power), 1, 0.00001);
916 cpl_test_abs(cpl_polynomial_get_coeff(poly, power), 2, 0.00001);
919 cpl_vector_delete(x);
920 cpl_vector_delete(y);
921 cpl_vector_delete(z);
922 cpl_polynomial_delete(poly);
934static void test_cr2res_get_license(
void)
948 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_DEBUG);
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();
970 return cpl_test_end(0);
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.
int * cr2res_vector_get_int(const cpl_vector *ycen)
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.
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)
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
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,...
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.
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
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image