73 const hdrl_imagelist * detlin)
75 const cpl_image * ima ;
76 const cpl_image * erra ;
77 const cpl_image * imb ;
78 const cpl_image * errb ;
79 const cpl_image * imc ;
80 const cpl_image * errc ;
82 const double * perra ;
84 const double * perrb ;
86 const double * perrc ;
91 double correction_factor;
95 if (!in || !detlin)
return -1 ;
110 if (!ima || !imb || !imc ) {
111 cpl_msg_error(cpl_func,
"Cannot access the detlin images") ;
114 pima = cpl_image_get_data_double_const(ima) ;
115 pimb = cpl_image_get_data_double_const(imb) ;
116 pimc = cpl_image_get_data_double_const(imc) ;
117 perra = cpl_image_get_data_double_const(erra);
118 perrb = cpl_image_get_data_double_const(errb);
119 perrc = cpl_image_get_data_double_const(errc);
123 nx = cpl_image_get_size_x(cur_ima) ;
124 ny = cpl_image_get_size_y(cur_ima) ;
125 if ((cpl_image_get_size_x(ima) != nx) ||
126 (cpl_image_get_size_x(imb) != nx) ||
127 (cpl_image_get_size_x(imc) != nx) ||
128 (cpl_image_get_size_y(ima) != ny) ||
129 (cpl_image_get_size_y(imb) != ny) ||
130 (cpl_image_get_size_y(imc) != ny)) {
131 cpl_msg_error(cpl_func,
"Incompatible sizes") ;
136 for (i=0 ; i<nx*ny ; i++) {
139 if (pdata[i] < CR2RES_DETLIN_THRESHOLD) continue ;
142 perr[i] = pow2(perra[i] * pdata[i]) + pow2(perrb[i] * pow2(pdata[i]))
143 + pow2(perrc[i] * pow3(pdata[i]))
144 + pow2(perr[i] * (pima[i] + 2. * pimb[i] * pdata[i]
145 + 3. * pimc[i] * pow2(pdata[i])));
146 perr[i] = sqrt(perr[i]);
148 correction_factor = pima[i] + \
149 ((pimb[i] + pimc[i] * pdata[i]) * pdata[i]);
150 pdata[i] = pdata[i] * correction_factor;
176 const cpl_vector * dits,
177 const cpl_vector * adus,
179 cpl_polynomial ** fitted,
182 cpl_matrix * samppos ;
183 cpl_polynomial * fitted_local ;
184 cpl_vector * error_local ;
185 cpl_vector * adusPsec ;
186 cpl_vector * y_tofit, *tmp;
187 cpl_vector * adus_loc, *dits_loc;
189 cpl_size i=0, first_satur=-1 ;
193 if (fitted == NULL || dits == NULL || adus == NULL)
return -1 ;
194 if (cpl_vector_get_size(dits) != cpl_vector_get_size(adus))
198 if (cpl_vector_get_min(adus) > CR2RES_DETLIN_THRESHOLD)
return -1;
199 if (cpl_vector_get_max(adus) < CR2RES_DETLIN_THRESHOLD)
return -1;
200 for (i = 0; i < cpl_vector_get_size(adus); i++) {
201 if (cpl_vector_get(adus,i) < CR2RES_DETLIN_THRESHOLD ) count_linear++;
202 if (cpl_vector_get(adus,i)>CR2RES_DETLIN_MAXFIT && first_satur==-1)
207 if (first_satur==-1) first_satur= cpl_vector_get_size(dits);
209 if (count_linear > first_satur-1) count_linear = first_satur-1;
211 adus_loc = cpl_vector_extract(adus, 0, first_satur-1, 1);
212 dits_loc = cpl_vector_extract(dits, 0, first_satur-1, 1);
215 adusPsec = cpl_vector_duplicate(adus_loc);
216 cpl_vector_divide(adusPsec, dits_loc);
217 tmp = cpl_vector_extract(adusPsec,0,count_linear-1,1);
218 aduPsec = cpl_vector_get_median(tmp);
219 cpl_vector_delete(tmp);
221 samppos = cpl_matrix_wrap(1,
222 cpl_vector_get_size(adus_loc),
223 cpl_vector_get_data(adus_loc)) ;
225 y_tofit = cpl_vector_new(cpl_vector_get_size(dits_loc));
226 for(i = 0; i < cpl_vector_get_size(dits_loc); i++) {
229 y = aduPsec / cpl_vector_get(adusPsec,i);
230 cpl_vector_set(y_tofit, i, y);
232 cpl_vector_delete(adusPsec);
235 fitted_local = cpl_polynomial_new(1);
237 cpl_polynomial_fit(fitted_local, samppos, NULL, y_tofit, NULL,
238 CPL_FALSE, NULL, &max_degree) != CPL_ERROR_NONE) {
241 cpl_vector_delete(adus_loc);
242 cpl_vector_delete(dits_loc);
243 cpl_matrix_unwrap(samppos) ;
244 cpl_vector_delete(y_tofit);
245 cpl_polynomial_delete(fitted_local) ;
251 error_local = cpl_vector_new(max_degree+1) ;
252 cpl_size nc = max_degree + 1;
253 cpl_size ndata = cpl_vector_get_size(y_tofit);
256 for (i = 0; i < max_degree + 1; i++) {
257 cpl_vector_set(error_local, i, 0);
266 cpl_matrix * hankel = cpl_matrix_new(nc, nc);
267 cpl_matrix * mx = cpl_matrix_new(nc, 1);
271 cr2res_matrix_fill_normal_vandermonde(hankel, mx, adus_loc, CPL_FALSE,
273 cpl_matrix * inverse = cpl_matrix_invert_create(hankel);
274 cpl_vector * resids = cpl_vector_new(ndata);
276 cpl_vector_fill_polynomial_fit_residual(resids, y_tofit, NULL,
277 fitted_local, samppos, NULL);
278 for (i = 0; i < ndata; i++) {
279 cpl_vector_set(resids, i, fabs(cpl_vector_get(resids, i)));
282 cpl_matrix_multiply_scalar(inverse,
283 cpl_vector_get_sum(resids) / (
double)(ndata - nc));
285 for (i = 0; i < max_degree + 1; i++) {
286 cpl_vector_set(error_local, i, sqrt(cpl_matrix_get(inverse, i, i)));
288 cpl_matrix_delete(hankel);
289 cpl_matrix_delete(mx);
290 cpl_matrix_delete(inverse);
291 cpl_vector_delete(resids);
293 cpl_vector_delete(y_tofit);
294 cpl_matrix_unwrap(samppos) ;
295 cpl_vector_delete(dits_loc);
296 cpl_vector_delete(adus_loc);
299 for (i=0 ; i<=max_degree ; i++) {
301 cur_coeff = cpl_polynomial_get_coeff(fitted_local, &i) ;
302 if (isnan(cur_coeff)) {
303 cpl_polynomial_delete(fitted_local) ;
304 cpl_vector_delete(error_local) ;
312 if (cpl_error_get_code()) {
314 cpl_polynomial_delete(fitted_local) ;
315 cpl_vector_delete(error_local) ;
322 *fitted = fitted_local ;
323 if (error != NULL) *error = error_local ;
324 else cpl_vector_delete(error_local) ;