UVES Pipeline Reference Manual  5.4.0
irplib_utils-test.c
1 /* *
2  * This file is part of the ESO IRPLIB package *
3  * Copyright (C) 2004,2005 European Southern Observatory *
4  * *
5  * This library 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, 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 <irplib_utils.h>
29 #include <string.h>
30 #include <float.h>
31 #include <stdint.h>
32 
33 /*-----------------------------------------------------------------------------
34  Function prototypes
35  -----------------------------------------------------------------------------*/
36 
37 static IRPLIB_UTIL_SET_ROW(my_table_set_row);
38 static IRPLIB_UTIL_CHECK(my_table_check);
39 
40 static void test_irplib_image_split(void);
41 static void test_irplib_dfs_table_convert(void);
42 static void test_irplib_isnaninf(void);
43 static void bench_irplib_image_split(int, int);
44 static void frameset_sort_test(int sz);
45 static void test_irplib_aligned_alloc(void);
46 
47 /*----------------------------------------------------------------------------*/
51 /*----------------------------------------------------------------------------*/
52 
53 
54 /*----------------------------------------------------------------------------*/
58 /*----------------------------------------------------------------------------*/
59 
60 int main(void)
61 {
62  /* Initialize CPL for unit testing */
63  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
64 
65  test_irplib_isnaninf();
66 
67  test_irplib_dfs_table_convert();
68 
69  test_irplib_image_split();
70 
71  frameset_sort_test(122); /* test even */
72  frameset_sort_test(127); /* test odd */
73 
74  test_irplib_aligned_alloc();
75 
76  if (cpl_msg_get_level() <= CPL_MSG_INFO) {
77  bench_irplib_image_split(1024, 100);
78  } else {
79  bench_irplib_image_split(64, 1);
80  }
81 
82  return cpl_test_end(0);
83 }
84 
85 
86 /*----------------------------------------------------------------------------*/
91 /*----------------------------------------------------------------------------*/
92 static void test_irplib_isnaninf(void)
93 {
94  double infinity = DBL_MAX * DBL_MAX;
95  double number[] = {17, 0};
96 
97  /* The computation oo/oo must result in NaN according to
98  the IEEE 754 standard. However, some GCC 4.x versions erroneously
99  optimize this to 1.
100 
101  Alternatively, a NaN could be produced using a IEEE 754 defined bit
102  pattern. But that is likely to depend on the machine's word size.
103  Therefore this test is disabled.
104 
105  double not_a_number = infinity / infinity;
106  */
107 
108  cpl_test_zero(irplib_isnan(infinity) );
109  /* cpl_test( irplib_isnan(not_a_number) ); */
110  cpl_test_zero(irplib_isnan(number[0]) );
111  cpl_test_zero(irplib_isnan(number[1]) );
112 
113  cpl_test( irplib_isinf(infinity) );
114  /* cpl_test_zero(irplib_isinf(not_a_number) ); */
115  cpl_test_zero(irplib_isinf(number[0]) );
116  cpl_test_zero(irplib_isinf(number[1]) );
117 
118  return;
119 }
120 
121 
122 static void test_irplib_aligned_alloc(void)
123 {
124  void * ptr = NULL;
125  size_t alignment[] = {2, 4, 8, 16, 32, 64, 128, 4096};
126  char zero[100] = {0};
127  size_t i;
128 
129  for (i = 0; i < sizeof(alignment)/sizeof(alignment[0]); i++) {
130  ptr = irplib_aligned_malloc(alignment[i], 100);
131  cpl_test_nonnull(ptr);
132  cpl_test_error(CPL_ERROR_NONE);
133  cpl_test_eq(((intptr_t)ptr % alignment[i]), 0);
134  irplib_aligned_free(ptr);
135  cpl_test_error(CPL_ERROR_NONE);
136  }
137  /* invalid alignment */
138  ptr = irplib_aligned_malloc(5, 100);
139  cpl_test_null(ptr);
140  irplib_aligned_free(NULL);
141 
142  for (i = 0; i < sizeof(alignment)/sizeof(alignment[0]); i++) {
143  ptr = irplib_aligned_calloc(alignment[i], 100, 1);
144  cpl_test_nonnull(ptr);
145  cpl_test_error(CPL_ERROR_NONE);
146  cpl_test_eq(((intptr_t)ptr % alignment[i]), 0);
147  cpl_test_eq(memcmp(ptr, zero, 100), 0);
148  irplib_aligned_free(ptr);
149  cpl_test_error(CPL_ERROR_NONE);
150  }
151  /* invalid alignment */
152  ptr = irplib_aligned_calloc(5, 100, 1);
153  cpl_test_null(ptr);
154  irplib_aligned_free(NULL);
155 }
156 
157 
158 static cpl_boolean my_table_set_row(cpl_table * self,
159  const char * line,
160  int irow,
161  const cpl_frame * rawframe,
162  const cpl_parameterlist * parlist)
163 {
164 
165  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
166  cpl_ensure(line != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
167  cpl_ensure(irow >= 0, CPL_ERROR_ILLEGAL_INPUT, CPL_FALSE);
168  cpl_ensure(rawframe != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
169  cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
170 
171  return CPL_TRUE;
172 
173 }
174 
175 static cpl_error_code my_table_check(cpl_table * self,
176  const cpl_frameset * useframes,
177  const cpl_parameterlist * parlist)
178 {
179 
180  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
181  cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
182  cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
183 
184  return CPL_ERROR_NONE;
185 
186 }
187 
188 
189 /*----------------------------------------------------------------------------*/
195 /*----------------------------------------------------------------------------*/
196 static void test_irplib_dfs_table_convert(void)
197 {
198 
199  /* FIXME: Room for improvement... */
200  cpl_error_code error
201  = irplib_dfs_table_convert(NULL, NULL, NULL, 1024, '#',
202  NULL, NULL, NULL, NULL, NULL, NULL,
203  NULL, NULL, NULL, my_table_set_row,
204  my_table_check);
205 
206  cpl_test_eq_error(error, CPL_ERROR_NULL_INPUT);
207 
208  error =
209  irplib_table_read_from_frameset(NULL, NULL, 1024, '#', NULL,
210  my_table_set_row);
211 
212  cpl_test_eq_error(error, CPL_ERROR_NULL_INPUT);
213 }
214 
215 
216 /*----------------------------------------------------------------------------*/
222 /*----------------------------------------------------------------------------*/
223 static void bench_irplib_image_split(int nxy, int nsplit) {
224 
225  const double th_low = 0.0;
226  const double th_high = 50.0;
227  const double alt_low = th_low - 1.0;
228  const double alt_high = th_high + 1.0;
229  cpl_image * test = cpl_image_new(nxy, nxy, CPL_TYPE_FLOAT);
230  double tsum = 0.0;
231  int i;
232 
233  for (i = 0; i < nsplit; i++) {
234  double time1;
235  const double time0 = cpl_test_get_cputime();
236  const cpl_error_code error =
237  irplib_image_split(test, NULL, test, NULL,
238  th_low, CPL_TRUE, th_high, CPL_TRUE,
239  alt_low, alt_high,
240  CPL_TRUE, CPL_FALSE, CPL_TRUE);
241  time1 = cpl_test_get_cputime();
242 
243  cpl_test_eq_error(error, CPL_ERROR_NONE);
244 
245  if (time1 > time0) tsum += time1 - time0;
246  }
247 
248  cpl_msg_info(cpl_func,"Time to split with image size %d [ms]: %g", nxy,
249  1e3*tsum/nsplit);
250 
251  cpl_image_delete(test);
252 
253 }
254 
255 
256 /*----------------------------------------------------------------------------*/
262 /*----------------------------------------------------------------------------*/
263 static void test_irplib_image_split(void) {
264 
265  const double th_low = 0.0;
266  const double th_high = 50.0;
267  const double alt_low = th_low - 1.0;
268  const double alt_high = th_high + 1.0;
269 
270  cpl_image * test = cpl_image_new(100, 100, CPL_TYPE_DOUBLE);
271  cpl_image * result = cpl_image_new(100, 100, CPL_TYPE_DOUBLE);
272 
273  /* Various error conditions */
274  cpl_error_code error
275  = irplib_image_split(NULL, test, result, test,
276  0.0, CPL_FALSE, 0.0, CPL_FALSE,
277  0.0, 0.0,
278  CPL_FALSE, CPL_FALSE, CPL_FALSE);
279  cpl_test_eq_error(error, CPL_ERROR_NULL_INPUT);
280 
281 
282  error = irplib_image_split(test, NULL, NULL, NULL,
283  th_low, CPL_TRUE, th_high, CPL_TRUE,
284  alt_low, alt_high,
285  CPL_TRUE, CPL_FALSE, CPL_TRUE);
286  cpl_test_eq_error(error, CPL_ERROR_NULL_INPUT);
287 
288  error = irplib_image_split(test, NULL, result, NULL,
289  th_low, CPL_TRUE, alt_low, CPL_TRUE,
290  alt_low, alt_high,
291  CPL_TRUE, CPL_FALSE, CPL_TRUE);
292 
293  cpl_test_eq_error(error, CPL_ERROR_ILLEGAL_INPUT);
294 
295  /* Verify against cpl_image_threshold() */
296  error = cpl_image_fill_noise_uniform(test, -100.0, 100.0);
297  cpl_test_eq_error(error, CPL_ERROR_NONE);
298 
299  error = irplib_image_split(test, NULL, result, NULL,
300  th_low, CPL_TRUE, th_high, CPL_TRUE,
301  alt_low, alt_high,
302  CPL_TRUE, CPL_FALSE, CPL_TRUE);
303  cpl_test_eq_error(error, CPL_ERROR_NONE);
304 
305  error = cpl_image_threshold(test, th_low, th_high, alt_low, alt_high);
306  cpl_test_eq_error(error, CPL_ERROR_NONE);
307 
308  error = cpl_image_subtract(result, test);
309  cpl_test_eq_error(error, CPL_ERROR_NONE);
310 
311  cpl_test_leq(cpl_image_get_absflux(result), DBL_EPSILON);
312 
313  cpl_image_delete(test);
314  cpl_image_delete(result);
315 
316 }
317 
318 static void frameset_sort_test(int sz)
319 {
320  /* 1. create a test frameset - each frame should contain EXPTIME property */
321  cpl_frameset * pframeset = cpl_frameset_new();
322  int * idx = cpl_malloc(sz * sizeof(*idx));
323  double * exptime = cpl_malloc(sz * sizeof(*exptime));
324  cpl_error_code error;
325  int i;
326 
327  cpl_test_nonnull(pframeset);
328 
329  for (i = 0; i < sz; i++) {
330  cpl_frame * pframe = cpl_frame_new();
331  cpl_propertylist * plist = cpl_propertylist_new();
332  char * filename = cpl_sprintf("dummyon%d.fits", i);
333  const double value = (i % 2) > 0 ? i : sz - i - 1;
334 
335 
336  cpl_test_nonnull(pframe);
337  /* assign exptime; */
338  error = cpl_frame_set_filename(pframe, filename);
339  cpl_test_eq_error(error, CPL_ERROR_NONE);
340  error = cpl_frame_set_tag(pframe, "ON");
341  cpl_test_eq_error(error, CPL_ERROR_NONE);
342  error = cpl_frame_set_type(pframe, CPL_FRAME_TYPE_IMAGE);
343  cpl_test_eq_error(error, CPL_ERROR_NONE);
344  error = cpl_frame_set_group(pframe, CPL_FRAME_GROUP_RAW);
345  cpl_test_eq_error(error, CPL_ERROR_NONE);
346 
347  error = cpl_frameset_insert(pframeset, pframe);
348  cpl_test_eq_error(error, CPL_ERROR_NONE);
349  error = cpl_propertylist_append_double(plist, "EXPTIME", value);
350  cpl_test_eq_error(error, CPL_ERROR_NONE);
351  error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
352  cpl_test_eq_error(error, CPL_ERROR_NONE);
353 
354  cpl_propertylist_delete(plist);
355  cpl_free(filename);
356  }
357 
358  error = irplib_frameset_sort(pframeset, idx, exptime);
359  cpl_test_eq_error(error, CPL_ERROR_NONE);
360 
361  for (i = 0; i < sz; i++) {
362  int k = i + 1 - (sz % 2);
363  int j = sz -i - 1 ;
364  cpl_test_eq(idx[i], (((i + (sz % 2)) % 2) == 0 ? k : j));
365  }
366 
367  cpl_free(idx);
368  cpl_free(exptime);
369  cpl_frameset_delete(pframeset);
370  cpl_test_zero(system("rm *.fits"));
371 }