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 #include <string.h>
00033 #include <math.h>
00034 #include <errno.h>
00035
00036 #include <cxmemory.h>
00037 #include <cxstrutils.h>
00038 #include <cxutils.h>
00039
00040 #include <cpl_msg.h>
00041 #include <cpl_parameter.h>
00042
00043 #include "gimacros.h"
00044 #include "gialias.h"
00045 #include "giarray.h"
00046 #include "gimatrix.h"
00047 #include "gichebyshev.h"
00048 #include "gimath.h"
00049 #include "gibias.h"
00050
00051
00060 struct GiBiasResults {
00061
00062 cxdouble mean;
00063 cxdouble sigma;
00064 cxdouble rms;
00065
00066 cx_string* limits;
00067
00068 cpl_matrix* coeffs;
00069
00070 cpl_image* model;
00071
00072 };
00073
00074 typedef struct GiBiasResults GiBiasResults;
00075
00076
00077
00078
00079
00080
00081 inline static void
00082 _giraffe_biasresults_clear(GiBiasResults *self)
00083 {
00084
00085 if (self != NULL) {
00086
00087 self->mean = 0.;
00088 self->sigma = 0.;
00089 self->rms = 0.;
00090
00091 if (self->limits) {
00092 cx_string_delete(self->limits);
00093 self->limits = NULL;
00094 }
00095
00096 if (self->coeffs) {
00097 cpl_matrix_delete(self->coeffs);
00098 self->coeffs = NULL;
00099 }
00100
00101 if (self->model) {
00102 cpl_image_delete(self->model);
00103 self->model = NULL;
00104 }
00105
00106 }
00107
00108 return;
00109
00110 }
00111
00112
00113
00114
00115
00116
00117 inline static void
00118 _giraffe_method_string(cx_string *string, GiBiasMethod method,
00119 GiBiasOption option)
00120 {
00121
00122 switch (method) {
00123 case GIBIAS_METHOD_UNIFORM:
00124 cx_string_set(string, "UNIFORM");
00125 break;
00126
00127 case GIBIAS_METHOD_PLANE:
00128 cx_string_set(string, "PLANE");
00129 break;
00130
00131 case GIBIAS_METHOD_CURVE:
00132 cx_string_set(string, "CURVE");
00133 break;
00134
00135 case GIBIAS_METHOD_PROFILE:
00136 cx_string_set(string, "PROFILE");
00137 break;
00138
00139 case GIBIAS_METHOD_MASTER:
00140 cx_string_set(string, "MASTER");
00141 break;
00142
00143 case GIBIAS_METHOD_ZMASTER:
00144 cx_string_set(string, "ZMASTER");
00145 break;
00146
00147 default:
00148 break;
00149 }
00150
00151 if (option != GIBIAS_OPTION_UNDEFINED) {
00152 switch (option) {
00153 case GIBIAS_OPTION_PLANE:
00154 cx_string_append(string, "+PLANE");
00155 break;
00156
00157 case GIBIAS_OPTION_CURVE:
00158 cx_string_append(string, "+CURVE");
00159 break;
00160
00161 default:
00162 break;
00163 }
00164 }
00165
00166 return;
00167
00168 }
00169
00170
00171 inline static void
00172 _giraffe_stringify_coefficients(cx_string *string, cpl_matrix *matrix)
00173 {
00174
00175 register cxint i, j;
00176
00177 cxchar *tmp = cx_line_alloc();
00178
00179 cxint nr = cpl_matrix_get_nrow(matrix);
00180 cxint nc = cpl_matrix_get_ncol(matrix);
00181
00182 cxsize sz = cx_line_max();
00183
00184 cxdouble *data = cpl_matrix_get_data(matrix);
00185
00186
00187 for (i = 0; i < nr; i++) {
00188 for (j = 0; j < nc; j++) {
00189 snprintf(tmp, sz, "%g", data[i * nc + j]);
00190 cx_string_append(string, tmp);
00191
00192 if (i != nr - 1 || j < nc - 1) {
00193 cx_string_append(string, ":");
00194 }
00195 }
00196 }
00197
00198 cx_free(tmp);
00199
00200 return;
00201
00202 }
00203
00204
00220 inline static cxbool
00221 _giraffe_compare_overscans(const GiImage* image1, const GiImage* image2)
00222 {
00223
00224 cxint32 l1ovscx = -1;
00225 cxint32 l1ovscy = -1;
00226 cxint32 l1prscx = -1;
00227 cxint32 l1prscy = -1;
00228 cxint32 l2ovscx = -1;
00229 cxint32 l2ovscy = -1;
00230 cxint32 l2prscx = -1;
00231 cxint32 l2prscy = -1;
00232
00233 cpl_propertylist *l1, *l2;
00234
00235
00236 cx_assert(image1 != NULL && image2 != NULL);
00237
00238 l1 = giraffe_image_get_properties(image1);
00239 l2 = giraffe_image_get_properties(image2);
00240
00241 if (cpl_propertylist_has(l1, GIALIAS_OVSCX)) {
00242 l1ovscx = cpl_propertylist_get_int(l1, GIALIAS_OVSCX);
00243 }
00244 if (cpl_propertylist_has(l1, GIALIAS_OVSCY)) {
00245 l1ovscy = cpl_propertylist_get_int(l1, GIALIAS_OVSCY);
00246 }
00247 if (cpl_propertylist_has(l1, GIALIAS_PRSCX)) {
00248 l1prscx = cpl_propertylist_get_int(l1, GIALIAS_PRSCX);
00249 }
00250 if (cpl_propertylist_has(l1, GIALIAS_PRSCY)) {
00251 l1prscy = cpl_propertylist_get_int(l1, GIALIAS_PRSCY);
00252 }
00253
00254 if (cpl_propertylist_has(l2, GIALIAS_OVSCX)) {
00255 l2ovscx = cpl_propertylist_get_int(l2, GIALIAS_OVSCX);
00256 }
00257 if (cpl_propertylist_has(l2, GIALIAS_OVSCY)) {
00258 l2ovscy = cpl_propertylist_get_int(l2, GIALIAS_OVSCY);
00259 }
00260 if (cpl_propertylist_has(l2, GIALIAS_PRSCX)) {
00261 l2prscx = cpl_propertylist_get_int(l2, GIALIAS_PRSCX);
00262 }
00263 if (cpl_propertylist_has(l2, GIALIAS_PRSCY)) {
00264 l2prscy = cpl_propertylist_get_int(l2, GIALIAS_PRSCY);
00265 }
00266
00267 if (l1ovscx != l2ovscx || l1ovscy != l2ovscy) {
00268 return FALSE;
00269 }
00270
00271 if (l1prscx != l2prscx || l1prscy != l2prscy) {
00272 return FALSE;
00273 }
00274
00275 return TRUE;
00276
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 inline static cpl_matrix*
00294 _giraffe_bias_get_areas(const cxchar* string)
00295 {
00296
00297 cxchar** regions = NULL;
00298
00299 cpl_matrix* areas = NULL;
00300
00301
00302 cx_assert(string != NULL);
00303
00304 regions = cx_strsplit(string, ",", -1);
00305
00306 if (regions == NULL) {
00307
00308 return NULL;
00309
00310 }
00311 else {
00312
00313 const cxsize nvalues = 4;
00314
00315 cxsize i = 0;
00316 cxsize nregions = 0;
00317
00318 while (regions[i] != NULL) {
00319 ++i;
00320 }
00321
00322 nregions = i;
00323 areas = cpl_matrix_new(nregions, nvalues);
00324
00325 i = 0;
00326 while (regions[i] != NULL) {
00327
00328 register cxsize j = 0;
00329
00330 cxchar** limits = cx_strsplit(regions[i], ":", nvalues);
00331
00332
00333 if (limits == NULL) {
00334
00335 cpl_matrix_delete(areas);
00336 areas = NULL;
00337
00338 return NULL;
00339
00340 }
00341
00342 for (j = 0; j < nvalues; ++j) {
00343
00344 cxchar* last = NULL;
00345
00346 cxint status = 0;
00347 cxlong value = 0;
00348
00349
00350 if (limits[j] == NULL || *limits[j] == '\0') {
00351 break;
00352 }
00353
00354 status = errno;
00355 errno = 0;
00356
00357 value = strtol(limits[j], &last, 10);
00358
00359
00360
00361
00362
00363 if ((errno == ERANGE &&
00364 (value == LONG_MAX || value == LONG_MIN)) ||
00365 (errno != 0 && value == 0)) {
00366
00367 break;
00368
00369 }
00370
00371 errno = status;
00372
00373
00374
00375
00376
00377
00378 if (*last != '\0') {
00379 break;
00380 }
00381
00382 cpl_matrix_set(areas, i, j, value);
00383
00384 }
00385
00386 cx_strfreev(limits);
00387 limits = NULL;
00388
00389 if (j != nvalues) {
00390
00391 cpl_matrix_delete(areas);
00392 areas = NULL;
00393
00394 cx_strfreev(regions);
00395 regions = NULL;
00396
00397 return NULL;
00398
00399 }
00400
00401 ++i;
00402
00403 }
00404
00405 cx_strfreev(regions);
00406 regions = NULL;
00407
00408 }
00409
00410 return areas;
00411
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 inline static cxint
00462 _giraffe_bias_compute_mean(GiBiasResults* results, const cpl_image* image,
00463 const cpl_matrix* areas, cxdouble kappa, cxint numiter,
00464 cxdouble maxfraction)
00465 {
00466
00467 const cxchar* const fctid = "giraffe_bias_compute_mean";
00468
00469
00470 const cxdouble* pdimg = NULL;
00471
00472 cxint j, l, k;
00473 cxint img_dimx, img_dimy;
00474 cxint ba_num_cols;
00475 cxint ba_num_rows;
00476 cxint curriter = 0;
00477 cxint x0, x1, x2, x3;
00478
00479 cxdouble sigma = 0.;
00480
00481 cxlong ntotal = 0L;
00482 cxlong naccepted = 0L;
00483 cxlong n = 0L;
00484 cxlong pixcount = 0L;
00485
00486 cxdouble currfraction = 2.;
00487
00488 cx_string* tmp = NULL;
00489
00490 cpl_matrix* matrix_zz1;
00491 cpl_matrix* matrix_zz1diff;
00492
00493
00494
00495
00496
00497
00498 if (results->limits == NULL) {
00499 cpl_msg_info(fctid, "Unable to store biaslimits return parameter, "
00500 "aborting...");
00501 return -3;
00502 }
00503
00504 if (cpl_image_get_type(image) != CPL_TYPE_DOUBLE) {
00505 cpl_msg_info(fctid, "Only images allowed of type double, "
00506 "aborting ...");
00507 return -3;
00508 }
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 if (areas == NULL) {
00520 cpl_msg_info(fctid, "Bias Areas: Missing bias areas, "
00521 "aborting ...");
00522 return -1;
00523 }
00524
00525 ba_num_cols = cpl_matrix_get_ncol(areas);
00526 ba_num_rows = cpl_matrix_get_nrow(areas);
00527
00528 for (j = 0; j < ba_num_rows; j++) {
00529 x3 = (cxint) cpl_matrix_get(areas, j, 3);
00530 x2 = (cxint) cpl_matrix_get(areas, j, 2);
00531 x1 = (cxint) cpl_matrix_get(areas, j, 1);
00532 x0 = (cxint) cpl_matrix_get(areas, j, 0);
00533
00534 ntotal += (cxulong) ((x3 - x2 + 1) * (x1 - x0 + 1));
00535 }
00536
00537 if (ntotal <= 0) {
00538 cpl_msg_info(fctid, "Bias Areas: Inconsistent specification, "
00539 "aborting ...");
00540 return -1;
00541 }
00542
00543 matrix_zz1 = cpl_matrix_new(ntotal, 1);
00544 matrix_zz1diff = cpl_matrix_new(ntotal, 1);
00545
00546
00547
00548
00549
00550
00551 img_dimx = cpl_image_get_size_x(image);
00552 img_dimy = cpl_image_get_size_y(image);
00553
00554 cx_string_set(results->limits, "");
00555
00556 for (j = 0; j < ba_num_rows; j++) {
00557
00558 x3 = (cxint) cpl_matrix_get(areas, j, 3);
00559 x2 = (cxint) cpl_matrix_get(areas, j, 2);
00560 x1 = (cxint) cpl_matrix_get(areas, j, 1);
00561 x0 = (cxint) cpl_matrix_get(areas, j, 0);
00562
00563 if ((x0 > img_dimx) || (x1 > img_dimx) ||
00564 (x2 > img_dimy) || (x3 > img_dimy)) {
00565 continue;
00566 }
00567
00568 tmp = cx_string_new();
00569
00570 cx_string_sprintf(tmp, "%d:%d:%d:%d;", x0, x1, x2, x3);
00571 cx_string_append(results->limits, cx_string_get(tmp));
00572
00573 cx_string_delete(tmp);
00574 tmp = NULL;
00575
00576 pdimg = cpl_image_get_data_double_const(image);
00577
00578 for (l = x2; l < x3 + 1; l++) {
00579 for (k = x0; k < x1 + 1; k++) {
00580 cpl_matrix_set(matrix_zz1, n, 1, pdimg[k + l * img_dimx]);
00581 n++;
00582 }
00583 }
00584 }
00585
00586 if (n != ntotal) {
00587 cpl_msg_info(fctid, "Bias Areas: Validation failed, aborting ...");
00588
00589 cpl_matrix_delete(matrix_zz1);
00590 cpl_matrix_delete(matrix_zz1diff);
00591
00592 return -3;
00593 }
00594
00595 cpl_msg_info(fctid, "Bias Areas: Using %s",
00596 cx_string_get(results->limits));
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 cpl_msg_info(fctid, "Sigma Clipping : Start");
00608
00609 naccepted = ntotal;
00610
00611 while ((naccepted > 0) && (curriter < numiter) &&
00612 (currfraction > maxfraction)) {
00613
00614 cxdouble ksigma = 0.;
00615
00616 results->mean = cpl_matrix_get_mean(matrix_zz1);
00617 sigma = giraffe_matrix_sigma_mean(matrix_zz1, results->mean);
00618
00619 for (k = 0; k < cpl_matrix_get_nrow(matrix_zz1); k++) {
00620 cpl_matrix_set(matrix_zz1diff, k, 0,
00621 cpl_matrix_get(matrix_zz1, k, 0) - results->mean);
00622 }
00623
00624 cpl_msg_info(fctid, "bias[%d]: mean = %5g, sigma = %6.3g, "
00625 "ratio = %6.3g, accepted = %ld\n", curriter,
00626 results->mean, sigma, currfraction, naccepted);
00627
00628 ksigma = sigma * kappa;
00629
00630 pixcount = 0L;
00631 for (l = 0; l < cpl_matrix_get_nrow(matrix_zz1); l++) {
00632 if (fabs(cpl_matrix_get(matrix_zz1diff, l, 0)) > ksigma) {
00633 continue;
00634 }
00635
00636 cpl_matrix_set(matrix_zz1, pixcount, 0,
00637 cpl_matrix_get(matrix_zz1, l, 0));
00638 ++pixcount;
00639 }
00640
00641 cpl_matrix_resize(matrix_zz1, 0, 0, 0, pixcount -
00642 cpl_matrix_get_nrow(matrix_zz1));
00643
00644 cpl_matrix_resize(matrix_zz1diff, 0, 0, 0, pixcount -
00645 cpl_matrix_get_nrow(matrix_zz1diff));
00646
00647 if (pixcount == naccepted) {
00648 break;
00649 }
00650
00651 naccepted = pixcount;
00652
00653 currfraction = (cxdouble) naccepted / (cxdouble) ntotal;
00654 ++curriter;
00655 }
00656
00657 cpl_msg_info(fctid, "Sigma Clipping : End");
00658
00659
00660
00661
00662
00663
00664 results->mean = cpl_matrix_get_mean(matrix_zz1);
00665 results->rms = giraffe_matrix_sigma_mean(matrix_zz1, results->mean);
00666
00667 results->sigma = results->rms / sqrt(cpl_matrix_get_nrow(matrix_zz1));
00668
00669
00670 cpl_msg_info(fctid, "Sigma Clipping Results : bias[%d]: mean = %5g, "
00671 "sigma = %6.3g, ratio = %6.3g, accepted=%ld\n", curriter,
00672 results->mean, results->rms, currfraction, naccepted);
00673
00674
00675
00676
00677
00678
00679 if (matrix_zz1 != NULL) {
00680 cpl_matrix_delete(matrix_zz1);
00681 }
00682
00683 if (matrix_zz1diff != NULL) {
00684 cpl_matrix_delete(matrix_zz1diff);
00685 }
00686
00687 return EXIT_SUCCESS;
00688
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 inline static cxint
00745 _giraffe_bias_compute_plane(GiBiasResults* results, const cpl_image* image,
00746 const cpl_matrix* areas, cxdouble kappa,
00747 cxint numiter, cxdouble maxfraction)
00748 {
00749
00750 const cxchar* const fctid = "giraffe_bias_compute_plane";
00751
00752
00753 cxint j = 0;
00754 cxint nx = 0;
00755 cxint ny = 0;
00756 cxint nareas = 0;
00757 cxint iteration = 0;
00758
00759 cxsize n = 0;
00760 cxsize ntotal = 0;
00761 cxsize naccepted = 0;
00762
00763 cxdouble fraction = 1.;
00764 cxdouble sigma = 0.;
00765
00766 cpl_matrix* xbs = NULL;
00767 cpl_matrix* ybs = NULL;
00768 cpl_matrix* zbs = NULL;
00769 cpl_matrix* coeffs = NULL;
00770
00771
00772 cx_assert(results->limits != NULL);
00773 cx_assert(results->coeffs == NULL);
00774
00775 cx_assert(areas != NULL);
00776
00777 cx_assert(cpl_image_get_type(image) == CPL_TYPE_DOUBLE);
00778
00779
00780
00781
00782
00783
00784 nareas = cpl_matrix_get_nrow(areas);
00785
00786 for (j = 0; j < nareas; j++) {
00787
00788 cxint x3 = (cxint) cpl_matrix_get(areas, j, 3);
00789 cxint x2 = (cxint) cpl_matrix_get(areas, j, 2);
00790 cxint x1 = (cxint) cpl_matrix_get(areas, j, 1);
00791 cxint x0 = (cxint) cpl_matrix_get(areas, j, 0);
00792
00793 ntotal += (cxsize) ((x3 - x2 + 1) * (x1 - x0 + 1));
00794
00795 }
00796
00797 if (ntotal <= 0) {
00798
00799 cpl_msg_info(fctid, "Bias Areas: Inconsistent specification, "
00800 "aborting ...");
00801 return -1;
00802
00803 }
00804
00805 nx = cpl_image_get_size_x(image);
00806 ny = cpl_image_get_size_y(image);
00807
00808 cpl_msg_info(fctid, "Bias Areas: specified are %zu points in %dx%d "
00809 "image", ntotal, nx, ny);
00810
00811
00812
00813
00814
00815
00816 results->mean = 0.;
00817 results->sigma = 0.;
00818 results->rms = 0.;
00819
00820 cx_string_set(results->limits, "");
00821
00822 xbs = cpl_matrix_new(ntotal, 1);
00823 ybs = cpl_matrix_new(ntotal, 1);
00824 zbs = cpl_matrix_new(1, ntotal);
00825
00826 for (j = 0; j < nareas; ++j) {
00827
00828 const cxdouble* _img = cpl_image_get_data_double_const(image);
00829
00830 cxint k = 0;
00831
00832 cx_string* tmp = NULL;
00833
00834
00835 cxint x3 = (cxint)cpl_matrix_get(areas, j, 3);
00836 cxint x2 = (cxint)cpl_matrix_get(areas, j, 2);
00837 cxint x1 = (cxint)cpl_matrix_get(areas, j, 1);
00838 cxint x0 = (cxint)cpl_matrix_get(areas, j, 0);
00839
00840 if ((x0 > nx) || (x1 > nx) || (x2 > ny) || (x3 > ny)) {
00841 continue;
00842 }
00843
00844 tmp = cx_string_new();
00845
00846 cx_string_sprintf(tmp, "%d:%d:%d:%d;", x0, x1, x2, x3);
00847 cx_string_append(results->limits, cx_string_get(tmp));
00848
00849 cx_string_delete(tmp);
00850 tmp = NULL;
00851
00852 for (k = x2; k < x3 + 1; ++k) {
00853
00854 register cxint l = 0;
00855
00856
00857 for (l = x0; l < x1 + 1; ++l) {
00858
00859 cpl_matrix_set(xbs, n, 0, l);
00860 cpl_matrix_set(ybs, n, 0, k);
00861 cpl_matrix_set(zbs, 0, n, _img[k * nx + l]);
00862 ++n;
00863
00864 }
00865
00866 }
00867
00868 }
00869
00870 cpl_matrix_set_size(xbs, n, 1);
00871 cpl_matrix_set_size(ybs, n, 1);
00872 cpl_matrix_set_size(zbs, 1, n);
00873
00874 if (n != ntotal) {
00875
00876 cpl_msg_info(fctid, "Bias Areas: Validation failed, aborting...");
00877
00878 cpl_matrix_delete(xbs);
00879 cpl_matrix_delete(ybs);
00880 cpl_matrix_delete(zbs);
00881
00882 return -1;
00883
00884 }
00885
00886 ntotal = n;
00887
00888 cpl_msg_info(fctid, "Bias Areas: Using %s [%zu pixels]",
00889 cx_string_get(results->limits), ntotal);
00890
00891
00892
00893
00894
00895
00896 cpl_msg_info(fctid, "Sigma Clipping : Start");
00897
00898 naccepted = ntotal;
00899
00900 while ((naccepted > 0) && (iteration < numiter) &&
00901 (fraction > maxfraction)) {
00902
00903 cxsize k = 0;
00904
00905 cxdouble ksigma = 0.;
00906
00907 cpl_matrix* base = NULL;
00908 cpl_matrix* fit = NULL;
00909
00910
00911 base = cpl_matrix_new(3, naccepted);
00912
00913 if (base == NULL) {
00914
00915 cpl_msg_info(fctid, "Sigma Clipping: Error creating design "
00916 "matrix");
00917
00918 cpl_matrix_delete(zbs);
00919 cpl_matrix_delete(ybs);
00920 cpl_matrix_delete(xbs);
00921
00922 return -2;
00923 }
00924
00925 for (k = 0; k < naccepted; ++k) {
00926
00927 cpl_matrix_set(base, 0, k, 1.);
00928 cpl_matrix_set(base, 1, k, cpl_matrix_get(xbs, k, 0));
00929 cpl_matrix_set(base, 2, k, cpl_matrix_get(ybs, k, 0));
00930
00931 }
00932
00933 cpl_matrix_delete(coeffs);
00934 coeffs = NULL;
00935
00936 coeffs = giraffe_matrix_leastsq(base, zbs);
00937
00938 if (coeffs == NULL) {
00939
00940 cpl_msg_info(fctid, "Sigma Clipping : Error in least square "
00941 "solution, aborting...");
00942
00943 cpl_matrix_delete(base);
00944 base = NULL;
00945
00946 cpl_matrix_delete(xbs);
00947 cpl_matrix_delete(ybs);
00948 cpl_matrix_delete(zbs);
00949
00950 return -2;
00951
00952 }
00953
00954
00955
00956
00957
00958
00959 fit = cpl_matrix_product_create(coeffs, base);
00960
00961 cpl_matrix_delete(base);
00962 base = NULL;
00963
00964 results->mean = cpl_matrix_get_mean(fit);
00965
00966 sigma = giraffe_matrix_sigma_fit(zbs, fit);
00967
00968 cpl_msg_info(fctid, "Sigma Clipping : bias plane[%d]: %g + "
00969 "%g * x + %g * y, sigma = %.5g, ratio = %.4g, "
00970 "accepted = %zu\n", iteration,
00971 cpl_matrix_get(coeffs, 0, 0),
00972 cpl_matrix_get(coeffs, 0, 1),
00973 cpl_matrix_get(coeffs, 0, 2),
00974 sigma, fraction, naccepted);
00975
00976
00977
00978
00979
00980
00981 ksigma = sigma * kappa;
00982
00983 n = 0;
00984
00985 for (j = 0; j < cpl_matrix_get_ncol(zbs); ++j) {
00986
00987 register cxdouble z = cpl_matrix_get(zbs, 0, j);
00988
00989 if (fabs(cpl_matrix_get(fit, 0, j) - z) > ksigma) {
00990 continue;
00991 }
00992
00993 cpl_matrix_set(xbs, n, 0, cpl_matrix_get(xbs, j, 0));
00994
00995 cpl_matrix_set(ybs, n, 0, cpl_matrix_get(ybs, j, 0));
00996
00997 cpl_matrix_set(zbs, 0, n, z);
00998 ++n;
00999
01000 }
01001
01002 cpl_matrix_set_size(xbs, n, 1);
01003 cpl_matrix_set_size(ybs, n, 1);
01004 cpl_matrix_set_size(zbs, 1, n);
01005
01006 cpl_matrix_delete(fit);
01007 fit = NULL;
01008
01009 if (n == naccepted) {
01010 break;
01011 }
01012
01013 naccepted = n;
01014
01015 fraction = (cxdouble)naccepted / (cxdouble)ntotal;
01016 ++iteration;
01017
01018 }
01019
01020 cpl_msg_info(fctid, "Sigma Clipping : End");
01021
01022
01023
01024
01025
01026
01027 results->coeffs = coeffs;
01028 results->rms = sigma;
01029
01030
01031
01032
01033
01034
01035
01036 results->sigma = sigma / sqrt(cpl_matrix_get_ncol(zbs));
01037
01038 cpl_msg_info(fctid, "Sigma Clipping Results (%d/%zu, sigma = %g)",
01039 iteration, naccepted, results->rms);
01040
01041
01042
01043
01044
01045
01046 cpl_matrix_delete(xbs);
01047 xbs = NULL;
01048
01049 cpl_matrix_delete(ybs);
01050 ybs = NULL;
01051
01052 cpl_matrix_delete(zbs);
01053 zbs = NULL;
01054
01055 return EXIT_SUCCESS;
01056
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101 inline static cxint
01102 _giraffe_bias_compute_curve(GiBiasResults* results, const cpl_image* image,
01103 const cpl_matrix *areas, cxdouble kappa,
01104 cxint numiter, cxdouble maxfraction,
01105 cxdouble xdeg, cxdouble ydeg,
01106 cxdouble xstep, cxdouble ystep)
01107 {
01108
01109 const cxchar* const fctid = "giraffe_bias_compute_curve";
01110
01111 cxint j = 0;
01112 cxint nx = 0;
01113 cxint ny = 0;
01114 cxint nareas = 0;
01115 cxint iteration = 0;
01116
01117 cxsize n = 0;
01118 cxsize ntotal = 0;
01119 cxsize naccepted = 0;
01120
01121 cxdouble fraction = 1.;
01122 cxdouble sigma = 0.;
01123
01124 cpl_matrix* xbs = NULL;
01125 cpl_matrix* ybs = NULL;
01126 cpl_matrix* zbs = NULL;
01127
01128 GiChebyshev2D* fit = NULL;
01129
01130
01131 cx_assert(results != NULL);
01132 cx_assert(results->limits != NULL);
01133 cx_assert(results->coeffs == NULL);
01134
01135 cx_assert(areas != NULL);
01136
01137 cx_assert(image != NULL);
01138 cx_assert(cpl_image_get_type(image) == CPL_TYPE_DOUBLE);
01139
01140
01141
01142
01143
01144
01145 nareas = cpl_matrix_get_nrow(areas);
01146
01147 for (j = 0; j < nareas; ++j) {
01148
01149 cxint x3 = (cxint)cpl_matrix_get(areas, j, 3);
01150 cxint x2 = (cxint)cpl_matrix_get(areas, j, 2);
01151 cxint x1 = (cxint)cpl_matrix_get(areas, j, 1);
01152 cxint x0 = (cxint)cpl_matrix_get(areas, j, 0);
01153
01154 ntotal += (cxulong) (ceil((1. + x3 - x2) / ystep) *
01155 ceil((1. + x1 - x0) / xstep));
01156 }
01157
01158 nx = cpl_image_get_size_x(image);
01159 ny = cpl_image_get_size_y(image);
01160
01161 cpl_msg_info(fctid, "Bias Areas: Found %zu points in %dx%d image",
01162 ntotal, nx, ny);
01163
01164
01165
01166
01167
01168
01169 results->mean = 0.;
01170 results->sigma = 0.;
01171 results->rms = 0.;
01172
01173 cx_string_set(results->limits, "");
01174
01175 xbs = cpl_matrix_new(ntotal, 1);
01176 ybs = cpl_matrix_new(ntotal, 1);
01177 zbs = cpl_matrix_new(1, ntotal);
01178
01179 for (j = 0; j < nareas; ++j) {
01180
01181 const cxdouble* _img = cpl_image_get_data_double_const(image);
01182
01183 cxint k = 0;
01184
01185 cx_string* tmp = NULL;
01186
01187
01188 cxint x3 = (cxint)cpl_matrix_get(areas, j, 3);
01189 cxint x2 = (cxint)cpl_matrix_get(areas, j, 2);
01190 cxint x1 = (cxint)cpl_matrix_get(areas, j, 1);
01191 cxint x0 = (cxint)cpl_matrix_get(areas, j, 0);
01192
01193 if ((x0 > nx) || (x1 > nx) ||
01194 (x2 > ny) || (x3 > ny)) {
01195 continue;
01196 }
01197
01198 tmp = cx_string_new();
01199
01200 cx_string_sprintf(tmp, "%d:%d:%d:%d;", x0, x1, x2, x3);
01201 cx_string_append(results->limits, cx_string_get(tmp));
01202
01203 cx_string_delete(tmp);
01204 tmp = NULL;
01205
01206 for (k = x2; k < x3 + 1; k += ystep) {
01207
01208 register cxint l = 0;
01209
01210
01211 for (l = x0; l < x1 + 1; l += xstep) {
01212
01213 cpl_matrix_set(xbs, n, 0, l);
01214 cpl_matrix_set(ybs, n, 0, k);
01215 cpl_matrix_set(zbs, 0, n, _img[k * nx + l]);
01216 ++n;
01217
01218 }
01219
01220 }
01221
01222 }
01223
01224 cpl_matrix_set_size(xbs, n, 1);
01225 cpl_matrix_set_size(ybs, n, 1);
01226 cpl_matrix_set_size(zbs, 1, n);
01227
01228 if (n <= 0) {
01229
01230 cpl_msg_info(fctid, "Bias Areas: Validation failed, aborting...");
01231
01232 cpl_matrix_delete(xbs);
01233 cpl_matrix_delete(ybs);
01234 cpl_matrix_delete(zbs);
01235
01236 return -1;
01237
01238 }
01239
01240 ntotal = n;
01241
01242 cpl_msg_info(fctid, "Bias Areas: Using %s [%zu pixels]",
01243 cx_string_get(results->limits), ntotal);
01244
01245
01246
01247
01248
01249
01250 cpl_msg_info(fctid, "Sigma Clipping : Start");
01251
01252 naccepted = ntotal;
01253
01254 while ((naccepted > 0) && (iteration < numiter) &&
01255 (fraction > maxfraction)) {
01256
01257 cxint status = 0;
01258
01259 cxdouble ksigma = 0.;
01260
01261 cpl_matrix* base = NULL;
01262 cpl_matrix* coeffs = NULL;
01263 cpl_matrix* _coeffs = NULL;
01264 cpl_matrix* _fit = NULL;
01265
01266
01267 base = giraffe_chebyshev_base2d(0., 0., nx, ny,
01268 xdeg, ydeg, xbs, ybs);
01269
01270 if (base == NULL) {
01271
01272 cpl_msg_info(fctid, "Sigma Clipping: Error creating design "
01273 "matrix");
01274
01275 cpl_matrix_delete(zbs);
01276 cpl_matrix_delete(ybs);
01277 cpl_matrix_delete(xbs);
01278
01279 return -2;
01280 }
01281
01282 _coeffs = giraffe_matrix_leastsq(base, zbs);
01283
01284 cpl_matrix_delete(base);
01285 base = NULL;
01286
01287 if (_coeffs == NULL) {
01288
01289 cpl_msg_info(fctid, "Sigma Clipping : Error in least square "
01290 "solution, aborting...");
01291
01292 cpl_matrix_delete(xbs);
01293 cpl_matrix_delete(ybs);
01294 cpl_matrix_delete(zbs);
01295
01296 return -2;
01297
01298 }
01299
01300
01301
01302
01303
01304
01305 coeffs = cpl_matrix_wrap(xdeg, ydeg, cpl_matrix_get_data(_coeffs));
01306
01307 if (fit != NULL) {
01308 giraffe_chebyshev2d_delete(fit);
01309 fit = NULL;
01310 }
01311
01312 fit = giraffe_chebyshev2d_new(xdeg - 1, ydeg - 1);
01313 status = giraffe_chebyshev2d_set(fit, 0., nx, 0., ny,
01314 coeffs);
01315
01316 if (status != 0) {
01317
01318 giraffe_chebyshev2d_delete(fit);
01319 fit = NULL;
01320
01321 cpl_matrix_unwrap(coeffs);
01322 coeffs = NULL;
01323
01324 cpl_matrix_delete(_coeffs);
01325 _coeffs = NULL;
01326
01327 cpl_matrix_delete(xbs);
01328 cpl_matrix_delete(ybs);
01329 cpl_matrix_delete(zbs);
01330
01331 return -2;
01332
01333 }
01334
01335 cpl_matrix_unwrap(coeffs);
01336 coeffs = NULL;
01337
01338 cpl_matrix_delete(_coeffs);
01339 _coeffs = NULL;
01340
01341 _fit = cpl_matrix_new(1, cpl_matrix_get_ncol(zbs));
01342
01343 for (j = 0; j < cpl_matrix_get_ncol(_fit); ++j) {
01344
01345 cxdouble x = cpl_matrix_get(xbs, n, 0);
01346 cxdouble y = cpl_matrix_get(ybs, n, 0);
01347 cxdouble z = giraffe_chebyshev2d_eval(fit, x, y);
01348
01349 cpl_matrix_set(_fit, 0, j, z);
01350
01351 }
01352
01353 results->mean = cpl_matrix_get_mean(_fit);
01354
01355 sigma = giraffe_matrix_sigma_fit(zbs, _fit);
01356
01357 cpl_msg_info(fctid, "Sigma Clipping : bias surface[%d]: "
01358 "sigma = %8.5g, ratio = %7.4g, accepted = %zu\n",
01359 iteration, sigma, fraction, naccepted);
01360
01361
01362
01363
01364
01365
01366 ksigma = sigma * kappa;
01367
01368 n = 0;
01369
01370 for (j = 0; j < cpl_matrix_get_ncol(zbs); ++j) {
01371
01372 register cxdouble z = cpl_matrix_get(zbs, 0, j);
01373
01374 if (fabs(cpl_matrix_get(_fit, 0, j) - z) > ksigma) {
01375 continue;
01376 }
01377
01378 cpl_matrix_set(xbs, n, 0, cpl_matrix_get(xbs, j, 0));
01379 cpl_matrix_set(ybs, n, 0, cpl_matrix_get(ybs, j, 0));
01380 cpl_matrix_set(zbs, 0, n, z);
01381 ++n;
01382
01383 }
01384
01385 cpl_matrix_set_size(xbs, n, 1);
01386 cpl_matrix_set_size(ybs, n, 1);
01387 cpl_matrix_set_size(zbs, 1, n);
01388
01389 cpl_matrix_delete(_fit);
01390 _fit = NULL;
01391
01392
01393 if (n == naccepted) {
01394 break;
01395 }
01396
01397 naccepted = n;
01398
01399 fraction = (cxdouble)naccepted / (cxdouble)ntotal;
01400 ++iteration;
01401
01402 }
01403
01404 cpl_msg_info(fctid, "Sigma Clipping : End");
01405
01406
01407
01408
01409
01410
01411 results->coeffs = cpl_matrix_duplicate(giraffe_chebyshev2d_coeffs(fit));
01412 results->rms = sigma;
01413
01414
01415
01416
01417
01418
01419
01420 results->sigma = sigma / sqrt(cpl_matrix_get_ncol(zbs));
01421
01422 cpl_msg_info(fctid, "Sigma Clipping Results (%d/%zu, sigma = %g)",
01423 iteration, naccepted, results->rms);
01424
01425
01426
01427
01428
01429
01430 giraffe_chebyshev2d_delete(fit);
01431 fit = NULL;
01432
01433 cpl_matrix_delete(xbs);
01434 xbs = NULL;
01435
01436 cpl_matrix_delete(ybs);
01437 ybs = NULL;
01438
01439 cpl_matrix_delete(zbs);
01440 zbs = NULL;
01441
01442 return EXIT_SUCCESS;
01443
01444 }
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470 inline static cxint
01471 _giraffe_bias_compute_profile(GiBiasResults* results, const cpl_image* image,
01472 const cpl_matrix* areas, cxchar axis)
01473 {
01474
01475 const cxchar* const fctid = "_giraffe_bias_compute_profile";
01476
01477
01478 cxint nx = 0;
01479 cxint ny = 0;
01480 cxint sx = 0;
01481 cxint sy = 0;
01482
01483 cxsize j = 0;
01484 cxsize npixel = 0;
01485 cxsize ntotal = 0;
01486 cxsize nareas = 0;
01487 cxsize nvalid = 0;
01488
01489 cxdouble rms = 0.;
01490 cxdouble sigma = 0.;
01491
01492 cpl_matrix* _areas = NULL;
01493
01494 cpl_image* profile = NULL;
01495 cpl_image* model = NULL;
01496
01497
01498 cx_assert(results != NULL);
01499 cx_assert(results->limits != NULL);
01500 cx_assert(results->model == NULL);
01501
01502 cx_assert(areas != NULL);
01503
01504 cx_assert(image != NULL);
01505 cx_assert(cpl_image_get_type(image) == CPL_TYPE_DOUBLE);
01506
01507 cx_assert((axis == 'x') || (axis == 'y'));
01508
01509
01510 nx = cpl_image_get_size_x(image);
01511 ny = cpl_image_get_size_y(image);
01512
01513
01514
01515
01516
01517
01518 _areas = cpl_matrix_duplicate(areas);
01519 cx_assert(_areas != NULL);
01520
01521 nareas = cpl_matrix_get_nrow(_areas);
01522
01523 if (axis == 'y') {
01524
01525 for (j = 0; j < nareas; ++j) {
01526
01527 cxint y_1 = (cxint)cpl_matrix_get(_areas, j, 3);
01528 cxint y_0 = (cxint)cpl_matrix_get(_areas, j, 2);
01529 cxint x_1 = (cxint)cpl_matrix_get(_areas, j, 1);
01530 cxint x_0 = (cxint)cpl_matrix_get(_areas, j, 0);
01531
01532
01533 if (x_0 < 0) {
01534 x_0 = 0;
01535 cpl_matrix_set(_areas, j, 0, x_0);
01536 }
01537
01538 if (x_1 >= nx) {
01539 x_1 = nx - 1;
01540 cpl_matrix_set(_areas, j, 1, x_1);
01541 }
01542
01543 if (y_0 != 0) {
01544 y_0 = 0;
01545 cpl_matrix_set(_areas, j, 2, y_0);
01546 }
01547
01548 if (y_1 != ny - 1) {
01549 y_1 = ny - 1;
01550 cpl_matrix_set(_areas, j, 3, y_1);
01551 }
01552
01553 if ((x_1 >= x_0) && (y_1 >= y_0)) {
01554 ntotal += (y_1 - y_0 + 1) * (x_1 - x_0 + 1);
01555 }
01556
01557 }
01558
01559 sx = nareas;
01560 sy = ny;
01561 }
01562 else {
01563
01564 for (j = 0; j < nareas; ++j) {
01565
01566 cxint y_1 = (cxint)cpl_matrix_get(_areas, j, 3);
01567 cxint y_0 = (cxint)cpl_matrix_get(_areas, j, 2);
01568 cxint x_1 = (cxint)cpl_matrix_get(_areas, j, 1);
01569 cxint x_0 = (cxint)cpl_matrix_get(_areas, j, 0);
01570
01571
01572 if (x_0 != 0) {
01573 x_0 = 0;
01574 cpl_matrix_set(_areas, j, 0, x_0);
01575 }
01576
01577 if (x_1 != nx) {
01578 x_1 = nx - 1;
01579 cpl_matrix_set(_areas, j, 1, x_1);
01580 }
01581
01582 if (y_0 < 0) {
01583 y_0 = 0;
01584 cpl_matrix_set(_areas, j, 2, y_0);
01585 }
01586
01587 if (y_1 >= ny) {
01588 y_1 = ny - 1;
01589 cpl_matrix_set(_areas, j, 3, y_1);
01590 }
01591
01592 if ((x_1 >= x_0) && (y_1 >= y_0)) {
01593 ntotal += (y_1 - y_0 + 1) * (x_1 - x_0 + 1);
01594 }
01595
01596 }
01597
01598 sx = nareas;
01599 sy = nx;
01600
01601 }
01602
01603 cpl_msg_info(fctid, "Bias Areas: Found %zu points in %dx%d image",
01604 ntotal, nx, ny);
01605
01606
01607
01608
01609
01610
01611 results->mean = 0.;
01612 results->sigma = 0.;
01613 results->rms = 0.;
01614
01615 cx_string_set(results->limits, "");
01616
01617 profile = cpl_image_new(sx, sy, CPL_TYPE_DOUBLE);
01618
01619 for (j = 0; j < nareas; ++j) {
01620
01621 cxint y_1 = (cxint)cpl_matrix_get(_areas, j, 3);
01622 cxint y_0 = (cxint)cpl_matrix_get(_areas, j, 2);
01623 cxint x_1 = (cxint)cpl_matrix_get(_areas, j, 1);
01624 cxint x_0 = (cxint)cpl_matrix_get(_areas, j, 0);
01625
01626 if ((x_1 >= x_0) && (y_1 >= y_0)) {
01627
01628 cx_string* tmp = cx_string_new();
01629
01630
01631 cx_string_sprintf(tmp, "%d:%d:%d:%d;", x_0, x_1, y_0, y_1);
01632 cx_string_append(results->limits, cx_string_get(tmp));
01633
01634 cx_string_delete(tmp);
01635 tmp = NULL;
01636
01637
01638
01639
01640
01641
01642 ++nvalid;
01643
01644
01645
01646
01647
01648
01649 if (axis == 'y') {
01650
01651 cxint i = 0;
01652 cxint sz = x_1 - x_0 + 1;
01653
01654 cxdouble residual = 0.;
01655
01656 const cxdouble* _img = cpl_image_get_data_double_const(image);
01657
01658 cxdouble* _profile = cpl_image_get_data_double(profile);
01659
01660
01661 for (i = y_0; i < y_1 + 1; ++i) {
01662
01663 register cxint k = i * nx;
01664 register cxint l = 0;
01665
01666 cxdouble m = giraffe_array_mean(&_img[k + x_0], sz);
01667
01668 _profile[i * sx + j] = m;
01669
01670 for (l = x_0; l < x_1 + 1; ++l) {
01671 residual += (_img[k + l] - m) * (_img[k + l] - m);
01672 }
01673 ++npixel;
01674
01675 }
01676
01677
01678
01679
01680
01681
01682 rms += residual / (sz - 1);
01683 sigma += residual / (sz * (sz - 1));
01684
01685 }
01686 else {
01687
01688 cxint i = 0;
01689 cxint sz = y_1 - y_0 + 1;
01690
01691 cxdouble residual = 0.;
01692
01693 const cxdouble* _img = cpl_image_get_data_double_const(image);
01694
01695 cxdouble* _profile = cpl_image_get_data_double(profile);
01696 cxdouble* buffer = cx_calloc(sz, sizeof(cxdouble));
01697
01698
01699 for (i = x_0; i < x_1 + 1; ++i) {
01700
01701 register cxint l = 0;
01702
01703 register cxdouble m = 0.;
01704
01705
01706 for (l = y_0; l < y_1 + 1; ++l) {
01707 buffer[l - y_0] = _img[l * nx + i];
01708 }
01709
01710 m = giraffe_array_mean(buffer, sz);
01711 _profile[i * sx + j] = m;
01712
01713 for (l = 0; l < sz; ++l) {
01714 residual += (buffer[l] - m) * (buffer[l] - m);
01715 }
01716 ++npixel;
01717
01718 }
01719
01720
01721
01722
01723
01724
01725 rms += residual / (sz - 1);
01726 sigma += residual / (sz * (sz - 1));
01727
01728 cx_free(buffer);
01729 buffer = NULL;
01730
01731 }
01732
01733 }
01734
01735 }
01736
01737 cpl_matrix_delete(_areas);
01738 _areas = NULL;
01739
01740
01741
01742
01743
01744
01745 model = cpl_image_collapse_create(profile, 1);
01746
01747 cpl_image_delete(profile);
01748 profile = NULL;
01749
01750 cpl_image_divide_scalar(model, nvalid);
01751 results->model = model;
01752
01753 model = NULL;
01754
01755 results->mean = cpl_image_get_mean(results->model);
01756
01757 if (nvalid > 0) {
01758 results->rms = sqrt(rms / (sy * nvalid));
01759 results->sigma = sqrt(sigma / sy) / nvalid;
01760 }
01761
01762 return EXIT_SUCCESS;
01763
01764 }
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791 inline static cxint
01792 _giraffe_bias_fit_profile(GiBiasResults* results, const cpl_image* profile,
01793 cxint order)
01794 {
01795
01796 cxint i = 0;
01797
01798 cxint sy = cpl_image_get_size_y(profile);
01799 cxint nc = order + 1;
01800
01801 cxdouble* _profile = (cxdouble*)cpl_image_get_data_double_const(profile);
01802
01803 cpl_matrix* base = NULL;
01804 cpl_matrix* baseT = NULL;
01805 cpl_matrix* coeff = NULL;
01806 cpl_matrix* fit = NULL;
01807 cpl_matrix* x = cpl_matrix_new(sy, 1);
01808 cpl_matrix* y = cpl_matrix_wrap(sy, 1, _profile);
01809 cpl_matrix* covy = cpl_matrix_new(sy, sy);
01810 cpl_matrix* covc = cpl_matrix_new(nc, nc);
01811
01812
01813 if ((x == NULL) || (y == NULL) || (covy == NULL) || (covc == NULL)) {
01814
01815 cpl_matrix_delete(covc);
01816 cpl_matrix_delete(covy);
01817 cpl_matrix_unwrap(y);
01818 cpl_matrix_delete(x);
01819
01820 return -1;
01821 }
01822
01823
01824
01825
01826
01827
01828
01829 for (i = 0; i < sy; ++i)
01830 {
01831 cpl_matrix_set(x, i, 0, i);
01832 }
01833
01834 baseT = giraffe_chebyshev_base1d(0., sy, nc, x);
01835 base = cpl_matrix_transpose_create(baseT);
01836
01837 cpl_matrix_delete(baseT);
01838 baseT = NULL;
01839
01840 cpl_matrix_delete(x);
01841 x = NULL;
01842
01843 if (base == NULL) {
01844 cpl_matrix_unwrap(y);
01845 return -2;
01846 }
01847
01848 cpl_matrix_fill_diagonal(covy, results->rms * results->rms, 0);
01849
01850
01851
01852
01853
01854
01855
01856 coeff = giraffe_matrix_solve_cholesky(base, y, covy, covc);
01857
01858 cpl_matrix_delete(covy);
01859 covy = NULL;
01860
01861 if (coeff == NULL) {
01862
01863 cpl_matrix_delete(base);
01864 base = NULL;
01865
01866 cpl_matrix_unwrap(y);
01867 y = NULL;
01868
01869 return -3;
01870
01871 }
01872
01873
01874 fit = cpl_matrix_product_create(base, coeff);
01875
01876 cpl_matrix_delete(coeff);
01877 coeff = NULL;
01878
01879 cpl_matrix_delete(base);
01880 base = NULL;
01881
01882 if (fit == NULL) {
01883
01884 cpl_matrix_unwrap(y);
01885 y = NULL;
01886
01887 return -3;
01888
01889 }
01890
01891
01892
01893
01894
01895
01896 for (i = 0; i < sy; ++i)
01897 {
01898 cpl_matrix_set(y, i, 0, cpl_matrix_get(fit, i, 0));
01899 }
01900
01901 cpl_matrix_delete(fit);
01902 fit = NULL;
01903
01904 cpl_matrix_unwrap(y);
01905 y = NULL;
01906
01907
01908
01909
01910
01911
01912
01913
01914 results->mean = cpl_image_get_mean(results->model);
01915 results->sigma = sqrt(cpl_matrix_get(covc, 0, 0));
01916
01917 #if 0
01918 cpl_image_save(results->model, "idiot.fits", CPL_BPP_IEEE_FLOAT,
01919 0, CPL_IO_DEFAULT);
01920 #endif
01921
01922
01923
01924
01925
01926 cpl_matrix_delete(covc);
01927 covc = NULL;
01928
01929 return EXIT_SUCCESS;
01930 }
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962 inline static cxint
01963 _giraffe_bias_compute(GiBiasResults* results, cpl_image* img,
01964 const cpl_matrix* biasareas,
01965 const cpl_image* master_bias,
01966 const cpl_image* bad_pixel_map,
01967 GiBiasMethod method, GiBiasOption option,
01968 GiBiasModel model, cxbool remove_bias, cxdouble mbias,
01969 cxdouble xdeg, cxdouble ydeg, cxdouble xstep,
01970 cxdouble ystep, cxdouble sigma, cxint numiter,
01971 cxdouble maxfraction)
01972 {
01973
01974 const cxchar* const fctid = "giraffe_bias_compute";
01975
01976 cxint i;
01977 cxint j;
01978 cxint img_dimx;
01979 cxint img_dimy;
01980 cxint img_centerx;
01981 cxint img_centery;
01982 cxint master_bias_dimx;
01983 cxint master_bias_dimy;
01984 cxint bad_pixel_dimx;
01985 cxint bad_pixel_dimy;
01986
01987 cxint error_code = 0;
01988
01989 cx_string* s = NULL;
01990
01991 const cpl_matrix* coeff = NULL;
01992
01993
01994 cx_assert(results != NULL);
01995 cx_assert(results->limits == NULL);
01996 cx_assert(results->coeffs == NULL);
01997 cx_assert(results->model == NULL);
01998
01999 cx_assert(img != NULL);
02000 cx_assert(cpl_image_get_type(img) == CPL_TYPE_DOUBLE);
02001
02002 cx_assert(biasareas != NULL);
02003
02004
02005
02006
02007
02008
02009 img_dimx = cpl_image_get_size_x(img);
02010 img_dimy = cpl_image_get_size_y(img);
02011
02012 img_centerx = img_dimx / 2;
02013 img_centery = img_dimy / 2;
02014
02015 results->limits = cx_string_new();
02016
02017
02018
02019
02020
02021
02022 if (remove_bias) {
02023 cpl_msg_info(fctid, "Bias correction will be done.");
02024 }
02025 else {
02026 cpl_msg_warning(fctid, "No Bias correction will be done!");
02027 }
02028
02029
02030 if (model == GIBIAS_MODEL_MEAN) {
02031
02032
02033
02034
02035
02036 cpl_msg_info(fctid, "Using bias model 'MEAN' ...");
02037
02038 if ((option == GIBIAS_OPTION_PLANE) ||
02039 (method == GIBIAS_METHOD_PLANE)) {
02040
02041 cpl_msg_error(fctid, "Can not use MEAN model with PLANE method.");
02042 return -3;
02043
02044 }
02045
02046 error_code = _giraffe_bias_compute_mean(results, img, biasareas,
02047 sigma, numiter, maxfraction);
02048
02049
02050 }
02051 else if ((method == GIBIAS_METHOD_CURVE) ||
02052 ((method != GIBIAS_METHOD_PROFILE) &&
02053 (option == GIBIAS_OPTION_CURVE))) {
02054
02055
02056
02057
02058
02059
02060 cpl_msg_info(fctid, "Using bias model 'CURVE' ...");
02061
02062 error_code = _giraffe_bias_compute_curve(results, img, biasareas,
02063 sigma, numiter, maxfraction, xdeg, ydeg, xstep, ystep);
02064
02065 if (error_code != EXIT_SUCCESS) {
02066
02067 cpl_msg_error(fctid, "Error during calculation of bias curve, "
02068 "aborting...");
02069 return error_code;
02070
02071 }
02072
02073 coeff = results->coeffs;
02074
02075 }
02076 else {
02077
02078
02079
02080
02081
02082 cpl_msg_info(fctid, "Using bias model 'PLANE (FITTED)' ...");
02083
02084 error_code = _giraffe_bias_compute_plane(results, img, biasareas,
02085 sigma, numiter, maxfraction);
02086
02087 if (error_code == EXIT_SUCCESS) {
02088
02089 coeff = results->coeffs;
02090
02091 results->mean = cpl_matrix_get(coeff, 0, 0) +
02092 cpl_matrix_get(coeff, 0, 1) * img_centerx +
02093 cpl_matrix_get(coeff, 0, 2) * img_centery;
02094
02095 }
02096 else {
02097
02098 cpl_msg_error(fctid, "Error during calculation of bias plane, "
02099 "aborting...");
02100 return error_code;
02101
02102 }
02103
02104 }
02105
02106
02107
02108
02109
02110
02111 s = cx_string_new();
02112 _giraffe_method_string(s, method, option);
02113
02114 cpl_msg_info(fctid, "Using bias method '%s'", cx_string_get(s));
02115
02116 cx_string_delete(s);
02117 s = NULL;
02118
02119
02120 switch (method) {
02121 case GIBIAS_METHOD_UNIFORM:
02122 {
02123
02124
02125
02126
02127
02128 if (model == GIBIAS_MODEL_MEAN) {
02129
02130 cpl_msg_info(fctid, "bias value (areas mean) = %f, "
02131 "bias sigma = %f", results->mean, results->sigma);
02132
02133 }
02134 else {
02135
02136 cpl_msg_info(fctid, "bias value at (%d, %d) = %f, "
02137 "bias sigma = %f", img_centerx, img_centery,
02138 results->mean, results->sigma);
02139
02140 }
02141
02142 if (remove_bias == TRUE) {
02143
02144 cpl_image_subtract_scalar(img, results->mean);
02145
02146 }
02147
02148 break;
02149 }
02150
02151 case GIBIAS_METHOD_PLANE:
02152 {
02153
02154 if (coeff == NULL) {
02155
02156 error_code = _giraffe_bias_compute_plane(results, img,
02157 biasareas, sigma, numiter, maxfraction);
02158
02159 if (error_code == EXIT_SUCCESS) {
02160
02161 coeff = results->coeffs;
02162
02163 results->mean = cpl_matrix_get(coeff, 0, 0) +
02164 cpl_matrix_get(coeff, 0, 1) * img_centerx +
02165 cpl_matrix_get(coeff, 0, 2) * img_centery;
02166
02167 }
02168 else {
02169
02170 cpl_msg_error(fctid, "Error during calculation of bias "
02171 "plane, aborting...");
02172 return error_code;
02173
02174 }
02175
02176 }
02177
02178 cpl_msg_info(fctid, "bias value at (%d, %d) = %f, bias sigma = %f, "
02179 "bias plane = %g + %g * x + %g * y", img_centerx,
02180 img_centery, results->mean, results->sigma,
02181 cpl_matrix_get(coeff, 0, 0),
02182 cpl_matrix_get(coeff, 0, 1),
02183 cpl_matrix_get(coeff, 0, 2));
02184
02185 if (remove_bias == TRUE) {
02186
02187
02188
02189 cxdouble* _img = cpl_image_get_data_double(img);
02190
02191 #if 0
02192 cpl_image* bsmodel = cpl_image_new(img_dimx, img_dimy,
02193 CPL_TYPE_DOUBLE);
02194 cxdouble* _bsmodel = cpl_image_get_data_double(bsmodel);
02195 #endif
02196
02197
02198 for (j = 0; j < img_dimy; j++) {
02199
02200 cxsize jj = j * img_dimx;
02201
02202 for (i = 0; i < img_dimx; i++) {
02203
02204 #if 0
02205 _bsmodel[jj + i] = cpl_matrix_get(coeff, 0, 0)
02206 + cpl_matrix_get(coeff, 0, 1) * i
02207 + cpl_matrix_get(coeff, 0, 2) * j;
02208 #endif
02209
02210 _img[jj + i] -= cpl_matrix_get(coeff, 0, 0)
02211 + cpl_matrix_get(coeff, 0, 1) * i
02212 + cpl_matrix_get(coeff, 0, 2) * j;
02213
02214 }
02215
02216 }
02217
02218 #if 0
02219 cpl_image_save(bsmodel, "idiot.fits", CPL_BPP_IEEE_FLOAT,
02220 0, CPL_IO_DEFAULT);
02221 cpl_image_delete(bsmodel);
02222 #endif
02223
02224 }
02225
02226 break;
02227
02228 }
02229
02230 case GIBIAS_METHOD_CURVE:
02231 {
02232
02233 if (coeff == NULL) {
02234
02235 error_code =
02236 _giraffe_bias_compute_curve(results, img, biasareas,
02237 sigma, numiter, maxfraction,
02238 xdeg, ydeg, xstep, ystep);
02239
02240 if (error_code != EXIT_SUCCESS) {
02241
02242 cpl_msg_error(fctid, "Error during calculation of bias "
02243 "surface curve, aborting...");
02244 return error_code;
02245
02246 }
02247
02248 coeff = results->coeffs;
02249
02250 }
02251
02252 cpl_msg_info(fctid, "bias value %f, bias sigma = %f\n",
02253 results->mean, results->sigma);
02254
02255
02256 if (remove_bias == TRUE) {
02257
02258 cpl_image* bsmodel = NULL;
02259
02260 cpl_matrix* x = cpl_matrix_new(img_dimx * img_dimy, 1);
02261 cpl_matrix* y = cpl_matrix_new(img_dimx * img_dimy, 1);
02262 cpl_matrix* fit = NULL;
02263
02264
02265 for (j = 0; j < img_dimy; ++j) {
02266
02267 register cxsize jj = j * img_dimx;
02268
02269 for (i = 0; i < img_dimx; ++i) {
02270
02271 cpl_matrix_set(x, jj + i, 0, i);
02272 cpl_matrix_set(y, jj + i, 0, j);
02273
02274 }
02275
02276 }
02277
02278 fit = giraffe_chebyshev_fit2d(0., 0., img_dimx, img_dimy,
02279 coeff, x, y);
02280
02281 cpl_matrix_delete(y);
02282 y = NULL;
02283
02284 cpl_matrix_delete(x);
02285 x = NULL;
02286
02287 bsmodel = cpl_image_wrap_double(img_dimx, img_dimy,
02288 cpl_matrix_get_data(fit));
02289
02290 #if 0
02291 cpl_image_save(bsmodel, "idiot.fits", CPL_BPP_IEEE_FLOAT,
02292 0, CPL_IO_DEFAULT);
02293 #endif
02294
02295 cpl_image_subtract(img, bsmodel);
02296
02297 cpl_image_unwrap(bsmodel);
02298 bsmodel = NULL;
02299
02300 cpl_matrix_delete(fit);
02301 fit = NULL;
02302
02303 }
02304
02305 break;
02306
02307 }
02308
02309 case GIBIAS_METHOD_PROFILE:
02310 {
02311
02312 error_code = _giraffe_bias_compute_profile(results, img,
02313 biasareas, 'y');
02314
02315 if (error_code != EXIT_SUCCESS) {
02316
02317 cpl_msg_error(fctid, "Error computing the bias area(s) "
02318 "profile");
02319 return error_code;
02320
02321 }
02322
02323 if (option == GIBIAS_OPTION_CURVE) {
02324
02325 error_code = _giraffe_bias_fit_profile(results, results->model,
02326 ydeg - 1);
02327 if (error_code != EXIT_SUCCESS) {
02328
02329 cpl_msg_error(fctid, "Error fitting the bias profile");
02330 return error_code;
02331
02332 }
02333
02334 }
02335
02336 if (remove_bias == TRUE) {
02337
02338 const cxdouble* _bias =
02339 cpl_image_get_data_double(results->model);
02340
02341 cxdouble* _img = cpl_image_get_data_double(img);
02342
02343
02344 cx_assert(_bias != NULL);
02345 cx_assert(_img != NULL);
02346
02347 for (j = 0; j < img_dimy; ++j) {
02348
02349 cxsize jj = j * img_dimx;
02350
02351
02352 for (i = 0; i < img_dimx; ++i) {
02353 _img[jj + i] -= _bias[j];
02354 }
02355
02356 }
02357
02358 }
02359
02360 break;
02361
02362 }
02363
02364 case GIBIAS_METHOD_MASTER:
02365 case GIBIAS_METHOD_ZMASTER:
02366 {
02367
02368 cxdouble biasdrift = 0.;
02369
02370 if (master_bias == NULL) {
02371
02372 cpl_msg_error(fctid, "Master Bias Frame required with MASTER "
02373 "method.");
02374 return -5;
02375
02376 }
02377
02378 master_bias_dimx = cpl_image_get_size_x(master_bias);
02379 master_bias_dimy = cpl_image_get_size_y(master_bias);
02380
02381 if ((master_bias_dimx != img_dimx) ||
02382 (master_bias_dimy != img_dimy)) {
02383
02384 cpl_msg_error(fctid, "Invalid master bias! Size should "
02385 "be [%d, %d] but is [%d, %d].", img_dimx, img_dimy,
02386 master_bias_dimx, master_bias_dimy);
02387 return -7;
02388
02389 }
02390
02391 if (coeff == NULL) {
02392
02393 if (option == GIBIAS_OPTION_CURVE) {
02394
02395 error_code = _giraffe_bias_compute_curve(results, img,
02396 biasareas, sigma, numiter, maxfraction, xdeg,
02397 ydeg, xstep, ystep);
02398
02399 if (error_code != EXIT_SUCCESS) {
02400
02401 cpl_msg_error(fctid, "Error during calculation of "
02402 "bias surface curve, aborting...");
02403 return error_code;
02404
02405 }
02406
02407 coeff = results->coeffs;
02408
02409 }
02410 else {
02411
02412
02413
02414
02415
02416 error_code = _giraffe_bias_compute_plane(results, img,
02417 biasareas, sigma, numiter, maxfraction);
02418
02419 if (error_code == EXIT_SUCCESS) {
02420
02421 coeff = results->coeffs;
02422
02423 results->mean = cpl_matrix_get(coeff, 0, 0) +
02424 cpl_matrix_get(coeff, 0, 1) * img_centerx +
02425 cpl_matrix_get(coeff, 0, 2) * img_centery;
02426
02427 }
02428 else {
02429
02430 cpl_msg_error(fctid, "Error during calculation of "
02431 "bias surface plane, aborting...");
02432 return error_code;
02433
02434 }
02435
02436 }
02437
02438 }
02439
02440 if (method == GIBIAS_METHOD_ZMASTER) {
02441
02442
02443
02444
02445
02446
02447
02448 biasdrift = results->mean - mbias;
02449
02450 cpl_msg_info(fctid, "Using bias drift value %.4g", biasdrift);
02451
02452 }
02453
02454
02455
02456
02457
02458
02459 if (option == GIBIAS_OPTION_CURVE) {
02460
02461
02462
02463 cpl_msg_info(fctid, "Computed bias mean = %.4f, bias "
02464 "sigma = %.4e", results->mean, results->sigma);
02465
02466 }
02467 else {
02468
02469 if (option == GIBIAS_OPTION_PLANE) {
02470
02471 cpl_msg_info(fctid, "Bias plane = %.4e + "
02472 "%.4e * x + %.4e * y",
02473 cpl_matrix_get(coeff, 0, 0),
02474 cpl_matrix_get(coeff, 0, 1),
02475 cpl_matrix_get(coeff, 0, 2));
02476 cpl_msg_info(fctid, "Computed bias mean = %.4f, "
02477 "bias sigma = %.4e at (%d, %d)",
02478 results->mean, results->sigma,
02479 img_centerx, img_centery);
02480
02481 }
02482 else {
02483
02484 cpl_msg_info(fctid, "Computed bias mean = %.4f, bias "
02485 "sigma = %.4e",
02486 results->mean, results->sigma);
02487
02488 }
02489
02490 }
02491
02492
02493
02494
02495
02496
02497 if (remove_bias == TRUE) {
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514 if (bad_pixel_map == NULL) {
02515
02516 cpl_image_subtract(img, master_bias);
02517
02518 if (biasdrift != 0.) {
02519 cpl_image_subtract_scalar(img, biasdrift);
02520 }
02521
02522 }
02523 else {
02524
02525 bad_pixel_dimx = cpl_image_get_size_x(bad_pixel_map);
02526 bad_pixel_dimy = cpl_image_get_size_y(bad_pixel_map);
02527
02528 if ((bad_pixel_dimx != img_dimx) ||
02529 (bad_pixel_dimy != img_dimy)) {
02530
02531 cpl_msg_error(fctid, "Invalid bad pixel map size "
02532 "should be [%d, %d] but is [%d, %d].",
02533 img_dimx, img_dimy,
02534 bad_pixel_dimx, bad_pixel_dimy);
02535 return -6;
02536
02537 }
02538
02539 if (option == GIBIAS_OPTION_CURVE) {
02540
02541 const cxint* _bpix =
02542 cpl_image_get_data_int_const(bad_pixel_map);
02543
02544 const cxdouble* _mbias =
02545 cpl_image_get_data_double_const(master_bias);
02546
02547 cxdouble* _img = cpl_image_get_data_double(img);
02548
02549 cpl_matrix* x =
02550 cpl_matrix_new(img_dimx * img_dimy, 1);
02551 cpl_matrix* y =
02552 cpl_matrix_new(img_dimx * img_dimy, 1);
02553 cpl_matrix* fit = NULL;
02554
02555
02556 for (j = 0; j < img_dimy; ++j) {
02557
02558 register cxsize jj = j * img_dimx;
02559
02560 for (i = 0; i < img_dimx; ++i) {
02561
02562 cpl_matrix_set(x, jj + i, 0, i);
02563 cpl_matrix_set(y, jj + i, 0, j);
02564
02565 }
02566 }
02567
02568 fit = giraffe_chebyshev_fit2d(0., 0.,
02569 img_dimx, img_dimy,
02570 coeff, x, y);
02571
02572 cpl_matrix_delete(y);
02573 y = NULL;
02574
02575 cpl_matrix_delete(x);
02576 x = NULL;
02577
02578
02579 for (j = 0; j < img_dimy; ++j) {
02580
02581 register cxsize jj = j * img_dimx;
02582
02583 for (i = 0; i < img_dimx; ++i) {
02584
02585 if (!(_bpix[jj + i] & GIR_M_PIX_SET)) {
02586
02587 _img[jj + i] -= (_mbias[jj + i] +
02588 biasdrift);
02589
02590 }
02591 else {
02592 _img[jj + i] -= cpl_matrix_get(fit, i, j);
02593 }
02594
02595 }
02596
02597 }
02598
02599 cpl_matrix_delete(fit);
02600 fit = NULL;
02601
02602 }
02603 else if (option == GIBIAS_OPTION_PLANE) {
02604
02605 const cxint* _bpix =
02606 cpl_image_get_data_int_const(bad_pixel_map);
02607
02608 const cxdouble* _mbias =
02609 cpl_image_get_data_double_const(master_bias);
02610
02611 cxdouble* _img = cpl_image_get_data_double(img);
02612
02613
02614 for (j = 0; j < img_dimy; j++) {
02615
02616 cxsize jj = j * img_dimx;
02617
02618 for (i = 0; i < img_dimx; i++) {
02619
02620 if (!(_bpix[jj + i] & GIR_M_PIX_SET)) {
02621
02622 _img[jj + i] -= (_mbias[jj + i] +
02623 biasdrift);
02624
02625 }
02626 else {
02627
02628 _img[jj + i] -=
02629 cpl_matrix_get(coeff, 0, 0) +
02630 cpl_matrix_get(coeff, 0, 1) * j +
02631 cpl_matrix_get(coeff, 0, 2) * i;
02632 }
02633
02634 }
02635
02636 }
02637
02638 }
02639 else {
02640
02641 const cxint* _bpix =
02642 cpl_image_get_data_int_const(bad_pixel_map);
02643
02644 const cxdouble* _mbias =
02645 cpl_image_get_data_double_const(master_bias);
02646
02647 cxdouble* _img = cpl_image_get_data_double(img);
02648
02649
02650 for (j = 0; j < img_dimy; j++) {
02651
02652 cxsize jj = j * img_dimx;
02653
02654 for (i = 0; i < img_dimx; i++) {
02655
02656 if (!(_bpix[jj + i] & GIR_M_PIX_SET)) {
02657
02658 _img[jj + i] -= (_mbias[jj + i] +
02659 biasdrift);
02660
02661 }
02662 else {
02663
02664 _img[jj + i] -= results->mean;
02665
02666 }
02667
02668 }
02669
02670 }
02671
02672 }
02673
02674 }
02675
02676 }
02677
02678 break;
02679
02680 }
02681
02682 default:
02683 {
02684
02685 cpl_msg_error(fctid, "Invalid method, aborting...");
02686 return -4;
02687 break;
02688
02689 }
02690
02691 }
02692
02693
02694 cpl_msg_info(fctid, "Resulting biaslimits : %s",
02695 cx_string_get(results->limits));
02696
02697 return 0;
02698
02699 }
02700
02701
02719 cpl_matrix *
02720 giraffe_get_raw_areas(const GiImage *image)
02721 {
02722
02723 const cxchar *const _id = "giraffe_get_raw_areas";
02724
02725 cxint32 prescx = 0;
02726 cxint32 prescy = 0;
02727 cxint32 ovrscx = 0;
02728 cxint32 ovrscy = 0;
02729
02730 cxint32 winx = 0;
02731 cxint32 winy = 0;
02732
02733 cxint32 tprescx = 0;
02734 cxint32 tprescy = 0;
02735 cxint32 tovrscx = 0;
02736 cxint32 tovrscy = 0;
02737
02738 cxint32 row = 0;
02739
02740 cpl_matrix *m_tmp;
02741 cpl_propertylist *properties;
02742
02743
02744 properties = giraffe_image_get_properties(image);
02745 if (!properties) {
02746 cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
02747 return NULL;
02748 }
02749
02750 winx = cpl_propertylist_get_int(properties, GIALIAS_WINX);
02751 winy = cpl_propertylist_get_int(properties, GIALIAS_WINY);
02752
02753 if (cpl_propertylist_has(properties, GIALIAS_PRSCX)) {
02754 tprescx = cpl_propertylist_get_int(properties, GIALIAS_PRSCX);
02755 if (tprescx > 0) {
02756 prescx = tprescx;
02757 }
02758 }
02759 if (cpl_propertylist_has(properties, GIALIAS_PRSCY)) {
02760 tprescy = cpl_propertylist_get_int(properties, GIALIAS_PRSCY);
02761 if (tprescy > 0) {
02762 prescy = tprescy;
02763 }
02764 }
02765 if (cpl_propertylist_has(properties, GIALIAS_OVSCX)) {
02766 tovrscx = cpl_propertylist_get_int(properties, GIALIAS_OVSCX);
02767 if (tovrscx > 0) {
02768 ovrscx = tovrscx;
02769 }
02770 }
02771 if (cpl_propertylist_has(properties, GIALIAS_OVSCY)) {
02772 tovrscy = cpl_propertylist_get_int(properties, GIALIAS_OVSCY);
02773 if (tovrscy > 0) {
02774 ovrscy = tovrscy;
02775 }
02776 }
02777
02778
02779 m_tmp = cpl_matrix_new(1, 4);
02780
02781 if (prescx > 0) {
02782
02783 cpl_matrix_set(m_tmp, row, 0, 0.0);
02784 cpl_matrix_set(m_tmp, row, 1, (cxdouble) prescx - 1);
02785 cpl_matrix_set(m_tmp, row, 2, 0.0);
02786 cpl_matrix_set(m_tmp, row, 3, (cxdouble) winy - 1);
02787
02788 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02789 row++;
02790 }
02791
02792 if (ovrscx > 0) {
02793
02794 cpl_matrix_set(m_tmp, row, 0, (cxdouble) winx - ovrscx);
02795 cpl_matrix_set(m_tmp, row, 1, (cxdouble) winx - 1);
02796 cpl_matrix_set(m_tmp, row, 2, 0.0);
02797 cpl_matrix_set(m_tmp, row, 3, (cxdouble) winy - 1);
02798
02799 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02800 row++;
02801 }
02802
02803 if (!(prescy == 0 || prescx == 0 || ovrscx == 0)) {
02804
02805 cpl_matrix_set(m_tmp, row, 0, (cxdouble) prescx);
02806 cpl_matrix_set(m_tmp, row, 1, (cxdouble) winx - ovrscx - 1);
02807 cpl_matrix_set(m_tmp, row, 2, 0.0);
02808 cpl_matrix_set(m_tmp, row, 3, (cxdouble) prescy - 1);
02809
02810 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02811 row++;
02812
02813 }
02814 else if (!(prescy == 0 || prescx == 0)) {
02815
02816 cpl_matrix_set(m_tmp, row, 0, (cxdouble) prescx);
02817 cpl_matrix_set(m_tmp, row, 1, (cxdouble) winx - 1);
02818 cpl_matrix_set(m_tmp, row, 2, 0.0);
02819 cpl_matrix_set(m_tmp, row, 3, (cxdouble) prescy - 1);
02820
02821 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02822 row++;
02823
02824 }
02825 else if (!(prescy == 0 || ovrscx == 0)) {
02826
02827 cpl_matrix_set(m_tmp, row, 0, 0.0);
02828 cpl_matrix_set(m_tmp, row, 1, (cxdouble) winx - ovrscx - 1);
02829 cpl_matrix_set(m_tmp, row, 2, 0.0);
02830 cpl_matrix_set(m_tmp, row, 3, (cxdouble) prescy - 1);
02831
02832 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02833 row++;
02834
02835 }
02836 else if (prescy > 0) {
02837
02838 cpl_matrix_set(m_tmp, row, 0, 0.0);
02839 cpl_matrix_set(m_tmp, row, 1, (cxdouble) winx - 1);
02840 cpl_matrix_set(m_tmp, row, 2, 0.0);
02841 cpl_matrix_set(m_tmp, row, 3, (cxdouble) prescy - 1);
02842
02843 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02844 row++;
02845 }
02846
02847 if (!(ovrscy == 0 || prescx == 0 || ovrscx == 0)) {
02848
02849 cpl_matrix_set(m_tmp, row, 0, (cxdouble) prescx);
02850 cpl_matrix_set(m_tmp, row, 1, (cxdouble) winx - ovrscx - 1);
02851 cpl_matrix_set(m_tmp, row, 2, (cxdouble) winy - ovrscy);
02852 cpl_matrix_set(m_tmp, row, 3, (cxdouble) winy - 1);
02853
02854 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02855 row++;
02856
02857 }
02858 else if (!(ovrscy == 0 || prescx == 0)) {
02859
02860 cpl_matrix_set(m_tmp, row, 0, (cxdouble) prescx);
02861 cpl_matrix_set(m_tmp, row, 1, (cxdouble) winx - 1);
02862 cpl_matrix_set(m_tmp, row, 2, (cxdouble) winy - ovrscy);
02863 cpl_matrix_set(m_tmp, row, 3, (cxdouble) winy - 1);
02864
02865 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02866 row++;
02867
02868 }
02869 else if (!(ovrscy == 0 || ovrscx == 0)) {
02870
02871 cpl_matrix_set(m_tmp, row, 0, 0.0);
02872 cpl_matrix_set(m_tmp, row, 1, (cxdouble) winx - ovrscx - 1);
02873 cpl_matrix_set(m_tmp, row, 2, (cxdouble) winy - ovrscy);
02874 cpl_matrix_set(m_tmp, row, 3, (cxdouble) winy - 1);
02875
02876 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02877 row++;
02878
02879 }
02880 else if (ovrscy > 0) {
02881
02882 cpl_matrix_set(m_tmp, row, 0, 0.0);
02883 cpl_matrix_set(m_tmp, row, 1, (cxdouble) winx - 1);
02884 cpl_matrix_set(m_tmp, row, 2, (cxdouble) winy - ovrscy);
02885 cpl_matrix_set(m_tmp, row, 3, (cxdouble) winy - 1);
02886
02887 cpl_matrix_resize(m_tmp, 0, 1, 0, 0);
02888 row++;
02889 }
02890
02891 cpl_matrix_resize(m_tmp, 0, -1, 0, 0);
02892 row--;
02893
02894 if (row == 0) {
02895 cpl_matrix_delete(m_tmp);
02896 return NULL;
02897 }
02898
02899 return m_tmp;
02900 }
02901
02902
02921 cxint
02922 giraffe_trim_raw_areas(GiImage *image)
02923 {
02924
02925 const cxchar *fctid = "giraffe_trim_raw_areas";
02926
02927 cxint nx, ny;
02928 cxint newlx, newly, newux, newuy;
02929
02930 cxint ovscx = 0;
02931 cxint ovscy = 0;
02932 cxint prscx = 0;
02933 cxint prscy = 0;
02934
02935 cpl_propertylist *properties = giraffe_image_get_properties(image);
02936
02937 cpl_image *_image = giraffe_image_get(image);
02938 cpl_image *tmp;
02939
02940
02941 if (!properties) {
02942 cpl_msg_error(fctid, "Image does not contain any properties!");
02943 return 1;
02944 }
02945
02946 nx = cpl_image_get_size_x(_image);
02947 ny = cpl_image_get_size_y(_image);
02948
02949 if (cpl_propertylist_has(properties, GIALIAS_NAXIS1)) {
02950 cxint _nx = cpl_propertylist_get_int(properties, GIALIAS_NAXIS1);
02951
02952 if (_nx != nx) {
02953 cpl_msg_warning(fctid, "Image size (%d) and image property `%s' "
02954 "(%d) are not consistent! Using image size ...",
02955 nx, GIALIAS_NAXIS1, _nx);
02956 }
02957 }
02958 else {
02959 cpl_msg_warning(fctid, "Image does not contain any property `%s'. "
02960 "Using image size (%d)", GIALIAS_NAXIS1, nx);
02961 }
02962
02963
02964 if (cpl_propertylist_has(properties, GIALIAS_NAXIS2)) {
02965 cxint _ny = cpl_propertylist_get_int(properties, GIALIAS_NAXIS2);
02966
02967 if (_ny != ny) {
02968 cpl_msg_warning(fctid, "Image size (%d) and image property `%s' "
02969 "(%d) are not consistent! Using image size ...",
02970 ny, GIALIAS_NAXIS2, _ny);
02971 }
02972 }
02973 else {
02974 cpl_msg_warning(fctid, "Image does not contain any property `%s'. "
02975 "Using image size (%d)", GIALIAS_NAXIS2, ny);
02976 }
02977
02978 if (cpl_propertylist_has(properties, GIALIAS_OVSCX)) {
02979 ovscx = cpl_propertylist_get_int(properties, GIALIAS_OVSCX);
02980 }
02981
02982 if (cpl_propertylist_has(properties, GIALIAS_OVSCY)) {
02983 ovscy = cpl_propertylist_get_int(properties, GIALIAS_OVSCY);
02984 }
02985
02986 if (cpl_propertylist_has(properties, GIALIAS_PRSCX)) {
02987 prscx = cpl_propertylist_get_int(properties, GIALIAS_PRSCX);
02988 }
02989
02990 if (cpl_propertylist_has(properties, GIALIAS_PRSCY)) {
02991 prscy = cpl_propertylist_get_int(properties, GIALIAS_PRSCY);
02992 }
02993
02994
02995
02996
02997
02998 newlx = prscx + 1;
02999 newly = prscy + 1;
03000 newux = nx - ovscx;
03001 newuy = ny - ovscy;
03002
03003 tmp = cpl_image_extract(_image, newlx, newly, newux, newuy);
03004
03005 giraffe_image_set(image, tmp);
03006 cpl_image_delete(tmp);
03007
03008 _image = giraffe_image_get(image);
03009
03010 nx = cpl_image_get_size_x(_image);
03011 ny = cpl_image_get_size_y(_image);
03012
03013
03014
03015
03016
03017
03018 cpl_propertylist_set_int(properties, GIALIAS_NAXIS1, nx);
03019 cpl_propertylist_set_int(properties, GIALIAS_NAXIS2, ny);
03020
03021 if (cpl_propertylist_has(properties, GIALIAS_CRPIX1)) {
03022 cxdouble crpix1 = cpl_propertylist_get_double(properties,
03023 GIALIAS_CRPIX1);
03024
03025
03026
03027
03028
03029
03030 crpix1 += (cxdouble)prscx;
03031 cpl_propertylist_set_double(properties, GIALIAS_CRPIX1, crpix1);
03032 }
03033
03034 if (cpl_propertylist_has(properties, GIALIAS_CRPIX2)) {
03035 cxdouble crpix2 = cpl_propertylist_get_double(properties,
03036 GIALIAS_CRPIX2);
03037
03038 crpix2 -= (cxdouble) prscy;
03039 cpl_propertylist_set_double(properties, GIALIAS_CRPIX2, crpix2);
03040 }
03041
03042 cpl_propertylist_erase(properties, GIALIAS_OVSCX);
03043 cpl_propertylist_erase(properties, GIALIAS_OVSCY);
03044 cpl_propertylist_erase(properties, GIALIAS_PRSCX);
03045 cpl_propertylist_erase(properties, GIALIAS_PRSCY);
03046
03047 return 0;
03048
03049 }
03050
03051
03113 cxint
03114 giraffe_bias_remove(GiImage* result, const GiImage* raw,
03115 const GiImage* master_bias, const GiImage* bad_pixels,
03116 const cpl_matrix* biaslimits, const GiBiasConfig* config)
03117 {
03118
03119 const cxchar* const fctid = "giraffe_bias_remove";
03120
03121 cxint error_code;
03122
03123 cxdouble bias_value = 0.;
03124
03125 cx_string* s;
03126
03127 cpl_matrix* areas = NULL;
03128
03129 cpl_image* _raw = giraffe_image_get(raw);
03130 cpl_image* _master_bias = giraffe_image_get(master_bias);
03131 cpl_image* _bad_pixels = giraffe_image_get(bad_pixels);
03132 cpl_image* timage;
03133
03134 cpl_propertylist* properties;
03135
03136 GiBiasResults bias_results = {0., 0., 0., NULL, NULL, NULL};
03137
03138
03139 cx_assert(raw != NULL);
03140 cx_assert(config != NULL);
03141 cx_assert(biaslimits == NULL);
03142
03143 if (result == NULL) {
03144 return 1;
03145 }
03146
03147
03148
03149
03150
03151
03152 if (strncmp(config->areas, "None", 4) == 0) {
03153
03154 cpl_msg_info(fctid, "No bias areas specified, using pre/overscan"
03155 "regions of the raw frame.");
03156
03157 cpl_error_reset();
03158 areas = giraffe_get_raw_areas(raw);
03159 if (areas == NULL) {
03160 if (cpl_error_get_code() == CPL_ERROR_NULL_INPUT) {
03161 cpl_msg_error(fctid, "Invalid raw image! Image does not "
03162 "contain any properties!");
03163 }
03164 else {
03165 cpl_msg_error(fctid, "Invalid raw image! Image does not "
03166 "contain or has invalid pre- and overscan "
03167 "properties.");
03168 }
03169
03170 return 1;
03171 }
03172
03173 }
03174 else {
03175
03176 areas = _giraffe_bias_get_areas(config->areas);
03177
03178 if (areas == NULL) {
03179
03180 cpl_msg_error(fctid, "Invalid bias area specification '%s'!",
03181 config->areas);
03182 return 1;
03183
03184 }
03185
03186 cpl_msg_info(fctid, "Using bias area(s) '%s' for bias computation",
03187 config->areas);
03188
03189 }
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202 if (master_bias != NULL) {
03203 cpl_propertylist *_properties;
03204 cxbool is_same_size = FALSE;
03205
03206 is_same_size = _giraffe_compare_overscans(raw, master_bias);
03207
03208
03209
03210
03211
03212
03213 if (is_same_size==FALSE) {
03214 cpl_msg_info(fctid, "PRE/OVRSCAN Regions do not match between "
03215 "RAW Image and Masterbias Image.");
03216
03217 return 1;
03218 }
03219
03220 _properties = giraffe_image_get_properties(master_bias);
03221
03222 if (cpl_propertylist_has(_properties, GIALIAS_BIASVALUE)) {
03223 bias_value = cpl_propertylist_get_double(_properties,
03224 GIALIAS_BIASVALUE);
03225 }
03226 }
03227
03228
03229
03230
03231
03232
03233
03234 if (bad_pixels != NULL) {
03235 cxbool is_same_size = FALSE;
03236
03237 is_same_size = _giraffe_compare_overscans(raw, bad_pixels);
03238
03239
03240
03241
03242
03243
03244 if (is_same_size == FALSE) {
03245 cpl_msg_info(fctid, "PRE/OVRSCAN Regions do not match between "
03246 "RAW Image and Bad Pixel Image.");
03247
03248 return 1;
03249 }
03250 }
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261 timage = cpl_image_duplicate(_raw);
03262
03263
03264
03265
03266
03267
03268
03269 error_code = _giraffe_bias_compute(&bias_results, timage,
03270 areas, _master_bias,
03271 _bad_pixels, config->method,
03272 config->option, config->model,
03273 config->remove, bias_value,
03274 config->xdeg, config->ydeg,
03275 config->xstep, config->ystep,
03276 config->sigma, config->iterations,
03277 config->fraction);
03278
03279 cpl_matrix_delete(areas);
03280 areas = NULL;
03281
03282
03283
03284
03285
03286
03287 if (error_code) {
03288
03289 _giraffe_biasresults_clear(&bias_results);
03290
03291 cpl_msg_error(fctid, "Bias computation failed with error %d!",
03292 error_code);
03293 return 1;
03294
03295 }
03296
03297
03298
03299
03300
03301
03302 properties = giraffe_image_get_properties(raw);
03303
03304 if (config->remove == TRUE) {
03305
03306 giraffe_image_set(result, timage);
03307 cpl_image_delete(timage);
03308
03309 giraffe_image_set_properties(result, properties);
03310
03311 }
03312 else {
03313
03314 cpl_image_delete(timage);
03315
03316 giraffe_image_set(result, _raw);
03317 giraffe_image_set_properties(result, properties);
03318
03319 }
03320
03321
03322
03323
03324
03325
03326 properties = giraffe_image_get_properties(result);
03327
03328 if (config->remove == TRUE) {
03329
03330 cpl_propertylist_set_int(properties, GIALIAS_BITPIX, -32);
03331 cpl_propertylist_set_double(properties, GIALIAS_BZERO, 0.);
03332 cpl_propertylist_set_double(properties, GIALIAS_BSCALE, 1.);
03333
03334 if (cpl_propertylist_has(properties, GIALIAS_GIRFTYPE)) {
03335 cpl_propertylist_set_string(properties,
03336 GIALIAS_GIRFTYPE, "BRMIMG");
03337 }
03338 else {
03339 cpl_propertylist_append_string(properties,
03340 GIALIAS_GIRFTYPE, "BRMIMG");
03341 }
03342 cpl_propertylist_set_comment(properties, GIALIAS_GIRFTYPE,
03343 "GIRAFFE bias subtracted frame");
03344
03345
03346
03347
03348
03349 giraffe_trim_raw_areas(result);
03350
03351
03352
03353
03354
03355
03356
03357
03358 #if 0
03359 if (cpl_propertylist_has(properties, GIALIAS_CONAD)) {
03360 cxdouble conad = cpl_propertylist_get_double(properties, GIALIAS_CONAD);
03361
03362 if (conad > 0.) {
03363
03364 cpl_image* _result = giraffe_image_get(result);
03365
03366 cpl_msg_info(fctid, "Converting bias subtracted frame to "
03367 "electrons; conversion factor is %.2f e-/ADU",
03368 conad);
03369 cpl_image_multiply_scalar(_result, conad);
03370 }
03371 else {
03372 cpl_msg_warning(fctid, "Invalid conversion factor %.2f "
03373 "e-/ADU! Bias subtracted image will not be "
03374 "converted.", conad);
03375 }
03376 }
03377 else {
03378 cpl_msg_info(fctid, "Conversion factor not found. Bias subtracted "
03379 "image will remain in ADU");
03380 }
03381 #endif
03382 }
03383
03384 s = cx_string_new();
03385
03386 _giraffe_method_string(s, config->method, config->option);
03387 cpl_propertylist_append_string(properties, GIALIAS_BIASMETHOD, cx_string_get(s));
03388
03389 cx_string_delete(s);
03390
03391 cpl_propertylist_append_double(properties, GIALIAS_BIASVALUE,
03392 bias_results.mean);
03393 cpl_propertylist_append_double(properties, GIALIAS_BIASERROR,
03394 bias_results.sigma);
03395 cpl_propertylist_append_double(properties, GIALIAS_BIASSIGMA,
03396 bias_results.rms);
03397
03398 if (bias_results.coeffs) {
03399 cpl_propertylist_append_double(properties, GIALIAS_BCLIPSIGMA,
03400 config->sigma);
03401 cpl_propertylist_append_int(properties, GIALIAS_BCLIPNITER,
03402 config->iterations);
03403 cpl_propertylist_append_double(properties, GIALIAS_BCLIPMFRAC,
03404 config->fraction);
03405 }
03406
03407 if (bias_results.limits) {
03408 cpl_propertylist_append_string(properties, GIALIAS_BIASAREAS,
03409 cx_string_get(bias_results.limits));
03410 }
03411
03412 if (bias_results.coeffs) {
03413 s = cx_string_new();
03414
03415 _giraffe_stringify_coefficients(s, bias_results.coeffs);
03416 cpl_propertylist_append_string(properties, GIALIAS_BIASPLANE,
03417 cx_string_get(s));
03418
03419 cx_string_delete(s);
03420 }
03421
03422
03423
03424
03425
03426
03427 _giraffe_biasresults_clear(&bias_results);
03428
03429 return 0;
03430
03431 }
03432
03433
03444 GiBiasConfig*
03445 giraffe_bias_config_create(cpl_parameterlist* list)
03446 {
03447
03448 const cxchar* s;
03449 cpl_parameter* p;
03450
03451 GiBiasConfig* config = NULL;
03452
03453
03454 if (!list) {
03455 return NULL;
03456 }
03457
03458 config = cx_calloc(1, sizeof *config);
03459
03460
03461
03462
03463
03464
03465 config->method = GIBIAS_METHOD_UNDEFINED;
03466 config->option = GIBIAS_OPTION_UNDEFINED;
03467 config->model = GIBIAS_MODEL_UNDEFINED;
03468 config->mbias = 0.;
03469 config->xdeg = 1;
03470 config->ydeg = 1;
03471
03472
03473 p = cpl_parameterlist_find(list, "giraffe.biasremoval.remove");
03474 config->remove = cpl_parameter_get_bool(p);
03475
03476 p = cpl_parameterlist_find(list, "giraffe.biasremoval.method");
03477 s = cpl_parameter_get_string(p);
03478
03479 if (!strcmp(s, "UNIFORM")) {
03480 config->method = GIBIAS_METHOD_UNIFORM;
03481 }
03482
03483 if (!strcmp(s, "PLANE")) {
03484 config->method = GIBIAS_METHOD_PLANE;
03485 }
03486
03487 if (!strcmp(s, "CURVE")) {
03488 config->method = GIBIAS_METHOD_CURVE;
03489 }
03490
03491 if (!strcmp(s, "PROFILE")) {
03492 config->method = GIBIAS_METHOD_PROFILE;
03493 }
03494
03495 if (!strcmp(s, "MASTER")) {
03496 config->method = GIBIAS_METHOD_MASTER;
03497 }
03498
03499 if (!strcmp(s, "ZMASTER")) {
03500 config->method = GIBIAS_METHOD_ZMASTER;
03501 }
03502
03503 if (!strcmp(s, "PROFILE+CURVE")) {
03504 config->method = GIBIAS_METHOD_PROFILE;
03505 config->option = GIBIAS_OPTION_CURVE;
03506 }
03507
03508 if (!strcmp(s, "MASTER+PLANE")) {
03509 config->method = GIBIAS_METHOD_MASTER;
03510 config->option = GIBIAS_OPTION_PLANE;
03511 }
03512
03513 if (!strcmp(s, "ZMASTER+PLANE")) {
03514 config->method = GIBIAS_METHOD_ZMASTER;
03515 config->option = GIBIAS_OPTION_PLANE;
03516 }
03517
03518 if (!strcmp(s, "MASTER+CURVE")) {
03519 config->method = GIBIAS_METHOD_MASTER;
03520 config->option = GIBIAS_OPTION_CURVE;
03521 }
03522
03523 if (!strcmp(s, "ZMASTER+CURVE")) {
03524 config->method = GIBIAS_METHOD_ZMASTER;
03525 config->option = GIBIAS_OPTION_CURVE;
03526 }
03527
03528 cx_assert(config->method != GIBIAS_METHOD_UNDEFINED);
03529
03530 p = cpl_parameterlist_find(list, "giraffe.biasremoval.areas");
03531 s = cpl_parameter_get_string(p);
03532 config->areas = cx_strdup(s);
03533
03534 p = cpl_parameterlist_find(list, "giraffe.biasremoval.sigma");
03535 config->sigma = cpl_parameter_get_double(p);
03536
03537 p = cpl_parameterlist_find(list, "giraffe.biasremoval.iterations");
03538 config->iterations = cpl_parameter_get_int(p);
03539
03540 p = cpl_parameterlist_find(list, "giraffe.biasremoval.fraction");
03541 config->fraction = cpl_parameter_get_double(p);
03542
03543 if (config->method == GIBIAS_METHOD_CURVE ||
03544 config->option == GIBIAS_OPTION_CURVE) {
03545 p = cpl_parameterlist_find(list, "giraffe.biasremoval.xorder");
03546 config->xdeg = 1 + cpl_parameter_get_int(p);
03547
03548 p = cpl_parameterlist_find(list, "giraffe.biasremoval.yorder");
03549 config->ydeg = 1 + cpl_parameter_get_int(p);
03550 }
03551
03552 p = cpl_parameterlist_find(list, "giraffe.biasremoval.xstep");
03553 config->xstep = cpl_parameter_get_int(p);
03554
03555 p = cpl_parameterlist_find(list, "giraffe.biasremoval.ystep");
03556 config->ystep = cpl_parameter_get_int(p);
03557
03558 return config;
03559
03560 }
03561
03562
03575 void
03576 giraffe_bias_config_destroy(GiBiasConfig* config)
03577 {
03578
03579 if (config) {
03580 if (config->areas) {
03581 cx_free(config->areas);
03582 config->areas = NULL;
03583 }
03584
03585 cx_free(config);
03586 }
03587
03588 return;
03589 }
03590
03591
03603 void
03604 giraffe_bias_config_add(cpl_parameterlist* list)
03605 {
03606
03607 cpl_parameter* p;
03608
03609
03610 if (!list) {
03611 return;
03612 }
03613
03614 p = cpl_parameter_new_value("giraffe.biasremoval.remove",
03615 CPL_TYPE_BOOL,
03616 "Enable bias removal",
03617 "giraffe.biasremoval",
03618 TRUE);
03619 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "remove-bias");
03620 cpl_parameterlist_append(list, p);
03621
03622
03623 p = cpl_parameter_new_enum("giraffe.biasremoval.method",
03624 CPL_TYPE_STRING,
03625 "Bias removal method",
03626 "giraffe.biasremoval",
03627 "PROFILE", 11, "UNIFORM", "PLANE", "CURVE",
03628 "PROFILE", "MASTER", "ZMASTER", "PROFILE+CURVE",
03629 "MASTER+PLANE", "MASTER+CURVE", "ZMASTER+PLANE",
03630 "ZMASTER+CURVE");
03631 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bsremove-method");
03632 cpl_parameterlist_append(list, p);
03633
03634
03635 p = cpl_parameter_new_value("giraffe.biasremoval.areas",
03636 CPL_TYPE_STRING,
03637 "Bias areas to use "
03638 "(Xl0:Xr0:Yl0:Yr0, ... ,Xln:Xrn:Yln:Yrn)",
03639 "giraffe.biasremoval",
03640 "5:40:0:4095");
03641 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bsremove-areas");
03642 cpl_parameterlist_append(list, p);
03643
03644
03645 p = cpl_parameter_new_value("giraffe.biasremoval.sigma",
03646 CPL_TYPE_DOUBLE,
03647 "Sigma Clipping: sigma threshold factor",
03648 "giraffe.biasremoval",
03649 2.5);
03650 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bsremove-sigma");
03651 cpl_parameterlist_append(list, p);
03652
03653
03654 p = cpl_parameter_new_value("giraffe.biasremoval.iterations",
03655 CPL_TYPE_INT,
03656 "Sigma Clipping: maximum number of "
03657 "iterations",
03658 "giraffe.biasremoval",
03659 5);
03660 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bsremove-niter");
03661 cpl_parameterlist_append(list, p);
03662
03663
03664 p = cpl_parameter_new_value("giraffe.biasremoval.fraction",
03665 CPL_TYPE_DOUBLE,
03666 "Sigma Clipping: minimum fraction of points "
03667 "accepted/total [0.0..1.0]",
03668 "giraffe.biasremoval",
03669 0.8);
03670 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bsremove-mfrac");
03671 cpl_parameterlist_append(list, p);
03672
03673
03674 p = cpl_parameter_new_value("giraffe.biasremoval.xorder",
03675 CPL_TYPE_INT,
03676 "Order of X polynomial fit (CURVE method "
03677 "only)",
03678 "giraffe.biasremoval",
03679 1);
03680 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bsremove-xorder");
03681 cpl_parameterlist_append(list, p);
03682
03683 p = cpl_parameter_new_value("giraffe.biasremoval.yorder",
03684 CPL_TYPE_INT,
03685 "Order of Y polynomial fit (CURVE method "
03686 "only)",
03687 "giraffe.biasremoval",
03688 1);
03689 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bsremove-yorder");
03690 cpl_parameterlist_append(list, p);
03691
03692
03693 p = cpl_parameter_new_value("giraffe.biasremoval.xstep",
03694 CPL_TYPE_INT,
03695 "Sampling step along X (CURVE method only)",
03696 "giraffe.biasremoval",
03697 1);
03698 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bsremove-xstep");
03699 cpl_parameterlist_append(list, p);
03700
03701
03702 p = cpl_parameter_new_value("giraffe.biasremoval.ystep",
03703 CPL_TYPE_INT,
03704 "Sampling step along Y (CURVE method only)",
03705 "giraffe.biasremoval",
03706 1);
03707 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bsremove-ystep");
03708 cpl_parameterlist_append(list, p);
03709
03710 return;
03711 }