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 #ifndef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 #include <math.h>
00036
00037 #include <cxmemory.h>
00038 #include <cxmessages.h>
00039 #include <cxstrutils.h>
00040 #include <cxstring.h>
00041
00042 #include <cpl_propertylist.h>
00043 #include <cpl_matrix.h>
00044 #include <cpl_image.h>
00045 #include <cpl_msg.h>
00046
00047 #include "gialias.h"
00048 #include "gimacros.h"
00049 #include "gimath.h"
00050 #include "gichebyshev.h"
00051 #include "gimatrix.h"
00052 #include "gislight.h"
00053
00054
00063 struct GiSLightSetup {
00064 cxint xstep;
00065 cxint ystep;
00066 cxdouble ewidth;
00067 cxint iswidth;
00068 cxbool istrim;
00069 cpl_matrix* slices;
00070 };
00071
00072 typedef struct GiSLightSetup GiSLightSetup;
00073
00074
00075 inline static GiSLightSetup*
00076 _giraffe_slightsetup_new(cxint nslices)
00077 {
00078
00079 GiSLightSetup* self = cx_calloc(1, sizeof *self);
00080
00081 if (self != NULL) {
00082 self->slices = cpl_matrix_new(nslices, 3);
00083 }
00084
00085 return self;
00086
00087 }
00088
00089
00090 inline static void
00091 _giraffe_slightsetup_delete(GiSLightSetup* self)
00092 {
00093
00094 if (self != NULL) {
00095
00096 if (self->slices != NULL) {
00097 cpl_matrix_delete(self->slices);
00098 self->slices = NULL;
00099 }
00100
00101 cx_free(self);
00102
00103 }
00104
00105 return;
00106
00107 }
00108
00109
00110 inline static cxint
00111 _giraffe_compute_isregion(cpl_matrix* xis, cpl_matrix* yis, cpl_matrix* zis,
00112 const cpl_image* image, const cpl_image* locy,
00113 const cpl_image* locw, const GiSLightSetup* setup)
00114 {
00115
00116 cxint nx = cpl_image_get_size_y(image);
00117 cxint ny = cpl_image_get_size_x(image);
00118 cxint oxend = 0;
00119 cxint ns = 0;
00120 cxint nsmax = 0;
00121 cxint iscount = 0;
00122 cxint ismax = ny * nx;
00123
00124
00125 cx_assert(xis != NULL);
00126 cx_assert(yis != NULL);
00127 cx_assert(zis != NULL);
00128
00129 cx_assert(setup->slices != NULL);
00130
00131
00132 if (nx != cpl_image_get_size_y(locy) ||
00133 nx != cpl_image_get_size_y(locw)) {
00134 return -1;
00135 }
00136
00137 if (setup->istrim == FALSE) {
00138
00139 cxint nregions = cpl_image_get_size_x(locy) - 1;
00140 cxint kmax = ny;
00141 cxint xs;
00142 cxint x;
00143
00144 for (xs = 0; xs < cpl_matrix_get_nrow(setup->slices); xs++) {
00145
00146 cxint xstart = CX_MAX(cpl_matrix_get(setup->slices, xs, 0), oxend);
00147 cxint xend = CX_MIN(cpl_matrix_get(setup->slices, xs, 1), nx - 1);
00148 cxint xstep = CX_MAX(cpl_matrix_get(setup->slices, xs, 2), 1);
00149
00150
00151 for (x = oxend; x < xstart; x += setup->xstep) {
00152
00153 cxint zx = x * ny;
00154 cxint lx = x * cpl_image_get_size_x(locy);
00155 cxint ylower = 0;
00156 cxint yupper = 0;
00157
00158 const cxdouble* _locy = cpl_image_get_data_const(locy);
00159 const cxdouble* _locw = cpl_image_get_data_const(locw);
00160 const cxdouble* _image = cpl_image_get_data_const(image);
00161
00162
00163 if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
00164 continue;
00165 }
00166
00167 ylower = (cxint)floor(_locy[lx] -
00168 (_locw[lx] + setup->ewidth));
00169 yupper = (cxint)ceil(_locy[lx + nregions] +
00170 (_locw[lx + nregions] + setup->ewidth));
00171
00172 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00173 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00174
00175
00176
00177
00178
00179
00180 if (ylower > setup->iswidth) {
00181
00182 register cxint k;
00183
00184 for (k = 0; k <= ylower; k += setup->ystep) {
00185 cpl_matrix_set(xis, iscount, 0, x);
00186 cpl_matrix_set(yis, iscount, 0, k);
00187 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00188 ++iscount;
00189 }
00190
00191 }
00192
00193
00194
00195
00196
00197
00198 if (ny - yupper > setup->iswidth) {
00199
00200 register cxint k;
00201
00202 for (k = yupper; k < kmax; k += setup->ystep) {
00203 cpl_matrix_set(xis, iscount, 0, x);
00204 cpl_matrix_set(yis, iscount, 0, k);
00205 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00206 ++iscount;
00207 }
00208
00209 }
00210
00211 }
00212
00213 for (x = xstart; x <= xend; x +=xstep) {
00214
00215 cxint zx = x * ny;
00216 cxint lx = x * cpl_image_get_size_x(locy);
00217 cxint ylower = 0;
00218 cxint yupper = 0;
00219
00220 const cxdouble* _locy = cpl_image_get_data_const(locy);
00221 const cxdouble* _locw = cpl_image_get_data_const(locw);
00222 const cxdouble* _image = cpl_image_get_data_const(image);
00223
00224
00225 if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
00226 continue;
00227 }
00228
00229 ylower = (cxint)floor(_locy[lx] -
00230 (_locw[lx] + setup->ewidth));
00231 yupper = (cxint)ceil(_locy[lx + nregions] +
00232 (_locw[lx + nregions] + setup->ewidth));
00233
00234 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00235 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00236
00237
00238
00239
00240
00241
00242 if (ylower > setup->iswidth) {
00243
00244 register cxint k;
00245
00246 for (k = 0; k <= ylower; k += setup->ystep) {
00247 cpl_matrix_set(xis, iscount, 0, x);
00248 cpl_matrix_set(yis, iscount, 0, k);
00249 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00250 ++iscount;
00251 }
00252
00253 }
00254
00255
00256
00257
00258
00259
00260 if (ny - yupper > setup->iswidth) {
00261
00262 register cxint k;
00263
00264 for (k = yupper; k < kmax; k += setup->ystep) {
00265 cpl_matrix_set(xis, iscount, 0, x);
00266 cpl_matrix_set(yis, iscount, 0, k);
00267 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00268 ++iscount;
00269 }
00270
00271 }
00272
00273 }
00274
00275 oxend = xend + 1;
00276
00277 }
00278
00279 for (x = oxend; x < nx; x += setup->xstep) {
00280
00281 cxint zx = x * ny;
00282 cxint lx = x * cpl_image_get_size_x(locy);
00283 cxint ylower = 0;
00284 cxint yupper = 0;
00285
00286 const cxdouble* _locy = cpl_image_get_data_const(locy);
00287 const cxdouble* _locw = cpl_image_get_data_const(locw);
00288 const cxdouble* _image = cpl_image_get_data_const(image);
00289
00290
00291 if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
00292 continue;
00293 }
00294
00295 ylower = (cxint)floor(_locy[lx] -
00296 (_locw[lx] + setup->ewidth));
00297 yupper = (cxint)ceil(_locy[lx + nregions] +
00298 (_locw[lx + nregions] + setup->ewidth));
00299
00300 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00301 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00302
00303
00304
00305
00306
00307
00308 if (ylower > setup->iswidth) {
00309
00310 register cxint k;
00311
00312 for (k = 0; k <= ylower; k += setup->ystep) {
00313 cpl_matrix_set(xis, iscount, 0, x);
00314 cpl_matrix_set(yis, iscount, 0, k);
00315 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00316 ++iscount;
00317 }
00318
00319 }
00320
00321
00322
00323
00324
00325
00326 if (ny - yupper > setup->iswidth) {
00327
00328 register cxint k;
00329
00330 for (k = yupper; k < kmax; k += setup->ystep) {
00331 cpl_matrix_set(xis, iscount, 0, x);
00332 cpl_matrix_set(yis, iscount, 0, k);
00333 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00334 ++iscount;
00335 }
00336
00337 }
00338
00339 }
00340
00341 }
00342
00343 nsmax = cpl_image_get_size_x(locy) - 1;
00344 for (ns = 0; ns < nsmax; ns++) {
00345
00346 cxint nregions = ns + 1;
00347 cxint xs = 0;
00348 cxint x;
00349
00350 oxend = 0;
00351
00352 for (xs = 0; xs < cpl_matrix_get_nrow(setup->slices); xs++) {
00353
00354 cxint xstart = CX_MAX(cpl_matrix_get(setup->slices, xs, 0), oxend);
00355 cxint xend = CX_MIN(cpl_matrix_get(setup->slices, xs, 1), nx - 1);
00356
00357
00358 for (x = oxend; x < xstart; x += setup->xstep) {
00359
00360 cxint k;
00361 cxint zx = x * ny;
00362 cxint lx = x * cpl_image_get_size_x(locy);
00363 cxint ylower = 0;
00364 cxint yupper = 0;
00365
00366 const cxdouble* _locy = cpl_image_get_data_const(locy);
00367 const cxdouble* _locw = cpl_image_get_data_const(locw);
00368 const cxdouble* _image = cpl_image_get_data_const(image);
00369
00370
00371 if (_locw[lx + ns] <= 0.) {
00372 continue;
00373 }
00374
00375 while (_locw[lx + nregions] <= 0. &&
00376 _locy[lx + nregions] <= 0.) {
00377 ++nregions;
00378 }
00379
00380
00381
00382 ylower = (cxint)floor(_locy[lx + nregions] -
00383 (_locw[lx + nregions] + setup->ewidth));
00384
00385
00386
00387 yupper = (cxint)ceil(_locy[lx + ns] +
00388 (_locw[lx + ns] + setup->ewidth));
00389
00390 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00391 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00392
00393 if (ylower - yupper <= setup->iswidth) {
00394 continue;
00395 }
00396
00397 for (k = yupper; k <= ylower && iscount < ismax;
00398 k += setup->ystep) {
00399 cpl_matrix_set(xis, iscount, 0, x);
00400 cpl_matrix_set(yis, iscount, 0, k);
00401 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00402 ++iscount;
00403 }
00404
00405 }
00406
00407 for (x = xstart; x <= xend; x += setup->xstep) {
00408
00409 cxint k;
00410 cxint zx = x * ny;
00411 cxint lx = x * cpl_image_get_size_x(locy);
00412 cxint ylower = 0;
00413 cxint yupper = 0;
00414
00415 const cxdouble* _locy = cpl_image_get_data_const(locy);
00416 const cxdouble* _locw = cpl_image_get_data_const(locw);
00417 const cxdouble* _image = cpl_image_get_data_const(image);
00418
00419
00420 if (_locw[lx + ns] <= 0.) {
00421 continue;
00422 }
00423
00424 while (_locw[lx + nregions] <= 0. &&
00425 _locy[lx + nregions] <= 0.) {
00426 ++nregions;
00427 }
00428
00429
00430
00431 ylower = (cxint)floor(_locy[lx + nregions] -
00432 (_locw[lx + nregions] + setup->ewidth));
00433
00434
00435
00436 yupper = (cxint)ceil(_locy[lx + ns] +
00437 (_locw[lx + ns] + setup->ewidth));
00438
00439 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00440 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00441
00442 if (ylower - yupper <= setup->iswidth) {
00443 continue;
00444 }
00445
00446 for (k = yupper; k <= ylower && iscount < ismax;
00447 k += setup->ystep) {
00448 cpl_matrix_set(xis, iscount, 0, x);
00449 cpl_matrix_set(yis, iscount, 0, k);
00450 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00451 ++iscount;
00452 }
00453
00454 }
00455
00456 oxend = xend + 1;
00457
00458 }
00459
00460 for (x = oxend; x < nx; x += setup->xstep) {
00461
00462 cxint k;
00463 cxint zx = x * ny;
00464 cxint lx = x * cpl_image_get_size_x(locy);
00465 cxint ylower = 0;
00466 cxint yupper = 0;
00467
00468 const cxdouble* _locy = cpl_image_get_data_const(locy);
00469 const cxdouble* _locw = cpl_image_get_data_const(locw);
00470 const cxdouble* _image = cpl_image_get_data_const(image);
00471
00472
00473 if (_locw[lx + ns] <= 0.) {
00474 continue;
00475 }
00476
00477 while (_locw[lx + nregions] <= 0. &&
00478 _locy[lx + nregions] <= 0.) {
00479 ++nregions;
00480 }
00481
00482
00483
00484 ylower = (cxint)floor(_locy[lx + nregions] -
00485 (_locw[lx + nregions] + setup->ewidth));
00486
00487
00488
00489 yupper = (cxint)ceil(_locy[lx + ns] +
00490 (_locw[lx + ns] + setup->ewidth));
00491
00492 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00493 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00494
00495 if (ylower - yupper <= setup->iswidth) {
00496 continue;
00497 }
00498
00499 for (k = yupper; k <= ylower && iscount < ismax;
00500 k += setup->ystep) {
00501 cpl_matrix_set(xis, iscount, 0, x);
00502 cpl_matrix_set(yis, iscount, 0, k);
00503 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00504 ++iscount;
00505 }
00506
00507 }
00508
00509 }
00510
00511 return iscount;
00512
00513 }
00514
00515
00516 inline static cxint
00517 _giraffe_compute_isregion_bpm(cpl_matrix* xis, cpl_matrix* yis,
00518 cpl_matrix* zis, const cpl_image* image,
00519 const cpl_image* locy, const cpl_image* locw,
00520 const cpl_image* bpixel,
00521 const GiSLightSetup* setup)
00522 {
00523
00524 cxint nx = cpl_image_get_size_y(image);
00525 cxint ny = cpl_image_get_size_x(image);
00526 cxint oxend = 0;
00527 cxint ns = 0;
00528 cxint nsmax = 0;
00529 cxint iscount = 0;
00530 cxint ismax = ny * nx;
00531
00532
00533 cx_assert(xis != NULL);
00534 cx_assert(yis != NULL);
00535 cx_assert(zis != NULL);
00536
00537 cx_assert(setup->slices != NULL);
00538
00539
00540 if (nx != cpl_image_get_size_y(locy) ||
00541 nx != cpl_image_get_size_y(locw)) {
00542 return -1;
00543 }
00544
00545 if (nx != cpl_image_get_size_y(bpixel) ||
00546 nx != cpl_image_get_size_y(bpixel)) {
00547 return -2;
00548 }
00549
00550 if (setup->istrim == FALSE) {
00551
00552 cxint nregions = cpl_image_get_size_x(locy) - 1;
00553 cxint kmax = ny;
00554 cxint xs;
00555 cxint x;
00556
00557
00558 for (xs = 0; xs < cpl_matrix_get_nrow(setup->slices); xs++) {
00559
00560 cxint xstart = CX_MAX(cpl_matrix_get(setup->slices, xs, 0), oxend);
00561 cxint xend = CX_MIN(cpl_matrix_get(setup->slices, xs, 1), nx - 1);
00562 cxint xstep = CX_MAX(cpl_matrix_get(setup->slices, xs, 2), 1);
00563
00564
00565 for (x = oxend; x < xstart; x += setup->xstep) {
00566
00567 cxint zx = x * ny;
00568 cxint lx = x * cpl_image_get_size_x(locy);
00569 cxint ylower = 0;
00570 cxint yupper = 0;
00571
00572 const cxdouble* _locy = cpl_image_get_data_const(locy);
00573 const cxdouble* _locw = cpl_image_get_data_const(locw);
00574 const cxdouble* _image = cpl_image_get_data_const(image);
00575
00576
00577 if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
00578 continue;
00579 }
00580
00581 ylower = (cxint)floor(_locy[lx] -
00582 (_locw[lx] + setup->ewidth));
00583 yupper = (cxint)ceil(_locy[lx + nregions] +
00584 (_locw[lx + nregions] + setup->ewidth));
00585
00586 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00587 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00588
00589
00590
00591
00592
00593
00594 if (ylower > setup->iswidth) {
00595
00596 register cxint k;
00597
00598 const cxint* _bpixel = cpl_image_get_data_const(bpixel);
00599
00600
00601 for (k = 0; k <= ylower; k += setup->ystep) {
00602
00603 if (_bpixel[zx + k] & GIR_M_PIX_SET) {
00604 continue;
00605 }
00606
00607 cpl_matrix_set(xis, iscount, 0, x);
00608 cpl_matrix_set(yis, iscount, 0, k);
00609 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00610 ++iscount;
00611 }
00612
00613 }
00614
00615
00616
00617
00618
00619
00620 if (ny - yupper > setup->iswidth) {
00621
00622 register cxint k;
00623
00624 const cxint* _bpixel = cpl_image_get_data_const(bpixel);
00625
00626
00627 for (k = yupper; k < kmax; k += setup->ystep) {
00628
00629 if (_bpixel[zx + k] & GIR_M_PIX_SET) {
00630 continue;
00631 }
00632
00633 cpl_matrix_set(xis, iscount, 0, x);
00634 cpl_matrix_set(yis, iscount, 0, k);
00635 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00636 ++iscount;
00637 }
00638
00639 }
00640
00641 }
00642
00643 for (x = xstart; x <= xend; x +=xstep) {
00644
00645 cxint zx = x * ny;
00646 cxint lx = x * cpl_image_get_size_x(locy);
00647 cxint ylower = 0;
00648 cxint yupper = 0;
00649
00650 const cxdouble* _locy = cpl_image_get_data_const(locy);
00651 const cxdouble* _locw = cpl_image_get_data_const(locw);
00652 const cxdouble* _image = cpl_image_get_data_const(image);
00653
00654
00655 if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
00656 continue;
00657 }
00658
00659 ylower = (cxint)floor(_locy[lx] -
00660 (_locw[lx] + setup->ewidth));
00661 yupper = (cxint)ceil(_locy[lx + nregions] +
00662 (_locw[lx + nregions] + setup->ewidth));
00663
00664 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00665 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00666
00667
00668
00669
00670
00671
00672 if (ylower > setup->iswidth) {
00673
00674 register cxint k;
00675
00676 const cxint* _bpixel = cpl_image_get_data_const(bpixel);
00677
00678
00679 for (k = 0; k <= ylower; k += setup->ystep) {
00680
00681 if (_bpixel[zx + k] & GIR_M_PIX_SET) {
00682 continue;
00683 }
00684
00685 cpl_matrix_set(xis, iscount, 0, x);
00686 cpl_matrix_set(yis, iscount, 0, k);
00687 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00688 ++iscount;
00689 }
00690
00691 }
00692
00693
00694
00695
00696
00697
00698 if (ny - yupper > setup->iswidth) {
00699
00700 register cxint k;
00701
00702 const cxint* _bpixel = cpl_image_get_data_const(bpixel);
00703
00704
00705 for (k = yupper; k < kmax; k += setup->ystep) {
00706
00707 if (_bpixel[zx + k] & GIR_M_PIX_SET) {
00708 continue;
00709 }
00710
00711 cpl_matrix_set(xis, iscount, 0, x);
00712 cpl_matrix_set(yis, iscount, 0, k);
00713 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00714 ++iscount;
00715 }
00716
00717 }
00718
00719 }
00720
00721 oxend = xend + 1;
00722
00723 }
00724
00725 for (x = oxend; x < nx; x += setup->xstep) {
00726
00727 cxint zx = x * ny;
00728 cxint lx = x * cpl_image_get_size_x(locy);
00729 cxint ylower = 0;
00730 cxint yupper = 0;
00731
00732 const cxdouble* _locy = cpl_image_get_data_const(locy);
00733 const cxdouble* _locw = cpl_image_get_data_const(locw);
00734 const cxdouble* _image = cpl_image_get_data_const(image);
00735
00736
00737 if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
00738 continue;
00739 }
00740
00741 ylower = (cxint)floor(_locy[lx] -
00742 (_locw[lx] + setup->ewidth));
00743 yupper = (cxint)ceil(_locy[lx + nregions] +
00744 (_locw[lx + nregions] + setup->ewidth));
00745
00746 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00747 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00748
00749
00750
00751
00752
00753
00754 if (ylower > setup->iswidth) {
00755
00756 register cxint k;
00757
00758 const cxint* _bpixel = cpl_image_get_data_const(bpixel);
00759
00760
00761 for (k = 0; k <= ylower; k += setup->ystep) {
00762
00763 if (_bpixel[zx + k] & GIR_M_PIX_SET) {
00764 continue;
00765 }
00766
00767 cpl_matrix_set(xis, iscount, 0, x);
00768 cpl_matrix_set(yis, iscount, 0, k);
00769 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00770 ++iscount;
00771 }
00772
00773 }
00774
00775
00776
00777
00778
00779
00780 if (ny - yupper > setup->iswidth) {
00781
00782 register cxint k;
00783
00784 const cxint* _bpixel = cpl_image_get_data_const(bpixel);
00785
00786
00787 for (k = yupper; k < kmax; k += setup->ystep) {
00788
00789 if (_bpixel[zx + k] & GIR_M_PIX_SET) {
00790 continue;
00791 }
00792
00793 cpl_matrix_set(xis, iscount, 0, x);
00794 cpl_matrix_set(yis, iscount, 0, k);
00795 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00796 ++iscount;
00797 }
00798
00799 }
00800
00801 }
00802
00803 }
00804
00805 nsmax = cpl_image_get_size_x(locy) - 1;
00806 for (ns = 0; ns < nsmax; ns++) {
00807
00808 cxint nregions = ns + 1;
00809 cxint xs = 0;
00810 cxint x;
00811
00812 oxend = 0;
00813
00814 for (xs = 0; xs < cpl_matrix_get_nrow(setup->slices); xs++) {
00815
00816 cxint xstart = CX_MAX(cpl_matrix_get(setup->slices, xs, 0), oxend);
00817 cxint xend = CX_MIN(cpl_matrix_get(setup->slices, xs, 1), nx - 1);
00818
00819
00820 for (x = oxend; x < xstart; x += setup->xstep) {
00821
00822 cxint zx = x * ny;
00823 cxint lx = x * cpl_image_get_size_x(locy);
00824 cxint ylower = 0;
00825 cxint yupper = 0;
00826
00827 const cxdouble* _locy = cpl_image_get_data_const(locy);
00828 const cxdouble* _locw = cpl_image_get_data_const(locw);
00829 const cxdouble* _image = cpl_image_get_data_const(image);
00830
00831
00832 if (_locw[lx + ns] <= 0.) {
00833 continue;
00834 }
00835
00836 while (_locw[lx + nregions] <= 0. &&
00837 _locy[lx + nregions] <= 0.) {
00838 ++nregions;
00839 }
00840
00841
00842
00843 ylower = (cxint)floor(_locy[lx + nregions] -
00844 (_locw[lx + nregions] + setup->ewidth));
00845
00846
00847
00848 yupper = (cxint)ceil(_locy[lx + ns] +
00849 (_locw[lx + ns] + setup->ewidth));
00850
00851 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00852 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00853
00854 if (ylower - yupper > setup->iswidth) {
00855
00856 register cxint k;
00857
00858 const cxint* _bpixel = cpl_image_get_data_const(bpixel);
00859
00860
00861 for (k = yupper; k <= ylower && iscount < ismax;
00862 k += setup->ystep) {
00863
00864 if (_bpixel[zx + k] & GIR_M_PIX_SET) {
00865 continue;
00866 }
00867
00868 cpl_matrix_set(xis, iscount, 0, x);
00869 cpl_matrix_set(yis, iscount, 0, k);
00870 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00871 ++iscount;
00872 }
00873
00874 }
00875
00876 }
00877
00878 for (x = xstart; x <= xend; x += setup->xstep) {
00879
00880 cxint zx = x * ny;
00881 cxint lx = x * cpl_image_get_size_x(locy);
00882 cxint ylower = 0;
00883 cxint yupper = 0;
00884
00885 const cxdouble* _locy = cpl_image_get_data_const(locy);
00886 const cxdouble* _locw = cpl_image_get_data_const(locw);
00887 const cxdouble* _image = cpl_image_get_data_const(image);
00888
00889
00890 if (_locw[lx + ns] <= 0.) {
00891 continue;
00892 }
00893
00894 while (_locw[lx + nregions] <= 0. &&
00895 _locy[lx + nregions] <= 0.) {
00896 ++nregions;
00897 }
00898
00899
00900
00901 ylower = (cxint)floor(_locy[lx + nregions] -
00902 (_locw[lx + nregions] + setup->ewidth));
00903
00904
00905
00906 yupper = (cxint)ceil(_locy[lx + ns] +
00907 (_locw[lx + ns] + setup->ewidth));
00908
00909 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00910 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00911
00912 if (ylower - yupper > setup->iswidth) {
00913
00914 register cxint k;
00915
00916 const cxint* _bpixel = cpl_image_get_data_const(bpixel);
00917
00918 for (k = yupper; k <= ylower && iscount < ismax;
00919 k += setup->ystep) {
00920
00921 if (_bpixel[zx + k] & GIR_M_PIX_SET) {
00922 continue;
00923 }
00924
00925 cpl_matrix_set(xis, iscount, 0, x);
00926 cpl_matrix_set(yis, iscount, 0, k);
00927 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00928 ++iscount;
00929
00930 }
00931
00932 }
00933
00934 }
00935
00936 oxend = xend + 1;
00937
00938 }
00939
00940 for (x = oxend; x < nx; x += setup->xstep) {
00941
00942 cxint zx = x * ny;
00943 cxint lx = x * cpl_image_get_size_x(locy);
00944 cxint ylower = 0;
00945 cxint yupper = 0;
00946
00947 const cxdouble* _locy = cpl_image_get_data_const(locy);
00948 const cxdouble* _locw = cpl_image_get_data_const(locw);
00949 const cxdouble* _image = cpl_image_get_data_const(image);
00950
00951
00952 if (_locw[lx + ns] <= 0.) {
00953 continue;
00954 }
00955
00956 while (_locw[lx + nregions] <= 0. &&
00957 _locy[lx + nregions] <= 0.) {
00958 ++nregions;
00959 }
00960
00961
00962
00963 ylower = (cxint)floor(_locy[lx + nregions] -
00964 (_locw[lx + nregions] + setup->ewidth));
00965
00966
00967
00968 yupper = (cxint)ceil(_locy[lx + ns] +
00969 (_locw[lx + ns] + setup->ewidth));
00970
00971 ylower = CX_MAX(CX_MIN(ny, ylower), 0);
00972 yupper = CX_MAX(CX_MIN(ny, yupper), 0);
00973
00974 if (ylower - yupper > setup->iswidth) {
00975
00976 register cxint k;
00977
00978 const cxint* _bpixel = cpl_image_get_data_const(bpixel);
00979
00980
00981 for (k = yupper; k <= ylower && iscount < ismax;
00982 k += setup->ystep) {
00983
00984 if (_bpixel[zx + k] & GIR_M_PIX_SET) {
00985 continue;
00986 }
00987
00988 cpl_matrix_set(xis, iscount, 0, x);
00989 cpl_matrix_set(yis, iscount, 0, k);
00990 cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
00991 ++iscount;
00992 }
00993
00994 }
00995
00996 }
00997
00998 }
00999
01000 return iscount;
01001
01002 }
01003
01004 static cpl_image*
01005 _giraffe_slight_fit_polynom(const cpl_image* image, const cpl_image* locy,
01006 const cpl_image* locw, const cpl_image* bpixel,
01007 cxint xorder, cxint yorder, cxint *iscount,
01008 const GiSLightSetup* setup)
01009 {
01010
01011 cxint i;
01012 cxint j;
01013 cxint nx = cpl_image_get_size_y(image);
01014 cxint ny = cpl_image_get_size_x(image);
01015
01016 cpl_image* slfit = NULL;
01017
01018 cpl_matrix* xis = cpl_matrix_new(nx * ny, 1);
01019 cpl_matrix* yis = cpl_matrix_new(nx * ny, 1);
01020 cpl_matrix* zis = cpl_matrix_new(1, nx * ny);
01021
01022
01023 *iscount = 0;
01024
01025 if (bpixel != NULL) {
01026 *iscount = _giraffe_compute_isregion_bpm(xis, yis, zis, image, locy,
01027 locw, bpixel, setup);
01028 }
01029 else {
01030 *iscount = _giraffe_compute_isregion(xis, yis, zis, image, locy,
01031 locw, setup);
01032 }
01033
01034 if (*iscount <= 0 || *iscount >= nx * ny) {
01035
01036 cpl_matrix_delete(xis);
01037 xis = NULL;
01038
01039 cpl_matrix_delete(yis);
01040 yis = NULL;
01041
01042 cpl_matrix_delete(zis);
01043 zis = NULL;
01044
01045 return NULL;
01046
01047 }
01048 else {
01049
01050 cxint status = 0;
01051
01052 cpl_matrix* base = NULL;
01053 cpl_matrix* coeff = NULL;
01054 cpl_matrix* chebyshev = NULL;
01055
01056 GiChebyshev2D* fit = NULL;
01057
01058 cpl_matrix_set_size(xis, *iscount, 1);
01059 cpl_matrix_set_size(yis, *iscount, 1);
01060 cpl_matrix_set_size(zis, 1, *iscount);
01061
01062 #if 0
01063
01064
01065
01066 cpl_image* tmp = cpl_image_new(ny, nx, CPL_TYPE_DOUBLE);
01067 cxdouble* _tmp = cpl_image_get_data(tmp);
01068
01069 for (i = 0; i < *iscount; i++) {
01070 cxint k = cpl_matrix_get(xis, i, 0) * cpl_image_get_size_x(tmp) +
01071 cpl_matrix_get(yis, i, 0);
01072 _tmp[k] = cpl_matrix_get(zis, 0, i);
01073 }
01074
01075 cpl_image_save(tmp, "idiot.fits", CPL_BPP_IEEE_FLOAT, NULL,
01076 CPL_IO_DEFAULT);
01077 cpl_image_delete(tmp);
01078 tmp = NULL;
01079
01080 #endif
01081
01082 base = giraffe_chebyshev_base2d(0., 0., nx, ny, xorder + 1,
01083 yorder + 1, xis, yis);
01084
01085 coeff = giraffe_matrix_leastsq(base, zis);
01086
01087 if (coeff == NULL) {
01088 cpl_matrix_delete(base);
01089 base = NULL;
01090
01091 cpl_matrix_delete(xis);
01092 xis = NULL;
01093
01094 cpl_matrix_delete(yis);
01095 yis = NULL;
01096
01097 cpl_matrix_delete(zis);
01098 zis = NULL;
01099
01100 return NULL;
01101 }
01102
01103 cpl_matrix_delete(base);
01104 base = NULL;
01105
01106 cpl_matrix_delete(xis);
01107 xis = NULL;
01108
01109 cpl_matrix_delete(yis);
01110 yis = NULL;
01111
01112 cpl_matrix_delete(zis);
01113 zis = NULL;
01114
01115
01116
01117
01118
01119
01120 chebyshev = cpl_matrix_wrap(xorder + 1, yorder + 1,
01121 cpl_matrix_get_data(coeff));
01122
01123 fit = giraffe_chebyshev2d_new(xorder, yorder);
01124 status = giraffe_chebyshev2d_set(fit, 0., nx, 0., ny, chebyshev);
01125
01126 if (status != 0) {
01127
01128 giraffe_chebyshev2d_delete(fit);
01129 fit = NULL;
01130
01131 cpl_matrix_unwrap(chebyshev);
01132 chebyshev = NULL;
01133
01134 cpl_matrix_delete(coeff);
01135 coeff = NULL;
01136
01137 return NULL;
01138
01139 }
01140
01141 cpl_matrix_unwrap(chebyshev);
01142 chebyshev = NULL;
01143
01144 cpl_matrix_delete(coeff);
01145 coeff = NULL;
01146
01147 slfit = cpl_image_new(ny, nx, CPL_TYPE_DOUBLE);
01148
01149 if (slfit == NULL) {
01150 giraffe_chebyshev2d_delete(fit);
01151 fit = NULL;
01152
01153 return NULL;
01154 }
01155
01156
01157 for (i = 0; i < nx; i++) {
01158
01159 cxdouble* _slfit = cpl_image_get_data(slfit);
01160
01161 for (j = 0; j < ny; j++) {
01162 cxint k = i * ny + j;
01163 cxdouble value = giraffe_chebyshev2d_eval(fit, i, j);
01164
01165 _slfit[k] = value > 0. ? value : 0.;
01166 }
01167
01168 }
01169
01170 giraffe_chebyshev2d_delete(fit);
01171 fit = NULL;
01172
01173 }
01174
01175 return slfit;
01176 }
01177
01178
01204 cxint
01205 giraffe_adjust_scattered_light(GiImage* result, const GiImage* image,
01206 const GiLocalization* localization,
01207 const GiImage* bpixel, GiImage* phff,
01208 const GiSLightConfig* config)
01209 {
01210
01211 const cxchar *const fctid = "giraffe_adjust_scattered_light";
01212
01213
01214 if (image == NULL) {
01215 return -1;
01216 }
01217
01218 if (localization == NULL) {
01219 return -1;
01220 }
01221
01222 if (localization->locy == NULL || localization->locw == NULL) {
01223 return -1;
01224 }
01225
01226 if (config == NULL) {
01227 return -2;
01228 }
01229
01230
01231
01232
01233
01234
01235
01236 if (phff != NULL) {
01237 cpl_msg_warning(fctid, "Photometric flat field correction is not "
01238 "implemented! Ignoring photometric flat field.");
01239 }
01240
01241
01242 if (strncmp(config->model, "polynom", 7) != 0) {
01243 cpl_msg_error(fctid, "Scattered light model `%s' is not supported!",
01244 config->model);
01245 return -3;
01246 }
01247 else {
01248
01249 cxint iscount = 0;
01250
01251 cx_string* s = NULL;
01252
01253 const cpl_image* _image = giraffe_image_get(image);
01254 const cpl_image* _locy = giraffe_image_get(localization->locy);
01255 const cpl_image* _locw = giraffe_image_get(localization->locw);
01256 const cpl_image* _bpixel = NULL;
01257
01258 cpl_propertylist* properties = NULL;
01259
01260 cpl_image* slfit = NULL;
01261
01262 GiSLightSetup* setup = _giraffe_slightsetup_new(1);
01263
01264
01265 setup->xstep = config->xstep;
01266 setup->ystep = config->ystep;
01267 setup->ewidth = config->ewidth;
01268 setup->iswidth = config->iswidth;
01269 setup->istrim = config->istrim;
01270
01271 cpl_matrix_set(setup->slices, 0, 0, 0);
01272 cpl_matrix_set(setup->slices, 0, 1, cpl_image_get_size_y(_image));
01273 cpl_matrix_set(setup->slices, 0, 2, config->xstep);
01274
01275
01276 if (bpixel != NULL) {
01277 _bpixel = giraffe_image_get(bpixel);
01278 }
01279
01280 slfit = _giraffe_slight_fit_polynom(_image, _locy, _locw, _bpixel,
01281 config->xorder[0],
01282 config->yorder[0],
01283 &iscount, setup);
01284 if (slfit == NULL) {
01285 cpl_msg_error(fctid, "Fitting scattered light model failed!");
01286
01287 _giraffe_slightsetup_delete(setup);
01288 setup = NULL;
01289
01290 return 1;
01291 }
01292
01293 _giraffe_slightsetup_delete(setup);
01294 setup = NULL;
01295
01296 giraffe_image_set(result, slfit);
01297
01298 cpl_image_delete(slfit);
01299 slfit = NULL;
01300
01301 giraffe_image_set_properties(result,
01302 giraffe_image_get_properties(image));
01303 properties = giraffe_image_get_properties(result);
01304
01305 cpl_propertylist_update_string(properties, GIALIAS_SLMNAME,
01306 config->model);
01307 cpl_propertylist_set_comment(properties, GIALIAS_SLMNAME,
01308 "Scattered light model type.");
01309
01310
01311 s = cx_string_new();
01312
01313 if (strncmp(config->model, "polynom", 7) == 0) {
01314
01315 cx_string_sprintf(s, "%d:%d", config->xorder[0],
01316 config->yorder[0]);
01317
01318 cpl_propertylist_update_string(properties, GIALIAS_SLMORDER,
01319 cx_string_get(s));
01320 cpl_propertylist_set_comment(properties, GIALIAS_SLMORDER,
01321 "Scattered light polynom order "
01322 "X:Y.");
01323
01324 }
01325 else if (strncmp(config->model, "polyfrac", 8) == 0) {
01326
01327 cx_string_sprintf(s, "%d:%d/%d:%d", config->xorder[0],
01328 config->yorder[0], config->xorder[1],
01329 config->yorder[1]);
01330
01331 cpl_propertylist_update_string(properties, GIALIAS_SLMORDER,
01332 cx_string_get(s));
01333 cpl_propertylist_set_comment(properties, GIALIAS_SLMORDER,
01334 "Scattered light polynom fraction "
01335 "order Xn:Yn/Xd:Xd.");
01336
01337 }
01338
01339
01340 cx_string_sprintf(s, "%d:%d", config->xstep, config->ystep);
01341
01342 cpl_propertylist_update_string(properties, GIALIAS_SLMSTEPS,
01343 cx_string_get(s));
01344 cpl_propertylist_set_comment(properties, GIALIAS_SLMSTEPS,
01345 "Scattered light X, Y sampling step.");
01346
01347 cx_string_delete(s);
01348 s = NULL;
01349
01350
01351 cpl_propertylist_update_double(properties, GIALIAS_SLMEWIDTH,
01352 config->ewidth);
01353 cpl_propertylist_set_comment(properties, GIALIAS_SLMEWIDTH,
01354 "Extra pixels added to spectrum "
01355 "width.");
01356
01357 cpl_propertylist_update_int(properties, GIALIAS_SLMIWIDTH,
01358 config->iswidth);
01359 cpl_propertylist_set_comment(properties, GIALIAS_SLMIWIDTH,
01360 "Minimum required inter-spectrum "
01361 "region width.");
01362
01363 cpl_propertylist_update_bool(properties, GIALIAS_SLMTRIM,
01364 config->istrim);
01365 cpl_propertylist_set_comment(properties, GIALIAS_SLMTRIM,
01366 "Removal of first and last "
01367 "inter-spectrum region.");
01368
01369 }
01370
01371 return 0;
01372 }
01373
01374
01386 GiSLightConfig*
01387 giraffe_slight_config_create(cpl_parameterlist* list)
01388 {
01389
01390 const cxchar* s;
01391
01392 cpl_parameter* p = NULL;
01393
01394 GiSLightConfig* config = NULL;
01395
01396
01397 if (list == NULL) {
01398 return NULL;
01399 }
01400
01401 config = cx_calloc(1, sizeof *config);
01402
01403 p = cpl_parameterlist_find(list, "giraffe.slight.model.name");
01404 config->model = cx_strdup(cpl_parameter_get_string(p));
01405
01406 if (strncmp(config->model, "polynom", 7) != 0 &&
01407 strncmp(config->model, "polyfrac", 8) != 0) {
01408 giraffe_slight_config_destroy(config);
01409 return NULL;
01410 }
01411
01412 p = cpl_parameterlist_find(list, "giraffe.slight.model.order");
01413 s = cpl_parameter_get_default_string(p);
01414
01415 if (sscanf(s, "%d,%d", &config->xorder[0], &config->yorder[0]) != 2) {
01416 giraffe_slight_config_destroy(config);
01417 return NULL;
01418 }
01419
01420 config->xorder[1] = 0;
01421 config->yorder[1] = 0;
01422
01423 s = cpl_parameter_get_string(p);
01424
01425 if (s == NULL) {
01426 giraffe_slight_config_destroy(config);
01427 return NULL;
01428 }
01429 else {
01430
01431 cxchar** values = cx_strsplit(s, ",", 5);
01432
01433 if (values == NULL) {
01434 giraffe_slight_config_destroy(config);
01435 return NULL;
01436 }
01437 else {
01438
01439 cxchar* last;
01440
01441 config->xorder[0] = strtol(values[0], &last, 10);
01442
01443 if (*last != '\0') {
01444 cx_strfreev(values);
01445 giraffe_slight_config_destroy(config);
01446
01447 return NULL;
01448 }
01449
01450 if (values[1] != NULL) {
01451
01452 config->yorder[0] = strtol(values[1], &last, 10);
01453
01454 if (*last != '\0') {
01455 cx_strfreev(values);
01456 giraffe_slight_config_destroy(config);
01457
01458 return NULL;
01459 }
01460
01461 }
01462
01463 if (strncmp(config->model, "polyfrac", 8) == 0) {
01464
01465 if (values[2] != NULL) {
01466
01467 config->xorder[1] = strtol(values[2], &last, 10);
01468
01469 if (*last != '\0') {
01470 cx_strfreev(values);
01471 giraffe_slight_config_destroy(config);
01472
01473 return NULL;
01474 }
01475
01476 }
01477
01478 if (values[3] != NULL) {
01479
01480 config->yorder[1] = strtol(values[3], &last, 10);
01481
01482 if (*last != '\0') {
01483 cx_strfreev(values);
01484 giraffe_slight_config_destroy(config);
01485
01486 return NULL;
01487 }
01488
01489 }
01490
01491 }
01492
01493 cx_strfreev(values);
01494 values = NULL;
01495
01496 }
01497
01498 }
01499
01500
01501 p = cpl_parameterlist_find(list, "giraffe.slight.xstep");
01502 config->xstep = cpl_parameter_get_int(p);
01503
01504 p = cpl_parameterlist_find(list, "giraffe.slight.ystep");
01505 config->ystep = cpl_parameter_get_int(p);
01506
01507 p = cpl_parameterlist_find(list, "giraffe.slight.xslice");
01508 s = cpl_parameter_get_default_string(p);
01509
01510
01511
01512
01513
01514
01515
01516 if (strncmp(s, "none", 4) != 0) {
01517 giraffe_slight_config_destroy(config);
01518 return NULL;
01519 }
01520
01521 s = cpl_parameter_get_string(p);
01522
01523 if (s == NULL) {
01524 giraffe_slight_config_destroy(config);
01525 return NULL;
01526 }
01527 else {
01528
01529 cxchar** slices = cx_strsplit(s, ",", -1);
01530
01531 if (slices == NULL) {
01532 giraffe_slight_config_destroy(config);
01533 return NULL;
01534 }
01535 else {
01536 cx_strfreev(slices);
01537 slices = NULL;
01538 }
01539
01540 }
01541
01542
01543 p = cpl_parameterlist_find(list, "giraffe.slight.ewidth");
01544 config->ewidth = cpl_parameter_get_double(p);
01545
01546 p = cpl_parameterlist_find(list, "giraffe.slight.iswidth");
01547 config->iswidth = cpl_parameter_get_int(p);
01548
01549 p = cpl_parameterlist_find(list, "giraffe.slight.istrim");
01550 config->istrim = cpl_parameter_get_bool(p);
01551
01552 p = cpl_parameterlist_find(list, "giraffe.slight.phffcorrection");
01553 config->phffcor = cpl_parameter_get_bool(p);
01554
01555 p = cpl_parameterlist_find(list, "giraffe.slight.remove");
01556 config->remove = cpl_parameter_get_bool(p);
01557
01558 return config;
01559
01560 }
01561
01562
01576 void
01577 giraffe_slight_config_destroy(GiSLightConfig *config)
01578 {
01579
01580 if (config != NULL) {
01581
01582 if (config->model != NULL) {
01583 cx_free((cxchar*)config->model);
01584 config->model = NULL;
01585 }
01586
01587 cx_free(config);
01588
01589 }
01590
01591 return;
01592
01593 }
01594
01595
01608 void
01609 giraffe_slight_config_add(cpl_parameterlist* list)
01610 {
01611
01612 cpl_parameter* p;
01613
01614
01615 if (list == NULL) {
01616 return;
01617 }
01618
01619 p = cpl_parameter_new_enum("giraffe.slight.model.name",
01620 CPL_TYPE_STRING,
01621 "Name of the scattered light model to use.",
01622 "giraffe.slight",
01623 "polynom", 2, "polynom", "polyfrac");
01624 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-model");
01625 cpl_parameterlist_append(list, p);
01626
01627
01628 p = cpl_parameter_new_value("giraffe.slight.model.order",
01629 CPL_TYPE_STRING,
01630 "Scattered light model fit X and Y order.",
01631 "giraffe.slight",
01632 "4,2");
01633 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-order");
01634 cpl_parameterlist_append(list, p);
01635
01636
01637 p = cpl_parameter_new_value("giraffe.slight.xstep",
01638 CPL_TYPE_INT,
01639 "Interspectrum region sampling step along "
01640 "the dispersion direction.",
01641 "giraffe.slight",
01642 10);
01643 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-xstep");
01644 cpl_parameterlist_append(list, p);
01645
01646
01647 p = cpl_parameter_new_value("giraffe.slight.ystep",
01648 CPL_TYPE_INT,
01649 "Interspectrum region sampling step along "
01650 "the spatial direction.",
01651 "giraffe.slight",
01652 1);
01653 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-ystep");
01654 cpl_parameterlist_append(list, p);
01655
01656
01657 p = cpl_parameter_new_value("giraffe.slight.xslice",
01658 CPL_TYPE_STRING,
01659 "Interspectrum region sampling step along "
01660 "the dispersion direction for a specific "
01661 "region. This overrides 'xstep' for the "
01662 "given region.",
01663 "giraffe.slight",
01664 "none");
01665 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-xslice");
01666 cpl_parameterlist_append(list, p);
01667
01668
01669 p = cpl_parameter_new_value("giraffe.slight.ewidth",
01670 CPL_TYPE_DOUBLE,
01671 "Extra width [pixels] added to both sides "
01672 "of a spectrum trace.",
01673 "giraffe.slight",
01674 0.5);
01675 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-ewidth");
01676 cpl_parameterlist_append(list, p);
01677
01678
01679 p = cpl_parameter_new_value("giraffe.slight.iswidth",
01680 CPL_TYPE_INT,
01681 "Minimum width [pixels] required for "
01682 "interspectrum regions.",
01683 "giraffe.slight",
01684 2);
01685 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-iswidth");
01686 cpl_parameterlist_append(list, p);
01687
01688
01689 p = cpl_parameter_new_value("giraffe.slight.istrim",
01690 CPL_TYPE_BOOL,
01691 "Turn off using the first and last "
01692 "interspectrum region.",
01693 "giraffe.slight",
01694 TRUE);
01695 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-istrim");
01696 cpl_parameterlist_append(list, p);
01697
01698
01699 p = cpl_parameter_new_value("giraffe.slight.phffcorrection",
01700 CPL_TYPE_BOOL,
01701 "Use photometric flat field correction.",
01702 "giraffe.slight",
01703 FALSE);
01704 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-phff");
01705 cpl_parameterlist_append(list, p);
01706
01707
01708 p = cpl_parameter_new_value("giraffe.slight.remove",
01709 CPL_TYPE_BOOL,
01710 "Remove scattered light from the input "
01711 "frame.",
01712 "giraffe.slight",
01713 FALSE);
01714 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-remove");
01715 cpl_parameterlist_append(list, p);
01716
01717 return;
01718
01719 }