CR2RE Pipeline Reference Manual 1.7.0
hdrl_persistence-test.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2017 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 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24
25/*-----------------------------------------------------------------------------
26 Includes
27 -----------------------------------------------------------------------------*/
28
29#include "hdrl.h"
30#include <math.h>
31#include <cpl.h>
32#include "hdrl_persistence.c"
33
34
35#if 0
36static cpl_error_code get_error_and_reset(void){
37 cpl_error_code r = cpl_error_get_code();
38 cpl_error_reset();
39 return r;
40}
41#endif
42
43/*-----------------------------------------------------------------------------
44 Define
45 -----------------------------------------------------------------------------*/
46//#define cpl_ensure_no_error cpl_test_eq(get_error_and_reset(), CPL_ERROR_NONE);
47#define ARRAY_LEN(a) (sizeof((a))/sizeof((a)[0]))
48
49#if 0
50static void
51test_example(void) {
52
53 /* Below some example to verify results */
54 cpl_frame* frm = cpl_frame_new();
55 cpl_ensure_no_error; //one way to test no error
56 cpl_test_error(CPL_ERROR_NONE); //another way to test no error
57 cpl_test_nonnull(frm); // test created frame is not null.
58
59 cpl_image_add_scalar(NULL, 1);
60 cpl_test_error(CPL_ERROR_NULL_INPUT); //test expected error
61
62 cpl_test_eq(1, 1); //test results are as expected
63 cpl_test_abs(1, 1, HDRL_EPS_DATA);//test results are as expected within accuracy
64 cpl_test_rel(1, 1, HDRL_EPS_DATA);
65
66
67 /* free memory */
68 cpl_frame_delete(frm);
69 /* verify no error is set by this unit test */
70 cpl_test_error(CPL_ERROR_NONE);
71 return;
72}
73#endif
74
75static hdrl_imagelist *
76test_hdrl_persistence_mkhilist(
77 const int n,
78 const cpl_size nx,
79 const cpl_size ny,
80 const bool zero)
81{
82 hdrl_imagelist * list = hdrl_imagelist_new();
83 for (int i=0; i<n; i++) {
84 hdrl_image * hi = hdrl_image_new(nx, ny);
85 cpl_image * im = hdrl_image_get_image(hi);
86 if (!zero) cpl_image_fill_noise_uniform(im, -1, 1);
87 hdrl_imagelist_set(list, hi, i);
88 }
89
90 return list;
91}
92
93static const char *
94test_hdrl_persistence_make_trapMEF(
95 const char * fn,
96 int maxx,
97 int maxy,
98 cpl_type maxt,
99 int denx,
100 int deny,
101 cpl_type dent,
102 int fullwellx,
103 int fullwelly,
104 cpl_type fullwellt,
105 int tabrows,
106 const char * tabc1n,
107 cpl_type tabc1t,
108 const char * tabc2n,
109 cpl_type tabc2t)
110{
111 cpl_image * max = cpl_image_new(maxx, maxy, maxt);
112 cpl_image * den = cpl_image_new(denx, deny, dent);
113 cpl_image * fullwell = cpl_image_new(fullwellx, fullwelly, fullwellt);
114 cpl_table * frac = cpl_table_new(tabrows);
115 cpl_table_new_column(frac, tabc1n, tabc1t);
116 cpl_table_new_column(frac, tabc2n, tabc2t);
117
118 cpl_propertylist * plist = cpl_propertylist_new();
119
120 cpl_image_save(0, fn, CPL_TYPE_DOUBLE, 0, CPL_IO_CREATE);
121
122 cpl_propertylist_update_string(plist, "EXTNAME", "PERSIST_TRAP_MAX");
123 cpl_image_save(max, fn, cpl_image_get_type(max), plist, CPL_IO_EXTEND);
124
125 cpl_propertylist_update_string(plist, "EXTNAME", "PERSIST_TRAP_DENSITY");
126 cpl_image_save(den, fn, cpl_image_get_type(den), plist, CPL_IO_EXTEND);
127
128 cpl_propertylist_update_string(plist, "EXTNAME", "PERSIST_FULL_WELL");
129 cpl_image_save(fullwell, fn, cpl_image_get_type(fullwell), plist, CPL_IO_EXTEND);
130
131 cpl_propertylist_update_string(plist, "EXTNAME", "PERSIST_TRAP_FRACTION");
132 cpl_table_save(frac, 0, plist, fn, CPL_IO_EXTEND);
133 cpl_propertylist_delete(plist);
134 cpl_table_delete(frac);
135 cpl_image_delete(den);
136 cpl_image_delete(fullwell);
137 cpl_image_delete(max);
138 return fn;
139}
140
141
142/*----------------------------------------------------------------------------*/
149/*----------------------------------------------------------------------------*/
150static cpl_error_code test_hdrl_persistence_read_info(
151 const char * traps_,
152 cpl_image ** maximum,
153 cpl_image ** density,
154 cpl_image ** fullwell,
155 cpl_table ** frac)
156{
157 // maximum, density, fullwell, and frac checks: they should be non-NULL but pt to NULL
158 cpl_error_ensure(
159 maximum && !*maximum && density && !*density && fullwell && !*fullwell
160 && frac && !*frac, CPL_ERROR_NULL_INPUT, return CPL_ERROR_ILLEGAL_INPUT,
161 " Input should be non-NULL but pointers to NULL");
162
163
164 // traps_ checks
165 cpl_size extmax = cpl_fits_find_extension(traps_, "PERSIST_TRAP_MAX");
166 cpl_size extdens = cpl_fits_find_extension(traps_,"PERSIST_TRAP_DENSITY");
167 cpl_size extfullwell = cpl_fits_find_extension(traps_,"PERSIST_FULL_WELL");
168 cpl_size extfraction = cpl_fits_find_extension(traps_, "PERSIST_TRAP_FRACTION");
169
170 cpl_error_ensure(!cpl_error_get_code(), CPL_ERROR_ILLEGAL_INPUT,
171 return CPL_ERROR_DATA_NOT_FOUND,
172 "Can not find at least one of the required extensions");
173
174 *maximum = cpl_image_load(traps_, CPL_TYPE_DOUBLE, 0, extmax);
175 if(cpl_error_get_code() != CPL_ERROR_NONE) {
176 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
177 "Couldn't load maximum trap map");
178 }
179
180 *density = cpl_image_load(traps_, CPL_TYPE_DOUBLE, 0, extdens);
181 if(cpl_error_get_code() != CPL_ERROR_NONE) {
182 cpl_image_delete(*maximum);
183 *maximum = NULL;
184 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
185 "Couldn't load trap density map");
186 }
187
188 *fullwell = cpl_image_load(traps_, CPL_TYPE_DOUBLE, 0, extfullwell);
189 if(cpl_error_get_code() != CPL_ERROR_NONE) {
190 cpl_image_delete(*maximum);
191 cpl_image_delete(*density);
192 *maximum = NULL;
193 *density = NULL;
194 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
195 "Couldn't load full well map");
196 }
197
198 *frac = cpl_table_load(traps_, extfraction, 0);
199 if(cpl_error_get_code() != CPL_ERROR_NONE) {
200 cpl_image_delete(*maximum);
201 cpl_image_delete(*density);
202 cpl_image_delete(*fullwell);
203 *maximum = NULL;
204 *density = NULL;
205 *fullwell = NULL;
206
207 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
208 "Couldn't load trap fraction table");
209 }
210 return CPL_ERROR_NONE;
211}
212
213
214
215
216
217static void
218test_hdrl_persistence_verify_inputs(void)
219{
220 /* Test function:
221 * static cpl_error_code hdrl_persistence_verify_inputs(
222 const hdrl_parameter * param_,
223 const cpl_array * dates_,
224 const cpl_array * exps_,
225 const hdrl_imagelist * illums_,
226 const char * traps_,
227 const cpl_mask * bpm_,
228 const cpl_imagelist * srcmasks_,
229 cpl_image ** maximum,
230 cpl_image ** density,
231 cpl_table ** frac);
232
233 1) Verify that any case of invalid inputs (test each input) is properly
234 handled (gracefully exit, set proper error code) and that error code is
235 as expected
236 2) Define some (dummy) inputs and verify the result error code is
237 CPL_ERROR_NONE
238 */
239
240 /* LEGEND:
241 * bad1_*: NULL, or non-NULL for pointers to pointers to be populated
242 * bad2_*: too few
243 * bad3_*: too many
244 * bad4_*: wrong type
245 * bad5_*: wrong size (for images)
246 */
247
248 /* dates input variations */
249 cpl_array * good_dates = cpl_array_new(2, CPL_TYPE_DOUBLE);
250 cpl_array * bad1_dates = NULL; // NULL
251 cpl_array * bad2_dates = cpl_array_new(0, CPL_TYPE_DOUBLE); // too few
252 cpl_array * bad3_dates = cpl_array_new(3, CPL_TYPE_DOUBLE); // too many
253 cpl_array * bad4_dates = cpl_array_new(2, CPL_TYPE_STRING); // bad type
254
255 /* exps input variations */
256 cpl_array * good_exps = cpl_array_new(1, CPL_TYPE_DOUBLE);
257 cpl_array * bad1_exps = NULL; // NULL
258 cpl_array * bad2_exps = cpl_array_new(0, CPL_TYPE_DOUBLE); // too few
259 cpl_array * bad3_exps = cpl_array_new(2, CPL_TYPE_DOUBLE); // too many
260 cpl_array * bad4_exps = cpl_array_new(1, CPL_TYPE_STRING); // bad type
261
262 /* illums input variations */
263 hdrl_imagelist * good_illums = test_hdrl_persistence_mkhilist(1, 3, 3, 0);
264 hdrl_imagelist * bad1_illums = NULL;
265 hdrl_imagelist * bad2_illums = hdrl_imagelist_new();
266 hdrl_imagelist * bad3_illums = test_hdrl_persistence_mkhilist(2, 3, 3, 0);
267 hdrl_imagelist * bad5_illums = test_hdrl_persistence_mkhilist(1, 4, 4, 0);
268
269 /* traps input variations */
270 const char * good_trap = test_hdrl_persistence_make_trapMEF("good_vi_trap.fits",
271 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 6,
272 "TAU", CPL_TYPE_FLOAT, "NU", CPL_TYPE_FLOAT);
273/*
274 char * bad1_trap = NULL;
275 char * bad2_trap = test_hdrl_persistence_make_trapMEF("bad2_vi_trap.fits",
276 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 5,
277 "TAU", CPL_TYPE_FLOAT, "NU", CPL_TYPE_FLOAT);
278 char * bad3_trap = test_hdrl_persistence_make_trapMEF("bad3_vi_trap.fits",
279 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 7,
280 "TAU", CPL_TYPE_FLOAT, "NU", CPL_TYPE_FLOAT);
281 char * bad4a_trap = test_hdrl_persistence_make_trapMEF("bad4a_vi_trap.fits",
282 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 6,
283 "TAU", CPL_TYPE_DOUBLE, "NU", CPL_TYPE_FLOAT);
284 char * bad4b_trap = test_hdrl_persistence_make_trapMEF("bad4b_vi_trap.fits",
285 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 6,
286 "TAU", CPL_TYPE_FLOAT, "NU", CPL_TYPE_DOUBLE);
287 char * bad5a_trap = test_hdrl_persistence_make_trapMEF("bad5a_vi_trap.fits",
288 3, 4, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 6,
289 "TAU", CPL_TYPE_FLOAT, "NU", CPL_TYPE_FLOAT);
290 char * bad5b_trap = test_hdrl_persistence_make_trapMEF("bad5b_vi_trap.fits",
291 3, 3, CPL_TYPE_DOUBLE, 3, 4, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 6,
292 "TAU", CPL_TYPE_FLOAT, "NU", CPL_TYPE_FLOAT);
293*/
294
295 /* bpm input variations */
296 cpl_mask * good_bpm = cpl_mask_new(3, 3);
297 //cpl_mask * bad1_bpm = NULL; // it's ok for bpm to be NULL
298
299 /* srcmasks input variations */
300 cpl_imagelist * good_srcmasks = cpl_imagelist_new();
301 cpl_imagelist_set(good_srcmasks, cpl_image_new(3, 3, CPL_TYPE_INT), 0);
302 //cpl_imagelist * bad1_srcmasks = NULL; // it's ok for bpm to be NULL
303 cpl_imagelist * bad2_srcmasks = cpl_imagelist_new(); // too few
304 cpl_imagelist * bad3_srcmasks = cpl_imagelist_new(); // too many
305 cpl_imagelist_set(bad3_srcmasks, cpl_image_new(3, 3, CPL_TYPE_INT), 0);
306 cpl_imagelist_set(bad3_srcmasks, cpl_image_new(3, 3, CPL_TYPE_INT), 1);
307 cpl_imagelist * bad4_srcmasks = cpl_imagelist_new(); // wrong type
308 cpl_imagelist_set(bad4_srcmasks, cpl_image_new(3, 3, CPL_TYPE_FLOAT), 0);
309
310 /* maximum trap map input variations */
311 cpl_image * good_max = NULL;
312 cpl_image * bad1_max = cpl_image_new(3, 3, CPL_TYPE_DOUBLE); // pre-exist
313
314 /* density map input variations */
315 cpl_image * good_den = NULL;
316 cpl_image * bad1_den = cpl_image_new(3, 3, CPL_TYPE_DOUBLE); // pre-exist
317
318 /* density map input variations */
319 cpl_image * good_fullwell = NULL;
320 cpl_image * bad1_fullwell = cpl_image_new(3, 3, CPL_TYPE_DOUBLE); // pre-exist
321
322 /* fraction table input variations */
323 cpl_table * good_frac = NULL;
324 cpl_table * bad1_frac = cpl_table_new(3); // pre-existing
325
326 test_hdrl_persistence_read_info(good_trap, &good_max, &good_den, &good_fullwell, &good_frac);
327
328 /* basic NULL tests (bad1_*) */
329
330 hdrl_persistence_verify_inputs(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
331 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
332
333 hdrl_persistence_verify_inputs(1.0,
334 10., 1000.0, CPL_FALSE, good_dates, good_exps, good_illums,
335 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
336 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
337
338 hdrl_persistence_verify_inputs(1.0,
339 1.0, 1.0, CPL_FALSE, bad1_dates, good_exps, good_illums,
340 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
341 cpl_test_error(CPL_ERROR_NULL_INPUT);
342
343 hdrl_persistence_verify_inputs(1.0,
344 1.0, 1.0, CPL_FALSE, good_dates, bad1_exps, good_illums,
345 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
346 cpl_test_error(CPL_ERROR_NULL_INPUT);
347
348 hdrl_persistence_verify_inputs(1.0,
349 1.0, 1.0, CPL_FALSE, good_dates, good_exps, bad1_illums,
350 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
351 cpl_test_error(CPL_ERROR_NULL_INPUT);
352
353 hdrl_persistence_verify_inputs(1.0,
354 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
355 good_srcmasks, NULL, good_den, good_fullwell, good_frac);
356 cpl_test_error(CPL_ERROR_NULL_INPUT);
357
358 hdrl_persistence_verify_inputs(1.0,
359 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
360 good_srcmasks, good_max, NULL, good_fullwell, good_frac);
361 cpl_test_error(CPL_ERROR_NULL_INPUT);
362
363 hdrl_persistence_verify_inputs(1.0,
364 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
365 good_srcmasks, good_max, good_den, good_fullwell, NULL);
366 cpl_test_error(CPL_ERROR_NULL_INPUT);
367
368 /* non-NULL tests (bad1_*) */
369/*
370ToDo Now they should preexist - change this
371 hdrl_persistence_verify_inputs(
372 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
373 good_srcmasks, bad1_max, good_den, good_fullwell, good_frac);
374 cpl_test_error(CPL_ERROR_NULL_INPUT);
375
376 hdrl_persistence_verify_inputs(
377 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
378 good_srcmasks, good_max, bad1_den, good_fullwell, good_frac);
379 cpl_test_error(CPL_ERROR_NULL_INPUT);
380
381 hdrl_persistence_verify_inputs(
382 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
383 good_srcmasks, good_max, good_den, good_fullwell, bad1_frac);
384 cpl_test_error(CPL_ERROR_NULL_INPUT);
385*/
386
387 /* count requirement checks (bad2_* bad3_*) */
388
389 hdrl_persistence_verify_inputs(1.0,
390 1.0, 1.0, CPL_FALSE, bad2_dates, good_exps, good_illums,
391 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
392 cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
393
394 hdrl_persistence_verify_inputs(1.0,
395 1.0, 1.0, CPL_FALSE, bad3_dates, good_exps, good_illums,
396 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
397 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
398
399 hdrl_persistence_verify_inputs(1.0,
400 1.0, 1.0, CPL_FALSE, good_dates, bad2_exps, good_illums,
401 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
402 cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
403
404 hdrl_persistence_verify_inputs(1.0,
405 1.0, 1.0, CPL_FALSE, good_dates, bad3_exps, good_illums,
406 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
407 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
408
409 hdrl_persistence_verify_inputs(1.0,
410 1.0, 1.0, CPL_FALSE, good_dates, good_exps, bad2_illums,
411 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
412 cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
413
414 hdrl_persistence_verify_inputs(1.0,
415 1.0, 1.0, CPL_FALSE, good_dates, good_exps, bad3_illums,
416 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
417 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
418
419 hdrl_persistence_verify_inputs(1.0,
420 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
421 bad2_srcmasks, good_max, good_den, good_fullwell, good_frac);
422 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
423
424 hdrl_persistence_verify_inputs(1.0,
425 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
426 bad3_srcmasks, good_max, good_den, good_fullwell, good_frac);
427 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
428
429 /* type requirement checks (bad4_*) */
430
431 hdrl_persistence_verify_inputs(1.0,
432 1.0, 1.0, CPL_FALSE, bad4_dates, good_exps, good_illums,
433 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
434 cpl_test_error(CPL_ERROR_INVALID_TYPE);
435
436 hdrl_persistence_verify_inputs(1.0,
437 1.0, 1.0, CPL_FALSE, good_dates, bad4_exps, good_illums,
438 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
439 cpl_test_error(CPL_ERROR_INVALID_TYPE);
440
441 hdrl_persistence_verify_inputs(1.0,
442 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
443 bad4_srcmasks, good_max, good_den, good_fullwell, good_frac);
444 cpl_test_error(CPL_ERROR_INVALID_TYPE);
445
446 /* image size requirement checks (bad5_*) */
447
448 hdrl_persistence_verify_inputs(1.0,
449 1.0, 1.0, CPL_FALSE, good_dates, good_exps, bad5_illums,
450 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
451 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
452
453 /* everything is good check (this must come last) */
454
455 hdrl_persistence_verify_inputs(1.0,
456 1.0, 1.0, CPL_FALSE, good_dates, good_exps, good_illums,
457 good_srcmasks, good_max, good_den, good_fullwell, good_frac);
458 cpl_test_error(CPL_ERROR_NONE);
459
460 /* cleanup */
461
462 cpl_array_delete(good_dates);
463 cpl_array_delete(bad2_dates);
464 cpl_array_delete(bad3_dates);
465 cpl_array_delete(bad4_dates);
466 cpl_array_delete(bad2_exps);
467 cpl_array_delete(bad3_exps);
468 cpl_array_delete(bad4_exps);
469 cpl_array_delete(good_exps);
470 hdrl_imagelist_delete(good_illums);
471 hdrl_imagelist_delete(bad2_illums);
472 hdrl_imagelist_delete(bad3_illums);
473 hdrl_imagelist_delete(bad5_illums);
474 cpl_mask_delete(good_bpm);
475 cpl_imagelist_delete(good_srcmasks);
476 cpl_imagelist_delete(bad2_srcmasks);
477 cpl_imagelist_delete(bad3_srcmasks);
478 cpl_imagelist_delete(bad4_srcmasks);
479 cpl_image_delete(good_max);
480 cpl_image_delete(bad1_max);
481 cpl_image_delete(good_den);
482 cpl_image_delete(bad1_den);
483 cpl_image_delete(good_fullwell);
484 cpl_image_delete(bad1_fullwell);
485 cpl_table_delete(good_frac);
486 cpl_table_delete(bad1_frac);
487
488 cpl_test_error(CPL_ERROR_NONE);
489 return;
490}
491
492static void
493test_hdrl_persistence_threshhold_qi(void)
494{
495 /* Function to test:
496 * static cpl_error_code hdrl_persistence_threshhold_img(
497 hdrl_image * hdrl_img,
498 const double lower,
499 const cpl_image * upper);
500
501 1) Test invalid input and verify are handled properly and error code
502 is proper
503 2) Generate a hdrl_image with an image 10x10 pix of intensity
504 increasing at each pixel from 0 to 100. Set as lower threshold a
505 10x10 image set to 10, and as upper threshold a 10x10 image set to
506 90. Verify that the expected pixel position have proper value 10 and
507 the other expected pixel positions have value 90 (it may be useful
508 to save the image and check it wit ds9)
509 */
510 const cpl_size ny = 10;
511 const cpl_size nx = 10;
512
513 const hdrl_image * zero = hdrl_image_new(nx, ny);
514 cpl_image * tmp = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
515 cpl_image_fill_window(tmp, 1, 1, nx, ny, 90.0);
516 const hdrl_image * upper = hdrl_image_create(tmp, NULL);
517 cpl_image_fill_window(tmp, 1, 1, nx, ny, 10.0);
518 const hdrl_image * lower = hdrl_image_create(tmp, NULL);
519
520 hdrl_image * hi = hdrl_image_new(nx, ny);
521 for (int i=0, xpos=1; xpos <= nx; xpos++) {
522 for (int ypos=1 ; ypos <= ny; ypos++ ) {
523 hdrl_value val = { i++, 0.0 };
524 hdrl_image_set_pixel(hi, xpos, ypos, val);
525 }
526 }
527
528 hdrl_persistence_threshhold_img(NULL, zero, upper);
529 cpl_test_error(CPL_ERROR_NULL_INPUT);
530
531 hdrl_persistence_threshhold_img(hi, NULL, upper);
532 cpl_test_error(CPL_ERROR_NULL_INPUT);
533
534 hdrl_persistence_threshhold_img(NULL, NULL, NULL);
535 cpl_test_error(CPL_ERROR_NULL_INPUT);
536
537 hdrl_persistence_threshhold_img(hi, zero, upper);
538
539 cpl_test_abs(
540 hdrl_image_get_pixel(hi, 1, 1, NULL).data, 0.0, HDRL_EPS_DATA);
541 cpl_test_error(CPL_ERROR_NONE);
542
543 cpl_test_abs(
544 hdrl_image_get_pixel(hi, 1, 2, NULL).data, 1.0, HDRL_EPS_DATA);
545 cpl_test_error(CPL_ERROR_NONE);
546
547 cpl_test_abs(
548 hdrl_image_get_pixel(hi, 10, 9, NULL).data, 90.0, HDRL_EPS_DATA);
549 cpl_test_error(CPL_ERROR_NONE);
550
551 cpl_test_abs(
552 hdrl_image_get_pixel(hi, 10, 10, NULL).data, 90.0, HDRL_EPS_DATA);
553 cpl_test_error(CPL_ERROR_NONE);
554
555 hdrl_persistence_threshhold_img(hi, lower, hi); // uses itself as upper lim
556
557 cpl_test_abs( // 0.0 -> 10.0
558 hdrl_image_get_pixel(hi, 1, 1, NULL).data, 10.0, HDRL_EPS_DATA);
559 cpl_test_error(CPL_ERROR_NONE);
560
561 cpl_test_abs( // 1.0 -> 10.0
562 hdrl_image_get_pixel(hi, 1, 2, NULL).data, 10.0, HDRL_EPS_DATA);
563 cpl_test_error(CPL_ERROR_NONE);
564
565 cpl_test_abs( // last pixel val should remain unchanged
566 hdrl_image_get_pixel(hi, 10, 10, NULL).data, 90.0, HDRL_EPS_DATA);
567 cpl_test_error(CPL_ERROR_NONE);
568
570 hdrl_image_delete((hdrl_image *)zero);
571 hdrl_image_delete((hdrl_image *)upper);
572 hdrl_image_delete((hdrl_image *)lower);
573 cpl_image_delete(tmp);
574
575 cpl_test_error(CPL_ERROR_NONE);
576 return;
577}
578
579static void
580test_hdrl_persistence_zero_flagged_pixels(void)
581{
582 /*Function to test:
583 * static cpl_error_code hdrl_persistence_zero_flagged_pixels(
584 hdrl_image * hdrl_img,
585 const cpl_mask * mask,
586 const cpl_binary value);
587
588 1) Test invalid input and verify are handled properly and error code
589 is proper
590 2) Simulate hdrl image and mask 3x3 pixels. Mask certain known
591 position. Verify that after operation hdrl image values have proper
592 value either if masked or not.
593 */
594
595 const cpl_size ny = 3;
596 const cpl_size nx = 3;
597 cpl_image * tmp = cpl_image_new(ny, nx, CPL_TYPE_DOUBLE);
598 cpl_image_add_scalar(tmp, 7.0);
599 hdrl_image * hi = hdrl_image_create(tmp, NULL);
600
601 cpl_mask * srcmask = cpl_mask_new(nx, ny);
602 cpl_mask_set(srcmask, 2, 2, CPL_BINARY_1);
603
604 hdrl_persistence_zero_flagged_pixels(NULL, srcmask, CPL_BINARY_1);
605 cpl_test_error(CPL_ERROR_NULL_INPUT);
606
607 hdrl_persistence_zero_flagged_pixels(hi, NULL, CPL_BINARY_1);
608 cpl_test_error(CPL_ERROR_NULL_INPUT);
609
610 hdrl_persistence_zero_flagged_pixels(hi, srcmask, 's');
611 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
612
613 hdrl_persistence_zero_flagged_pixels(hi, srcmask, CPL_BINARY_1);
614 cpl_test_error(CPL_ERROR_NONE);
615
616 cpl_test_abs(
617 hdrl_image_get_pixel(hi, 2, 2, NULL).data, 0.0, HDRL_EPS_DATA);
618
619 cpl_test_abs(
620 hdrl_image_get_pixel(hi, 1, 2, NULL).data, 7.0, HDRL_EPS_DATA);
621
622 cpl_test_abs(
623 hdrl_image_get_pixel(hi, 2, 3, NULL).data, 7.0, HDRL_EPS_DATA);
624
626 cpl_mask_delete(srcmask);
627 cpl_image_delete(tmp);
628
629 return;
630}
631
632static void
633test_hdrl_persistence_compute_qi(void)
634{
635 /* Function to test:
636 * static cpl_error_code hdrl_persistence_compute_qi(
637 hdrl_imagelist * Q,
638 hdrl_imagelist * Qacc,
639 const double delt,
640 const hdrl_imagelist * hirhos,
641 const float * taud,
642 const double exptime,
643 const hdrl_image * hiillum,
644 const int n_tau,
645 const hdrl_imagelist * himaxs)
646
647 1) Verify invalid input
648 2) Generate valid input and verify results are proper (inspect a few
649 pixel values of the result)
650 */
651
652 const float taud[] = {1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0};
653 const int n_tau = 6;
654
655 const cpl_size ny = 20;
656 const cpl_size nx = 20;
657 hdrl_imagelist * hirhos = test_hdrl_persistence_mkhilist(n_tau, nx, ny, 0);
658 hdrl_imagelist * himaxs = test_hdrl_persistence_mkhilist(n_tau, nx, ny, 0);
659 hdrl_imagelist * Q = test_hdrl_persistence_mkhilist(n_tau, nx, ny, 1);
660 hdrl_imagelist * Qacc = test_hdrl_persistence_mkhilist(n_tau, nx, ny, 1);
661
662 /* Create an image with all pixels set to 1.0 and a single sharp Gaussian
663 * peak in the image at coordinate (100, 100). */
664 cpl_image * peak_img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
665 cpl_test_error(CPL_ERROR_NONE);
666 cpl_image_fill_gaussian(peak_img, 10, 10, 1000.0, 1.0, 0.5);
667 cpl_test_error(CPL_ERROR_NONE);
668 cpl_image_add_scalar(peak_img, 1.0);
669 cpl_test_error(CPL_ERROR_NONE);
670 const hdrl_image * hiillum = hdrl_image_create(peak_img, NULL);
671
672 double exptime = 300.0;
673 double diff = 58967.353850 - 58967.315219;
674 diff *= 24.0 * 3600.0;
675
676 hdrl_persistence_compute_qi(
677 NULL, Qacc, diff, hirhos, taud, exptime, hiillum, n_tau, himaxs);
678 cpl_test_error(CPL_ERROR_NULL_INPUT);
679
680 hdrl_persistence_compute_qi(
681 Q, NULL, diff, hirhos, taud, exptime, hiillum, n_tau, himaxs);
682 cpl_test_error(CPL_ERROR_NULL_INPUT);
683
684 hdrl_persistence_compute_qi(
685 Q, Qacc, diff, NULL, taud, exptime, hiillum, n_tau, himaxs);
686 cpl_test_error(CPL_ERROR_NULL_INPUT);
687
688 hdrl_persistence_compute_qi(
689 Q, Qacc, diff, hirhos, NULL, exptime, hiillum, n_tau, himaxs);
690 cpl_test_error(CPL_ERROR_NULL_INPUT);
691
692 hdrl_persistence_compute_qi(
693 Q, Qacc, diff, hirhos, taud, -1, hiillum, n_tau, himaxs);
694 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
695
696 hdrl_persistence_compute_qi(
697 Q, Qacc, diff, hirhos, taud, exptime, NULL, n_tau, himaxs);
698 cpl_test_error(CPL_ERROR_NULL_INPUT);
699
700 hdrl_persistence_compute_qi(
701 Q, Qacc, diff, hirhos, taud, exptime, hiillum, -1, himaxs);
702 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
703
704 hdrl_persistence_compute_qi(
705 Q, Qacc, diff, hirhos, taud, exptime, hiillum, n_tau, NULL);
706 cpl_test_error(CPL_ERROR_NULL_INPUT);
707
708 hdrl_persistence_compute_qi(
709 Q, Qacc, diff, hirhos, taud, exptime, hiillum, n_tau, himaxs);
710 cpl_test_error(CPL_ERROR_NONE);
711
712 // now we compare the hdrl_persistence_compute_qi() results to
713 // manually-computed values for some randomly-chosen pixels
714 typedef struct { int x; int y; } pixel_t;
715 pixel_t pixs[] = { {4,6}, {9,2} }; // some random pixels to test
716 for (size_t j = 0; j < ARRAY_LEN(pixs); ++j) {
717 const pixel_t p = pixs[j];
718
719 // first declare & initialise required inputs
720 hdrl_data_t illum = hdrl_image_get_pixel(hiillum, p.x, p.y, NULL).data;
721 hdrl_data_t q[] = { 0, 0, 0, 0, 0, 0 }; // starts as all zeros
722 hdrl_data_t qacc[] = { 0, 0, 0, 0, 0, 0 }; // starts as all zeros
723 hdrl_data_t rhos[] = { 0, 0, 0, 0, 0, 0 }; // next loop populates
724 hdrl_data_t maxs[] = { 0, 0, 0, 0, 0, 0 }; // next loop populates
725 for (size_t i = 0; i < ARRAY_LEN(rhos); ++i) {
726 hdrl_image * hi = hdrl_imagelist_get(hirhos, i);
727 rhos[i] = hdrl_image_get_pixel(hi, p.x, p.y, NULL).data;
728 hi = hdrl_imagelist_get(himaxs, i);
729 maxs[i] = hdrl_image_get_pixel(hi, p.x, p.y, NULL).data;
730 }
731
732 // now perform the calculations & comparisons
733 for (int i=0; i<n_tau; i++) {
734 // compute Qi
735 hdrl_data_t tmp = qacc[i] * exp(-diff/taud[i]);
736 tmp -= q[i];
737 tmp *= diff/taud[i];
738 q[i] += tmp;
739 // compare Qi
740 hdrl_image * hi = hdrl_imagelist_get(Q, i);
741 hdrl_data_t val = hdrl_image_get_pixel(hi, p.x, p.y, NULL).data;
742 //cpl_test_abs(q[i], val, HDRL_EPS_DATA); // not useful: always 0
743 // vs 0 after 1st frame
744 // as this test simulates
745
746 // compute Qacci
747 tmp = illum * rhos[i] * (1.0 - exp(-exptime/taud[i]));
748 if (tmp > maxs[i]) tmp = maxs[i]; // threshhold
749 qacc[i] = tmp;
750 // compare Qacci
751 hi = hdrl_imagelist_get(Qacc, i);
752 val = hdrl_image_get_pixel(hi, p.x, p.y, NULL).data;
753 cpl_test_abs(qacc[i], val, HDRL_EPS_DATA);
754 }
755 }
756
757 hdrl_image_delete((hdrl_image *)hiillum);
758 cpl_image_delete(peak_img);
761 hdrl_imagelist_delete(himaxs);
762 hdrl_imagelist_delete(hirhos);
763
764 cpl_test_error(CPL_ERROR_NONE);
765 return;
766}
767
768static void
769test_hdrl_persistence_calc_stats(void)
770{
771
772 /* Function to test:
773 * static cpl_propertylist * hdrl_persistence_calc_stats(
774 const hdrl_image * Qtot,
775 const double trim_perc)
776
777 1) Test invalid input
778 2) Generate valid input and verify statistics are as expected.
779 */
780
781 //cpl_image * im = cpl_image_create();
782 //cpl_propertylist * pl = hdrl_persistence_calc_stats(0, 0.1);
783 //cpl_propertylist_delete(pl);
784
785 cpl_test_error(CPL_ERROR_NONE);
786 return;
787}
788
789static void
790test_hdrl_persistence_compute(void)
791{
792 /* Function to test:
793 hdrl_persistence_result * hdrl_persistence_compute(
794 const hdrl_parameter * param_,
795 const cpl_array * dates_,
796 const cpl_array * exps_,
797 const hdrl_imagelist * illums_,
798 const char * traps_,
799 const cpl_mask * bpm_,
800 const cpl_imagelist * srcmasks_)
801
802 1) Verify invalid input
803 2) generate valid inputs and verify results are as expected
804 (for example that parameters have the expected value)
805 */
806
807 double det_turnover = 1.0;
808 const double mean_trim = 1.0;
809 const cpl_boolean cleanQ = CPL_FALSE;
810 const cpl_array * dates = cpl_array_new(2, CPL_TYPE_FLOAT);
811 const cpl_array * exps = cpl_array_new(1, CPL_TYPE_FLOAT);
812 hdrl_imagelist * illums = test_hdrl_persistence_mkhilist(1, 3, 3, 0);
813 const char * traps = test_hdrl_persistence_make_trapMEF("compute_trap.fits",
814 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 3, 3, CPL_TYPE_DOUBLE, 6,
815 "TAU", CPL_TYPE_FLOAT, "NU", CPL_TYPE_FLOAT);
816 const cpl_mask * bpm = cpl_mask_new(3, 3);
817 cpl_imagelist * srcmasks = cpl_imagelist_new();
818 cpl_imagelist_set(srcmasks, cpl_image_new(3, 3, CPL_TYPE_INT), 0);
819
820 // no point testing NULL or other invalid inputs here as that is already
821 // performed by test_hdrl_persistence_verify_inputs (hdrl_persistence_compute
822 // calls hdrl_persistence_verify_inputs as its 1st step)
823
824 det_turnover = -45727230.0;
825
826
827 cpl_table * frac = NULL;
828 cpl_image * maximum = NULL, * density = NULL, * fullwell = NULL;
829
830 test_hdrl_persistence_read_info(traps, &maximum, &density, &fullwell, &frac);
831
832 hdrl_image * persistence = NULL;
833 cpl_propertylist * persistence_qc = NULL;
834 double gain = 1.0;
835 hdrl_persistence_compute(gain, det_turnover,
836 mean_trim, cleanQ, dates,
837 exps, illums, srcmasks, maximum, density, fullwell, frac, &persistence, &persistence_qc);
838 /*ToDo Fix later*/
839 cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
840
841 hdrl_image_delete(persistence);
842 cpl_propertylist_delete(persistence_qc);
843 cpl_image_delete(maximum);
844 cpl_image_delete(density);
845 cpl_image_delete(fullwell);
846 cpl_table_delete(frac);
847
848 cpl_imagelist_delete(srcmasks);
849 cpl_mask_delete((cpl_mask *)bpm);
850 hdrl_imagelist_delete(illums);
851 cpl_array_delete((cpl_array *)exps);
852 cpl_array_delete((cpl_array *)dates);
853
854 cpl_test_error(CPL_ERROR_NONE);
855 return;
856}
857
858/*----------------------------------------------------------------------------*/
862/*----------------------------------------------------------------------------*/
863int main(void)
864{
865 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
866 //test_example();
867
868 test_hdrl_persistence_verify_inputs();
869 //test_hdrl_persistence_parameter_verify();
870 test_hdrl_persistence_threshhold_qi();
871 test_hdrl_persistence_zero_flagged_pixels();
872 test_hdrl_persistence_compute_qi();
873 test_hdrl_persistence_calc_stats();
874 //test_hdrl_persistence_parameter_create();
875 //test_hdrl_persistence_parameter_check();
876 test_hdrl_persistence_compute();
877 //cpl_test_error(CPL_ERROR_NONE);
878
879 return cpl_test_end(0);
880}
881
hdrl_value hdrl_image_get_pixel(const hdrl_image *self, cpl_size xpos, cpl_size ypos, int *pis_rejected)
get pixel values of hdrl_image
Definition hdrl_image.c:559
cpl_error_code hdrl_image_set_pixel(hdrl_image *self, cpl_size xpos, cpl_size ypos, hdrl_value value)
set pixel values of hdrl_image
Definition hdrl_image.c:594
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
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition hdrl_image.c:105
hdrl_image * hdrl_image_new(cpl_size nx, cpl_size ny)
create new zero filled hdrl image
Definition hdrl_image.c:311
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition hdrl_image.c:379
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
cpl_error_code hdrl_persistence_compute(const double gain, const double turnover, const double mean_trim, const cpl_boolean cleanQ, const cpl_array *dateobs, const cpl_array *exptimes, hdrl_imagelist *ilist_persistence, const cpl_imagelist *ilist_obj, const cpl_image *maximum, const cpl_image *density, const cpl_image *fullwell, const cpl_table *frac, hdrl_image **persistence, cpl_propertylist **persistence_qc)
generate the persistence map