ERIS Pipeline Reference Manual 1.8.10
eris_ifu_functions.c
1/* $Id: eris_ifu_utils.c,v 1.12 2013-03-25 11:46:49 cgarcia Exp $
2 *
3 * This file is part of the ERIS Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/*
22 * $Author: cgarcia $
23 * $Date: 2013-03-25 11:46:49 $
24 * $Revision: 1.12 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35
36#include <string.h>
37#include <gsl/gsl_interp.h>
38#include "eris_ifu_dfs.h"
39#include "eris_ifu_debug.h"
40#include "eris_ifu_utils.h"
41#include "eris_ifu_functions.h"
42#include "eris_ifu_distortion_static.h"
43#include "eris_ifu_flat_static.h"
44#include "eris_ifu_error.h"
45#include "eris_utils.h"
46/*----------------------------------------------------------------------------*/
51/*----------------------------------------------------------------------------*/
57/*----------------------------------------------------------------------------*/
58ifsInstrument eris_ifu_get_instrument_frame(cpl_frame *frame)
59{
60 ifsInstrument instrument = UNSET_INSTRUMENT;
61 const char *filename = NULL;
62 cpl_propertylist *header = NULL;
63
64 TRY
65 {
66 if (frame == NULL) {
67 BRK_WITH_ERROR(CPL_ERROR_NULL_INPUT);
68 }
69
70 filename = cpl_frame_get_filename(frame);
71 header = cpl_propertylist_load(filename, 0);
72 instrument = eris_ifu_get_instrument(header);
74 }
75 CATCH
76 {
77 instrument = UNSET_INSTRUMENT;
78 }
79
81 eris_check_error_code("eris_ifu_get_instrument_frame");
82 return instrument;
83}
84
85/*----------------------------------------------------------------------------*/
95/*----------------------------------------------------------------------------*/
96hdrl_image * eris_ifu_raw_hdrl_image(const cpl_image *cplImage)
97{
98 hdrl_image *image = NULL;
99 cpl_image *noiseImage = NULL;
100
101 cpl_ensure(cplImage, CPL_ERROR_NULL_INPUT, NULL);
102
103 TRY
104 {
105 noiseImage = eris_ifu_calc_noise_map(cplImage, 2.10, 0.);
106 image = hdrl_image_create (cplImage, noiseImage);
107 }
108 CATCH
109 {
110 }
111
112 cpl_image_delete(noiseImage);
113 eris_check_error_code("eris_ifu_raw_hdrl_image");
114 return image;
115}
116
117/*----------------------------------------------------------------------------*/
129/*----------------------------------------------------------------------------*/
130cpl_image* eris_ifu_calc_noise_map(const cpl_image *data,
131 double gain,
132 double readnoise)
133{
134 cpl_image *noiseImg = NULL;
135
136 cpl_ensure(data, CPL_ERROR_NULL_INPUT, NULL);
137 cpl_ensure(gain > 0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
138 cpl_ensure(readnoise >= 0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
139
140 TRY
141 {
143 noiseImg = cpl_image_duplicate(data));
144
145 /* calculate initial noise estimate
146 sigma = sqrt(counts * gain + readnoise^2) / gain */
147 cpl_image_abs(noiseImg);
148 cpl_image_multiply_scalar(noiseImg, gain);
149 cpl_image_add_scalar(noiseImg, readnoise * readnoise);
150 cpl_image_power(noiseImg, 0.5);
151 cpl_image_divide_scalar(noiseImg, gain);
152 }
153 CATCH
154 {
155 CATCH_MSG();
156 eris_ifu_free_image(&noiseImg);
157 }
158 eris_check_error_code("eris_ifu_calc_noise_map");
159 return noiseImg;
160}
161
162/*----------------------------------------------------------------------------*/
172/*----------------------------------------------------------------------------*/
173hdrl_imagelist* eris_ifu_load_exposure_frameset(const cpl_frameset *frameset,
174 int exposureCorrectionMode) {
175 hdrl_imagelist *imageList = NULL;
176 hdrl_image *tmpImage = NULL;
177 const cpl_frame *frame = NULL;
178 cpl_size frameCnt;
179 cpl_ensure(frameset, CPL_ERROR_NULL_INPUT, NULL);
180
181 TRY
182 {
183 frameCnt = cpl_frameset_get_size(frameset);
184 imageList = hdrl_imagelist_new();
185 for (cpl_size ix=0; ix<frameCnt; ix++) {
186 frame = cpl_frameset_get_position_const(frameset, ix);
188 frame, exposureCorrectionMode, NULL);
189 hdrl_imagelist_set(imageList, tmpImage,
190 hdrl_imagelist_get_size(imageList));
191 }
192 }
193 CATCH
194 {
195 imageList = NULL;
196 }
197 eris_check_error_code("eris_ifu_load_exposure_frameset");
198 return imageList;
199
200}
201/*----------------------------------------------------------------------------*/
212/*----------------------------------------------------------------------------*/
213hdrl_image* eris_ifu_load_exposure_frame(const cpl_frame *frame,
214 int exposureCorrectionMode,
215 cpl_image *dqi) {
216
217 hdrl_image *image = NULL;
218 const char *filename;
219
220 cpl_ensure(frame, CPL_ERROR_NULL_INPUT, NULL);
221 TRY
222 {
223 filename = cpl_frame_get_filename(frame);
225 filename, exposureCorrectionMode, dqi);
226 }
227 CATCH
228 {
229 image = NULL;
230 }
231 eris_check_error_code("eris_ifu_load_exposure_frame");
232 return image;
233
234}
235/*----------------------------------------------------------------------------*/
236//TODO: why should one set flagged pixels to 1 in the image? Isn't sufficient
237//to flag them? That is also a different convention from the one of using NaN
245/*----------------------------------------------------------------------------*/
246cpl_error_code eris_ifu_add_badpix_border(cpl_image *data, cpl_boolean add_ones,
247 cpl_image *dqi)
248{
249 cpl_error_code err = CPL_ERROR_NONE;
250 cpl_size x = 0;
251 cpl_size y = 0;
252
253 cpl_ensure_code(data, CPL_ERROR_NULL_INPUT);
254
255 TRY
256 {
257 for (x = 1; x <= ERIS_IFU_DETECTOR_SIZE_X; x++) {
258 /* reject lower border*/
259 for (y = 1;
260 y <= ERIS_IFU_DETECTOR_BP_BORDER;
261 y++)
262 {
263 cpl_image_reject(data, x, y);
264 if (dqi != NULL) {
265 cpl_image_set(dqi, x, y, ERIS_DQI_BP);
266 }
267 if (add_ones) {
268 cpl_image_set(data, x, y, 1.);
269 }
270 }
271
272 /* reject upper border*/
273 for (y = ERIS_IFU_DETECTOR_SIZE_Y-ERIS_IFU_DETECTOR_BP_BORDER+1;
274 y <= ERIS_IFU_DETECTOR_SIZE_Y;
275 y++)
276 {
277 cpl_image_reject(data, x, y);
278 if (dqi != NULL) {
279 cpl_image_set(dqi, x, y, ERIS_DQI_BP);
280 }
281 if (add_ones) {
282 cpl_image_set(data, x, y, 1.);
283 }
284 }
285 }
287
288 for (y = ERIS_IFU_DETECTOR_BP_BORDER+1; y <= ERIS_IFU_DETECTOR_SIZE_Y-ERIS_IFU_DETECTOR_BP_BORDER; y++) {
289 /* reject remaining left border*/
290 for (x = 1; x <= ERIS_IFU_DETECTOR_BP_BORDER; x++) {
291 cpl_image_reject(data, x, y);
292 if (dqi != NULL) {
293 cpl_image_set(dqi, x, y, ERIS_DQI_BP);
294 }
295 if (add_ones) {
296 cpl_image_set(data, x, y, 1.);
297 }
298 }
299
300 /* reject remaining right border*/
301 for (x = ERIS_IFU_DETECTOR_SIZE_X-ERIS_IFU_DETECTOR_BP_BORDER+1;
302 x <= ERIS_IFU_DETECTOR_SIZE_X;
303 x++)
304 {
305 cpl_image_reject(data, x, y);
306 if (dqi != NULL) {
307 cpl_image_set(dqi, x, y, ERIS_DQI_BP);
308 }
309 if (add_ones) {
310 cpl_image_set(data, x, y, 1.);
311 }
312 }
313 }
315 }
316 CATCH
317 {
318 err = cpl_error_get_code();
319 }
320 eris_check_error_code("eris_ifu_add_badpix_border");
321 return err;
322}
323
324/*----------------------------------------------------------------------------*/
361/*----------------------------------------------------------------------------*/
362hdrl_image* eris_ifu_load_exposure_file(const char *filename,
363 int exposureCorrectionMode,
364 cpl_image *dqi)
365{
366 hdrl_image *image = NULL;
367 cpl_image *dataImage = NULL;
368 cpl_image *noiseImage = NULL;
369 cpl_propertylist *header = NULL;
370 ifsInstrument instrument = UNSET_INSTRUMENT;
371 double gain;
372 double ron;
373
374 cpl_ensure(filename, CPL_ERROR_NULL_INPUT, NULL);
375
376 TRY
377 {
378 dataImage = cpl_image_load(filename, CPL_TYPE_UNSPECIFIED, 0, 0);
379 eris_ifu_add_badpix_border(dataImage, CPL_FALSE, dqi);
380 eris_ifu_saturation_detection(dataImage, dqi);
381
382 // ==========
383 // correct data image
384 // ==========
385 if ((exposureCorrectionMode & LINE_EXPOSURE_CORRECTION) != 0) {
387 // cpl_image_save(dataImage,"line_corr_img.fits",
388 // CPL_TYPE_FLOAT,NULL,CPL_IO_CREATE);
389 }
390 if ((exposureCorrectionMode & COLUMN_EXPOSURE_CORRECTION) != 0) {
392 // cpl_image_save(dataImage,"col_corr_img.fits",
393 // CPL_TYPE_FLOAT,NULL,CPL_IO_CREATE);
394 }
395
396 // ==========
397 // fill noise image
398 // ==========
399 // get detector gain and readout noise parameters from FITS header
400 header = cpl_propertylist_load(filename, 0);
401 instrument = eris_ifu_get_instrument(header);
403 if (instrument == SPIFFI) {
404 //FITS header keywords are missing for SPIFFI, set defaults
405 gain = 2.1;
406 ron = 0.0;
407 } else if (instrument == SPIFFIER) {
408 gain = cpl_propertylist_get_double(header, FHDR_DET_CHIP_GAIN);
409 ron = cpl_propertylist_get_double(header, FHDR_DET_CHIP_RON);
411 } else {
412 gain = 0.;
413 ron = 0.;
414 }
415 noiseImage = eris_ifu_calc_noise_map(dataImage, gain, ron);
416 image = hdrl_image_create(dataImage, noiseImage);
417
418 }
419 CATCH
420 {
421 CATCH_MSGS();
423 }
424
426 eris_ifu_free_image(&dataImage);
427 eris_ifu_free_image(&noiseImage);
428 eris_check_error_code("eris_ifu_load_exposure_file");
429 return image;
430}
431
432/*----------------------------------------------------------------------------*/
446cpl_mask* eris_ifu_detect_crh(hdrl_image* image,
447 int exposureCorrectionMode,
448 hdrl_parameter *laCosmicParams,
449 bool maskImage)
450{
451 cpl_mask *mask = NULL;
452 cpl_ensure(image, CPL_ERROR_NULL_INPUT, NULL);
453 cpl_ensure(laCosmicParams, CPL_ERROR_NULL_INPUT, NULL);
454
455
456 TRY
457 {
458 if ((exposureCorrectionMode & COSMIC_RAY_EXPOSURE_DETECTION) &&
459 (laCosmicParams != NULL)) {
460 mask = hdrl_lacosmic_edgedetect(image, laCosmicParams);
461 cpl_msg_info(__func__,"CRH count %lld",cpl_mask_count(mask));
462 if (maskImage) {
464 hdrl_image_reject_from_mask(image, mask));
465 }
466 // if (loadingCnt == 0) {
467 // cpl_mask_save(mask,"crh.fits", NULL, CPL_IO_CREATE);
468 // } else {
469 // cpl_mask_save(mask,"crh.fits", NULL, CPL_IO_EXTEND);
470 // }
471 // loadingCnt++;
472 }
473 }
474 CATCH
475 {
476 CATCH_MSGS();
477 eris_ifu_free_mask(&mask);
478 }
479 eris_check_error_code("eris_ifu_detect_crh");
480 return mask;
481}
482
483/*----------------------------------------------------------------------------*/
489/*----------------------------------------------------------------------------*/
490/* TODO: this function expects a floating point image, should rather work with double
491 * filling of dqi to be understood: with real data works as implemented but code it's strange
492 */
493
494cpl_error_code eris_ifu_saturation_detection(cpl_image *image, cpl_image *dqi) {
495
496 cpl_ensure_code(image, CPL_ERROR_NULL_INPUT);
497 //TODO: you should not hard-code numbers, rather use a #define
498 const float satPixelValue = -45727232.0f;
499 const float satPixelLevel = satPixelValue + 1.f;
500
501 cpl_size nx = cpl_image_get_size_x(image);
502 cpl_size ny = cpl_image_get_size_y(image);
503 const float *data = cpl_image_get_data_float_const(image);
504 cpl_mask *mask = cpl_image_get_bpm(image);
505 cpl_binary *bp = cpl_mask_get_data(mask);
506 //int* qp = cpl_image_get_data_int(dqi);
507
508 int nSat = 0;
509 for (cpl_size iy=0; iy<ny; iy++) {
510 for (cpl_size ix=0; ix<nx; ix++) {
511 if (data[ix+iy*nx] <= satPixelLevel) {
512 if (dqi != NULL) {
513 cpl_image_add_scalar(dqi, ERIS_DQI_SAT);
514 //qp[ix+iy*nx] = ERIS_DQI_SAT;
515 }
516 bp[ix+iy*nx] = BAD_PIX;
517 nSat++;
518 }
519 }
520 }
521 cpl_image_set_bpm(image, mask);
522 //TODO: you should not hard-code numbers, rather use a #define
523 if (nSat > 50) {
524 cpl_msg_debug(__FUNCTION__, "Found %d saturated pixels", nSat);
525 }
526 eris_check_error_code("eris_ifu_saturation_detection");
527 return CPL_ERROR_NONE;
528}
529
530/*----------------------------------------------------------------------------*/
547/*----------------------------------------------------------------------------*/
548cpl_error_code eris_ifu_exposure_line_correction(cpl_image *image)
549{
550 cpl_error_code retVal = CPL_ERROR_NONE;
551 cpl_size nCols;
552 cpl_size nRows;
553 cpl_type type;
554 double *dData = NULL;
555 float *fData = NULL;
556 cpl_vector *borderVector = NULL;
557 double *borderData;
558 double borderMean;
559 double borderMedian;
560 float fborderMean;
561 float fborderMedian;
562 const int borderSize = 4;
563
564 cpl_ensure_code(image, CPL_ERROR_NULL_INPUT);
565 TRY
566 {
568 borderVector = cpl_vector_new(borderSize*2));
569 borderData = cpl_vector_get_data(borderVector);
570
571 nCols = cpl_image_get_size_x(image);
572 nRows = cpl_image_get_size_y(image);
573 if (nCols < borderSize*2) {
574 BRK_WITH_ERROR_MSG(CPL_ERROR_ILLEGAL_INPUT,
575 "CPL image too small");
576 }
577 type = cpl_image_get_type(image);
578 if (type == CPL_TYPE_FLOAT) {
579 fData = cpl_image_get_data_float(image);
580 } else if (type == CPL_TYPE_DOUBLE) {
581 dData = cpl_image_get_data_double(image);
582 } else {
583 BRK_WITH_ERROR_MSG(CPL_ERROR_INVALID_TYPE,
584 "CPL image type must be float or double");
585 }
586
587 for (cpl_size row=0; row<nRows; row++) {
588 for (int col=0; col<4; col++) {
589 if (type == CPL_TYPE_FLOAT) {
590 borderData[col] = fData[col+row*nCols];
591 borderData[col+borderSize] = fData[nCols-1-col+row*nCols];
592 } else {
593 borderData[col] = dData[col+row*nCols];
594 borderData[col+borderSize] = dData[nCols-1-col+row*nCols];
595 }
596 }
597 borderMean = cpl_vector_get_mean(borderVector);
598 borderMedian = cpl_vector_get_median(borderVector);
599 if (type == CPL_TYPE_FLOAT) {
600 fborderMean = (float) borderMean;
601 fborderMedian = (float) borderMedian;
602 }
603 for (int col=borderSize; col<(nCols-borderSize); col++) {
604 if (type == CPL_TYPE_FLOAT) {
605 fData[col+row*nCols] = fData[col+row*nCols] +
606 fborderMean - fborderMedian;
607 } else {
608 dData[col+row*nCols] = dData[col+row*nCols] +
609 borderMean - borderMedian;
610 }
611 }
612 }
614 }
615 CATCH
616 {
617 retVal = cpl_error_get_code();
618 }
619 eris_ifu_free_vector(&borderVector);
620 eris_check_error_code("eris_ifu_exposure_line_correction");
621 return retVal;
622}
623
624/*----------------------------------------------------------------------------*/
643/*----------------------------------------------------------------------------*/
644cpl_error_code eris_ifu_exposure_column_correction(cpl_image *image)
645{
646 cpl_error_code retVal = CPL_ERROR_NONE;
647 cpl_size nCols;
648 cpl_size nRows;
649 cpl_type type;
650 double *dData = NULL;
651 float *fData= NULL;
652 cpl_vector *borderVector = NULL;
653 double *borderData;
654 double borderMedian;
655 float fborderMedian;
656 const int borderSize = 4;
657
658 cpl_ensure_code(image, CPL_ERROR_NULL_INPUT);
659 TRY
660 {
662 borderVector = cpl_vector_new(borderSize*2));
663 borderData = cpl_vector_get_data(borderVector);
664
665 nCols = cpl_image_get_size_x(image);
666 nRows = cpl_image_get_size_y(image);
667 if (nRows < borderSize*2) {
668 BRK_WITH_ERROR_MSG(CPL_ERROR_ILLEGAL_INPUT,
669 "CPL image too small");
670 }
671 type = cpl_image_get_type(image);
672 if (type == CPL_TYPE_FLOAT) {
673 fData = cpl_image_get_data_float(image);
674 } else if (type == CPL_TYPE_DOUBLE) {
675 dData = cpl_image_get_data_double(image);
676 } else {
677 BRK_WITH_ERROR_MSG(CPL_ERROR_INVALID_TYPE,
678 "CPL image type must be float or double");
679 }
680
681 for (cpl_size col=0; col<nCols; col++) {
682 for (int row=0; row<4; row++) {
683 if (type == CPL_TYPE_FLOAT) {
684 borderData[row] = fData[col + row*nCols];
685 borderData[row+borderSize] = fData[col+(nRows-row-1)*nCols];
686 } else {
687 borderData[row] = dData[col + row*nCols];
688 borderData[row+borderSize] = dData[col+(nRows-row-1)*nCols];
689 }
690 }
691 borderMedian = cpl_vector_get_median(borderVector);
692 if (type == CPL_TYPE_FLOAT) {
693 fborderMedian = (float) borderMedian;
694 }
695 for (int row=borderSize; row<(nCols-borderSize); row++) {
696 if (type == CPL_TYPE_FLOAT) {
697 fData[col + row*nCols] = fData[col + row*nCols] -
698 fborderMedian;
699 } else {
700 dData[col + row*nCols] = dData[col + row*nCols] -
701 borderMedian;
702 }
703 }
704 }
706 }
707 CATCH
708 {
709 retVal = cpl_error_get_code();
710 }
711 eris_ifu_free_vector(&borderVector);
712 eris_check_error_code("eris_ifu_exposure_column_correction");
713 return retVal;
714}
715
716
727cpl_error_code eris_ifu_calc_bpm(const cpl_parameterlist *pl,
728 const char *recipe_name,
729 hdrl_image *master_img,
730 const hdrl_imagelist *imglist_on,
731 cpl_mask **bpm2dMask,
732 cpl_mask **bpm3dMask)
733{
734 cpl_error_code err = CPL_ERROR_NONE;
735 const cpl_parameter *param = NULL;
736 const char *bpmMethod = NULL;
737 char *parName = NULL;
738 hdrl_parameter *bpm2dParam = NULL;
739 hdrl_parameter *bpm3dParam = NULL;
740 cpl_image *bpm3dImg = NULL;
741 cpl_imagelist *bpm3dImageList = NULL;
742 cpl_mask *masterBpmMask = NULL;
743
744 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
745 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
746 cpl_ensure_code(master_img, CPL_ERROR_NULL_INPUT);
747 cpl_ensure_code(imglist_on, CPL_ERROR_NULL_INPUT);
748 cpl_ensure_code(bpm2dMask, CPL_ERROR_NULL_INPUT);
749 cpl_ensure_code(bpm3dMask, CPL_ERROR_NULL_INPUT);
750
751 TRY
752 {
753 parName = cpl_sprintf("eris.%s.bpm.method", recipe_name);
754 param = cpl_parameterlist_find_const(pl, parName);
755 eris_ifu_free_string(&parName);
756
757 bpmMethod = cpl_parameter_get_string(param);
758
759 if (strpbrk(bpmMethod, "2") != NULL)
760 {
761 parName = cpl_sprintf("eris.%s.2dBadPix", recipe_name);
762 bpm2dParam = hdrl_bpm_2d_parameter_parse_parlist(pl, parName);
763 eris_ifu_free_string(&parName);
764
765 cpl_msg_info(cpl_func, "Generating 2D bad pixel mask...");
766 *bpm2dMask = hdrl_bpm_2d_compute(master_img, bpm2dParam);
768 }
769
770 if (strpbrk(bpmMethod, "3") != NULL)
771 {
772 parName = cpl_sprintf("eris.%s.3dBadPix", recipe_name);
773 bpm3dParam = hdrl_bpm_3d_parameter_parse_parlist(pl, parName);
774 eris_ifu_free_string(&parName);
775
776 cpl_msg_info(cpl_func, "Generate 3D bad pixel mask");
777 bpm3dImageList = hdrl_bpm_3d_compute(imglist_on, bpm3dParam);
778
780 int imglistCnt = (int) cpl_imagelist_get_size(bpm3dImageList);
781 cpl_image *patternImg = NULL;
782
783 bpm3dImg = cpl_image_duplicate(cpl_imagelist_get(bpm3dImageList, 0));
784 patternImg = cpl_image_duplicate(
785 cpl_imagelist_get(bpm3dImageList, 0));
786 for (int i = 1; i < imglistCnt; i++) {
787 cpl_image *tmpImg = cpl_imagelist_get(bpm3dImageList, i);
788 cpl_image_add(bpm3dImg, tmpImg);
789 cpl_image_multiply_scalar(tmpImg, (double) (1<<i));
790 cpl_image_add(patternImg, tmpImg);
791 }
792
793 parName = cpl_sprintf("eris.%s.product_depth", recipe_name);
794 param = cpl_parameterlist_find_const(pl, parName);
795 eris_ifu_free_string(&parName);
796 int pd = cpl_parameter_get_int(param);
798 if (pd >= PD_DEBUG) {
799 cpl_image_save(bpm3dImg,ERIS_IFU_PRO_DARK_DBG_3D_FN".fits",
800 CPL_TYPE_INT, NULL, CPL_IO_CREATE);
801 cpl_image_save(patternImg,ERIS_IFU_PRO_DARK_DBG_3D_FN".fits",
802 CPL_TYPE_INT, NULL, CPL_IO_EXTEND);
803 }
804
805 *bpm3dMask = cpl_mask_threshold_image_create(bpm3dImg,
806 1.5, imglistCnt + 0.5);
807 cpl_image_delete(patternImg);
808 }
809
810 cpl_msg_info(cpl_func, "Generating master bad pixel mask...");
811 masterBpmMask = hdrl_image_get_mask(master_img);
812 if (*bpm2dMask != NULL) {
813 cpl_msg_info(cpl_func,"Number of 2D bad pixels: %lld",
814 cpl_mask_count(*bpm2dMask));
815 cpl_mask_or(masterBpmMask, *bpm2dMask);
816 }
817 if (bpm3dImg != NULL) {
818 cpl_msg_info(cpl_func,"Number of 3D bad pixels: %lld",
819 cpl_mask_count(*bpm3dMask));
820 cpl_mask_or(masterBpmMask, *bpm3dMask);
821 }
822 hdrl_image_reject_from_mask(master_img, masterBpmMask);
823 }
824 CATCH
825 {
826 err = cpl_error_get_code();
827
828 cpl_mask_delete(*bpm2dMask); // not using eris_ifu_free_image() here
829 cpl_mask_delete(*bpm3dMask); // because arg is allocated outside of function
830
831 eris_ifu_free_mask(&masterBpmMask);
832 masterBpmMask = cpl_mask_new(hdrl_image_get_size_x(master_img),
833 hdrl_image_get_size_y(master_img));
834 hdrl_image_reject_from_mask(master_img, masterBpmMask);
835 }
836
837 eris_ifu_free_hdrl_parameter(&bpm2dParam);
838 eris_ifu_free_hdrl_parameter(&bpm3dParam);
839 //eris_ifu_free_mask(&masterBpmMask);
840 eris_ifu_free_image(&bpm3dImg);
841 eris_ifu_free_imagelist(&bpm3dImageList);
842 eris_check_error_code("eris_ifu_calc_bpm");
843 return err;
844}
845
853hdrl_image *eris_ifu_warp_polynomial_image(const hdrl_image *hdrlInImg,
854 const cpl_polynomial *poly_u,
855 const cpl_polynomial *poly_v)
856{
857 hdrl_image *hdrlOutImg = NULL;
858 const cpl_image *inImgData = NULL,
859 *inImgErr = NULL;
860 cpl_image *outImgData = NULL,
861 *outImgErr = NULL;
862 cpl_vector *profile = NULL;
863 cpl_size nx = 0,
864 ny = 0;
865 cpl_type type = CPL_TYPE_UNSPECIFIED;
866
867 cpl_ensure(hdrlInImg, CPL_ERROR_NULL_INPUT, NULL);
868 cpl_ensure(poly_u, CPL_ERROR_NULL_INPUT, NULL);
869 cpl_ensure(poly_v, CPL_ERROR_NULL_INPUT, NULL);
870
871 TRY
872 {
873 inImgData = hdrl_image_get_image_const(hdrlInImg);
874 inImgErr = hdrl_image_get_error_const(hdrlInImg);
875
876 nx = cpl_image_get_size_x(inImgData);
877 ny = cpl_image_get_size_y(inImgData);
878 type = cpl_image_get_type(inImgData);
880
881 outImgData = cpl_image_new(nx, ny, type);
882 outImgErr = cpl_image_new(nx, ny, type);
883 profile = cpl_vector_new(CPL_KERNEL_DEF_SAMPLES);
884 cpl_vector_fill_kernel_profile(profile, CPL_KERNEL_TANH,
885 CPL_KERNEL_DEF_WIDTH);
886 cpl_image_warp_polynomial(outImgData, inImgData,
887 poly_u, poly_v,
888 profile, CPL_KERNEL_DEF_WIDTH,
889 profile, CPL_KERNEL_DEF_WIDTH);
890 cpl_image_warp_polynomial(outImgErr, inImgErr,
891 poly_u, poly_v,
892 profile, CPL_KERNEL_DEF_WIDTH,
893 profile, CPL_KERNEL_DEF_WIDTH);
894
895 hdrlOutImg = hdrl_image_create(outImgData, outImgErr);
896
897 // there can still be inconsistencies:
898 // warped data can have a value of zero and not be marked as bad
899 // so here we will mark zero data values as bad in the bpm
900 cpl_image *tmpImg = hdrl_image_get_image(hdrlOutImg);
901 double *ptmpImg = cpl_image_get_data(tmpImg);
902 cpl_mask *tmpMask = cpl_image_get_bpm(tmpImg);
903 cpl_binary *ptmpMask = cpl_mask_get_data(tmpMask);
904
905 int w = (int)hdrl_image_get_size_x(hdrlOutImg),
906 h = (int)hdrl_image_get_size_y(hdrlOutImg);
907
908 for (int y = 0; y < h; y++) {
909 for (int x = 0; x < w; x++) {
910 if (ptmpImg[y*w+x] == 0) {
911 ptmpMask[y*w+x] = BAD_PIX;
912 }
913 }
914 }
915 }
916 CATCH
917 {
918 eris_ifu_free_hdrl_image(&hdrlOutImg);
919 }
920 eris_ifu_free_image(&outImgData);
921 eris_ifu_free_image(&outImgErr);
922 eris_ifu_free_vector(&profile);
923 eris_check_error_code("eris_ifu_warp_polynomial_image");
924 return hdrlOutImg;
925}
926
927cpl_error_code eris_ifu_add_std_params(
928 cpl_parameterlist *pl,
929 const char *recipename)
930{
931
932 cpl_ensure_code(pl,CPL_ERROR_NULL_INPUT);
933 cpl_ensure_code(recipename,CPL_ERROR_NULL_INPUT);
934
935
936 cpl_error_code retVal = CPL_ERROR_NONE;
937 cpl_parameter *p = NULL;
938 char *pName = NULL;
939 char *recname_full = NULL;
940 hdrl_parameter *p_hdrl = NULL;
941 cpl_parameterlist *tmp_pl = NULL;
942
943 TRY
944 {
945 recname_full = cpl_sprintf("eris.%s", recipename);
946 pName = cpl_sprintf("%s.%s", recname_full, "instrument");
947 p = cpl_parameter_new_enum(pName, CPL_TYPE_STRING,
948 "Specifies the VLT instrument "
949 "{ERIS,SINFONI,NONE}",
950 recname_full, "ERIS", 3, "ERIS",
951 "SINFONI", "NONE");
952 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "instrument");
953 cpl_parameterlist_append(pl, p);
954 p = NULL;
955 eris_ifu_free_string(&pName);
956
957 // productDepthType pdMin = PD_SCIENCE;
958 // productDepthType pdMax = PD_DEBUG;
959 pName = cpl_sprintf("%s.%s", recname_full, "product_depth");
960 p = cpl_parameter_new_value(pName, CPL_TYPE_INT,
961 "Specifies the product output depth "
962 "(>0 for auxiliary products)",
963 recname_full, 0);
964 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
965 "product_depth");
966 cpl_parameterlist_append(pl, p);
967 p = NULL;
968 eris_ifu_free_string(&pName);
969
970 pName = cpl_sprintf("%s.%s", recname_full, "line_corr");
971 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
972 "If TRUE raw exposure image line "
973 "correction will be applied",
974 recname_full, CPL_FALSE);
975 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
976 "line_corr");
977 cpl_parameterlist_append(pl, p);
978 p = NULL;
979 eris_ifu_free_string(&pName);
980
981 pName = cpl_sprintf("%s.%s", recname_full, "col_corr");
982 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
983 "If TRUE raw exposure image column "
984 "correction will be applied",
985 recname_full, CPL_FALSE);
986 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
987 "col_corr");
988 cpl_parameterlist_append(pl, p);
989 p = NULL;
990 eris_ifu_free_string(&pName);
991
992 pName = cpl_sprintf("%s.%s", recname_full, "crh_corr");
993 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
994 "If TRUE raw exposure image cosmic ray "
995 "hit correction will be applied",
996 recname_full, CPL_FALSE);
997 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
998 "crh_corr");
999 cpl_parameterlist_append(pl, p);
1000 p = NULL;
1001 eris_ifu_free_string(&pName);
1002
1003 pName = cpl_sprintf("%s.%s", recname_full, "crh_detection");
1004 p = cpl_parameter_new_value(pName, CPL_TYPE_BOOL,
1005 "If TRUE raw exposure image cosmic ray "
1006 "hit detection will be applied",
1007 recname_full, CPL_FALSE);
1008 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
1009 "crh_detection");
1010 cpl_parameterlist_append(pl, p);
1011 p = NULL;
1012 eris_ifu_free_string(&pName);
1013
1014 p_hdrl = hdrl_lacosmic_parameter_create(5, 2., 3);
1015 tmp_pl = hdrl_lacosmic_parameter_create_parlist(recname_full, "crh",
1016 p_hdrl);
1018
1019
1020 pName = cpl_sprintf("%s.%s", recname_full, "pixel_saturation");
1021 p = cpl_parameter_new_value(pName, CPL_TYPE_DOUBLE,
1022 "Pixel saturation level ",
1023 recname_full, 18000.);
1024 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "pixel_saturation");
1025
1026 cpl_parameterlist_append(pl, p);
1027 p = NULL;
1028
1029
1030
1031 }
1032 CATCH
1033 {
1034 CATCH_MSGS();
1035 retVal = cpl_error_get_code();
1036 }
1037
1041 eris_ifu_free_string(&pName);
1042 eris_ifu_free_string(&recname_full);
1043 eris_check_error_code("eris_ifu_add_std_params");
1044 return retVal;
1045}
1046void eris_ifu_free_std_param(struct stdParamStruct * stdParams) {
1047
1048 if(stdParams != NULL) {
1049 hdrl_parameter_delete(stdParams->crh_detection);
1050 stdParams=NULL;
1051 }
1052
1053
1054 eris_check_error_code("eris_ifu_free_std_param");
1055 return;
1056}
1057cpl_error_code eris_ifu_fetch_std_param(
1058 const cpl_parameterlist *parlist,
1059 const char *recipename,
1060 struct stdParamStruct *stdParams)
1061{
1062
1063 cpl_ensure_code(parlist,CPL_ERROR_NULL_INPUT);
1064 cpl_ensure_code(recipename,CPL_ERROR_NULL_INPUT);
1065 cpl_ensure_code(stdParams,CPL_ERROR_NULL_INPUT);
1066
1067 cpl_error_code retVal = CPL_ERROR_NONE;
1068 cpl_parameter *p = NULL;
1069 char *pName = NULL;
1070 const char *instrument = NULL;
1071 char *recname_full = NULL;
1072 char *tmp_str = NULL;
1073
1074 TRY
1075 {
1076 recname_full = cpl_sprintf("eris.%s", recipename);
1077 pName = cpl_sprintf("%s.%s", recname_full, "product_depth");
1078 stdParams->productDepth = cpl_parameter_get_int(
1079 cpl_parameterlist_find_const(parlist, pName));
1081 eris_ifu_free_string(&pName);
1082
1083 stdParams->rawImageCorrectionMask = 0;
1084 pName = cpl_sprintf("%s.%s", recname_full, "line_corr");
1085 stdParams->line_corr = cpl_parameter_get_bool(
1086 cpl_parameterlist_find_const(parlist, pName));
1088 eris_ifu_free_string(&pName);
1089 if (stdParams->line_corr) {
1090 stdParams->rawImageCorrectionMask |= LINE_EXPOSURE_CORRECTION;
1091 }
1092
1093 pName = cpl_sprintf("%s.%s", recname_full, "col_corr");
1094 stdParams->col_corr = cpl_parameter_get_bool(
1095 cpl_parameterlist_find_const(parlist, pName));
1097 eris_ifu_free_string(&pName);
1098 if (stdParams->col_corr) {
1099 stdParams->rawImageCorrectionMask |= COLUMN_EXPOSURE_CORRECTION;
1100 }
1101
1102 pName = cpl_sprintf("%s.%s", recname_full, "crh_corr");
1103 stdParams->crh_corr = cpl_parameter_get_bool(
1104 cpl_parameterlist_find_const(parlist, pName));
1106 eris_ifu_free_string(&pName);
1107 if (stdParams->crh_corr) {
1108 stdParams->rawImageCorrectionMask |= COSMIC_RAY_EXPOSURE_CORRECTION;
1109 }
1110
1111 pName = cpl_sprintf("%s.%s", recname_full, "crh_detection");
1112 stdParams->crh_det = cpl_parameter_get_bool(
1113 cpl_parameterlist_find_const(parlist, pName));
1115 eris_ifu_free_string(&pName);
1116 if (stdParams->crh_det) {
1117 stdParams->rawImageCorrectionMask |= COSMIC_RAY_EXPOSURE_DETECTION;
1118 }
1119
1120 tmp_str = cpl_sprintf("%s.crh", recname_full);
1121
1122 stdParams->crh_detection =
1123 hdrl_lacosmic_parameter_parse_parlist(parlist, tmp_str);
1124 eris_ifu_free_string(&tmp_str);
1126
1127 pName = cpl_sprintf("%s.%s", recname_full, "instrument");
1128 instrument = cpl_parameter_get_string(
1129 cpl_parameterlist_find_const(parlist, pName));
1131 eris_ifu_free_string(&pName);
1132 if (strcmp(instrument, "SINFONI") == 0) {
1133 stdParams->instrument = SPIFFI;
1134 }
1135 else if(strcmp(instrument, "ERIS") == 0) {
1136 stdParams->instrument = SPIFFIER;
1137 }
1138 else {
1139 stdParams->instrument = OTHER_INSTRUMENT;
1140 }
1141 }
1142 CATCH
1143 {
1144 CATCH_MSGS();
1145 retVal = cpl_error_get_code();
1146 }
1147
1149 eris_ifu_free_string(&pName);
1150 eris_ifu_free_string(&tmp_str);
1151 eris_ifu_free_string(&recname_full);
1152 eris_check_error_code("eris_ifu_fetch_std_param");
1153 return retVal;
1154}
1155
1156cpl_error_code eris_parlist_config_add_all_recipes(cpl_parameterlist *pl,
1157 const char* recname)
1158{
1159 char *tmp_str1 = NULL,
1160 *recname_full = NULL;
1161 cpl_error_code err = CPL_ERROR_NONE;
1162 cpl_parameter *p = NULL;
1163
1164 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
1165 cpl_ensure_code(recname, CPL_ERROR_NULL_INPUT);
1166
1167 TRY
1168 {
1169 recname_full = cpl_sprintf("eris.%s", recname);
1170
1171 /* --instrument */
1172 tmp_str1 = cpl_sprintf("%s%s%s", "eris.", recname, ".instrument");
1173 p = cpl_parameter_new_enum(tmp_str1, CPL_TYPE_STRING,
1174 "Specifies the VLT instrument {ERIS,SINFONI,NONE}",
1175 recname_full, INSTRUMENT_ERIS, 3,
1176 INSTRUMENT_ERIS, INSTRUMENT_SINFONI, INSTRUMENT_NONE);
1177 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "instrument");
1178 cpl_parameterlist_append(pl, p);
1179 eris_ifu_free_string(&tmp_str1);
1180
1181 /* -- product_depth */
1182 tmp_str1 = cpl_sprintf("%s%s%s", "eris.", recname, ".product_depth");
1183 p = cpl_parameter_new_value(tmp_str1, CPL_TYPE_INT,
1184 "Specifies the product output depth "
1185 "instrument (>0 for auxillary products)",
1186 recname_full, 0);
1187 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
1188 "product_depth");
1189 cpl_parameterlist_append(pl, p);
1190 eris_ifu_free_string(&tmp_str1);
1191 }
1192 CATCH
1193 {
1194 CATCH_MSGS();
1195 err = cpl_error_get_code();
1197 eris_ifu_free_string(&tmp_str1);
1198 }
1199 eris_ifu_free_string(&tmp_str1);
1200 eris_ifu_free_string(&recname_full);
1201 eris_check_error_code("eris_parlist_config_add_all_recipes");
1202 return err;
1203}
1204
1205cpl_error_code eris_parlist_config_add_bpm(cpl_parameterlist *pl,
1206 const char* recname)
1207{
1208 char *tmp_str = NULL,
1209 *recname_full = NULL,
1210 *tmp_def_meth = NULL,
1211 *tmp_meth = NULL;
1212 cpl_error_code err = CPL_ERROR_NONE;
1213 cpl_parameterlist *tmp_pl = NULL;
1214 cpl_parameter *p = NULL;
1215 hdrl_parameter *p_hdrl1 = NULL;
1216 hdrl_parameter *p_hdrl2 = NULL;
1217
1218 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
1219 cpl_ensure_code(recname, CPL_ERROR_NULL_INPUT);
1220
1221 TRY
1222 {
1223 recname_full = cpl_sprintf("eris.%s", recname);
1224
1225 /* set default for bpm-method depending on recipe */
1226 if (strcmp(recname, REC_NAME_DISTORTION) == 0) {
1227 tmp_def_meth = cpl_sprintf("2d");
1228 tmp_meth = cpl_sprintf("LEGENDRE");
1229 } else {
1230 tmp_def_meth = cpl_sprintf("2d3d");
1231 tmp_meth = cpl_sprintf("FILTER");
1232 }
1233
1234 /* --bpm.method */
1235 tmp_str = cpl_sprintf("%s%s", recname_full, ".bpm.method");
1236 p = cpl_parameter_new_enum(tmp_str, CPL_TYPE_STRING,
1237 "Specifies the VLT instrument {2d,3d,2d3d}",
1238 recname_full, tmp_def_meth, 4,
1239 "2d", "3d", "2d3d", "none");
1240 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bpm.method");
1241 cpl_parameterlist_append(pl, p);
1242 eris_ifu_free_string(&tmp_str);
1243
1244 /* --collapse.sigclip/minmax (HDRL) */
1245 hdrl_parameter * mode_def =
1246 hdrl_collapse_mode_parameter_create(10., 1., 0., HDRL_MODE_MEDIAN, 0);
1247 p_hdrl1 = hdrl_collapse_sigclip_parameter_create(3., 3., 5);
1248 p_hdrl2 = hdrl_collapse_minmax_parameter_create(1., 1.);
1249 tmp_pl = hdrl_collapse_parameter_create_parlist(recname_full,
1250 "collapse", "MEDIAN",
1251 p_hdrl1, p_hdrl2, mode_def);
1256 hdrl_parameter_delete(mode_def);
1257 /* --2dBadPix.* (HDRL) */
1259 10., 10., 3, CPL_FILTER_MEDIAN, CPL_BORDER_NOP, 5, 5);
1260 // values from HDRL-Demo
1261 // 3, 3, 5, CPL_FILTER_MEDIAN, CPL_BORDER_FILTER, 3, 3));
1263 10., 10., 3, 20, 20, 10, 10, 2, 2);
1264 // values from HDRL-Demo
1265 // 3, 3, 5, 20, 20, 11, 11, 3, 3));
1266 tmp_pl = hdrl_bpm_2d_parameter_create_parlist(recname_full,
1267 "2dBadPix", tmp_meth,
1268 p_hdrl1, p_hdrl2);
1273
1274 /* --3dBadPix.* (HDRL) */
1275 p_hdrl1 = hdrl_bpm_3d_parameter_create(12., 12.,
1276 HDRL_BPM_3D_THRESHOLD_RELATIVE);
1277 tmp_pl = hdrl_bpm_3d_parameter_create_parlist(recname_full,
1278 "3dBadPix", p_hdrl1);
1282 }
1283 CATCH
1284 {
1285 CATCH_MSGS();
1286 err = cpl_error_get_code();
1288 eris_ifu_free_string(&tmp_str);
1292 }
1293 eris_ifu_free_string(&tmp_str);
1294 eris_ifu_free_string(&recname_full);
1295 eris_ifu_free_string(&tmp_def_meth);
1296 eris_ifu_free_string(&tmp_meth);
1297 eris_check_error_code("eris_parlist_config_add_bpm");
1298 return err;
1299}
1300
1301cpl_error_code eris_parlist_config_add_flat(cpl_parameterlist *pl,
1302 const char* recname)
1303{
1304 cpl_error_code err = CPL_ERROR_NONE;
1305 hdrl_parameter *p_hdrl = NULL;
1306 cpl_parameterlist *tmp_pl = NULL;
1307 cpl_parameter *p = NULL;
1308 char *tmp_str = NULL,
1309 *recname_full = NULL;
1310
1311 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
1312
1313 TRY
1314 {
1315 recname_full = cpl_sprintf("eris.%s", recname);
1316
1317 /* add mode parameter */
1318 tmp_str = cpl_sprintf("%s%s", recname_full, ".mode");
1319 // set default to segment, when this mode is implemented
1320 p = cpl_parameter_new_enum(tmp_str,
1321 CPL_TYPE_STRING,
1322 "Mode of flat-calculation",
1323 recname,
1324 flatModes[0], 3,
1325 flatModes[0],flatModes[1],flatModes[2]);
1326 // if (strcmp(recname, REC_NAME_DISTORTION)==0) {
1327 // BRK_IF_NULL(
1328 // /* fast-mode for distortion */
1329 // p = cpl_parameter_new_enum(tmp_str,
1330 // CPL_TYPE_STRING,
1331 // "Mode of flat-calculation",
1332 // recname,
1333 // flatModes[2], 3,
1334 // flatModes[0],flatModes[1],flatModes[2]));
1335 // } else {
1336 // BRK_IF_NULL(
1337 // /* hdrl-mode for flat */
1338 // p = cpl_parameter_new_enum(tmp_str,
1339 // CPL_TYPE_STRING,
1340 // "Mode of flat-calculation",
1341 // recname,
1342 // flatModes[1], 3,
1343 // flatModes[0],flatModes[1],flatModes[2]));
1344 // }
1345
1346 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"flat.mode");
1347 cpl_parameterlist_append(pl, p);
1348 eris_ifu_free_string(&tmp_str);
1349
1350 /* --flat_lo.* (HDRL) */
1351 p_hdrl = hdrl_flat_parameter_create(5, 5, HDRL_FLAT_FREQ_LOW);
1352 tmp_pl = hdrl_flat_parameter_create_parlist(recname_full, "flat_lo",
1353 p_hdrl);
1357
1358 /* --flat_hi.* (HDRL) */
1359 p_hdrl = hdrl_flat_parameter_create(7, 7, HDRL_FLAT_FREQ_HIGH);
1360 tmp_pl = hdrl_flat_parameter_create_parlist(recname_full, "flat_hi",
1361 p_hdrl);
1365
1366 /* QC FPN */
1367 tmp_str = cpl_sprintf("%s%s", recname_full, ".qc.fpn.xmin1");
1368 p = cpl_parameter_new_range(tmp_str, CPL_TYPE_INT,
1369 "Fixed Pattern Noise: qc_fpn_xmin1",
1370 recname_full,
1371 512, 1, ERIS_IFU_DETECTOR_SIZE_X);
1372 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "qc_fpn_xmin1");
1373 cpl_parameterlist_append(pl, p);
1374 eris_ifu_free_string(&tmp_str);
1375
1376 tmp_str = cpl_sprintf("%s%s", recname_full, ".qc.fpn.xmax1");
1377 p = cpl_parameter_new_range(tmp_str, CPL_TYPE_INT,
1378 "Fixed Pattern Noise: qc_fpn_xmax1",
1379 recname_full,
1380 1536, 1, ERIS_IFU_DETECTOR_SIZE_X);
1381 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "qc_fpn_xmax1");
1382 cpl_parameterlist_append(pl, p);
1383 eris_ifu_free_string(&tmp_str);
1384
1385 tmp_str = cpl_sprintf("%s%s", recname_full, ".qc.fpn.ymin1");
1386 p = cpl_parameter_new_range(tmp_str, CPL_TYPE_INT,
1387 "Fixed Pattern Noise: qc_fpn_ymin1",
1388 recname_full,
1389 512, 1, ERIS_IFU_DETECTOR_SIZE_Y);
1390 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "qc_fpn_ymin1");
1391 cpl_parameterlist_append(pl, p);
1392 eris_ifu_free_string(&tmp_str);
1393
1394 tmp_str = cpl_sprintf("%s%s", recname_full, ".qc.fpn.ymax1");
1395 p = cpl_parameter_new_range(tmp_str, CPL_TYPE_INT,
1396 "Fixed Pattern Noise: qc_fpn_ymax1",
1397 recname_full,
1398 1536, 1, ERIS_IFU_DETECTOR_SIZE_Y);
1399 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "qc_fpn_ymax1");
1400 cpl_parameterlist_append(pl, p);
1401 eris_ifu_free_string(&tmp_str);
1402
1403 tmp_str = cpl_sprintf("%s%s", recname_full, ".qc.fpn.xmin2");
1404 p = cpl_parameter_new_range(tmp_str, CPL_TYPE_INT,
1405 "Fixed Pattern Noise: qc_fpn_xmin2",
1406 recname_full,
1407 1350, 1, ERIS_IFU_DETECTOR_SIZE_X);
1408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "qc_fpn_xmin2");
1409 cpl_parameterlist_append(pl, p);
1410 eris_ifu_free_string(&tmp_str);
1411
1412 tmp_str = cpl_sprintf("%s%s", recname_full, ".qc.fpn.xmax2");
1413 p = cpl_parameter_new_range(tmp_str, CPL_TYPE_INT,
1414 "Fixed Pattern Noise: qc_fpn_xmax2",
1415 recname_full,
1416 1390, 1, ERIS_IFU_DETECTOR_SIZE_X);
1417 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "qc_fpn_xmax2");
1418 cpl_parameterlist_append(pl, p);
1419 eris_ifu_free_string(&tmp_str);
1420
1421 tmp_str = cpl_sprintf("%s%s", recname_full, ".qc.fpn.ymin2");
1422 p = cpl_parameter_new_range(tmp_str, CPL_TYPE_INT,
1423 "Fixed Pattern Noise: qc_fpn_ymin2",
1424 recname_full,
1425 1000, 1, ERIS_IFU_DETECTOR_SIZE_Y);
1426 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "qc_fpn_ymin2");
1427 cpl_parameterlist_append(pl, p);
1428 eris_ifu_free_string(&tmp_str);
1429
1430 tmp_str = cpl_sprintf("%s%s", recname_full, ".qc.fpn.ymax2");
1431 p = cpl_parameter_new_range(tmp_str, CPL_TYPE_INT,
1432 "Fixed Pattern Noise: qc_fpn_ymax2",
1433 recname_full,
1434 1200, 1, ERIS_IFU_DETECTOR_SIZE_Y);
1435 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "qc_fpn_ymax2");
1436 cpl_parameterlist_append(pl, p);
1437 eris_ifu_free_string(&tmp_str);
1438 }
1439 CATCH
1440 {
1441 CATCH_MSGS();
1442 err = cpl_error_get_code();
1445 }
1446 eris_ifu_free_string(&tmp_str);
1447 eris_ifu_free_string(&recname_full);
1448 eris_check_error_code("eris_parlist_config_add_flat");
1449 return err;
1450}
1451
1474cpl_vector* eris_ifu_polyfit_1d(const cpl_vector *x,
1475 const cpl_vector *y,
1476 const int degree)
1477{
1478 cpl_vector *fit_par = NULL;
1479 cpl_polynomial *poly_coeff = NULL;
1480 cpl_matrix *x_matrix = NULL;
1481 double *pfit_par = NULL,
1482 *px = NULL;
1483 cpl_size k = 0,
1484 mindeg1d = 0, //1,
1485 maxdeg1d = degree;
1486
1487 const cpl_boolean sampsym = CPL_FALSE;
1488
1489 cpl_ensure(x, CPL_ERROR_NULL_INPUT, NULL);
1490 cpl_ensure(y, CPL_ERROR_NULL_INPUT, NULL);
1491 cpl_ensure(degree > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1492
1493 TRY
1494 {
1495
1496 //
1497 // setup data for fitting
1498 //
1499 poly_coeff = cpl_polynomial_new(1);
1500
1501 // put x-vector into a matrix (cast away constness of x: is okay since
1502 // data is wrapped into a matrix which is passed as const again)
1503 px = cpl_vector_get_data((cpl_vector*)x);
1504 x_matrix = cpl_matrix_wrap(1, cpl_vector_get_size(x), px);
1505
1506 //
1507 // fit 1d data
1508 //
1509 cpl_polynomial_fit(poly_coeff,
1510 x_matrix,
1511 &sampsym,
1512 y,
1513 NULL,
1514 CPL_FALSE,
1515 &mindeg1d,
1516 &maxdeg1d);
1517
1518 cpl_matrix_unwrap(x_matrix); x_matrix = NULL;
1520
1521 //
1522 // put fit coefficients into a vector to return
1523 //
1524 fit_par = cpl_vector_new(degree + 1);
1525 pfit_par = cpl_vector_get_data(fit_par);
1526
1527 for(k = 0; k <= degree; k++) {
1528 pfit_par[k] = cpl_polynomial_get_coeff(poly_coeff, &k);
1529 }
1530 }
1531 CATCH
1532 {
1533 eris_ifu_free_vector(&fit_par);
1534 }
1535
1536 cpl_matrix_unwrap(x_matrix); x_matrix = NULL;
1537 cpl_polynomial_delete(poly_coeff); poly_coeff = NULL;
1538 eris_check_error_code("eris_ifu_polyfit_1d");
1539 return fit_par;
1540}
1541
1542cpl_polynomial * eris_ifu_1d_polynomial_fit(
1543 int nPoints,
1544 double *xdata,
1545 double *ydata,
1546 int degree)
1547{
1548 cpl_polynomial *fit = NULL;
1549 cpl_matrix *x_pos = NULL;
1550 cpl_vector *values = NULL;
1551 TRY
1552 {
1553 fit = cpl_polynomial_new(1);
1554 if (nPoints < degree+1) {
1555 for (cpl_size power=0; power<=degree; power++) {
1556 cpl_polynomial_set_coeff(fit, &power, 0.0);
1557 }
1558
1559 } else {
1560 x_pos = cpl_matrix_wrap(1, nPoints, xdata);
1561 values = cpl_vector_wrap(nPoints, ydata);
1562 const cpl_boolean sampsym = CPL_FALSE;
1563 const cpl_size maxdeg1d = degree;
1564 cpl_polynomial_fit(fit, x_pos, &sampsym, values, NULL,
1565 CPL_FALSE, NULL, &maxdeg1d);
1566 }
1567 }
1568 CATCH
1569 {
1570 CATCH_MSGS();
1571 if (fit != NULL) {
1572 cpl_polynomial_delete(fit);
1573 }
1574 fit = NULL;
1575 }
1576
1577 if (x_pos != NULL) {
1578 cpl_matrix_unwrap(x_pos);
1579 }
1580 if (values != NULL) {
1581 cpl_vector_unwrap(values);
1582 }
1583 eris_check_error_code("eris_ifu_1d_polynomial_fit");
1584 return fit;
1585}
1586
1637 double *xIn,
1638 double *yIn,
1639 int nIn,
1640 double *xOut,
1641 double *yOut,
1642 int nOut,
1643 const int interType)
1644{
1645 cpl_error_code retVal = CPL_ERROR_NONE;
1646 const gsl_interp_type *interp;
1647 int gsl_status;
1648 gsl_error_handler_t * gslErrorHandler;
1649 double *xIn2 = NULL;
1650 double *yIn2 = NULL;
1651 int nIn2 = 0;
1652
1653 TRY
1654 {
1655 gslErrorHandler = gsl_set_error_handler_off();
1656
1657 ASSURE((xIn != NULL && yIn != NULL && xOut != NULL &&
1658 yOut != NULL),
1659 CPL_ERROR_NULL_INPUT, "no NULL pointer allowed for arrays");
1660 ASSURE((nIn > 0 && nOut > 0),
1661 CPL_ERROR_ILLEGAL_INPUT, "invalid array size input");
1662
1663 remove_2nans(nIn, xIn, yIn, &nIn2, &xIn2, &yIn2);
1664
1665 gsl_interp_accel *acc = gsl_interp_accel_alloc();
1666 if (interType > 2){
1667 const int nPoints = interType;
1668 interp = gsl_interp_polynomial;
1669 gsl_interp *workspace = gsl_interp_alloc(interp, nPoints);
1670 size_t sx;
1671 for (int rx = 0; rx < nOut; rx++) {
1672 sx = gsl_interp_accel_find(acc, xIn2, nIn2,
1673 xOut[rx]);
1674 if (sx > (size_t) (nPoints / 2)) {
1675 sx -= nPoints / 2;
1676 }
1677 if (((cpl_size) sx + nPoints) > nIn2) {
1678 sx = nIn2 - nPoints;
1679 }
1680 gsl_status = gsl_interp_init(workspace, &xIn2[sx], &yIn2[sx],
1681 nPoints);
1682 if (gsl_status != 0) {
1683 BRK_WITH_ERROR_MSG(CPL_ERROR_UNSPECIFIED,
1684 "GSL interpolation routine returned error %d: %s",
1685 gsl_status, gsl_strerror(gsl_status));
1686 }
1687 gsl_status = gsl_interp_eval_e(workspace, &xIn2[sx],
1688 &yIn2[sx], xOut[rx], acc, &yOut[rx]);
1689 if (gsl_status != 0 && gsl_status != GSL_EDOM) {
1690 BRK_WITH_ERROR_MSG(CPL_ERROR_UNSPECIFIED,
1691 "GSL interpolation routine returned error %d: %s",
1692 gsl_status, gsl_strerror(gsl_status));
1693 }
1694 }
1695 gsl_interp_free(workspace);
1696 } else {
1697 switch (interType) {
1698 case 2:
1699 interp = gsl_interp_linear;
1700 break;
1701 case -1:
1702 interp = gsl_interp_cspline;
1703 break;
1704 case -2:
1705 interp = gsl_interp_cspline_periodic;
1706 break;
1707 case -3:
1708 interp = gsl_interp_akima;
1709 break;
1710 case -4:
1711 interp = gsl_interp_akima_periodic;
1712 break;
1713 case -5:
1714 interp = gsl_interp_steffen;
1715 break;
1716 default:
1717 BRK_WITH_ERROR_MSG(CPL_ERROR_UNSUPPORTED_MODE,
1718 "unknown interpolation type %d", interType);
1719 }
1720 gsl_interp *workspace = gsl_interp_alloc(interp, nIn2);
1721
1722 gsl_status = gsl_interp_init(workspace, xIn2, yIn2, nIn2);
1723 if (gsl_status != 0) {
1724 BRK_WITH_ERROR_MSG(CPL_ERROR_UNSPECIFIED,
1725 "GSL interpolation routine returned error %d: %s",
1726 gsl_status, gsl_strerror(gsl_status));
1727 }
1728 for (int rx = 0; rx < nOut; rx++) {
1729 gsl_status = gsl_interp_eval_e(workspace, xIn2, yIn2,
1730 xOut[rx], acc, &yOut[rx]);
1731 if (gsl_status != 0 && gsl_status != GSL_EDOM) {
1732 BRK_WITH_ERROR_MSG(CPL_ERROR_UNSPECIFIED,
1733 "GSL interpolation routine returned error %d: %s",
1734 gsl_status, gsl_strerror(gsl_status));
1735 }
1736 }
1737 gsl_interp_free(workspace);
1738 }
1739 gsl_interp_accel_free(acc);
1740
1741 }
1742 CATCH
1743 {
1744 retVal = cpl_error_get_code();
1745 }
1746 gsl_set_error_handler(gslErrorHandler);
1749 eris_check_error_code("eris_ifu_1d_interpolation");
1750 return retVal;
1751}
1752
1753void remove_2nans(int size_in, double *xin, double *yin, int *size_out, double **xout, double **yout) {
1754 int no_valids = 0,
1755 ox = 0;
1756
1757 for (int i = 0; i < size_in; i++) {
1758 if ((! eris_ifu_is_nan_or_inf(xin[i])) && (! eris_ifu_is_nan_or_inf(yin[i]))) {
1759 // if ((kmclipm_is_nan_or_inf(xin[i]) == 0) && (kmclipm_is_nan_or_inf(yin[i]) == 0)) {
1760 no_valids++;
1761 }
1762 }
1763
1764 *size_out = no_valids;
1765 *xout = (double *) cpl_calloc(no_valids, sizeof(double));
1766 *yout = (double *) cpl_calloc(no_valids, sizeof(double));
1767
1768 ox = 0;
1769 for (int i = 0; i < size_in; i++) {
1770 if ((! eris_ifu_is_nan_or_inf(xin[i])) && (! eris_ifu_is_nan_or_inf(yin[i]))) {
1771 // if ((kmclipm_is_nan_or_inf(xin[i]) == 0) && (kmclipm_is_nan_or_inf(yin[i]) == 0)) {
1772 (*xout)[ox] = xin[i];
1773 (*yout)[ox] = yin[i];
1774 ox++;
1775 }
1776 }
1777 eris_check_error_code("remove_2nans");
1778 return;
1779}
1780
1781
1782// now in eris_ifu_vector.h/.c
1783//
1785// @brief Compute the mean value of vector elements ignoring NaN values.
1786// @param v Input const cpl_vector
1787// @return Mean value of vector elements or undefined on error.
1788// */
1789//double eris_ifu_vector_get_mean(const cpl_vector *v)
1790//{
1791// double sum = 0.,
1792// mean = 0.;
1793// const double *pv = NULL;
1794// int n = 0;
1795
1796// cpl_ensure(v != NULL, CPL_ERROR_NULL_INPUT, -1.0);
1797
1798// TRY
1799// {
1800// BRK_IF_NULL(
1801// pv = cpl_vector_get_data_const(v));
1802
1803// for (int i = 0; i < cpl_vector_get_size(v); i++) {
1804// if (!isnan(pv[i])) {
1805// sum += pv[i];
1806// n++;
1807// }
1808// }
1809// mean = sum / (double)n;
1810// }
1811// CATCH
1812// {
1813// CATCH_MSGS();
1814// mean = 0./0.;
1815// }
1816// return mean;
1817//}
1818
1827double eris_ifu_image_get_mean(const cpl_image *image)
1828{
1829 cpl_size nr_valid_pix = 0,
1830 nx = 0,
1831 ny = 0;
1832 const double *pimg = NULL;
1833 double mean = 0.0,
1834 sum = 0.0;
1835
1836 cpl_ensure(image != NULL, CPL_ERROR_NULL_INPUT, -1.0);
1837
1838 TRY
1839 {
1840 nx = cpl_image_get_size_x(image);
1841 ny = cpl_image_get_size_y(image);
1842 nr_valid_pix = nx * ny;
1843
1845 pimg = cpl_image_get_data_double_const(image));
1846
1847 for (int j = 0; j < ny; j++) {
1848 for (int i = 0; i < nx; i++) {
1849 if (isnan(pimg[i+j*nx]))
1850 nr_valid_pix--;
1851 else
1852 sum += pimg[i+j*nx];
1853 }
1854 }
1855 mean = sum / (double) nr_valid_pix;
1856 }
1857 CATCH
1858 {
1859 CATCH_MSGS();
1860 mean = 0.0;
1861 }
1862 eris_check_error_code("eris_ifu_image_get_mean");
1863 return mean;
1864}
1865
1866cpl_error_code eris_ifu_line_gauss_fit(
1867 const cpl_vector *yIn,
1868 int center,
1869 int range,
1870 struct gaussParStruct *gaussPar)
1871{
1872 cpl_error_code retVal = CPL_ERROR_NONE;
1873 int start = 0;
1874 double pos = 0.,
1875 sigma = 0.,
1876 area = 0.,
1877 offset = 0.,
1878 mserr = 0.,
1879 *yInData = NULL,
1880 *pxVec = NULL;
1881 const double *pyVec = NULL;
1882 cpl_vector *xVec = NULL,
1883 *yVec = NULL,
1884 *yIn2 = NULL;
1885
1886 cpl_ensure_code(yIn, CPL_ERROR_NULL_INPUT);
1887 cpl_ensure_code(cpl_vector_get_size(yIn) == ERIS_IFU_DETECTOR_SIZE,
1888 CPL_ERROR_ILLEGAL_INPUT);
1889
1890 TRY
1891 {
1892 try_again_fit:
1894 yIn2 = cpl_vector_duplicate(yIn));
1896 yInData = cpl_vector_get_data(yIn2));
1897
1898 // calc start position in vector-data
1899 start = center-(range/2);
1900
1901 if (start < 0) {
1902 // no negative starting points!
1903 start = 0;
1904 range -= start;
1905 } else if (start >= ERIS_IFU_DETECTOR_SIZE_X-ERIS_IFU_DETECTOR_BP_BORDER) {
1906 start = ERIS_IFU_DETECTOR_SIZE_X - ERIS_IFU_DETECTOR_BP_BORDER - 1;
1907 }
1908 if (start + range >= ERIS_IFU_DETECTOR_SIZE_X-ERIS_IFU_DETECTOR_BP_BORDER) {
1909 // start position + range to fit are larger than input data!
1910 // decrease range accordingly
1911 range = ERIS_IFU_DETECTOR_SIZE_X-ERIS_IFU_DETECTOR_BP_BORDER - start;
1912 }
1914 yVec = cpl_vector_wrap(range, &yInData[start]));
1915
1917 pyVec = cpl_vector_get_data_const(yVec));
1918
1920 xVec = cpl_vector_new(range));
1922 pxVec = cpl_vector_get_data(xVec));
1923 for (int ix=0; ix<range; ix++) {
1924 pxVec[ix] = start + ix;
1925 }
1926
1927 cpl_errorstate prestate = cpl_errorstate_get();
1928 retVal = cpl_vector_fit_gaussian(xVec, NULL, yVec, NULL, CPL_FIT_ALL,
1929 &pos, &sigma, &area, &offset, &mserr, NULL, NULL);
1930
1931 gaussPar->errorCode = (int) retVal;
1932 if ((retVal == CPL_ERROR_NONE) ||
1933 ((retVal == CPL_ERROR_CONTINUE) &&
1934 (((pos > 2042) && (pos < ERIS_IFU_DETECTOR_SIZE_X-ERIS_IFU_DETECTOR_BP_BORDER)) ||
1935 ((pos < 7) && (pos >= ERIS_IFU_DETECTOR_BP_BORDER)))))
1936 {
1937 // retVal is perhaps bad, but fit is close enough for continuing
1938 if (retVal == CPL_ERROR_CONTINUE) {
1939 cpl_errorstate_set(prestate);
1940 retVal = CPL_ERROR_NONE;
1941 }
1942
1943 gaussPar->x0 = pos;
1944 gaussPar->sigma = sigma;
1945 gaussPar->area = area;
1946 gaussPar->offset = offset;
1947 gaussPar->peak = area / sqrt(2 * CPL_MATH_PI * sigma * sigma);
1948 gaussPar->mse = mserr;
1949
1950 } else {
1951 gaussPar->x0 = 0.;
1952 gaussPar->sigma = 0.;
1953 gaussPar->area = 0.;
1954 gaussPar->offset = 0.;
1955 gaussPar->peak = 0.;
1956 gaussPar->mse = 0.;
1957 }
1958
1959 if (retVal == CPL_ERROR_CONTINUE) {
1960 // Recover from "The iterative process did not converge" error
1961 cpl_errorstate_set(prestate);
1962 retVal = CPL_ERROR_NONE;
1963
1964 const int decrement = 9;
1965 if ((range - decrement) > 2) {
1966 range -= decrement; // decrease range,
1967 // in doubt that some artifact is disturbing the fit
1968 cpl_vector_unwrap(yVec); yVec = NULL;
1969 eris_ifu_free_vector(&xVec);
1970 eris_ifu_free_vector(&yIn2);
1971
1972 goto try_again_fit;
1973 }
1974 }
1975
1976 if (range <= GAUSS_PAR_RANGE_MAX) {
1977 for (int ix=0; ix<range; ix++) {
1978 gaussPar->range = range;
1979 gaussPar->xdata[ix] = pxVec[ix];
1980 gaussPar->ydata[ix] = pyVec[ix];
1981 }
1982 }
1983 }
1984 CATCH
1985 {
1986 gaussPar->x0 = 0.;
1987 gaussPar->sigma = 0.;
1988 gaussPar->area = 0.;
1989 gaussPar->offset = 0.;
1990 gaussPar->peak = 0.;
1991 gaussPar->mse = 0.;
1992 if (range <= GAUSS_PAR_RANGE_MAX) {
1993 for (int ix=0; ix<range; ix++) {
1994 gaussPar->range = 0.;
1995 gaussPar->xdata[ix] = 0.;
1996 gaussPar->ydata[ix] = 0.;
1997 }
1998 }
1999 }
2000 eris_ifu_free_vector(&xVec);
2001 eris_ifu_free_vector(&yIn2);
2002 if (yVec != NULL) {
2003 cpl_vector_unwrap(yVec); yVec = NULL;
2004 }
2005 eris_check_error_code("eris_ifu_line_gauss_fit");
2006 return retVal;
2007}
2008
2012cpl_vector* eris_ifu_calc_centers_collapse_chunk(const cpl_image* img,
2013 int chunk_center,
2014 int height)
2015{
2016 cpl_size nx = 0,
2017 ny = 0,
2018 chunk_top = 0,
2019 chunk_bottom = 0;
2020 double *pcollapsed_img = NULL;
2021 cpl_vector *tmp = NULL,
2022 *collapsed = NULL;
2023 cpl_image *collapsed_img = NULL;
2024
2025 cpl_ensure(chunk_center > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2026 cpl_ensure(height > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2027 // height should be even
2028 cpl_ensure(height % 2 == 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2029 cpl_ensure(img, CPL_ERROR_NULL_INPUT, NULL);
2030
2031 TRY
2032 {
2033 nx = cpl_image_get_size_x(img);
2034 ny = cpl_image_get_size_y(img);
2035
2036 /* lower and upper limit of chunk in y */
2037 chunk_bottom = chunk_center - height/2;
2038 chunk_top = ny - (chunk_center + height/2);
2039
2040 /* collapse image in y and convert to vector */
2041 collapsed_img = cpl_image_collapse_median_create(img, 0,
2042 chunk_bottom,
2043 chunk_top);
2044 pcollapsed_img = cpl_image_get_data_double(collapsed_img);
2045 tmp = cpl_vector_wrap(nx, pcollapsed_img);
2046 collapsed = cpl_vector_duplicate(tmp);
2047 }
2048 CATCH
2049 {
2050 CATCH_MSGS();
2051 eris_ifu_free_vector(&collapsed);
2052 }
2053
2054 cpl_vector_unwrap(tmp); tmp = NULL;
2055 eris_ifu_free_image(&collapsed_img);
2056 eris_check_error_code("eris_ifu_calc_centers_collapse_chunk");
2057 return collapsed;
2058}
2059
2063cpl_vector* eris_ifu_image_collapse(const cpl_image* img)
2064{
2065 cpl_size nx = 0;
2066 double *pcollapsed_img = NULL;
2067 cpl_vector *tmp = NULL,
2068 *collapsed = NULL;
2069 cpl_image *collapsed_img = NULL;
2070
2071 cpl_ensure(img, CPL_ERROR_NULL_INPUT, NULL);
2072
2073 TRY
2074 {
2075 nx = cpl_image_get_size_x(img);
2076
2077 /* collapse image in y and convert to vector */
2078 collapsed_img = cpl_image_collapse_median_create(img, 0, 0, 0);
2079 pcollapsed_img = cpl_image_get_data_double(collapsed_img);
2080 tmp = cpl_vector_wrap(nx, pcollapsed_img);
2081 collapsed = cpl_vector_duplicate(tmp);
2082 }
2083 CATCH
2084 {
2085 CATCH_MSGS();
2086 eris_ifu_free_vector(&collapsed);
2087 }
2088
2089 cpl_vector_unwrap(tmp); tmp = NULL;
2090 eris_ifu_free_image(&collapsed_img);
2091 eris_check_error_code("eris_ifu_image_collapse");
2092 return collapsed;
2093}
2094
2108cpl_error_code eris_ifu_slitpos_gauss(const cpl_image *profile_x,
2109 double *left_edge_pos,
2110 double *right_edge_pos,
2111 int llx,
2112 int productDepth)
2113{
2114 cpl_error_code err = CPL_ERROR_NONE;
2115 cpl_vector *x_left = NULL,
2116 *x_right = NULL,
2117 *y_left = NULL,
2118 *y_right = NULL,
2119 *y_left2 = NULL,
2120 *y_right2 = NULL,
2121 *profile_x_v = NULL,
2122 *tmpVector = NULL;
2123 int s = 0,
2124 s2 = 0;
2125 double *px_left = NULL,
2126 *px_right = NULL,
2127 *py_left = NULL,
2128 *py_right = NULL,
2129 x0 = 0.,
2130 sigma = 0.,
2131 area = 0.,
2132 offset = 0.,
2133 median = 0.;
2134 const double *pprofile_x = NULL;
2135 cpl_size maxpos = 0,
2136 minpos = 0,
2137 inBetween = 0;
2138
2139 cpl_ensure_code(profile_x, CPL_ERROR_NULL_INPUT);
2140 cpl_ensure_code(left_edge_pos, CPL_ERROR_NULL_INPUT);
2141 cpl_ensure_code(right_edge_pos, CPL_ERROR_NULL_INPUT);
2142
2143 TRY
2144 {
2145 s = (int) cpl_image_get_size_x(profile_x);
2146 s2 = (int)(s/2);
2147
2148 // create x-Vector (profile_x goes into y :-)
2149 // one for the left edge with 0-47
2150 // one for the right edge with 47-95
2151 // split profile_x into two and convert to vector
2152 x_left = cpl_vector_new(s2);
2153 x_right = cpl_vector_new(s2);
2154 y_left = cpl_vector_new(s2);
2155 y_right = cpl_vector_new(s2);
2156
2157 px_left = cpl_vector_get_data(x_left);
2158 px_right = cpl_vector_get_data(x_right);
2159 py_left = cpl_vector_get_data(y_left);
2160 py_right = cpl_vector_get_data(y_right);
2161
2162 //erw
2163 // BRK_IF_NULL(
2164 // pprofile_x = cpl_image_get_data_double_const(profile_x));
2165 tmpVector = cpl_vector_new_from_image_row(profile_x,1);
2166 profile_x_v = cpl_vector_filter_lowpass_create(
2167 tmpVector, CPL_LOWPASS_LINEAR, 2);
2168 eris_ifu_free_vector(&tmpVector);
2169 pprofile_x = cpl_vector_get_data(profile_x_v);
2170
2171 for (int i = 0; i < s2; i++) {
2172 px_left[i] = i;
2173 // subtract left value from right value (we need a positive peak)
2174 py_left[i] = pprofile_x[i+1] - pprofile_x[i];
2175 px_right[i] = i+s2+1;
2176 // subtract right value from left value (we need a positive peak)
2177 py_right[i] = pprofile_x[i+s2-1] - pprofile_x[i+s2];
2178 }
2179
2180 y_left2 = cpl_vector_filter_lowpass_create(y_left,
2181 CPL_LOWPASS_GAUSSIAN, 5);
2182 y_right2 = cpl_vector_filter_lowpass_create(y_right,
2183 CPL_LOWPASS_GAUSSIAN, 5);
2184
2185 // check that left differences don't start with a negative peak
2186 if (cpl_vector_get_min(y_left2) < -100) {
2187 maxpos = cpl_vector_get_maxpos(y_left2);
2188 cpl_vector *tmpVec = cpl_vector_extract(y_left2,0,maxpos,1);
2189 minpos = cpl_vector_get_minpos(tmpVec);
2190 cpl_vector_delete(tmpVec);
2191 median = cpl_vector_get_median_const(y_left2);
2192 if (cpl_vector_get(y_left2,minpos < median-10.)) {
2193 // if (maxpos > minpos) {
2194 // negative peak is to the left --> arc lamp from other slitlet
2195 inBetween = (cpl_size) (((double) (maxpos + minpos) / 2.) + .5);
2196 for (cpl_size vx = 0; vx < inBetween; vx++) {
2197 if (cpl_vector_get(y_left2, vx) < -10.) {
2198 cpl_vector_set(y_left2, vx, median);
2199 }
2200 }
2201 minpos = cpl_vector_get_minpos(y_left2);
2202 if (cpl_vector_get(y_left2,minpos < median-10.)) {
2203 inBetween = (cpl_size) (((double)(maxpos + minpos) / 2.) + .5);
2204 for (cpl_size vx = inBetween;
2205 vx < cpl_vector_get_size(y_left2); vx++) {
2206 if (cpl_vector_get(y_left2, vx) < -10.) {
2207 cpl_vector_set(y_left2, vx, median);
2208 }
2209 }
2210
2211 }
2212
2213 //BRK_WITH_ERROR(CPL_ERROR_EOL);
2214 } else {
2215 cpl_size vSize = cpl_vector_get_size(y_left2);
2216 for (cpl_size vx = maxpos; vx < vSize; vx++) {
2217 if (cpl_vector_get(y_left2, vx) < -10.) {
2218 cpl_vector_set(y_left2, vx, median);
2219 }
2220 }
2221 }
2222 }
2224
2225 // check that right differences don't end with a negative peak
2226 if (cpl_vector_get_min(y_right2) < -100.) {
2227 maxpos = cpl_vector_get_maxpos(y_right2);
2228 minpos = cpl_vector_get_minpos(y_right2);
2229 median = cpl_vector_get_median_const(y_right2);
2230 if (maxpos < minpos) {
2231 // negative peak is to the right--> arc lamp from other slitlet
2232 cpl_size vSize = cpl_vector_get_size(y_right2);
2233 inBetween = (cpl_size) (((double) (maxpos + minpos) / 2.) + .5);
2234 for (cpl_size vx = inBetween; vx < vSize; vx++) {
2235 if (cpl_vector_get(y_left2, vx) < -10.) {
2236 cpl_vector_set(y_left2, vx, median);
2237 }
2238 }
2239 BRK_WITH_ERROR(CPL_ERROR_EOL);
2240 } else {
2241 for (cpl_size vx=maxpos; vx<=0; vx--) {
2242 if (cpl_vector_get(y_right2, vx) < -10.) {
2243 cpl_vector_set(y_right2, vx, median);
2244 }
2245 }
2246 }
2247 }
2249
2250 if (productDepth & 8) {
2251 cpl_propertylist *pl = NULL;
2253 "eris_ifu_distortion_dbg_slitpos_profile_left_xy.fits",
2254 CPL_IO_CREATE, pl);
2256 "eris_ifu_distortion_dbg_slitpos_profile_left_xy.fits",
2257 CPL_IO_EXTEND, pl);
2259 "eris_ifu_distortion_dbg_slitpos_profile_right_xy.fits",
2260 CPL_IO_CREATE, pl);
2262 "eris_ifu_distortion_dbg_slitpos_profile_right_xy.fits",
2263 CPL_IO_EXTEND, pl);
2265 "eris_ifu_distortion_dbg_slitpos_profile_left_xy.fits",
2266 CPL_IO_EXTEND, pl);
2267 eris_ifu_save_vector_dbg(y_right2,
2268 "eris_ifu_distortion_dbg_slitpos_profile_right_xy.fits",
2269 CPL_IO_EXTEND, pl);
2270 }
2271
2272
2273 // fit gauss-function to left edge
2274 // cpl_msg_debug(cpl_func, " === FIT LEFT EDGE ======"
2275 // "=======================");
2276 err = eris_ifu_fit_gauss(x_left, y_left2, &x0, &sigma, &area, &offset);
2277 if (err != CPL_ERROR_NONE) {
2278 eris_ifu_free_vector(&profile_x_v);
2279 eris_ifu_free_vector(&tmpVector);
2280 eris_ifu_free_vector(&x_left);
2281 eris_ifu_free_vector(&x_right);
2282 eris_ifu_free_vector(&y_left);
2283 eris_ifu_free_vector(&y_right);
2284 eris_ifu_free_vector(&y_left2);
2285 eris_ifu_free_vector(&y_right2);
2286 return err;
2287 }
2288
2289 if (sigma > 25) {
2290 BRK_WITH_ERROR(CPL_ERROR_EOL);
2291 }
2292 // correct half pixel because of subtraction of y-values at beginning
2293 *left_edge_pos = llx + x0 + 0.5;
2294
2295 // fit gauss-function to right edge
2296 // cpl_msg_debug(cpl_func, " === FIT RIGHT EDGE ============================");
2297 err = eris_ifu_fit_gauss(x_right, y_right2, &x0, &sigma, &area, &offset);
2298 if (err != CPL_ERROR_NONE) {
2299 eris_ifu_free_vector(&profile_x_v);
2300 eris_ifu_free_vector(&tmpVector);
2301 eris_ifu_free_vector(&x_left);
2302 eris_ifu_free_vector(&x_right);
2303 eris_ifu_free_vector(&y_left);
2304 eris_ifu_free_vector(&y_right);
2305 eris_ifu_free_vector(&y_left2);
2306 eris_ifu_free_vector(&y_right2);
2307 return err;
2308 }
2309
2310 if (sigma > 25) {
2311 BRK_WITH_ERROR(CPL_ERROR_EOL);
2312 }
2313 // correct half pixel because of subtraction of y-values at beginning
2314 *right_edge_pos = llx + x0 - 0.5;
2315
2316 // cpl_msg_debug(cpl_func, "left/right edge : %g / %g",
2317 // *left_edge_pos, *right_edge_pos);
2318 }
2319 CATCH
2320 {
2321 err = cpl_error_get_code();
2322 if (err != CPL_ERROR_EOL) {
2323 CATCH_MSGS();
2324 }
2325 }
2326 eris_ifu_free_vector(&profile_x_v);
2327 eris_ifu_free_vector(&tmpVector);
2328 eris_ifu_free_vector(&x_left);
2329 eris_ifu_free_vector(&x_right);
2330 eris_ifu_free_vector(&y_left);
2331 eris_ifu_free_vector(&y_right);
2332 eris_ifu_free_vector(&y_left2);
2333 eris_ifu_free_vector(&y_right2);
2334 eris_check_error_code("eris_ifu_slitpos_gauss");
2335 return err;
2336}
2337
2347cpl_error_code eris_ifu_bpm_correction(hdrl_image *himg,
2348 hdrl_image *badPixelMaskImg)
2349{
2350 cpl_mask *m = cpl_mask_new(3,3); // 3x3 mask for filtering; use a cross pattern
2351 cpl_mask_set(m, 1,2, BAD_PIX);
2352 cpl_mask_set(m, 2,1, BAD_PIX);
2353 cpl_mask_set(m, 2,3, BAD_PIX);
2354 cpl_mask_set(m, 3,2, BAD_PIX);
2355
2356 cpl_image *filterd_image = cpl_image_duplicate(hdrl_image_get_image_const(himg));
2357 cpl_image_filter_mask(filterd_image, hdrl_image_get_image_const(himg), m, CPL_FILTER_AVERAGE,
2358 CPL_BORDER_FILTER);
2359
2360 cpl_image *filterd_error = cpl_image_duplicate(hdrl_image_get_error_const(himg));
2361 cpl_image *variance = cpl_image_duplicate(hdrl_image_get_error_const(himg));
2362 cpl_image_power(variance, 2.0);
2363 cpl_image_filter_mask(filterd_error, variance, m, CPL_FILTER_AVERAGE,
2364 CPL_BORDER_FILTER);
2365 cpl_image_delete(variance);
2366
2367 cpl_image_divide_scalar(filterd_error, (double) cpl_mask_count(m));
2368 cpl_image_power(filterd_error, 0.5);
2369
2370 if (badPixelMaskImg == NULL){
2371 cpl_image *badPixelMaskImg1 = cpl_image_new_from_mask(hdrl_image_get_mask_const(himg));
2372 cpl_image *badPixelMaskImg2 = cpl_image_cast(badPixelMaskImg1, CPL_TYPE_DOUBLE);
2373 cpl_image_delete(badPixelMaskImg1);
2374
2375 badPixelMaskImg = hdrl_image_new(
2377 hdrl_image_get_size_y(himg));
2378 hdrl_image_insert(badPixelMaskImg,
2379 badPixelMaskImg2, NULL, 1, 1);
2380
2381 cpl_image_delete(badPixelMaskImg2);
2382 }
2383
2384 cpl_image *filtered_mask = cpl_image_duplicate(hdrl_image_get_image_const(badPixelMaskImg));
2385
2386 cpl_mask_set(m, 2, 2, GOOD_PIX);
2387 cpl_image_filter_mask(filtered_mask, hdrl_image_get_image_const(badPixelMaskImg), m, CPL_FILTER_AVERAGE,
2388 CPL_BORDER_FILTER);
2389
2390
2391 // Get the places to be corrected
2392 double corr_thesh = 0.4;
2393 cpl_image_threshold(filtered_mask, corr_thesh, corr_thesh, 1.0, 0.0);
2394 cpl_image_multiply(filtered_mask, hdrl_image_get_image_const(badPixelMaskImg)); // To be corrected set to 1
2395 cpl_mask *corr_mask_t = cpl_mask_threshold_image_create(filtered_mask,-0.1, 0.1);
2396 cpl_mask_not(corr_mask_t);
2397 cpl_msg_info(__func__, "No. bad pixels to be corrected: %d", (int)cpl_mask_count(corr_mask_t));
2398 cpl_image_multiply(filterd_image, filtered_mask);
2399 cpl_image_multiply(filterd_error, filtered_mask);
2400
2401 cpl_image_subtract_scalar(filtered_mask, 1);
2402 cpl_image_multiply_scalar(filtered_mask, -1); // To be kept: set to 1;
2403 cpl_mask *corr_mask = cpl_mask_threshold_image_create(filtered_mask,-0.1, 0.1);
2404 cpl_mask_not(corr_mask);
2405 cpl_msg_debug(__func__, "No. bad pixels before correction: %d", (int)cpl_image_count_rejected(hdrl_image_get_image(himg)));
2406 cpl_mask_and(hdrl_image_get_mask(himg), corr_mask);
2407 cpl_mask_and(cpl_image_get_bpm(hdrl_image_get_error(himg)), corr_mask);
2408 cpl_msg_debug(__func__, "No. bad pixels after correction: %d", (int)cpl_image_count_rejected(hdrl_image_get_image(himg)));
2409
2410 cpl_image_multiply(hdrl_image_get_image(himg), filtered_mask);
2411 cpl_image_add(hdrl_image_get_image(himg), filterd_image);
2412
2413 cpl_image_multiply(hdrl_image_get_error(himg), filtered_mask);
2414 cpl_image_add(hdrl_image_get_error(himg), filterd_error);
2415
2416 cpl_image_multiply(hdrl_image_get_image(badPixelMaskImg), filtered_mask);
2417 cpl_mask_delete(m);
2418 cpl_image_delete(filtered_mask);
2419 cpl_image_delete(filterd_error);
2420 cpl_image_delete(filterd_image);
2421 cpl_mask_delete(corr_mask);
2422 cpl_mask_delete(corr_mask_t);
2423 eris_check_error_code("eris_ifu_bpm_correction");
2424 return cpl_error_get_code();
2425}
2426
2427double eris_ifu_auto_derot_corr(double alt, double rot)
2428{
2429 double za = 90.0-alt;
2430 double offset = -0.000379*za + 0.000500*pow(za,2);
2431 double alt_scale = 0.0467*za - 0.000265*pow(za,2);
2432 double pi = 3.14159265359;
2433 double derot_corr = offset + alt_scale * cos((rot - 15.4)*pi/180);
2434 eris_check_error_code("eris_ifu_auto_derot_corr");
2435 return derot_corr;
2436}
ifsInstrument eris_ifu_get_instrument(const cpl_propertylist *header)
Return the used instrument of the FITS file header.
#define BRK_WITH_ERROR(code)
Set a new CPL error, and exit the try-block.
#define ASSURE(condition, error,...)
error handling macro (from fors-pipeline)
#define BRK_IF_ERROR(function)
If function is or returns an error != CPL_ERROR_NONE, then the try-block is exited.
#define CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
#define BRK_WITH_ERROR_MSG(code,...)
Set a new CPL error, and exit the try-block.
#define CATCH_MSG()
Displays an error message.
#define TRY
Beginning of a TRY-block.
#define CATCH
End of a TRY-block, beginning of a CATCH-block.
#define BRK_IF_NULL(function)
If function is or returns a NULL pointer, then the try-block is exited.
#define CATCH_MSGS()
Displays an error message stack.
cpl_error_code eris_ifu_exposure_line_correction(cpl_image *image)
Perform line correction on a raw detector image.
cpl_error_code eris_ifu_slitpos_gauss(const cpl_image *profile_x, double *left_edge_pos, double *right_edge_pos, int llx, int productDepth)
eris_ifu_dist_slitpos_gauss
cpl_error_code eris_ifu_1d_interpolation(double *xIn, double *yIn, int nIn, double *xOut, double *yOut, int nOut, const int interType)
Perform 1D interpolation using GSL routines.
cpl_error_code eris_ifu_bpm_correction(hdrl_image *himg, hdrl_image *badPixelMaskImg)
eris_ifu_bpm_correction
cpl_vector * eris_ifu_calc_centers_collapse_chunk(const cpl_image *img, int chunk_center, int height)
hdrl_image * eris_ifu_load_exposure_frame(const cpl_frame *frame, int exposureCorrectionMode, cpl_image *dqi)
Read a raw detector exposure, perform some correction, add noise data.
cpl_vector * eris_ifu_image_collapse(const cpl_image *img)
cpl_error_code eris_ifu_calc_bpm(const cpl_parameterlist *pl, const char *recipe_name, hdrl_image *master_img, const hdrl_imagelist *imglist_on, cpl_mask **bpm2dMask, cpl_mask **bpm3dMask)
Create and apply 2D and/or 3D Badpixel-Mask based on parameter.
cpl_error_code eris_ifu_add_badpix_border(cpl_image *data, cpl_boolean add_ones, cpl_image *dqi)
Add image border frame to bad pixel map.
cpl_error_code eris_ifu_exposure_column_correction(cpl_image *image)
Perform column correction on a raw detector image.
cpl_vector * eris_ifu_polyfit_1d(const cpl_vector *x, const cpl_vector *y, const int degree)
An easy-to-handle wrapper to cpl_polynomial_fit() to fit a vector.
cpl_mask * eris_ifu_detect_crh(hdrl_image *image, int exposureCorrectionMode, hdrl_parameter *laCosmicParams, bool maskImage)
Detect Cosmic Ray Hits.
cpl_image * eris_ifu_calc_noise_map(const cpl_image *data, double gain, double readnoise)
Return an HDRL image containing a noise image.
cpl_error_code eris_ifu_saturation_detection(cpl_image *image, cpl_image *dqi)
Detect saturated pixel and mask them as bad pixels.
hdrl_image * eris_ifu_load_exposure_file(const char *filename, int exposureCorrectionMode, cpl_image *dqi)
Read a raw detector exposure, perform some correction, add noise data.
hdrl_imagelist * eris_ifu_load_exposure_frameset(const cpl_frameset *frameset, int exposureCorrectionMode)
Read a raw detector exposure, perform some correction, add noise data.
ifsInstrument eris_ifu_get_instrument_frame(cpl_frame *frame)
Return value of INSTRUME from a given input frame.
double eris_ifu_image_get_mean(const cpl_image *image)
‍**
hdrl_image * eris_ifu_raw_hdrl_image(const cpl_image *cplImage)
Return an HDRL image containing a noise image as well.
hdrl_image * eris_ifu_warp_polynomial_image(const hdrl_image *hdrlInImg, const cpl_polynomial *poly_u, const cpl_polynomial *poly_v)
eris_ifu_warp_polynomial_image
void eris_ifu_free_propertylist(cpl_propertylist **item)
free memory and set pointer to null
void eris_ifu_free_string(char **item)
free memory and set pointer to null
cpl_error_code eris_ifu_parameterlist_append_list(cpl_parameterlist *p1, const cpl_parameterlist *p2)
Append a parameterlist to another one.
void eris_ifu_free_double_array(double **item)
free memory and set pointer to null
void eris_ifu_free_vector(cpl_vector **item)
free memory and set pointer to null
cpl_error_code eris_ifu_save_vector_dbg(const cpl_vector *vec, const char *filename, int create, const cpl_propertylist *pl)
save vector
void eris_ifu_free_parameter(cpl_parameter **item)
free memory and set pointer to null
void eris_ifu_free_imagelist(cpl_imagelist **item)
free memory and set pointer to null
void eris_ifu_free_hdrl_image(hdrl_image **item)
free memory and set pointer to null
void eris_ifu_free_image(cpl_image **item)
free memory and set pointer to null
void eris_ifu_free_mask(cpl_mask **item)
free memory and set pointer to null
void eris_ifu_free_parameterlist(cpl_parameterlist **item)
free memory and set pointer to null
void eris_ifu_free_hdrl_parameter(hdrl_parameter **item)
free memory and set pointer to null
int eris_ifu_is_nan_or_inf(double A)
Checks if a value is nan, inf or -inf.
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
Definition: eris_utils.c:56
cpl_mask * hdrl_bpm_2d_compute(const hdrl_image *img_in, const hdrl_parameter *params)
Detect bad pixels on a single image with an iterative process.
Definition: hdrl_bpm_2d.c:1136
hdrl_parameter * hdrl_bpm_2d_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse parameter list to create input parameters for the BPM_2D.
Definition: hdrl_bpm_2d.c:896
hdrl_parameter * hdrl_bpm_2d_parameter_create_filtersmooth(double kappa_low, double kappa_high, int maxiter, cpl_filter_mode filter, cpl_border_mode border, int smooth_x, int smooth_y)
Creates BPM_2D Parameters object for HDRL_BPM_2D_FILTERSMOOTH.
Definition: hdrl_bpm_2d.c:137
cpl_parameterlist * hdrl_bpm_2d_parameter_create_parlist(const char *base_context, const char *prefix, const char *method_def, const hdrl_parameter *filtersmooth_def, const hdrl_parameter *legendresmooth_def)
Create parameter list for the BPM_2D computation.
Definition: hdrl_bpm_2d.c:798
hdrl_parameter * hdrl_bpm_2d_parameter_create_legendresmooth(double kappa_low, double kappa_high, int maxiter, int steps_x, int steps_y, int filter_size_x, int filter_size_y, int order_x, int order_y)
Creates BPM_2D Parameters object for HDRL_BPM_2D_LEGENDRESMOOTH.
Definition: hdrl_bpm_2d.c:191
cpl_parameterlist * hdrl_bpm_3d_parameter_create_parlist(const char *base_context, const char *prefix, const hdrl_parameter *defaults)
Create a parameter list for the BPM_3D computation.
Definition: hdrl_bpm_3d.c:231
cpl_imagelist * hdrl_bpm_3d_compute(const hdrl_imagelist *imglist, const hdrl_parameter *params)
detect bad pixels on a stack of identical images
Definition: hdrl_bpm_3d.c:409
hdrl_parameter * hdrl_bpm_3d_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse a parameterlist to create input parameters for the BPM_3D.
Definition: hdrl_bpm_3d.c:314
hdrl_parameter * hdrl_bpm_3d_parameter_create(double kappa_low, double kappa_high, hdrl_bpm_3d_method method)
Creates BPM Parameters object for the imagelist method.
Definition: hdrl_bpm_3d.c:108
hdrl_parameter * hdrl_collapse_sigclip_parameter_create(double kappa_low, double kappa_high, int niter)
create a parameter object for sigclipped mean
hdrl_parameter * hdrl_collapse_mode_parameter_create(double histo_min, double histo_max, double bin_size, hdrl_mode_type mode_method, cpl_size error_niter)
create a parameter object for the mode
cpl_parameterlist * hdrl_collapse_parameter_create_parlist(const char *base_context, const char *prefix, const char *method_def, hdrl_parameter *sigclip_def, hdrl_parameter *minmax_def, hdrl_parameter *mode_def)
Create parameters for the collapse.
hdrl_parameter * hdrl_collapse_minmax_parameter_create(double nlow, double nhigh)
create a parameter object for min-max rejected mean
hdrl_parameter * hdrl_flat_parameter_create(cpl_size filter_size_x, cpl_size filter_size_y, hdrl_flat_method method)
Creates FLAT Parameters object.
Definition: hdrl_flat.c:173
cpl_parameterlist * hdrl_flat_parameter_create_parlist(const char *base_context, const char *prefix, const hdrl_parameter *defaults)
Create a parameter list for the FLAT computation.
Definition: hdrl_flat.c:258
cpl_error_code hdrl_image_reject_from_mask(hdrl_image *self, const cpl_mask *map)
set bpm of hdrl_image
Definition: hdrl_image.c:407
cpl_mask * hdrl_image_get_mask(hdrl_image *himg)
get cpl bad pixel mask from image
Definition: hdrl_image.c:157
cpl_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
Definition: hdrl_image.c:131
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
Definition: hdrl_image.c:540
const cpl_mask * hdrl_image_get_mask_const(const hdrl_image *himg)
get cpl bad pixel mask from image
Definition: hdrl_image.c:175
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
Definition: hdrl_image.c:525
const cpl_image * hdrl_image_get_error_const(const hdrl_image *himg)
get error as cpl image
Definition: hdrl_image.c:144
cpl_error_code hdrl_image_insert(hdrl_image *self, const cpl_image *image, const cpl_image *error, cpl_size xpos, cpl_size ypos)
Copy cpl images into an hdrl image.
Definition: hdrl_image.c:715
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
Definition: hdrl_image.c:295
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:105
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:118
hdrl_image * hdrl_image_new(cpl_size nx, cpl_size ny)
create new zero filled hdrl image
Definition: hdrl_image.c:311
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
cpl_parameterlist * hdrl_lacosmic_parameter_create_parlist(const char *base_context, const char *prefix, const hdrl_parameter *defaults)
Create parameter list for the LaCosmic computation.
cpl_mask * hdrl_lacosmic_edgedetect(const hdrl_image *ima_in, const hdrl_parameter *params)
Detect bad-pixels / cosmic-rays on a single image.
hdrl_parameter * hdrl_lacosmic_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse parameterlist to create input parameters for the LaCosmic.
hdrl_parameter * hdrl_lacosmic_parameter_create(double sigma_lim, double f_lim, int max_iter)
Creates LaCosmic parameters object.
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter