00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include "naco_recipe.h"
00037
00038
00039
00040
00041
00042 #define RECIPE_STRING "naco_img_detlin"
00043
00044 #define DETLIN_LIMIT 0.75
00045 #define DETLIN_STABILITY 1/100.0
00046
00047 #define DETLIN_MAX_GRAD 1.5
00048 #define DETLIN_MAX_RESI 10.0
00049
00050
00051
00052
00053
00054 static cpl_error_code naco_img_detlin_load(cpl_imagelist *, cpl_vector *,
00055 const cpl_parameterlist *,
00056 const irplib_framelist *,
00057 const irplib_framelist *);
00058
00059 static cpl_image * naco_img_detlin_limit(const cpl_imagelist *);
00060 static cpl_image * naco_img_detlin_bpm(const cpl_imagelist *,
00061 const cpl_vector *,
00062 const cpl_image *);
00063
00064 static cpl_error_code naco_img_detlin_dit_diff(cpl_vector *);
00065
00066 static cpl_error_code naco_img_detlin_save(cpl_frameset *,
00067 const cpl_parameterlist *,
00068 const cpl_propertylist *,
00069 const cpl_imagelist *,
00070 const cpl_image *,
00071 const cpl_image *);
00072
00073 static cpl_imagelist * naco_imagelist_fit_polynomial(const cpl_imagelist *,
00074 const double *, int);
00075
00076 NACO_RECIPE_DEFINE(naco_img_detlin,
00077 NACO_PARAM_FORCE,
00078 "Detector linearity recipe",
00079 RECIPE_STRING " -- NACO imaging detector linearity recipe.\n"
00080 "The Set Of Frames (sof-file) must specify at least three "
00081 "pairs of files which must be tagged\n"
00082 "NACO-raw-file.fits " NACO_IMG_DETLIN_LAMP " and\n"
00083 "NACO-raw-file.fits " NACO_IMG_DETLIN_DARK "\n");
00084
00085
00089
00090
00091
00092
00093
00094
00095
00102
00103 static int naco_img_detlin(cpl_frameset * framelist,
00104 const cpl_parameterlist * parlist)
00105 {
00106 irplib_framelist * allframes = NULL;
00107 irplib_framelist * darkframes = NULL;
00108 irplib_framelist * lampframes = NULL;
00109 cpl_propertylist * qclist = cpl_propertylist_new();
00110 const cpl_propertylist * reflist;
00111 cpl_imagelist * iset = cpl_imagelist_new();
00112 cpl_image * lin_limit = NULL;
00113 cpl_vector * ditval = cpl_vector_new(4);
00114 cpl_imagelist * fitres = NULL;
00115 cpl_image * bpm = NULL;
00116 cpl_image * residual = NULL;
00117
00118
00119
00120 skip_if (naco_dfs_set_groups(framelist));
00121
00122 allframes = irplib_framelist_cast(framelist);
00123 skip_if(allframes == NULL);
00124
00125 darkframes = irplib_framelist_extract(allframes, NACO_IMG_DETLIN_DARK);
00126 skip_if (darkframes == NULL);
00127
00128 lampframes = irplib_framelist_extract(allframes, NACO_IMG_DETLIN_LAMP);
00129 skip_if (lampframes == NULL);
00130
00131
00132 cpl_msg_info(cpl_func, "Load the data");
00133 skip_if( irplib_framelist_load_propertylist(lampframes, 0, 0, "^("
00134 NACO_PFITS_REGEXP_DETLIN_FIRST
00135 ")$", CPL_FALSE));
00136
00137 skip_if(irplib_framelist_load_propertylist_all(lampframes, 0, "^("
00138 NACO_PFITS_REGEXP_DETLIN
00139 ")$",
00140 CPL_FALSE));
00141
00142 skip_if(irplib_framelist_load_propertylist_all(darkframes, 0, "^("
00143 NACO_PFITS_REGEXP_DETLIN
00144 ")$", CPL_FALSE));
00145
00146 skip_if (naco_img_detlin_load(iset, ditval, parlist, lampframes,
00147 darkframes));
00148
00149 reflist = irplib_framelist_get_propertylist_const(lampframes, 0);
00150 bug_if (cpl_propertylist_copy_property_regexp(qclist, reflist, "^("
00151 NACO_PFITS_REGEXP_DETLIN_COPY
00152 ")$", 0));
00153
00154 irplib_framelist_delete(lampframes);
00155 lampframes = NULL;
00156 irplib_framelist_delete(darkframes);
00157 darkframes = NULL;
00158
00159
00160 cpl_msg_info(cpl_func, "Compute the linearity limit");
00161 lin_limit = naco_img_detlin_limit(iset);
00162 skip_if (lin_limit == NULL);
00163
00164
00165 cpl_msg_info(cpl_func, "Compute the linearity coefficients");
00166 #if defined USE_CPL_FIT_IMAGELIST_POLYNOMIAL
00167 residual = cpl_image_new(cpl_image_get_size_x(lin_limit),
00168 cpl_image_get_size_y(lin_limit),
00169 CPL_TYPE_FLOAT);
00170 bug_if(0);
00171 cpl_vector_dump(ditval, stderr);
00172 fitres = cpl_fit_imagelist_polynomial(ditval, iset, 1, 4, CPL_FALSE,
00173 CPL_TYPE_FLOAT, residual);
00174 skip_if (fitres == NULL);
00175
00176 bug_if (cpl_imagelist_set(fitres, residual, 4));
00177 residual = NULL;
00178 #else
00179 fitres = naco_imagelist_fit_polynomial(iset, cpl_vector_get_data(ditval), 4);
00180 skip_if (fitres == NULL);
00181 #endif
00182
00183
00184 cpl_msg_info(cpl_func, "Compute the bad pixels map");
00185 skip_if (naco_img_detlin_dit_diff(ditval));
00186 bpm = naco_img_detlin_bpm(iset, ditval, cpl_imagelist_get(fitres, 4));
00187 cpl_imagelist_delete(iset);
00188 iset = NULL;
00189
00190 skip_if (bpm==NULL);
00191
00192
00193 cpl_msg_info(cpl_func, "Save the products");
00194 skip_if (naco_img_detlin_save(framelist, parlist, qclist, fitres,
00195 lin_limit, bpm));
00196
00197 end_skip;
00198
00199 irplib_framelist_delete(allframes);
00200 irplib_framelist_delete(lampframes);
00201 irplib_framelist_delete(darkframes);
00202 cpl_image_delete(lin_limit);
00203 cpl_image_delete(residual);
00204 cpl_imagelist_delete(fitres);
00205 cpl_image_delete(bpm);
00206 cpl_imagelist_delete(iset);
00207 cpl_vector_delete(ditval);
00208 cpl_propertylist_delete(qclist);
00209
00210 return cpl_error_get_code();
00211 }
00212
00213
00223
00224 static cpl_error_code naco_img_detlin_load(cpl_imagelist * lamplist,
00225 cpl_vector * ditval,
00226 const cpl_parameterlist * parlist,
00227 const irplib_framelist * lamps,
00228 const irplib_framelist * darks)
00229 {
00230 cpl_image * imlamp = NULL;
00231 cpl_image * imdark = NULL;
00232 double refmean, refdit;
00233 double dit_min, dit_max;
00234 const int nb_lamps = irplib_framelist_get_size(lamps);
00235 int dit_var = 0;
00236 int i;
00237 const cpl_boolean force = naco_parameterlist_get_bool(parlist, RECIPE_STRING,
00238 NACO_PARAM_FORCE);
00239
00240
00241 bug_if (0);
00242
00243 bug_if (lamplist == NULL);
00244 bug_if (darks == NULL);
00245 bug_if (ditval == NULL);
00246
00247 skip_if_lt(nb_lamps, 3, "lamp images");
00248
00249
00250 skip_if (irplib_framelist_get_size(darks) != nb_lamps);
00251
00252
00253 cpl_msg_info(cpl_func, "Checking DIT consistency");
00254
00255 skip_if(irplib_framelist_contains(lamps, NACO_PFITS_DOUBLE_DIT,
00256 CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00257
00258 skip_if(irplib_framelist_contains(darks, NACO_PFITS_DOUBLE_DIT,
00259 CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00260
00261
00262 cpl_msg_info(cpl_func, "Compute the differences lamp - dark");
00263
00264
00265 cpl_msg_info(cpl_func, "Check the lamp stability");
00266
00267 bug_if(cpl_vector_set_size(ditval, nb_lamps));
00268 refmean = refdit = dit_max = dit_min = 0.0;
00269 for (i=0 ; i < nb_lamps ; i++) {
00270 const char * lampname
00271 = cpl_frame_get_filename(irplib_framelist_get_const(lamps, i));
00272 const char * darkname
00273 = cpl_frame_get_filename(irplib_framelist_get_const(darks, i));
00274
00275
00276 const cpl_propertylist * plist
00277 = irplib_framelist_get_propertylist_const(lamps, i);
00278 const double dit_lamp = (double)naco_pfits_get_dit(plist);
00279 double dit_dark;
00280
00281
00282 bug_if (0);
00283
00284
00285 plist = irplib_framelist_get_propertylist_const(darks, i);
00286 dit_dark = naco_pfits_get_dit(plist);
00287 bug_if (0);
00288
00289
00290 irplib_ensure(fabs(dit_dark-dit_lamp) <= 1e-3,
00291 CPL_ERROR_INCOMPATIBLE_INPUT,
00292 "LAMP-DIT=%g and DARK-DIT=%g differ by more than %g",
00293 dit_lamp, dit_dark, 1e-3);
00294
00295 irplib_check(imlamp = cpl_image_load(lampname, CPL_TYPE_FLOAT, 0, 0),
00296 "Could not load FITS-image from %s", lampname);
00297
00298 cpl_image_delete(imdark);
00299 irplib_check(imdark = cpl_image_load(darkname, CPL_TYPE_FLOAT, 0, 0),
00300 "Could not load FITS-image from %s", darkname);
00301
00302 bug_if (cpl_image_subtract(imlamp, imdark));
00303
00304
00305 if (i > 0 && dit_lamp != refdit) {
00306 bug_if(cpl_imagelist_set(lamplist, imlamp, dit_var));
00307 imlamp = NULL;
00308 bug_if(cpl_vector_set(ditval, dit_var, dit_lamp));
00309 dit_var++;
00310 if (dit_lamp > dit_max) dit_max = dit_lamp;
00311 if (dit_lamp < dit_min) dit_min = dit_lamp;
00312 } else {
00313 const double mean = cpl_image_get_mean(imlamp);
00314
00315 cpl_image_delete(imlamp);
00316 imlamp = NULL;
00317
00318 bug_if(0);
00319
00320 if (i == 0) {
00321 refmean = mean;
00322 dit_max = dit_min = refdit = dit_lamp;
00323 } else if ((mean - refmean) > refmean * (DETLIN_STABILITY)) {
00324 irplib_ensure(force, CPL_ERROR_INCOMPATIBLE_INPUT,
00325 "Relative level difference # %d is too high:"
00326 " (%g - %g)/%g > %g", i+1, mean, refmean,
00327 refmean, (DETLIN_STABILITY));
00328
00329 cpl_msg_warning(cpl_func, "Relative level difference # %d "
00330 "is high: (%g - %g)/%g > %g", i+1, mean,
00331 refmean, refmean, (DETLIN_STABILITY));
00332 }
00333 }
00334 }
00335
00336
00337 skip_if_lt(i - dit_var, 2, "lamp frames for stability check");
00338
00339 if (dit_min >= dit_max) {
00340 cpl_msg_error(cpl_func, "Too small DIT range: %g - %g = %g", dit_max,
00341 dit_min, dit_max - dit_min);
00342 cpl_error_set(cpl_func, CPL_ERROR_DATA_NOT_FOUND);
00343 skip_if(1);
00344 }
00345
00346 bug_if(cpl_vector_set_size(ditval, dit_var));
00347
00348 end_skip;
00349
00350 cpl_image_delete(imlamp);
00351 cpl_image_delete(imdark);
00352
00353 return cpl_error_get_code();
00354 }
00355
00356
00362
00363 static cpl_image * naco_img_detlin_limit(const cpl_imagelist * iset)
00364 {
00365 cpl_image * lin_limit = NULL;
00366 int size_x, size_y;
00367 float * plin_limit;
00368 const float * pim1;
00369 const float * pim2;
00370 float ref_diff, cur_diff;
00371 int i, j;
00372
00373
00374 if (cpl_error_get_code()) return NULL;
00375
00376 skip_if_lt(cpl_imagelist_get_size(iset), 3, "images to compute the "
00377 "detector linearity limit");
00378
00379
00380 size_x = cpl_image_get_size_x(cpl_imagelist_get_const(iset, 0));
00381 size_y = cpl_image_get_size_y(cpl_imagelist_get_const(iset, 0));
00382
00383
00384 lin_limit = cpl_image_new(size_x, size_y, CPL_TYPE_FLOAT);
00385
00386 skip_if (lin_limit == NULL);
00387
00388 plin_limit = cpl_image_get_data_float(lin_limit);
00389
00390 bug_if(0);
00391
00392
00393 for (i=0 ; i<size_x*size_y ; i++) {
00394 pim1 = cpl_image_get_data_float_const(cpl_imagelist_get_const(iset, 0));
00395 pim2 = cpl_image_get_data_float_const(cpl_imagelist_get_const(iset, 1));
00396 ref_diff = pim2[i] - pim1[i];
00397 for (j=1 ; j<cpl_imagelist_get_size(iset)-1 ; j++) {
00398 pim1 = cpl_image_get_data_float_const(
00399 cpl_imagelist_get_const(iset, j));
00400 pim2 = cpl_image_get_data_float_const(
00401 cpl_imagelist_get_const(iset, j+1));
00402 cur_diff = pim2[i] - pim1[i];
00403 if (cur_diff < DETLIN_LIMIT*ref_diff) {
00404
00405 plin_limit[i] = pim1[i];
00406 break;
00407 }
00408
00409 if (j+1 == cpl_imagelist_get_size(iset)-1)
00410 plin_limit[i] = (float)0.0;
00411 }
00412 }
00413
00414 end_skip;
00415
00416 return lin_limit;
00417 }
00418
00419
00426
00427 static cpl_error_code naco_img_detlin_dit_diff(cpl_vector * self)
00428 {
00429
00430 double * dits;
00431 int i;
00432
00433 bug_if(0);
00434 bug_if(self == NULL);
00435
00436 dits = cpl_vector_get_data(self);
00437
00438 for (i = cpl_vector_get_size(self)-1; i > 0 ; i--) {
00439 dits[i] -= dits[i-1];
00440
00441 if (dits[i] == 0.0) break;
00442
00443 }
00444
00445 if (i > 0) {
00446 cpl_msg_error(cpl_func, "Consecutive (%d and %d) DITS are equal: "
00447 "%g", i-1, i, dits[i-1]);
00448
00449 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
00450 skip_if(1);
00451 }
00452
00453 end_skip;
00454
00455 return cpl_error_get_code();
00456
00457 }
00458
00459
00460
00468
00469 static cpl_image * naco_img_detlin_bpm(const cpl_imagelist * iset,
00470 const cpl_vector * ditdiff,
00471 const cpl_image * err_im)
00472 {
00473 cpl_image * imdiff = NULL;
00474 cpl_image * bpm = NULL;
00475 int * pbpm;
00476 const double * perr_im;
00477 const float * pim1;
00478 const float * pim2;
00479 float * pimdiff;
00480 const double * ditval = cpl_vector_get_data_const(ditdiff);
00481 float dit_ref, curr_val;
00482 int size_x, size_y;
00483 int ii, i, j, k;
00484
00485
00486 bug_if(0);
00487 skip_if_lt(cpl_imagelist_get_size(iset), 3, "images to compute the "
00488 "bad pixel map");
00489
00490
00491 size_x = cpl_image_get_size_x(cpl_imagelist_get_const(iset, 0));
00492 size_y = cpl_image_get_size_y(cpl_imagelist_get_const(iset, 0));
00493 bug_if(0);
00494
00495
00496
00497 bpm = cpl_image_new(size_x, size_y, CPL_TYPE_INT);
00498 bug_if(0);
00499 pbpm = cpl_image_get_data_int(bpm);
00500
00501 imdiff = cpl_image_new(size_x, 1, CPL_TYPE_FLOAT);
00502 bug_if(0);
00503 pimdiff = cpl_image_get_data_float(imdiff);
00504
00505
00506 dit_ref = (float)ditval[1];
00507 perr_im = cpl_image_get_data_double_const(err_im);
00508
00509 for (ii = 0, j=0 ; j < size_y ; j++) {
00510 pim1 = cpl_image_get_data_float_const(cpl_imagelist_get_const(iset, 1));
00511 pim2 = cpl_image_get_data_float_const(cpl_imagelist_get_const(iset, 0));
00512
00513 for (i=0 ; i < size_x ; i++, ii++) {
00514 const float fdiff = pim1[ii] - pim2[ii];
00515
00516 pimdiff[i] = fdiff;
00517
00518
00519 if (fdiff * dit_ref < 0.0) pbpm[ii] |= 2;
00520
00521
00522 if (perr_im[ii] > DETLIN_MAX_RESI) pbpm[ii] |= 4;
00523 }
00524
00525 for (k=1 ; k < cpl_imagelist_get_size(iset)-1 ; k++) {
00526 const float dit_diff = ditval[k+1] * DETLIN_MAX_GRAD;
00527
00528 pim2 = pim1;
00529 pim1 = cpl_image_get_data_float_const(
00530 cpl_imagelist_get_const(iset, k+1));
00531
00532 ii -= size_x;
00533 for (i=0 ; i < size_x ; i++, ii++) {
00534 if ((pbpm[ii] & 1) == 0) {
00535
00536 const float fdiff = pimdiff[i];
00537
00538 curr_val = pim1[ii] - pim2[ii];
00539 if (dit_diff * dit_ref < 0.0
00540 ? (curr_val * dit_ref < fdiff * dit_diff)
00541 : (curr_val * dit_ref > fdiff * dit_diff)) {
00542 pbpm[ii] |= 1;
00543 }
00544 }
00545 }
00546 }
00547 }
00548
00549 end_skip;
00550
00551 cpl_image_delete(imdiff);
00552
00553 return bpm;
00554 }
00555
00556
00567
00568 static cpl_error_code naco_img_detlin_save(cpl_frameset * set,
00569 const cpl_parameterlist * parlist,
00570 const cpl_propertylist * qclist,
00571 const cpl_imagelist * fitres,
00572 const cpl_image * lin_limit,
00573 const cpl_image * bpm)
00574 {
00575
00576 bug_if(0);
00577
00578
00579 skip_if (irplib_dfs_save_image(set, parlist, set,
00580 cpl_imagelist_get_const(fitres, 0),
00581 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00582 NACO_IMG_DETLIN_A, qclist, NULL,
00583 naco_pipe_id,
00584 RECIPE_STRING "_A" CPL_DFS_FITS));
00585
00586
00587 skip_if (irplib_dfs_save_image(set, parlist, set,
00588 cpl_imagelist_get_const(fitres, 1),
00589 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00590 NACO_IMG_DETLIN_B, qclist, NULL, naco_pipe_id,
00591 RECIPE_STRING "_B" CPL_DFS_FITS));
00592
00593
00594 skip_if (irplib_dfs_save_image(set, parlist, set,
00595 cpl_imagelist_get_const(fitres, 2),
00596 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00597 NACO_IMG_DETLIN_C, qclist, NULL, naco_pipe_id,
00598 RECIPE_STRING "_C" CPL_DFS_FITS));
00599
00600
00601 skip_if (irplib_dfs_save_image(set, parlist, set,
00602 cpl_imagelist_get_const(fitres, 3),
00603 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00604 NACO_IMG_DETLIN_D, qclist, NULL, naco_pipe_id,
00605 RECIPE_STRING "_D" CPL_DFS_FITS));
00606
00607
00608 skip_if (irplib_dfs_save_image(set, parlist, set,
00609 cpl_imagelist_get_const(fitres, 4),
00610 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00611 NACO_IMG_DETLIN_Q, qclist, NULL, naco_pipe_id,
00612 RECIPE_STRING "_Q" CPL_DFS_FITS));
00613
00614
00615 skip_if (irplib_dfs_save_image(set, parlist, set, lin_limit, CPL_BPP_IEEE_FLOAT,
00616 RECIPE_STRING, NACO_IMG_DETLIN_LIM, qclist, NULL,
00617 naco_pipe_id,
00618 RECIPE_STRING "_limit" CPL_DFS_FITS));
00619
00620
00621 skip_if (irplib_dfs_save_image(set, parlist, set, bpm, CPL_BPP_8_UNSIGNED,
00622 RECIPE_STRING, NACO_IMG_DETLIN_BPM, qclist, NULL,
00623 naco_pipe_id,
00624 RECIPE_STRING "_bpm" CPL_DFS_FITS));
00625
00626 end_skip;
00627
00628 return cpl_error_get_code();
00629 }
00630
00631
00632
00633
00662
00663 static cpl_imagelist * naco_imagelist_fit_polynomial(
00664 const cpl_imagelist * ilist,
00665 const double * dit,
00666 int deg)
00667 {
00668 cpl_imagelist * fitres;
00669 const cpl_image * image;
00670 int ni, nx, ny;
00671
00672
00673 cpl_ensure(ilist != NULL, CPL_ERROR_NULL_INPUT, NULL);
00674 cpl_ensure(dit != NULL, CPL_ERROR_NULL_INPUT, NULL);
00675 cpl_ensure(deg > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00676
00677 ni = cpl_imagelist_get_size(ilist);
00678 cpl_ensure(ni >= deg, CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
00679
00680 image = cpl_imagelist_get_const(ilist, 0);
00681
00682 cpl_ensure(cpl_image_get_type(image) == CPL_TYPE_FLOAT,
00683 CPL_ERROR_TYPE_MISMATCH, NULL);
00684
00685 nx = cpl_image_get_size_x(image);
00686 ny = cpl_image_get_size_y(image);
00687
00688 do {
00689
00690 double f, f_prod;
00691 double * pimad;
00692 const float* pi;
00693 cpl_matrix * mv;
00694 cpl_matrix * mb;
00695 cpl_matrix * mx;
00696 double * pv;
00697 const int npix = nx * ny;
00698 int nsing = 0;
00699 int i, j, k;
00700 cpl_errorstate prestate = cpl_errorstate_get();
00701
00702
00703
00704 fitres = cpl_imagelist_new();
00705 for (i=0; i < deg+1; i++) {
00706 cpl_imagelist_set(fitres, cpl_image_new(nx, ny, CPL_TYPE_DOUBLE),
00707 i);
00708 }
00709
00710
00711 pv = cpl_malloc(ni * deg * sizeof(double));
00712 mv = cpl_matrix_wrap(ni, deg, pv);
00713
00714
00715
00716 mb = cpl_matrix_wrap(ni, 1, (double*)dit);
00717
00718
00719 for (i=0; i < npix; i++) {
00720
00721 for (j=0; j < ni; j++) {
00722 pi = cpl_image_get_data_const(cpl_imagelist_get_const(ilist,j));
00723 f_prod = f = (double)pi[i];
00724 pv[deg * j] = f;
00725 for (k=1; k < deg; k++) {
00726 f_prod *= f;
00727 pv[deg * j + k] = f_prod;
00728 }
00729 }
00730
00731
00732
00733
00734 mx = cpl_matrix_solve_normal(mv, mb);
00735
00736 if (mx == NULL) {
00737 cpl_errorstate_set(prestate);
00738 for (k=0; k < deg+1; k++) {
00739 pimad =
00740 cpl_image_get_data_double(cpl_imagelist_get(fitres,k));
00741 pimad[i] = 0.0;
00742 }
00743 nsing++;
00744 } else {
00745 double err, sq_err;
00746 const double * px = cpl_matrix_get_data(mx);
00747
00748
00749 for (k=0; k < deg; k++) {
00750 pimad = cpl_image_get_data_double(
00751 cpl_imagelist_get(fitres, k));
00752 pimad[i] = px[k];
00753 }
00754
00755
00756 sq_err=0.0;
00757 for (j=0; j < ni; j++) {
00758
00759 err = dit[j];
00760
00761 for (k=0; k < deg; k++)
00762 err -= px[k] * pv[deg * j + k];
00763 sq_err += err * err;
00764 }
00765 sq_err /= (double)ni;
00766 pimad=cpl_image_get_data_double(cpl_imagelist_get(fitres, deg));
00767 pimad[i] = sq_err;
00768 cpl_matrix_delete(mx);
00769 }
00770 }
00771
00772 cpl_matrix_delete(mv);
00773 (void)cpl_matrix_unwrap(mb);
00774
00775 if (nsing == npix) {
00776 cpl_imagelist_delete(fitres);
00777 cpl_ensure(0, CPL_ERROR_SINGULAR_MATRIX, NULL);
00778 }
00779
00780
00781 } while (0);
00782
00783
00784 return fitres;
00785 }