28#include "hdrl_DER_SNR.h"
29#include "hdrl_spectrum.h"
30#include "hdrl_random.h"
45static inline cpl_image * get_noisy_flux(
const cpl_image * img);
47#define ARR_SIZE(a) ((cpl_size)((sizeof((a)) / sizeof((a[0])))))
50cpl_image * get_error(
const int* data,
const int* map, cpl_size length){
53 cpl_array * wav = cpl_array_new(length, HDRL_TYPE_DATA);
54 cpl_image * flux = cpl_image_new(length, 1, HDRL_TYPE_DATA);
56 for(cpl_size j = 0; j < length; ++j){
57 cpl_image_set(flux, map[j] + 1, 1, data[j]);
58 cpl_array_set(wav, map[j], j + 1);
61 const hdrl_data_t *flux_p =
62 (
const hdrl_data_t *)cpl_image_get_data_const(flux);
64 const cpl_binary *msk = NULL;
67 cpl_image_delete(flux);
68 cpl_array_delete(wav);
73void test_DER_SNR_sort(
void){
76 1, 5, 10, 5, 23, 1, 8, 17, 21, 7, 11, 13, 5, 99, 12, 4,
77 1, 5, 10, 5, 23, 1, 8, 17, 21, 7, 11, 13, 5, 99, 12, 4
80 int map1[ARR_SIZE(data)] = {0};
81 int map2[ARR_SIZE(data)] = {0};
83 const cpl_size length = ARR_SIZE(data);
85 for(cpl_size i = 0; i < length; ++i){
90 for(cpl_size i = 0; i < length; ++i){
92 const cpl_size source = i;
93 const cpl_size dest = ((double)rand() / (double)RAND_MAX) * (length - 1);
95 cpl_test(dest >= 0 && dest < length);
97 const int data_s = map1[source];
98 const int data_d = map1[dest];
100 map1[source] = data_d;
104 cpl_image * flux_e_unsorted = get_error(data, map1, length);
105 cpl_image * flux_e_sorted = get_error(data, map2, length);
109 for(cpl_size i = 0; i < length; ++i){
111 const double data1 = cpl_image_get(flux_e_sorted, i + 1, 1, &rej1);
114 const double data2 = cpl_image_get(flux_e_unsorted, map1[i] + 1, 1, &rej2);
116 cpl_test_eq(rej1, rej2);
117 cpl_test_abs(data1, data2, 1e-3);
120 cpl_image_delete(flux_e_sorted);
121 cpl_image_delete(flux_e_unsorted);
124void test_DER_SNR(
void){
127 1, 5, 10, 5, 23, 1, 8, 17, 21, 7, 11, 13, 5, 99, 12, 4,
128 1, 5, 10, 5, 23, 1, 8, 17, 21, 7, 11, 13, 5, 99, 12, 4
131 cpl_array * wav = cpl_array_new(ARR_SIZE(data), HDRL_TYPE_DATA);
132 cpl_image * flux = cpl_image_new(ARR_SIZE(data), 1, HDRL_TYPE_DATA);
134 for(cpl_size i = 0; i < ARR_SIZE(data); ++i){
135 cpl_image_set(flux, i +1, 1, data[i]);
136 cpl_array_set(wav, i, i + 1);
139 const hdrl_data_t * flux_p =
140 (
const hdrl_data_t *)cpl_image_get_data_const(flux);
142 const cpl_binary *msk = NULL;
145 ARR_SIZE(data) - 1, ARR_SIZE(data));
146 cpl_test_abs(err, 12.105, 1e-3);
151 cpl_test_eq(cpl_image_get_size_x(flux), cpl_image_get_size_x(flux_e));
152 cpl_test_eq(cpl_image_get_size_y(flux), cpl_image_get_size_y(flux_e));
155 err = cpl_image_get(flux_e, 7, 1, &rej);
156 cpl_test_abs(err, 13.921, 1e-3);
158 err = cpl_image_get(flux_e, 6, 1, &rej);
159 cpl_test_abs(err, 13.921, 1e-3);
161 err = cpl_image_get(flux_e, 1, 1, &rej);
162 cpl_test_abs(err, 2.421, 1e-3);
164 cpl_image_delete(flux_e);
168 cpl_image_reject(flux, 2, 1);
170 flux_p = (
const hdrl_data_t *)cpl_image_get_data_const(flux);
171 const cpl_mask *mask = cpl_image_get_bpm_const(flux);
172 msk = cpl_mask_get_data_const(mask);
176 cpl_test(cpl_image_is_rejected(flux_e, 2, 1));
179 err = cpl_image_get(flux_e, 6, 1, &rej);
180 cpl_test_abs(err, 14.829, 1e-3);
185 cpl_image_delete(flux_e);
187 for(cpl_size i = 1; i <= 11; i++)
190 cpl_image_reject(flux, i, 1);
193 flux_p = (
const hdrl_data_t *)cpl_image_get_data_const(flux);
194 mask = cpl_image_get_bpm_const(flux);
195 msk = cpl_mask_get_data_const(mask);
198 cpl_test(cpl_image_is_rejected(flux_e, 6, 1));
199 cpl_test(!cpl_image_is_rejected(flux, 6, 1));
201 cpl_image_delete(flux_e);
202 cpl_image_delete(flux);
203 cpl_array_delete(wav);
206void test_DER_SNR_performance(
void){
208 static const int sz = 2000;
209 static const double delta = 3.14 / 2000.0;
210 static const double peak = 1e3;
211 static const int n_iter = 100;
213 cpl_image * flux = cpl_image_new(sz, 1, HDRL_TYPE_DATA);
214 cpl_array * lambdas = cpl_array_new(sz, HDRL_TYPE_DATA);
216 for(cpl_size i = 0; i < sz; i++){
217 double x = delta * (i+1);
218 cpl_array_set(lambdas, i, x);
219 cpl_image_set(flux, i + 1, 1, peak * sin(x));
222 cpl_image * std_dev_theo = cpl_image_power_create(flux, 1./2.);
223 cpl_image * DER_SNR_avg = cpl_image_new(sz, 1,HDRL_TYPE_DATA);
225 for(cpl_size i = 0; i < n_iter; ++i){
226 cpl_image * noisy_flux_i = get_noisy_flux(flux);
228 const hdrl_data_t * noisy_flux =
229 (
const hdrl_data_t *)cpl_image_get_data_const(noisy_flux_i);
231 const cpl_binary *msk = NULL;
234 cpl_image_divide_scalar(e, n_iter);
235 cpl_image_add(DER_SNR_avg, e);
238 cpl_image_delete(noisy_flux_i);
241 cpl_image * ratio = cpl_image_divide_create(std_dev_theo, DER_SNR_avg);
242 double avg_ratio = cpl_image_get_absflux(ratio) / sz;
244 cpl_test_leq(avg_ratio, 1.1);
245 cpl_test_leq(.9, avg_ratio);
247 cpl_image_delete(flux);
248 cpl_image_delete(DER_SNR_avg);
249 cpl_array_delete(lambdas);
250 cpl_image_delete(ratio);
251 cpl_image_delete(std_dev_theo);
261 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
267 test_DER_SNR_performance();
269 return cpl_test_end(0);
278cpl_image * get_noisy_flux(
const cpl_image * img){
280 cpl_size sx = cpl_image_get_size_x(img);
281 cpl_size sy = cpl_image_get_size_y(img);
283 cpl_image * to_ret = cpl_image_new(sx, sy, HDRL_TYPE_DATA);
285 hdrl_random_state * rng = hdrl_random_state_new(1, NULL);
287 for(cpl_size x = 1; x <= sx; x++){
288 for(cpl_size y = 1; y <= sy; y++){
290 double clean_value = cpl_image_get(img, x, y, &rej);
291 double noisy_value = hdrl_random_poisson(rng, clean_value);
292 cpl_image_set(to_ret, x, y, noisy_value);
296 hdrl_random_state_delete(rng);
hdrl_error_t estimate_noise_window(const hdrl_data_t *flux, const cpl_binary *msk, cpl_size start, cpl_size stop, const cpl_size sz)
Estimate the noise in the pixels between [start, stop]. The noise calculation is done using the formu...
cpl_image * estimate_noise_DER_SNR(const hdrl_data_t *flux_in, const cpl_binary *msk_in, const cpl_array *wavelengths, const cpl_size length, const cpl_size half_window)
For every pixel in position i in img_arg, the function estimates the noise using the pixels in the wi...