NACO Pipeline Reference Manual  4.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_table_read_from_frameset(void);
43 static void test_irplib_isnaninf(void);
44 static void bench_irplib_image_split(int, int);
45 static void frameset_sort_test(int sz);
46 static void test_irplib_aligned_alloc(void);
47 
48 /*----------------------------------------------------------------------------*/
52 /*----------------------------------------------------------------------------*/
53 
54 
55 /*----------------------------------------------------------------------------*/
59 /*----------------------------------------------------------------------------*/
60 
61 int main(void)
62 {
63  /* Initialize CPL for unit testing */
64  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
65 
66  test_irplib_isnaninf();
67 
68  test_irplib_dfs_table_convert();
69  test_irplib_table_read_from_frameset();
70 
71  test_irplib_image_split();
72 
73  frameset_sort_test(122); /* test even */
74  frameset_sort_test(127); /* test odd */
75 
76  test_irplib_aligned_alloc();
77 
78  if (cpl_msg_get_level() <= CPL_MSG_INFO) {
79  bench_irplib_image_split(1024, 100);
80  } else {
81  bench_irplib_image_split(64, 1);
82  }
83 
84  return cpl_test_end(0);
85 }
86 
87 
88 /*----------------------------------------------------------------------------*/
93 /*----------------------------------------------------------------------------*/
94 static void test_irplib_isnaninf(void)
95 {
96  double infinity = DBL_MAX * DBL_MAX;
97  double number[] = {17, 0};
98 
99  /* The computation oo/oo must result in NaN according to
100  the IEEE 754 standard. However, some GCC 4.x versions erroneously
101  optimize this to 1.
102 
103  Alternatively, a NaN could be produced using a IEEE 754 defined bit
104  pattern. But that is likely to depend on the machine's word size.
105  Therefore this test is disabled.
106 
107  double not_a_number = infinity / infinity;
108  */
109 
110  cpl_test_zero(irplib_isnan(infinity) );
111  /* cpl_test( irplib_isnan(not_a_number) ); */
112  cpl_test_zero(irplib_isnan(number[0]) );
113  cpl_test_zero(irplib_isnan(number[1]) );
114 
115  cpl_test( irplib_isinf(infinity) );
116  /* cpl_test_zero(irplib_isinf(not_a_number) ); */
117  cpl_test_zero(irplib_isinf(number[0]) );
118  cpl_test_zero(irplib_isinf(number[1]) );
119 
120  return;
121 }
122 
123 
124 static void test_irplib_aligned_alloc(void)
125 {
126  void * ptr = NULL;
127  size_t alignment[] = {2, 4, 8, 16, 32, 64, 128, 4096};
128  char zero[100] = {0};
129  size_t i;
130 
131  for (i = 0; i < sizeof(alignment)/sizeof(alignment[0]); i++) {
132  ptr = irplib_aligned_malloc(alignment[i], 100);
133  cpl_test_nonnull(ptr);
134  cpl_test_error(CPL_ERROR_NONE);
135  cpl_test_eq(((intptr_t)ptr % alignment[i]), 0);
136  irplib_aligned_free(ptr);
137  cpl_test_error(CPL_ERROR_NONE);
138  }
139  /* invalid alignment */
140  ptr = irplib_aligned_malloc(5, 100);
141  cpl_test_null(ptr);
142  irplib_aligned_free(NULL);
143 
144  for (i = 0; i < sizeof(alignment)/sizeof(alignment[0]); i++) {
145  ptr = irplib_aligned_calloc(alignment[i], 100, 1);
146  cpl_test_nonnull(ptr);
147  cpl_test_error(CPL_ERROR_NONE);
148  cpl_test_eq(((intptr_t)ptr % alignment[i]), 0);
149  cpl_test_eq(memcmp(ptr, zero, 100), 0);
150  irplib_aligned_free(ptr);
151  cpl_test_error(CPL_ERROR_NONE);
152  }
153  /* invalid alignment */
154  ptr = irplib_aligned_calloc(5, 100, 1);
155  cpl_test_null(ptr);
156  irplib_aligned_free(NULL);
157 }
158 
159 
160 static cpl_boolean my_table_set_row(cpl_table * self,
161  const char * line,
162  int irow,
163  const cpl_frame * rawframe,
164  const cpl_parameterlist * parlist)
165 {
166  char str[32] = "";
167  double val = 0.0;
168 
169  cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
170  cpl_ensure(line != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
171  cpl_ensure(irow >= 0, CPL_ERROR_ILLEGAL_INPUT, CPL_FALSE);
172  cpl_ensure(rawframe != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
173  cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
174 
175  cpl_test_assert(sscanf(line, "%31s %lf", &str[0], &val) != EOF);
176 
177  cpl_test_assert(cpl_table_set_string(self, "MYLABEL1", (cpl_size)irow, str)
178  == CPL_ERROR_NONE);
179  cpl_test_assert(cpl_table_set_double(self, "MYLABEL2", (cpl_size)irow, val)
180  == CPL_ERROR_NONE);
181 
182  return CPL_TRUE;
183 
184 }
185 
186 static cpl_error_code my_table_check(cpl_table * self,
187  const cpl_frameset * useframes,
188  const cpl_parameterlist * parlist)
189 {
190 
191  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
192  cpl_ensure_code(useframes != NULL, CPL_ERROR_NULL_INPUT);
193  cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
194 
195  return CPL_ERROR_NONE;
196 
197 }
198 
199 
200 /*----------------------------------------------------------------------------*/
206 /*----------------------------------------------------------------------------*/
207 static void test_irplib_dfs_table_convert(void)
208 {
209 
210  /* FIXME: Room for improvement... */
211  cpl_error_code error
212  = irplib_dfs_table_convert(NULL, NULL, NULL, 1024, '#',
213  NULL, NULL, NULL, NULL, NULL, NULL,
214  NULL, NULL, NULL, my_table_set_row,
215  my_table_check);
216 
217  cpl_test_eq_error(error, CPL_ERROR_NULL_INPUT);
218 }
219 
220 
221 /*----------------------------------------------------------------------------*/
227 /*----------------------------------------------------------------------------*/
228 static void test_irplib_table_read_from_frameset(void)
229 {
230  cpl_size initial_failed = cpl_test_get_failed();
231  cpl_error_code error;
232  FILE * file;
233  const char * filename1 = "dummy_input_file_for_irplib_utils_test_1.txt";
234  const char * filename2 = "dummy_input_file_for_irplib_utils_test_2.txt";
235  const int expected_rows = 5;
236  cpl_table * self;
237  cpl_parameterlist * parlist = cpl_parameterlist_new();
238  cpl_frameset * useframes = cpl_frameset_new();
239  cpl_frame * frame;
240 
241  cpl_test_nonnull(parlist);
242  cpl_test_nonnull(useframes);
243 
244  error =
245  irplib_table_read_from_frameset(NULL, NULL, 1024, '#', NULL,
246  my_table_set_row);
247 
248  cpl_test_eq_error(error, CPL_ERROR_NULL_INPUT);
249 
250  /* Test similar example as indicated in the documentation comments of
251  * irplib_table_read_from_frameset.
252  * First we need to generate some dummy input files and add their names to
253  * the frameset. */
254  file = fopen(filename1, "w");
255  cpl_test_nonnull(file);
256  cpl_test(fprintf(file, "abc 1.2\nde 4.3\nfhij 5.6\n") >= 0);
257  (void) fclose(file);
258  file = fopen(filename2, "w");
259  cpl_test_nonnull(file);
260  cpl_test(fprintf(file, "klm -7.8\nnopq 9\n") >= 0);
261  (void) fclose(file);
262 
263  frame = cpl_frame_new();
264  cpl_test_nonnull(frame);
265  cpl_test_eq_error(cpl_frame_set_filename(frame, filename1), CPL_ERROR_NONE);
266  cpl_test_eq_error(cpl_frame_set_tag(frame, "TEXT"), CPL_ERROR_NONE);
267  cpl_test_eq_error(cpl_frame_set_type(frame, CPL_FRAME_TYPE_ANY),
268  CPL_ERROR_NONE);
269  cpl_test_eq_error(cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW),
270  CPL_ERROR_NONE);
271  cpl_test_eq_error(cpl_frame_set_level(frame, CPL_FRAME_LEVEL_TEMPORARY),
272  CPL_ERROR_NONE);
273  cpl_test_eq_error(cpl_frameset_insert(useframes, frame), CPL_ERROR_NONE);
274  frame = cpl_frame_new();
275  cpl_test_nonnull(frame);
276  cpl_test_eq_error(cpl_frame_set_filename(frame, filename2), CPL_ERROR_NONE);
277  cpl_test_eq_error(cpl_frame_set_tag(frame, "TEXT"), CPL_ERROR_NONE);
278  cpl_test_eq_error(cpl_frame_set_type(frame, CPL_FRAME_TYPE_ANY),
279  CPL_ERROR_NONE);
280  cpl_test_eq_error(cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW),
281  CPL_ERROR_NONE);
282  cpl_test_eq_error(cpl_frame_set_level(frame, CPL_FRAME_LEVEL_TEMPORARY),
283  CPL_ERROR_NONE);
284  cpl_test_eq_error(cpl_frameset_insert(useframes, frame), CPL_ERROR_NONE);
285 
286  self = cpl_table_new(expected_rows);
287  cpl_test_nonnull(self);
288  cpl_table_new_column(self, "MYLABEL1", CPL_TYPE_STRING);
289  cpl_table_new_column(self, "MYLABEL2", CPL_TYPE_DOUBLE);
290  cpl_table_set_column_unit(self, "MYLABEL2", "Some_SI_Unit");
291 
292  error = irplib_table_read_from_frameset(self, useframes, 1024, '#', parlist,
293  my_table_set_row);
294  cpl_test_eq_error(error, CPL_ERROR_NONE);
295 
296  /* Check parsed table: */
297  cpl_test_eq(cpl_table_get_nrow(self), expected_rows);
298  cpl_test_eq_string(cpl_table_get_string(self, "MYLABEL1", 0), "abc");
299  cpl_test_eq_string(cpl_table_get_string(self, "MYLABEL1", 1), "de");
300  cpl_test_eq_string(cpl_table_get_string(self, "MYLABEL1", 2), "fhij");
301  cpl_test_eq_string(cpl_table_get_string(self, "MYLABEL1", 3), "klm");
302  cpl_test_eq_string(cpl_table_get_string(self, "MYLABEL1", 4), "nopq");
303  cpl_test_abs(cpl_table_get_double(self, "MYLABEL2", 0, NULL),
304  1.2, DBL_EPSILON);
305  cpl_test_abs(cpl_table_get_double(self, "MYLABEL2", 1, NULL),
306  4.3, DBL_EPSILON);
307  cpl_test_abs(cpl_table_get_double(self, "MYLABEL2", 2, NULL),
308  5.6, DBL_EPSILON);
309  cpl_test_abs(cpl_table_get_double(self, "MYLABEL2", 3, NULL),
310  -7.8, DBL_EPSILON);
311  cpl_test_abs(cpl_table_get_double(self, "MYLABEL2", 4, NULL),
312  9.0, DBL_EPSILON);
313 
314  cpl_table_delete(self);
315  cpl_parameterlist_delete(parlist);
316  cpl_frameset_delete(useframes);
317 
318  /* Delete dummy input files if none of these unit tests failed. */
319  if (cpl_test_get_failed() == initial_failed) {
320  (void) remove(filename1);
321  (void) remove(filename2);
322  }
323 }
324 
325 
326 /*----------------------------------------------------------------------------*/
332 /*----------------------------------------------------------------------------*/
333 static void bench_irplib_image_split(int nxy, int nsplit) {
334 
335  const double th_low = 0.0;
336  const double th_high = 50.0;
337  const double alt_low = th_low - 1.0;
338  const double alt_high = th_high + 1.0;
339  cpl_image * test = cpl_image_new(nxy, nxy, CPL_TYPE_FLOAT);
340  double tsum = 0.0;
341  int i;
342 
343  for (i = 0; i < nsplit; i++) {
344  double time1;
345  const double time0 = cpl_test_get_cputime();
346  const cpl_error_code error =
347  irplib_image_split(test, NULL, test, NULL,
348  th_low, CPL_TRUE, th_high, CPL_TRUE,
349  alt_low, alt_high,
350  CPL_TRUE, CPL_FALSE, CPL_TRUE);
351  time1 = cpl_test_get_cputime();
352 
353  cpl_test_eq_error(error, CPL_ERROR_NONE);
354 
355  if (time1 > time0) tsum += time1 - time0;
356  }
357 
358  cpl_msg_info(cpl_func,"Time to split with image size %d [ms]: %g", nxy,
359  1e3*tsum/nsplit);
360 
361  cpl_image_delete(test);
362 
363 }
364 
365 
366 /*----------------------------------------------------------------------------*/
372 /*----------------------------------------------------------------------------*/
373 static void test_irplib_image_split(void) {
374 
375  const double th_low = 0.0;
376  const double th_high = 50.0;
377  const double alt_low = th_low - 1.0;
378  const double alt_high = th_high + 1.0;
379 
380  cpl_image * test = cpl_image_new(100, 100, CPL_TYPE_DOUBLE);
381  cpl_image * result = cpl_image_new(100, 100, CPL_TYPE_DOUBLE);
382 
383  /* Various error conditions */
384  cpl_error_code error
385  = irplib_image_split(NULL, test, result, test,
386  0.0, CPL_FALSE, 0.0, CPL_FALSE,
387  0.0, 0.0,
388  CPL_FALSE, CPL_FALSE, CPL_FALSE);
389  cpl_test_eq_error(error, CPL_ERROR_NULL_INPUT);
390 
391 
392  error = irplib_image_split(test, NULL, NULL, NULL,
393  th_low, CPL_TRUE, th_high, CPL_TRUE,
394  alt_low, alt_high,
395  CPL_TRUE, CPL_FALSE, CPL_TRUE);
396  cpl_test_eq_error(error, CPL_ERROR_NULL_INPUT);
397 
398  error = irplib_image_split(test, NULL, result, NULL,
399  th_low, CPL_TRUE, alt_low, CPL_TRUE,
400  alt_low, alt_high,
401  CPL_TRUE, CPL_FALSE, CPL_TRUE);
402 
403  cpl_test_eq_error(error, CPL_ERROR_ILLEGAL_INPUT);
404 
405  /* Verify against cpl_image_threshold() */
406  error = cpl_image_fill_noise_uniform(test, -100.0, 100.0);
407  cpl_test_eq_error(error, CPL_ERROR_NONE);
408 
409  error = irplib_image_split(test, NULL, result, NULL,
410  th_low, CPL_TRUE, th_high, CPL_TRUE,
411  alt_low, alt_high,
412  CPL_TRUE, CPL_FALSE, CPL_TRUE);
413  cpl_test_eq_error(error, CPL_ERROR_NONE);
414 
415  error = cpl_image_threshold(test, th_low, th_high, alt_low, alt_high);
416  cpl_test_eq_error(error, CPL_ERROR_NONE);
417 
418  error = cpl_image_subtract(result, test);
419  cpl_test_eq_error(error, CPL_ERROR_NONE);
420 
421  cpl_test_leq(cpl_image_get_absflux(result), DBL_EPSILON);
422 
423  cpl_image_delete(test);
424  cpl_image_delete(result);
425 
426 }
427 
428 static void frameset_sort_test(int sz)
429 {
430  /* 1. create a test frameset - each frame should contain EXPTIME property */
431  cpl_frameset * pframeset = cpl_frameset_new();
432  int * idx = cpl_malloc(sz * sizeof(*idx));
433  double * exptime = cpl_malloc(sz * sizeof(*exptime));
434  cpl_error_code error;
435  int i;
436 
437  cpl_test_nonnull(pframeset);
438 
439  for (i = 0; i < sz; i++) {
440  cpl_frame * pframe = cpl_frame_new();
441  cpl_propertylist * plist = cpl_propertylist_new();
442  char * filename = cpl_sprintf("dummyon%d.fits", i);
443  const double value = (i % 2) > 0 ? i : sz - i - 1;
444 
445 
446  cpl_test_nonnull(pframe);
447  /* assign exptime; */
448  error = cpl_frame_set_filename(pframe, filename);
449  cpl_test_eq_error(error, CPL_ERROR_NONE);
450  error = cpl_frame_set_tag(pframe, "ON");
451  cpl_test_eq_error(error, CPL_ERROR_NONE);
452  error = cpl_frame_set_type(pframe, CPL_FRAME_TYPE_IMAGE);
453  cpl_test_eq_error(error, CPL_ERROR_NONE);
454  error = cpl_frame_set_group(pframe, CPL_FRAME_GROUP_RAW);
455  cpl_test_eq_error(error, CPL_ERROR_NONE);
456 
457  error = cpl_frameset_insert(pframeset, pframe);
458  cpl_test_eq_error(error, CPL_ERROR_NONE);
459  error = cpl_propertylist_append_double(plist, "EXPTIME", value);
460  cpl_test_eq_error(error, CPL_ERROR_NONE);
461  error = cpl_propertylist_save(plist, filename, CPL_IO_CREATE);
462  cpl_test_eq_error(error, CPL_ERROR_NONE);
463 
464  cpl_propertylist_delete(plist);
465  cpl_free(filename);
466  }
467 
468  error = irplib_frameset_sort(pframeset, idx, exptime);
469  cpl_test_eq_error(error, CPL_ERROR_NONE);
470 
471  for (i = 0; i < sz; i++) {
472  int k = i + 1 - (sz % 2);
473  int j = sz -i - 1 ;
474  cpl_test_eq(idx[i], (((i + (sz % 2)) % 2) == 0 ? k : j));
475  }
476 
477  cpl_free(idx);
478  cpl_free(exptime);
479  cpl_frameset_delete(pframeset);
480  cpl_test_zero(system("rm *.fits"));
481 }
cpl_error_code irplib_table_read_from_frameset(cpl_table *self, const cpl_frameset *useframes, int maxlinelen, char commentchar, const cpl_parameterlist *parlist, cpl_boolean(*table_set_row)(cpl_table *, const char *, int, const cpl_frame *, const cpl_parameterlist *))
Set the rows of a table with data from one or more (ASCII) files.
Definition: irplib_utils.c:989
cpl_error_code irplib_dfs_table_convert(cpl_table *self, cpl_frameset *allframes, const cpl_frameset *useframes, int maxlinelen, char commentchar, const char *product_name, const char *procatg, const cpl_parameterlist *parlist, const char *recipe_name, const cpl_propertylist *mainlist, const cpl_propertylist *extlist, const char *remregexp, const char *instrume, const char *pipe_id, cpl_boolean(*table_set_row)(cpl_table *, const char *, int, const cpl_frame *, const cpl_parameterlist *), cpl_error_code(*table_check)(cpl_table *, const cpl_frameset *, const cpl_parameterlist *))
Create a DFS product with one table from one or more (ASCII) file(s)
Definition: irplib_utils.c:860
int main(void)
Find a plugin and submit it to some tests.
Definition: recipe_main.c:61
cpl_error_code irplib_image_split(const cpl_image *self, cpl_image *im_low, cpl_image *im_mid, cpl_image *im_high, double th_low, cpl_boolean isleq_low, double th_high, cpl_boolean isgeq_high, double alt_low, double alt_high, cpl_boolean isbad_low, cpl_boolean isbad_mid, cpl_boolean isbad_high)
Split the values in an image in three according to two thresholds.
Definition: irplib_utils.c:665