GIRAFFE Pipeline Reference Manual

gislight.c
1 /*
2  * This file is part of the GIRAFFE Pipeline
3  * Copyright (C) 2002-2019 European Southern Observatory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #ifndef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23 
24 
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <math.h>
28 
29 #include <cxmemory.h>
30 #include <cxmessages.h>
31 #include <cxstrutils.h>
32 #include <cxstring.h>
33 
34 #include <cpl_propertylist.h>
35 #include <cpl_matrix.h>
36 #include <cpl_image.h>
37 #include <cpl_msg.h>
38 
39 #include "gialias.h"
40 #include "gimacros.h"
41 #include "gimath.h"
42 #include "gichebyshev.h"
43 #include "gimatrix.h"
44 #include "gislight.h"
45 
46 
55 struct GiSLightSetup {
56  cxint xstep;
57  cxint ystep;
58  cxdouble ewidth;
59  cxint iswidth;
60  cxbool istrim;
61  cpl_matrix* slices;
62 };
63 
64 typedef struct GiSLightSetup GiSLightSetup;
65 
66 
67 inline static GiSLightSetup*
68 _giraffe_slightsetup_new(cxint nslices)
69 {
70 
71  GiSLightSetup* self = cx_calloc(1, sizeof *self);
72 
73  if (self != NULL) {
74  self->slices = cpl_matrix_new(nslices, 3);
75  }
76 
77  return self;
78 
79 }
80 
81 
82 inline static void
83 _giraffe_slightsetup_delete(GiSLightSetup* self)
84 {
85 
86  if (self != NULL) {
87 
88  if (self->slices != NULL) {
89  cpl_matrix_delete(self->slices);
90  self->slices = NULL;
91  }
92 
93  cx_free(self);
94 
95  }
96 
97  return;
98 
99 }
100 
101 
102 inline static cxint
103 _giraffe_compute_isregion(cpl_matrix* xis, cpl_matrix* yis, cpl_matrix* zis,
104  const cpl_image* image, const cpl_image* locy,
105  const cpl_image* locw, const GiSLightSetup* setup)
106 {
107 
108  cxint nx = cpl_image_get_size_y(image);
109  cxint ny = cpl_image_get_size_x(image);
110  cxint oxend = 0;
111  cxint ns = 0;
112  cxint nsmax = 0;
113  cxint iscount = 0;
114  cxint ismax = ny * nx;
115 
116 
117  cx_assert(xis != NULL);
118  cx_assert(yis != NULL);
119  cx_assert(zis != NULL);
120 
121  cx_assert(setup->slices != NULL);
122 
123 
124  if (nx != cpl_image_get_size_y(locy) ||
125  nx != cpl_image_get_size_y(locw)) {
126  return -1;
127  }
128 
129  if (setup->istrim == FALSE) {
130 
131  cxint nregions = cpl_image_get_size_x(locy) - 1;
132  cxint kmax = ny;
133  cxint xs;
134  cxint x;
135 
136  for (xs = 0; xs < cpl_matrix_get_nrow(setup->slices); xs++) {
137 
138  cxint xstart = CX_MAX(cpl_matrix_get(setup->slices, xs, 0), oxend);
139  cxint xend = CX_MIN(cpl_matrix_get(setup->slices, xs, 1), nx - 1);
140  cxint xstep = CX_MAX(cpl_matrix_get(setup->slices, xs, 2), 1);
141 
142 
143  for (x = oxend; x < xstart; x += setup->xstep) {
144 
145  cxint zx = x * ny;
146  cxint lx = x * cpl_image_get_size_x(locy);
147  cxint ylower = 0;
148  cxint yupper = 0;
149 
150  const cxdouble* _locy = cpl_image_get_data_const(locy);
151  const cxdouble* _locw = cpl_image_get_data_const(locw);
152  const cxdouble* _image = cpl_image_get_data_const(image);
153 
154 
155  if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
156  continue;
157  }
158 
159  ylower = (cxint)floor(_locy[lx] -
160  (_locw[lx] + setup->ewidth));
161  yupper = (cxint)ceil(_locy[lx + nregions] +
162  (_locw[lx + nregions] + setup->ewidth));
163 
164  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
165  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
166 
167 
168  /*
169  * First inter spectrum region
170  */
171 
172  if (ylower > setup->iswidth) {
173 
174  register cxint k;
175 
176  for (k = 0; k <= ylower; k += setup->ystep) {
177  cpl_matrix_set(xis, iscount, 0, x);
178  cpl_matrix_set(yis, iscount, 0, k);
179  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
180  ++iscount;
181  }
182 
183  }
184 
185 
186  /*
187  * Last inter spectrum region
188  */
189 
190  if (ny - yupper > setup->iswidth) {
191 
192  register cxint k;
193 
194  for (k = yupper; k < kmax; k += setup->ystep) {
195  cpl_matrix_set(xis, iscount, 0, x);
196  cpl_matrix_set(yis, iscount, 0, k);
197  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
198  ++iscount;
199  }
200 
201  }
202 
203  }
204 
205  for (x = xstart; x <= xend; x +=xstep) {
206 
207  cxint zx = x * ny;
208  cxint lx = x * cpl_image_get_size_x(locy);
209  cxint ylower = 0;
210  cxint yupper = 0;
211 
212  const cxdouble* _locy = cpl_image_get_data_const(locy);
213  const cxdouble* _locw = cpl_image_get_data_const(locw);
214  const cxdouble* _image = cpl_image_get_data_const(image);
215 
216 
217  if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
218  continue;
219  }
220 
221  ylower = (cxint)floor(_locy[lx] -
222  (_locw[lx] + setup->ewidth));
223  yupper = (cxint)ceil(_locy[lx + nregions] +
224  (_locw[lx + nregions] + setup->ewidth));
225 
226  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
227  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
228 
229 
230  /*
231  * First inter spectrum region
232  */
233 
234  if (ylower > setup->iswidth) {
235 
236  register cxint k;
237 
238  for (k = 0; k <= ylower; k += setup->ystep) {
239  cpl_matrix_set(xis, iscount, 0, x);
240  cpl_matrix_set(yis, iscount, 0, k);
241  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
242  ++iscount;
243  }
244 
245  }
246 
247 
248  /*
249  * Last inter spectrum region
250  */
251 
252  if (ny - yupper > setup->iswidth) {
253 
254  register cxint k;
255 
256  for (k = yupper; k < kmax; k += setup->ystep) {
257  cpl_matrix_set(xis, iscount, 0, x);
258  cpl_matrix_set(yis, iscount, 0, k);
259  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
260  ++iscount;
261  }
262 
263  }
264 
265  }
266 
267  oxend = xend + 1;
268 
269  }
270 
271  for (x = oxend; x < nx; x += setup->xstep) {
272 
273  cxint zx = x * ny;
274  cxint lx = x * cpl_image_get_size_x(locy);
275  cxint ylower = 0;
276  cxint yupper = 0;
277 
278  const cxdouble* _locy = cpl_image_get_data_const(locy);
279  const cxdouble* _locw = cpl_image_get_data_const(locw);
280  const cxdouble* _image = cpl_image_get_data_const(image);
281 
282 
283  if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
284  continue;
285  }
286 
287  ylower = (cxint)floor(_locy[lx] -
288  (_locw[lx] + setup->ewidth));
289  yupper = (cxint)ceil(_locy[lx + nregions] +
290  (_locw[lx + nregions] + setup->ewidth));
291 
292  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
293  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
294 
295 
296  /*
297  * First inter spectrum region
298  */
299 
300  if (ylower > setup->iswidth) {
301 
302  register cxint k;
303 
304  for (k = 0; k <= ylower; k += setup->ystep) {
305  cpl_matrix_set(xis, iscount, 0, x);
306  cpl_matrix_set(yis, iscount, 0, k);
307  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
308  ++iscount;
309  }
310 
311  }
312 
313 
314  /*
315  * Last inter spectrum region
316  */
317 
318  if (ny - yupper > setup->iswidth) {
319 
320  register cxint k;
321 
322  for (k = yupper; k < kmax; k += setup->ystep) {
323  cpl_matrix_set(xis, iscount, 0, x);
324  cpl_matrix_set(yis, iscount, 0, k);
325  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
326  ++iscount;
327  }
328 
329  }
330 
331  }
332 
333  }
334 
335  nsmax = cpl_image_get_size_x(locy) - 1;
336  for (ns = 0; ns < nsmax; ns++) {
337 
338  cxint nregions = ns + 1;
339  cxint xs = 0;
340  cxint x;
341 
342  oxend = 0;
343 
344  for (xs = 0; xs < cpl_matrix_get_nrow(setup->slices); xs++) {
345 
346  cxint xstart = CX_MAX(cpl_matrix_get(setup->slices, xs, 0), oxend);
347  cxint xend = CX_MIN(cpl_matrix_get(setup->slices, xs, 1), nx - 1);
348 
349 
350  for (x = oxend; x < xstart; x += setup->xstep) {
351 
352  cxint k;
353  cxint zx = x * ny;
354  cxint lx = x * cpl_image_get_size_x(locy);
355  cxint ylower = 0;
356  cxint yupper = 0;
357 
358  const cxdouble* _locy = cpl_image_get_data_const(locy);
359  const cxdouble* _locw = cpl_image_get_data_const(locw);
360  const cxdouble* _image = cpl_image_get_data_const(image);
361 
362 
363  if (_locw[lx + ns] <= 0.) {
364  continue;
365  }
366 
367  while (_locw[lx + nregions] <= 0. &&
368  _locy[lx + nregions] <= 0.) {
369  ++nregions;
370  }
371 
372  /* Lower border of upper spectrum */
373 
374  ylower = (cxint)floor(_locy[lx + nregions] -
375  (_locw[lx + nregions] + setup->ewidth));
376 
377  /* Upper border of lower spectrum */
378 
379  yupper = (cxint)ceil(_locy[lx + ns] +
380  (_locw[lx + ns] + setup->ewidth));
381 
382  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
383  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
384 
385  if (ylower - yupper <= setup->iswidth) {
386  continue;
387  }
388 
389  for (k = yupper; k <= ylower && iscount < ismax;
390  k += setup->ystep) {
391  cpl_matrix_set(xis, iscount, 0, x);
392  cpl_matrix_set(yis, iscount, 0, k);
393  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
394  ++iscount;
395  }
396 
397  }
398 
399  for (x = xstart; x <= xend; x += setup->xstep) {
400 
401  cxint k;
402  cxint zx = x * ny;
403  cxint lx = x * cpl_image_get_size_x(locy);
404  cxint ylower = 0;
405  cxint yupper = 0;
406 
407  const cxdouble* _locy = cpl_image_get_data_const(locy);
408  const cxdouble* _locw = cpl_image_get_data_const(locw);
409  const cxdouble* _image = cpl_image_get_data_const(image);
410 
411 
412  if (_locw[lx + ns] <= 0.) {
413  continue;
414  }
415 
416  while (_locw[lx + nregions] <= 0. &&
417  _locy[lx + nregions] <= 0.) {
418  ++nregions;
419  }
420 
421  /* Lower border of upper spectrum */
422 
423  ylower = (cxint)floor(_locy[lx + nregions] -
424  (_locw[lx + nregions] + setup->ewidth));
425 
426  /* Upper border of lower spectrum */
427 
428  yupper = (cxint)ceil(_locy[lx + ns] +
429  (_locw[lx + ns] + setup->ewidth));
430 
431  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
432  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
433 
434  if (ylower - yupper <= setup->iswidth) {
435  continue;
436  }
437 
438  for (k = yupper; k <= ylower && iscount < ismax;
439  k += setup->ystep) {
440  cpl_matrix_set(xis, iscount, 0, x);
441  cpl_matrix_set(yis, iscount, 0, k);
442  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
443  ++iscount;
444  }
445 
446  }
447 
448  oxend = xend + 1;
449 
450  }
451 
452  for (x = oxend; x < nx; x += setup->xstep) {
453 
454  cxint k;
455  cxint zx = x * ny;
456  cxint lx = x * cpl_image_get_size_x(locy);
457  cxint ylower = 0;
458  cxint yupper = 0;
459 
460  const cxdouble* _locy = cpl_image_get_data_const(locy);
461  const cxdouble* _locw = cpl_image_get_data_const(locw);
462  const cxdouble* _image = cpl_image_get_data_const(image);
463 
464 
465  if (_locw[lx + ns] <= 0.) {
466  continue;
467  }
468 
469  while (_locw[lx + nregions] <= 0. &&
470  _locy[lx + nregions] <= 0.) {
471  ++nregions;
472  }
473 
474  /* Lower border of upper spectrum */
475 
476  ylower = (cxint)floor(_locy[lx + nregions] -
477  (_locw[lx + nregions] + setup->ewidth));
478 
479  /* Upper border of lower spectrum */
480 
481  yupper = (cxint)ceil(_locy[lx + ns] +
482  (_locw[lx + ns] + setup->ewidth));
483 
484  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
485  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
486 
487  if (ylower - yupper <= setup->iswidth) {
488  continue;
489  }
490 
491  for (k = yupper; k <= ylower && iscount < ismax;
492  k += setup->ystep) {
493  cpl_matrix_set(xis, iscount, 0, x);
494  cpl_matrix_set(yis, iscount, 0, k);
495  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
496  ++iscount;
497  }
498 
499  }
500 
501  }
502 
503  return iscount;
504 
505 }
506 
507 
508 inline static cxint
509 _giraffe_compute_isregion_bpm(cpl_matrix* xis, cpl_matrix* yis,
510  cpl_matrix* zis, const cpl_image* image,
511  const cpl_image* locy, const cpl_image* locw,
512  const cpl_image* bpixel,
513  const GiSLightSetup* setup)
514 {
515 
516  cxint nx = cpl_image_get_size_y(image);
517  cxint ny = cpl_image_get_size_x(image);
518  cxint oxend = 0;
519  cxint ns = 0;
520  cxint nsmax = 0;
521  cxint iscount = 0;
522  cxint ismax = ny * nx;
523 
524 
525  cx_assert(xis != NULL);
526  cx_assert(yis != NULL);
527  cx_assert(zis != NULL);
528 
529  cx_assert(setup->slices != NULL);
530 
531 
532  if (nx != cpl_image_get_size_y(locy) ||
533  nx != cpl_image_get_size_y(locw)) {
534  return -1;
535  }
536 
537  if (nx != cpl_image_get_size_y(bpixel) ||
538  nx != cpl_image_get_size_y(bpixel)) {
539  return -2;
540  }
541 
542  if (setup->istrim == FALSE) {
543 
544  cxint nregions = cpl_image_get_size_x(locy) - 1;
545  cxint kmax = ny;
546  cxint xs;
547  cxint x;
548 
549 
550  for (xs = 0; xs < cpl_matrix_get_nrow(setup->slices); xs++) {
551 
552  cxint xstart = CX_MAX(cpl_matrix_get(setup->slices, xs, 0), oxend);
553  cxint xend = CX_MIN(cpl_matrix_get(setup->slices, xs, 1), nx - 1);
554  cxint xstep = CX_MAX(cpl_matrix_get(setup->slices, xs, 2), 1);
555 
556 
557  for (x = oxend; x < xstart; x += setup->xstep) {
558 
559  cxint zx = x * ny;
560  cxint lx = x * cpl_image_get_size_x(locy);
561  cxint ylower = 0;
562  cxint yupper = 0;
563 
564  const cxdouble* _locy = cpl_image_get_data_const(locy);
565  const cxdouble* _locw = cpl_image_get_data_const(locw);
566  const cxdouble* _image = cpl_image_get_data_const(image);
567 
568 
569  if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
570  continue;
571  }
572 
573  ylower = (cxint)floor(_locy[lx] -
574  (_locw[lx] + setup->ewidth));
575  yupper = (cxint)ceil(_locy[lx + nregions] +
576  (_locw[lx + nregions] + setup->ewidth));
577 
578  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
579  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
580 
581 
582  /*
583  * First inter spectrum region
584  */
585 
586  if (ylower > setup->iswidth) {
587 
588  register cxint k;
589 
590  const cxint* _bpixel = cpl_image_get_data_const(bpixel);
591 
592 
593  for (k = 0; k <= ylower; k += setup->ystep) {
594 
595  if (_bpixel[zx + k] & GIR_M_PIX_SET) {
596  continue;
597  }
598 
599  cpl_matrix_set(xis, iscount, 0, x);
600  cpl_matrix_set(yis, iscount, 0, k);
601  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
602  ++iscount;
603  }
604 
605  }
606 
607 
608  /*
609  * Last inter spectrum region
610  */
611 
612  if (ny - yupper > setup->iswidth) {
613 
614  register cxint k;
615 
616  const cxint* _bpixel = cpl_image_get_data_const(bpixel);
617 
618 
619  for (k = yupper; k < kmax; k += setup->ystep) {
620 
621  if (_bpixel[zx + k] & GIR_M_PIX_SET) {
622  continue;
623  }
624 
625  cpl_matrix_set(xis, iscount, 0, x);
626  cpl_matrix_set(yis, iscount, 0, k);
627  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
628  ++iscount;
629  }
630 
631  }
632 
633  }
634 
635  for (x = xstart; x <= xend; x +=xstep) {
636 
637  cxint zx = x * ny;
638  cxint lx = x * cpl_image_get_size_x(locy);
639  cxint ylower = 0;
640  cxint yupper = 0;
641 
642  const cxdouble* _locy = cpl_image_get_data_const(locy);
643  const cxdouble* _locw = cpl_image_get_data_const(locw);
644  const cxdouble* _image = cpl_image_get_data_const(image);
645 
646 
647  if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
648  continue;
649  }
650 
651  ylower = (cxint)floor(_locy[lx] -
652  (_locw[lx] + setup->ewidth));
653  yupper = (cxint)ceil(_locy[lx + nregions] +
654  (_locw[lx + nregions] + setup->ewidth));
655 
656  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
657  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
658 
659 
660  /*
661  * First inter spectrum region
662  */
663 
664  if (ylower > setup->iswidth) {
665 
666  register cxint k;
667 
668  const cxint* _bpixel = cpl_image_get_data_const(bpixel);
669 
670 
671  for (k = 0; k <= ylower; k += setup->ystep) {
672 
673  if (_bpixel[zx + k] & GIR_M_PIX_SET) {
674  continue;
675  }
676 
677  cpl_matrix_set(xis, iscount, 0, x);
678  cpl_matrix_set(yis, iscount, 0, k);
679  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
680  ++iscount;
681  }
682 
683  }
684 
685 
686  /*
687  * Last inter spectrum region
688  */
689 
690  if (ny - yupper > setup->iswidth) {
691 
692  register cxint k;
693 
694  const cxint* _bpixel = cpl_image_get_data_const(bpixel);
695 
696 
697  for (k = yupper; k < kmax; k += setup->ystep) {
698 
699  if (_bpixel[zx + k] & GIR_M_PIX_SET) {
700  continue;
701  }
702 
703  cpl_matrix_set(xis, iscount, 0, x);
704  cpl_matrix_set(yis, iscount, 0, k);
705  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
706  ++iscount;
707  }
708 
709  }
710 
711  }
712 
713  oxend = xend + 1;
714 
715  }
716 
717  for (x = oxend; x < nx; x += setup->xstep) {
718 
719  cxint zx = x * ny;
720  cxint lx = x * cpl_image_get_size_x(locy);
721  cxint ylower = 0;
722  cxint yupper = 0;
723 
724  const cxdouble* _locy = cpl_image_get_data_const(locy);
725  const cxdouble* _locw = cpl_image_get_data_const(locw);
726  const cxdouble* _image = cpl_image_get_data_const(image);
727 
728 
729  if (_locw[lx] <= 0. || _locw[lx + nregions] <= 0.) {
730  continue;
731  }
732 
733  ylower = (cxint)floor(_locy[lx] -
734  (_locw[lx] + setup->ewidth));
735  yupper = (cxint)ceil(_locy[lx + nregions] +
736  (_locw[lx + nregions] + setup->ewidth));
737 
738  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
739  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
740 
741 
742  /*
743  * First inter spectrum region
744  */
745 
746  if (ylower > setup->iswidth) {
747 
748  register cxint k;
749 
750  const cxint* _bpixel = cpl_image_get_data_const(bpixel);
751 
752 
753  for (k = 0; k <= ylower; k += setup->ystep) {
754 
755  if (_bpixel[zx + k] & GIR_M_PIX_SET) {
756  continue;
757  }
758 
759  cpl_matrix_set(xis, iscount, 0, x);
760  cpl_matrix_set(yis, iscount, 0, k);
761  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
762  ++iscount;
763  }
764 
765  }
766 
767 
768  /*
769  * Last inter spectrum region
770  */
771 
772  if (ny - yupper > setup->iswidth) {
773 
774  register cxint k;
775 
776  const cxint* _bpixel = cpl_image_get_data_const(bpixel);
777 
778 
779  for (k = yupper; k < kmax; k += setup->ystep) {
780 
781  if (_bpixel[zx + k] & GIR_M_PIX_SET) {
782  continue;
783  }
784 
785  cpl_matrix_set(xis, iscount, 0, x);
786  cpl_matrix_set(yis, iscount, 0, k);
787  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
788  ++iscount;
789  }
790 
791  }
792 
793  }
794 
795  }
796 
797  nsmax = cpl_image_get_size_x(locy) - 1;
798  for (ns = 0; ns < nsmax; ns++) {
799 
800  cxint nregions = ns + 1;
801  cxint xs = 0;
802  cxint x;
803 
804  oxend = 0;
805 
806  for (xs = 0; xs < cpl_matrix_get_nrow(setup->slices); xs++) {
807 
808  cxint xstart = CX_MAX(cpl_matrix_get(setup->slices, xs, 0), oxend);
809  cxint xend = CX_MIN(cpl_matrix_get(setup->slices, xs, 1), nx - 1);
810 
811 
812  for (x = oxend; x < xstart; x += setup->xstep) {
813 
814  cxint zx = x * ny;
815  cxint lx = x * cpl_image_get_size_x(locy);
816  cxint ylower = 0;
817  cxint yupper = 0;
818 
819  const cxdouble* _locy = cpl_image_get_data_const(locy);
820  const cxdouble* _locw = cpl_image_get_data_const(locw);
821  const cxdouble* _image = cpl_image_get_data_const(image);
822 
823 
824  if (_locw[lx + ns] <= 0.) {
825  continue;
826  }
827 
828  while (_locw[lx + nregions] <= 0. &&
829  _locy[lx + nregions] <= 0.) {
830  ++nregions;
831  }
832 
833  /* Lower border of upper spectrum */
834 
835  ylower = (cxint)floor(_locy[lx + nregions] -
836  (_locw[lx + nregions] + setup->ewidth));
837 
838  /* Upper border of lower spectrum */
839 
840  yupper = (cxint)ceil(_locy[lx + ns] +
841  (_locw[lx + ns] + setup->ewidth));
842 
843  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
844  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
845 
846  if (ylower - yupper > setup->iswidth) {
847 
848  register cxint k;
849 
850  const cxint* _bpixel = cpl_image_get_data_const(bpixel);
851 
852 
853  for (k = yupper; k <= ylower && iscount < ismax;
854  k += setup->ystep) {
855 
856  if (_bpixel[zx + k] & GIR_M_PIX_SET) {
857  continue;
858  }
859 
860  cpl_matrix_set(xis, iscount, 0, x);
861  cpl_matrix_set(yis, iscount, 0, k);
862  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
863  ++iscount;
864  }
865 
866  }
867 
868  }
869 
870  for (x = xstart; x <= xend; x += setup->xstep) {
871 
872  cxint zx = x * ny;
873  cxint lx = x * cpl_image_get_size_x(locy);
874  cxint ylower = 0;
875  cxint yupper = 0;
876 
877  const cxdouble* _locy = cpl_image_get_data_const(locy);
878  const cxdouble* _locw = cpl_image_get_data_const(locw);
879  const cxdouble* _image = cpl_image_get_data_const(image);
880 
881 
882  if (_locw[lx + ns] <= 0.) {
883  continue;
884  }
885 
886  while (_locw[lx + nregions] <= 0. &&
887  _locy[lx + nregions] <= 0.) {
888  ++nregions;
889  }
890 
891  /* Lower border of upper spectrum */
892 
893  ylower = (cxint)floor(_locy[lx + nregions] -
894  (_locw[lx + nregions] + setup->ewidth));
895 
896  /* Upper border of lower spectrum */
897 
898  yupper = (cxint)ceil(_locy[lx + ns] +
899  (_locw[lx + ns] + setup->ewidth));
900 
901  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
902  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
903 
904  if (ylower - yupper > setup->iswidth) {
905 
906  register cxint k;
907 
908  const cxint* _bpixel = cpl_image_get_data_const(bpixel);
909 
910  for (k = yupper; k <= ylower && iscount < ismax;
911  k += setup->ystep) {
912 
913  if (_bpixel[zx + k] & GIR_M_PIX_SET) {
914  continue;
915  }
916 
917  cpl_matrix_set(xis, iscount, 0, x);
918  cpl_matrix_set(yis, iscount, 0, k);
919  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
920  ++iscount;
921 
922  }
923 
924  }
925 
926  }
927 
928  oxend = xend + 1;
929 
930  }
931 
932  for (x = oxend; x < nx; x += setup->xstep) {
933 
934  cxint zx = x * ny;
935  cxint lx = x * cpl_image_get_size_x(locy);
936  cxint ylower = 0;
937  cxint yupper = 0;
938 
939  const cxdouble* _locy = cpl_image_get_data_const(locy);
940  const cxdouble* _locw = cpl_image_get_data_const(locw);
941  const cxdouble* _image = cpl_image_get_data_const(image);
942 
943 
944  if (_locw[lx + ns] <= 0.) {
945  continue;
946  }
947 
948  while (_locw[lx + nregions] <= 0. &&
949  _locy[lx + nregions] <= 0.) {
950  ++nregions;
951  }
952 
953  /* Lower border of upper spectrum */
954 
955  ylower = (cxint)floor(_locy[lx + nregions] -
956  (_locw[lx + nregions] + setup->ewidth));
957 
958  /* Upper border of lower spectrum */
959 
960  yupper = (cxint)ceil(_locy[lx + ns] +
961  (_locw[lx + ns] + setup->ewidth));
962 
963  ylower = CX_MAX(CX_MIN(ny, ylower), 0);
964  yupper = CX_MAX(CX_MIN(ny, yupper), 0);
965 
966  if (ylower - yupper > setup->iswidth) {
967 
968  register cxint k;
969 
970  const cxint* _bpixel = cpl_image_get_data_const(bpixel);
971 
972 
973  for (k = yupper; k <= ylower && iscount < ismax;
974  k += setup->ystep) {
975 
976  if (_bpixel[zx + k] & GIR_M_PIX_SET) {
977  continue;
978  }
979 
980  cpl_matrix_set(xis, iscount, 0, x);
981  cpl_matrix_set(yis, iscount, 0, k);
982  cpl_matrix_set(zis, 0, iscount, _image[zx + k]);
983  ++iscount;
984  }
985 
986  }
987 
988  }
989 
990  }
991 
992  return iscount;
993 
994 }
995 
996 static cpl_image*
997 _giraffe_slight_fit_polynom(const cpl_image* image, const cpl_image* locy,
998  const cpl_image* locw, const cpl_image* bpixel,
999  cxint xorder, cxint yorder, cxint *iscount,
1000  const GiSLightSetup* setup)
1001 {
1002 
1003  cxint i;
1004  cxint j;
1005  cxint nx = cpl_image_get_size_y(image);
1006  cxint ny = cpl_image_get_size_x(image);
1007 
1008  cpl_image* slfit = NULL;
1009 
1010  cpl_matrix* xis = cpl_matrix_new(nx * ny, 1);
1011  cpl_matrix* yis = cpl_matrix_new(nx * ny, 1);
1012  cpl_matrix* zis = cpl_matrix_new(1, nx * ny);
1013 
1014 
1015  *iscount = 0;
1016 
1017  if (bpixel != NULL) {
1018  *iscount = _giraffe_compute_isregion_bpm(xis, yis, zis, image, locy,
1019  locw, bpixel, setup);
1020  }
1021  else {
1022  *iscount = _giraffe_compute_isregion(xis, yis, zis, image, locy,
1023  locw, setup);
1024  }
1025 
1026  if (*iscount <= 0 || *iscount >= nx * ny) {
1027 
1028  cpl_matrix_delete(xis);
1029  xis = NULL;
1030 
1031  cpl_matrix_delete(yis);
1032  yis = NULL;
1033 
1034  cpl_matrix_delete(zis);
1035  zis = NULL;
1036 
1037  return NULL;
1038 
1039  }
1040  else {
1041 
1042  cxint status = 0;
1043 
1044  cpl_matrix* base = NULL;
1045  cpl_matrix* coeff = NULL;
1046  cpl_matrix* chebyshev = NULL;
1047 
1048  GiChebyshev2D* fit = NULL;
1049 
1050  cpl_matrix_set_size(xis, *iscount, 1);
1051  cpl_matrix_set_size(yis, *iscount, 1);
1052  cpl_matrix_set_size(zis, 1, *iscount);
1053 
1054 #if 0
1055 
1056  // FIXME: For tests only!
1057 
1058  cpl_image* tmp = cpl_image_new(ny, nx, CPL_TYPE_DOUBLE);
1059  cxdouble* _tmp = cpl_image_get_data(tmp);
1060 
1061  for (i = 0; i < *iscount; i++) {
1062  cxint k = cpl_matrix_get(xis, i, 0) * cpl_image_get_size_x(tmp) +
1063  cpl_matrix_get(yis, i, 0);
1064  _tmp[k] = cpl_matrix_get(zis, 0, i);
1065  }
1066 
1067  cpl_image_save(tmp, "idiot.fits", CPL_BPP_IEEE_FLOAT, NULL,
1068  CPL_IO_DEFAULT);
1069  cpl_image_delete(tmp);
1070  tmp = NULL;
1071 
1072 #endif
1073 
1074  base = giraffe_chebyshev_base2d(0., 0., nx, ny, xorder + 1,
1075  yorder + 1, xis, yis);
1076 
1077  coeff = giraffe_matrix_leastsq(base, zis);
1078 
1079  if (coeff == NULL) {
1080  cpl_matrix_delete(base);
1081  base = NULL;
1082 
1083  cpl_matrix_delete(xis);
1084  xis = NULL;
1085 
1086  cpl_matrix_delete(yis);
1087  yis = NULL;
1088 
1089  cpl_matrix_delete(zis);
1090  zis = NULL;
1091 
1092  return NULL;
1093  }
1094 
1095  cpl_matrix_delete(base);
1096  base = NULL;
1097 
1098  cpl_matrix_delete(xis);
1099  xis = NULL;
1100 
1101  cpl_matrix_delete(yis);
1102  yis = NULL;
1103 
1104  cpl_matrix_delete(zis);
1105  zis = NULL;
1106 
1107 
1108  /*
1109  * Compute scattered light model
1110  */
1111 
1112  chebyshev = cpl_matrix_wrap(xorder + 1, yorder + 1,
1113  cpl_matrix_get_data(coeff));
1114 
1115  fit = giraffe_chebyshev2d_new(xorder, yorder);
1116  status = giraffe_chebyshev2d_set(fit, 0., nx, 0., ny, chebyshev);
1117 
1118  if (status != 0) {
1119 
1120  giraffe_chebyshev2d_delete(fit);
1121  fit = NULL;
1122 
1123  cpl_matrix_unwrap(chebyshev);
1124  chebyshev = NULL;
1125 
1126  cpl_matrix_delete(coeff);
1127  coeff = NULL;
1128 
1129  return NULL;
1130 
1131  }
1132 
1133  cpl_matrix_unwrap(chebyshev);
1134  chebyshev = NULL;
1135 
1136  cpl_matrix_delete(coeff);
1137  coeff = NULL;
1138 
1139  slfit = cpl_image_new(ny, nx, CPL_TYPE_DOUBLE);
1140 
1141  if (slfit == NULL) {
1142  giraffe_chebyshev2d_delete(fit);
1143  fit = NULL;
1144 
1145  return NULL;
1146  }
1147 
1148 
1149  for (i = 0; i < nx; i++) {
1150 
1151  cxdouble* _slfit = cpl_image_get_data(slfit);
1152 
1153  for (j = 0; j < ny; j++) {
1154  cxint k = i * ny + j;
1155  cxdouble value = giraffe_chebyshev2d_eval(fit, i, j);
1156 
1157  _slfit[k] = value > 0. ? value : 0.;
1158  }
1159 
1160  }
1161 
1162  giraffe_chebyshev2d_delete(fit);
1163  fit = NULL;
1164 
1165  }
1166 
1167  return slfit;
1168 }
1169 
1170 
1196 cxint
1197 giraffe_adjust_scattered_light(GiImage* result, const GiImage* image,
1198  const GiLocalization* localization,
1199  const GiImage* bpixel, GiImage* phff,
1200  const GiSLightConfig* config)
1201 {
1202 
1203  const cxchar *const fctid = "giraffe_adjust_scattered_light";
1204 
1205 
1206  if (image == NULL) {
1207  return -1;
1208  }
1209 
1210  if (localization == NULL) {
1211  return -1;
1212  }
1213 
1214  if (localization->locy == NULL || localization->locw == NULL) {
1215  return -1;
1216  }
1217 
1218  if (config == NULL) {
1219  return -2;
1220  }
1221 
1222 
1223  /* FIXME: Remove support for unused code path, namely support for models
1224  * other than 'polynom' and photometric flat fields. This was
1225  * foreseen in the original code, but never implemented.
1226  */
1227 
1228  if (phff != NULL) {
1229  cpl_msg_warning(fctid, "Photometric flat field correction is not "
1230  "implemented! Ignoring photometric flat field.");
1231  }
1232 
1233 
1234  if (strncmp(config->model, "polynom", 7) != 0) {
1235  cpl_msg_error(fctid, "Scattered light model `%s' is not supported!",
1236  config->model);
1237  return -3;
1238  }
1239  else {
1240 
1241  cxint iscount = 0;
1242 
1243  cx_string* s = NULL;
1244 
1245  const cpl_image* _image = giraffe_image_get(image);
1246  const cpl_image* _locy = giraffe_image_get(localization->locy);
1247  const cpl_image* _locw = giraffe_image_get(localization->locw);
1248  const cpl_image* _bpixel = NULL;
1249 
1250  cpl_propertylist* properties = NULL;
1251 
1252  cpl_image* slfit = NULL;
1253 
1254  GiSLightSetup* setup = _giraffe_slightsetup_new(1);
1255 
1256 
1257  setup->xstep = config->xstep;
1258  setup->ystep = config->ystep;
1259  setup->ewidth = config->ewidth;
1260  setup->iswidth = config->iswidth;
1261  setup->istrim = config->istrim;
1262 
1263  cpl_matrix_set(setup->slices, 0, 0, 0);
1264  cpl_matrix_set(setup->slices, 0, 1, cpl_image_get_size_y(_image));
1265  cpl_matrix_set(setup->slices, 0, 2, config->xstep);
1266 
1267 
1268  if (bpixel != NULL) {
1269  _bpixel = giraffe_image_get(bpixel);
1270  }
1271 
1272  slfit = _giraffe_slight_fit_polynom(_image, _locy, _locw, _bpixel,
1273  config->xorder[0],
1274  config->yorder[0],
1275  &iscount, setup);
1276  if (slfit == NULL) {
1277  cpl_msg_error(fctid, "Fitting scattered light model failed!");
1278 
1279  _giraffe_slightsetup_delete(setup);
1280  setup = NULL;
1281 
1282  return 1;
1283  }
1284 
1285  _giraffe_slightsetup_delete(setup);
1286  setup = NULL;
1287 
1288  giraffe_image_set(result, slfit);
1289 
1290  cpl_image_delete(slfit);
1291  slfit = NULL;
1292 
1295  properties = giraffe_image_get_properties(result);
1296 
1297  cpl_propertylist_update_string(properties, GIALIAS_SLMNAME,
1298  config->model);
1299  cpl_propertylist_set_comment(properties, GIALIAS_SLMNAME,
1300  "Scattered light model type.");
1301 
1302 
1303  s = cx_string_new();
1304 
1305  if (strncmp(config->model, "polynom", 7) == 0) {
1306 
1307  cx_string_sprintf(s, "%d:%d", config->xorder[0],
1308  config->yorder[0]);
1309 
1310  cpl_propertylist_update_string(properties, GIALIAS_SLMORDER,
1311  cx_string_get(s));
1312  cpl_propertylist_set_comment(properties, GIALIAS_SLMORDER,
1313  "Scattered light polynom order "
1314  "X:Y.");
1315 
1316  }
1317  else if (strncmp(config->model, "polyfrac", 8) == 0) {
1318 
1319  cx_string_sprintf(s, "%d:%d/%d:%d", config->xorder[0],
1320  config->yorder[0], config->xorder[1],
1321  config->yorder[1]);
1322 
1323  cpl_propertylist_update_string(properties, GIALIAS_SLMORDER,
1324  cx_string_get(s));
1325  cpl_propertylist_set_comment(properties, GIALIAS_SLMORDER,
1326  "Scattered light polynom fraction "
1327  "order Xn:Yn/Xd:Xd.");
1328 
1329  }
1330 
1331 
1332  cx_string_sprintf(s, "%d:%d", config->xstep, config->ystep);
1333 
1334  cpl_propertylist_update_string(properties, GIALIAS_SLMSTEPS,
1335  cx_string_get(s));
1336  cpl_propertylist_set_comment(properties, GIALIAS_SLMSTEPS,
1337  "Scattered light X, Y sampling step.");
1338 
1339  cx_string_delete(s);
1340  s = NULL;
1341 
1342 
1343  cpl_propertylist_update_double(properties, GIALIAS_SLMEWIDTH,
1344  config->ewidth);
1345  cpl_propertylist_set_comment(properties, GIALIAS_SLMEWIDTH,
1346  "Extra pixels added to spectrum "
1347  "width.");
1348 
1349  cpl_propertylist_update_int(properties, GIALIAS_SLMIWIDTH,
1350  config->iswidth);
1351  cpl_propertylist_set_comment(properties, GIALIAS_SLMIWIDTH,
1352  "Minimum required inter-spectrum "
1353  "region width.");
1354 
1355  cpl_propertylist_update_bool(properties, GIALIAS_SLMTRIM,
1356  config->istrim);
1357  cpl_propertylist_set_comment(properties, GIALIAS_SLMTRIM,
1358  "Removal of first and last "
1359  "inter-spectrum region.");
1360 
1361  }
1362 
1363  return 0;
1364 }
1365 
1366 
1378 GiSLightConfig*
1379 giraffe_slight_config_create(cpl_parameterlist* list)
1380 {
1381 
1382  const cxchar* s;
1383 
1384  cpl_parameter* p = NULL;
1385 
1386  GiSLightConfig* config = NULL;
1387 
1388 
1389  if (list == NULL) {
1390  return NULL;
1391  }
1392 
1393  config = cx_calloc(1, sizeof *config);
1394 
1395  p = cpl_parameterlist_find(list, "giraffe.slight.model.name");
1396  config->model = cx_strdup(cpl_parameter_get_string(p));
1397 
1398  if (strncmp(config->model, "polynom", 7) != 0 &&
1399  strncmp(config->model, "polyfrac", 8) != 0) {
1401  return NULL;
1402  }
1403 
1404  p = cpl_parameterlist_find(list, "giraffe.slight.model.order");
1405  s = cpl_parameter_get_default_string(p);
1406 
1407  if (sscanf(s, "%d,%d", &config->xorder[0], &config->yorder[0]) != 2) {
1409  return NULL;
1410  }
1411 
1412  config->xorder[1] = 0;
1413  config->yorder[1] = 0;
1414 
1415  s = cpl_parameter_get_string(p);
1416 
1417  if (s == NULL) {
1419  return NULL;
1420  }
1421  else {
1422 
1423  cxchar** values = cx_strsplit(s, ",", 5);
1424 
1425  if (values == NULL) {
1427  return NULL;
1428  }
1429  else {
1430 
1431  cxchar* last;
1432 
1433  config->xorder[0] = strtol(values[0], &last, 10);
1434 
1435  if (*last != '\0') {
1436  cx_strfreev(values);
1438 
1439  return NULL;
1440  }
1441 
1442  if (values[1] != NULL) {
1443 
1444  config->yorder[0] = strtol(values[1], &last, 10);
1445 
1446  if (*last != '\0') {
1447  cx_strfreev(values);
1449 
1450  return NULL;
1451  }
1452 
1453  }
1454 
1455  if (strncmp(config->model, "polyfrac", 8) == 0) {
1456 
1457  if (values[2] != NULL) {
1458 
1459  config->xorder[1] = strtol(values[2], &last, 10);
1460 
1461  if (*last != '\0') {
1462  cx_strfreev(values);
1464 
1465  return NULL;
1466  }
1467 
1468  }
1469 
1470  if (values[3] != NULL) {
1471 
1472  config->yorder[1] = strtol(values[3], &last, 10);
1473 
1474  if (*last != '\0') {
1475  cx_strfreev(values);
1477 
1478  return NULL;
1479  }
1480 
1481  }
1482 
1483  }
1484 
1485  cx_strfreev(values);
1486  values = NULL;
1487 
1488  }
1489 
1490  }
1491 
1492 
1493  p = cpl_parameterlist_find(list, "giraffe.slight.xstep");
1494  config->xstep = cpl_parameter_get_int(p);
1495 
1496  p = cpl_parameterlist_find(list, "giraffe.slight.ystep");
1497  config->ystep = cpl_parameter_get_int(p);
1498 
1499  p = cpl_parameterlist_find(list, "giraffe.slight.xslice");
1500  s = cpl_parameter_get_default_string(p);
1501 
1502 
1503  /* FIXME: Whether slices should be supported is still TBD. Currently
1504  * there the parameter is accepted, but its support is not
1505  * implemented!
1506  */
1507 
1508  if (strncmp(s, "none", 4) != 0) {
1510  return NULL;
1511  }
1512 
1513  s = cpl_parameter_get_string(p);
1514 
1515  if (s == NULL) {
1517  return NULL;
1518  }
1519  else {
1520 
1521  cxchar** slices = cx_strsplit(s, ",", -1);
1522 
1523  if (slices == NULL) {
1525  return NULL;
1526  }
1527  else {
1528  cx_strfreev(slices);
1529  slices = NULL;
1530  }
1531 
1532  }
1533 
1534 
1535  p = cpl_parameterlist_find(list, "giraffe.slight.ewidth");
1536  config->ewidth = cpl_parameter_get_double(p);
1537 
1538  p = cpl_parameterlist_find(list, "giraffe.slight.iswidth");
1539  config->iswidth = cpl_parameter_get_int(p);
1540 
1541  p = cpl_parameterlist_find(list, "giraffe.slight.istrim");
1542  config->istrim = cpl_parameter_get_bool(p);
1543 
1544  p = cpl_parameterlist_find(list, "giraffe.slight.phffcorrection");
1545  config->phffcor = cpl_parameter_get_bool(p);
1546 
1547  p = cpl_parameterlist_find(list, "giraffe.slight.remove");
1548  config->remove = cpl_parameter_get_bool(p);
1549 
1550  return config;
1551 
1552 }
1553 
1554 
1568 void
1569 giraffe_slight_config_destroy(GiSLightConfig *config)
1570 {
1571 
1572  if (config != NULL) {
1573 
1574  if (config->model != NULL) {
1575  cx_free((cxchar*)config->model);
1576  config->model = NULL;
1577  }
1578 
1579  cx_free(config);
1580 
1581  }
1582 
1583  return;
1584 
1585 }
1586 
1587 
1600 void
1601 giraffe_slight_config_add(cpl_parameterlist* list)
1602 {
1603 
1604  cpl_parameter* p;
1605 
1606 
1607  if (list == NULL) {
1608  return;
1609  }
1610 
1611  p = cpl_parameter_new_enum("giraffe.slight.model.name",
1612  CPL_TYPE_STRING,
1613  "Name of the scattered light model to use.",
1614  "giraffe.slight",
1615  "polynom", 2, "polynom", "polyfrac");
1616  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-model");
1617  cpl_parameterlist_append(list, p);
1618 
1619 
1620  p = cpl_parameter_new_value("giraffe.slight.model.order",
1621  CPL_TYPE_STRING,
1622  "Scattered light model fit X and Y order.",
1623  "giraffe.slight",
1624  "4,2");
1625  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-order");
1626  cpl_parameterlist_append(list, p);
1627 
1628 
1629  p = cpl_parameter_new_value("giraffe.slight.xstep",
1630  CPL_TYPE_INT,
1631  "Interspectrum region sampling step along "
1632  "the dispersion direction.",
1633  "giraffe.slight",
1634  10);
1635  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-xstep");
1636  cpl_parameterlist_append(list, p);
1637 
1638 
1639  p = cpl_parameter_new_value("giraffe.slight.ystep",
1640  CPL_TYPE_INT,
1641  "Interspectrum region sampling step along "
1642  "the spatial direction.",
1643  "giraffe.slight",
1644  1);
1645  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-ystep");
1646  cpl_parameterlist_append(list, p);
1647 
1648 
1649  p = cpl_parameter_new_value("giraffe.slight.xslice",
1650  CPL_TYPE_STRING,
1651  "Interspectrum region sampling step along "
1652  "the dispersion direction for a specific "
1653  "region. This overrides 'xstep' for the "
1654  "given region.",
1655  "giraffe.slight",
1656  "none");
1657  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-xslice");
1658  cpl_parameterlist_append(list, p);
1659 
1660 
1661  p = cpl_parameter_new_value("giraffe.slight.ewidth",
1662  CPL_TYPE_DOUBLE,
1663  "Extra width [pixels] added to both sides "
1664  "of a spectrum trace.",
1665  "giraffe.slight",
1666  0.5);
1667  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-ewidth");
1668  cpl_parameterlist_append(list, p);
1669 
1670 
1671  p = cpl_parameter_new_value("giraffe.slight.iswidth",
1672  CPL_TYPE_INT,
1673  "Minimum width [pixels] required for "
1674  "interspectrum regions.",
1675  "giraffe.slight",
1676  2);
1677  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-iswidth");
1678  cpl_parameterlist_append(list, p);
1679 
1680 
1681  p = cpl_parameter_new_value("giraffe.slight.istrim",
1682  CPL_TYPE_BOOL,
1683  "Turn off using the first and last "
1684  "interspectrum region.",
1685  "giraffe.slight",
1686  TRUE);
1687  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-istrim");
1688  cpl_parameterlist_append(list, p);
1689 
1690 
1691  p = cpl_parameter_new_value("giraffe.slight.phffcorrection",
1692  CPL_TYPE_BOOL,
1693  "Use photometric flat field correction.",
1694  "giraffe.slight",
1695  FALSE);
1696  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-phff");
1697  cpl_parameterlist_append(list, p);
1698 
1699 
1700  p = cpl_parameter_new_value("giraffe.slight.remove",
1701  CPL_TYPE_BOOL,
1702  "Remove scattered light from the input "
1703  "frame.",
1704  "giraffe.slight",
1705  FALSE);
1706  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight-remove");
1707  cpl_parameterlist_append(list, p);
1708 
1709  return;
1710 
1711 }
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
Definition: giimage.c:282
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
Definition: giimage.c:218
cxint giraffe_image_set(GiImage *self, cpl_image *image)
Sets the image data.
Definition: giimage.c:244
cxint giraffe_image_set_properties(GiImage *self, cpl_propertylist *properties)
Attaches a property list to an image.
Definition: giimage.c:312
cpl_matrix * giraffe_matrix_leastsq(const cpl_matrix *mA, const cpl_matrix *mB)
Computes the solution of an equation using a pseudo-inverse.
Definition: gimatrix.c:503
void giraffe_slight_config_add(cpl_parameterlist *list)
Adds parameters for the scattered light computation.
Definition: gislight.c:1601
GiSLightConfig * giraffe_slight_config_create(cpl_parameterlist *list)
Creates a setup structure for the scattered light computation.
Definition: gislight.c:1379
cxint giraffe_adjust_scattered_light(GiImage *result, const GiImage *image, const GiLocalization *localization, const GiImage *bpixel, GiImage *phff, const GiSLightConfig *config)
Compute a scattered light model for a given image.
Definition: gislight.c:1197
void giraffe_slight_config_destroy(GiSLightConfig *config)
Destroys a scattered light setup structure.
Definition: gislight.c:1569

This file is part of the GIRAFFE Pipeline Reference Manual 2.16.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Dec 15 2022 21:18:51 by doxygen 1.9.1 written by Dimitri van Heesch, © 1997-2004