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