CR2RE Pipeline Reference Manual 1.7.0
hdrl_spectrum.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2017 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#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27#include "hdrl_spectrum.h"
28
29#include "hdrl_DER_SNR.h"
30#include "hdrl_utils.h"
31
32#include <math.h>
33
42/*----------------------------------------------------------------------------*/
43
45/*-----------------------------------------------------------------------------
46 Private Functions
47 -----------------------------------------------------------------------------*/
48typedef cpl_error_code (* operate_image_mutable) (hdrl_image * self,
49 const hdrl_image * other);
50
51typedef cpl_error_code (* operate_image_scalar_mutable) (hdrl_image * self,
52 hdrl_value scalar);
53
54static inline cpl_error_code
55operate_spectra_flux_mutate(hdrl_spectrum1D * self,
56 const hdrl_spectrum1D * other,
57 operate_image_mutable func);
58
59static inline hdrl_spectrum1D *
60operate_spectra_flux_create(const hdrl_spectrum1D * self,
61 const hdrl_spectrum1D * other,
62 operate_image_mutable func);
63
64static inline cpl_error_code
65operate_spectra_scalar_flux_mutate(hdrl_spectrum1D * self,
66 hdrl_value scalar,
67 operate_image_scalar_mutable func);
68
69static inline hdrl_spectrum1D *
70operate_spectra_scalar_flux_create(const hdrl_spectrum1D * self,
71 hdrl_value scalar,
72 operate_image_scalar_mutable func);
73
74static inline
75hdrl_spectrum1D * hdrl_spectrum1D_wrap(hdrl_image * arg_flux,
76 cpl_array * wavelength,
77 hdrl_spectrum1D_wave_scale scale);
78
79static inline int compare_double(const void * a, const void * b);
80
81static inline cpl_boolean is_uniformly_sampled(const double * v, cpl_size sz,
82 double * bin);
83
84
85static inline cpl_boolean
86is_wlen_selected(const cpl_bivector * windows, const cpl_boolean is_internal,
87 const hdrl_data_t w);
88
89/*-----------------------------------------------------------------------------
90 Functions
91 -----------------------------------------------------------------------------*/
92
93/* ---------------------------------------------------------------------------*/
116/* ---------------------------------------------------------------------------*/
117hdrl_spectrum1D * hdrl_spectrum1D_create(const cpl_image * arg_flux,
118 const cpl_image * arg_flux_e,
119 const cpl_array * wavelength,
120 hdrl_spectrum1D_wave_scale wave_scale){
121
122 cpl_ensure(arg_flux != NULL && wavelength != NULL && arg_flux_e != NULL,
123 CPL_ERROR_NULL_INPUT, NULL);
124
125 cpl_ensure(cpl_image_get_size_y(arg_flux) == 1
126 && cpl_image_get_size_y(arg_flux_e) == 1,
127 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
128
129 cpl_ensure(cpl_image_get_size_x(arg_flux) == cpl_array_get_size(wavelength)
130 && cpl_image_get_size_x(arg_flux_e) == cpl_array_get_size(wavelength),
131 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
132
133 cpl_image * flux_error = cpl_image_cast(arg_flux_e, HDRL_TYPE_ERROR);
134 cpl_image * flux = cpl_image_cast(arg_flux, HDRL_TYPE_DATA);
135
136 hdrl_image * flux_img = hdrl_image_wrap(flux, flux_error, NULL, CPL_TRUE);
137 cpl_array * lambda = cpl_array_cast(wavelength, HDRL_TYPE_DATA);
138
139 return hdrl_spectrum1D_wrap(flux_img, lambda, wave_scale);
140}
141
142/* ---------------------------------------------------------------------------*/
159/* ---------------------------------------------------------------------------*/
161 calculate_analytic_spectrum_point func,
162 const cpl_array * wavelength,
163 hdrl_spectrum1D_wave_scale scale){
164
165 cpl_ensure(wavelength != NULL, CPL_ERROR_NULL_INPUT, NULL);
166 cpl_ensure(func != NULL, CPL_ERROR_NULL_INPUT, NULL);
167
168 cpl_size sx = cpl_array_get_size(wavelength);
169 cpl_image * flux = cpl_image_new(sx, 1, HDRL_TYPE_DATA);
170 cpl_image * flux_e = cpl_image_new(sx, 1, HDRL_TYPE_ERROR);
171
172 for(cpl_size i = 0; i < sx; ++i){
173 hdrl_data_t lambda = cpl_array_get(wavelength, i, NULL);
174 hdrl_value v = func(lambda);
175 cpl_image_set(flux, i + 1, 1, v.data);
176 cpl_image_set(flux_e, i + 1, 1, v.error);
177 }
178
179 hdrl_spectrum1D * to_ret =
180 hdrl_spectrum1D_create(flux, flux_e, wavelength, scale);
181
182 cpl_image_delete(flux);
183 cpl_image_delete(flux_e);
184
185 return to_ret;
186}
187
188/* ---------------------------------------------------------------------------*/
203/* ---------------------------------------------------------------------------*/
205 (const cpl_image * arg_flux,
206 const cpl_array * wavelength,
207 hdrl_spectrum1D_wave_scale scale){
208
209 cpl_ensure(arg_flux != NULL, CPL_ERROR_NULL_INPUT, NULL);
210
211 cpl_size sx = cpl_image_get_size_x(arg_flux);
212 cpl_size sy = cpl_image_get_size_y(arg_flux);
213
214 cpl_ensure(sy == 1 && sx > 0, CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
215
216 cpl_image * zero_errors = cpl_image_new(sx, sy, HDRL_TYPE_ERROR);
217 cpl_image_fill_window(zero_errors, 1, 1, sx, sy, 0.0);
218
219 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_create
220 (arg_flux, zero_errors, wavelength, scale);
221
222 cpl_image_delete(zero_errors);
223
224 return to_ret;
225
226}
227
228/* ---------------------------------------------------------------------------*/
249/* ---------------------------------------------------------------------------*/
251 (const cpl_image * arg_flux,
252 cpl_size half_window,
253 const cpl_array * wavelength,
254 hdrl_spectrum1D_wave_scale scale){
255 cpl_ensure(arg_flux != NULL, CPL_ERROR_NULL_INPUT, NULL);
256 cpl_ensure(wavelength != NULL, CPL_ERROR_NULL_INPUT, NULL);
257
258 cpl_size sx = cpl_image_get_size_x(arg_flux);
259 cpl_size sy = cpl_image_get_size_y(arg_flux);
260
261 cpl_ensure(sy == 1 && sx > 0, CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
262
263 cpl_image * flux = cpl_image_cast(arg_flux, HDRL_TYPE_DATA);
264
265 const hdrl_data_t * flux_data =
266 (const hdrl_data_t*)cpl_image_get_data_const(flux);
267 const cpl_mask * mask_in = cpl_image_get_bpm_const(flux);
268 const cpl_binary * msk_in =
269 mask_in == NULL ? NULL : cpl_mask_get_data_const(mask_in);
270
271 cpl_image * DER_SNR_errors = estimate_noise_DER_SNR
272 (flux_data, msk_in, wavelength, sx, half_window);
273
274 if(!DER_SNR_errors || cpl_error_get_code() != CPL_ERROR_NONE){
275 cpl_image_delete(flux);
276 cpl_image_delete(DER_SNR_errors);
277 return NULL;
278 }
279
280 /* DER_SNR_errors might contain more bad pixels than flux, e.g. 1 good pixel
281 * in position i that is surrounded by bad pixels
282 */
283 cpl_mask * msk = cpl_image_unset_bpm(DER_SNR_errors);
284 cpl_mask_delete(cpl_image_set_bpm(flux, msk));
285
286 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_create
287 (flux , DER_SNR_errors, wavelength, scale);
288
289 cpl_image_delete(DER_SNR_errors);
290 cpl_image_delete(flux);
291
292 return to_ret;
293}
294
295/* ---------------------------------------------------------------------------*/
301/* ---------------------------------------------------------------------------*/
302hdrl_spectrum1D * hdrl_spectrum1D_duplicate(const hdrl_spectrum1D* self)
303{
304 if(!self) return NULL;
305
306 hdrl_image * flux = hdrl_image_duplicate(self->flux);
307 cpl_array * lambdas = cpl_array_duplicate(self->wavelength);
308
309
310 return hdrl_spectrum1D_wrap(flux, lambdas, self->wave_scale);
311}
312
313
314/* ---------------------------------------------------------------------------*/
321/* ---------------------------------------------------------------------------*/
322void hdrl_spectrum1D_delete(hdrl_spectrum1D ** p_self){
323
324 if(!p_self) return;
325
326 hdrl_spectrum1D * spectrum = *p_self;
327
328 if(!spectrum) return;
329
330 cpl_array_delete(spectrum->wavelength);
331 hdrl_image_delete(spectrum->flux);
332 cpl_free(spectrum);
333
334 *p_self = NULL;
335}
336
342/* ---------------------------------------------------------------------------*/
343cpl_size hdrl_spectrum1D_get_size(const hdrl_spectrum1D * self){
344
345 if(!self) return 0;
346
347 return cpl_array_get_size(self->wavelength);
348}
349
355/* ---------------------------------------------------------------------------*/
356const hdrl_image*
357hdrl_spectrum1D_get_flux(const hdrl_spectrum1D * self){
358
359 if(!self) return NULL;
360
361 return self->flux;
362}
363
370/* ---------------------------------------------------------------------------*/
371hdrl_spectrum1D_wavelength
372hdrl_spectrum1D_get_wavelength(const hdrl_spectrum1D * self){
373
374 hdrl_spectrum1D_wavelength to_ret = {NULL, NULL,
375 hdrl_spectrum1D_wave_scale_linear};
376
377 cpl_ensure(self != NULL,
378 CPL_ERROR_NULL_INPUT, to_ret);
379
380 const hdrl_image * flux = hdrl_spectrum1D_get_flux(self);
381
382 const cpl_array * lambdas = self->wavelength;
383
384 const cpl_mask *
385 mask = cpl_image_get_bpm_const(hdrl_image_get_image_const(flux));
386
387 to_ret.bpm = mask;
388 to_ret.wavelength = lambdas;
389 to_ret.scale = hdrl_spectrum1D_get_scale(self);
390 return to_ret;
391}
392
398/* ---------------------------------------------------------------------------*/
399hdrl_spectrum1D_wave_scale
400hdrl_spectrum1D_get_scale(const hdrl_spectrum1D * self){
401 cpl_ensure(self != NULL,
402 CPL_ERROR_NULL_INPUT, hdrl_spectrum1D_wave_scale_linear);
403
404 return self->wave_scale;
405}
406
414/* ---------------------------------------------------------------------------*/
415hdrl_value
416hdrl_spectrum1D_get_flux_value(const hdrl_spectrum1D * self, int idx, int * rej){
417
418 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, ((hdrl_value){0.0, 0.0}));
419
420 const hdrl_image * flx = hdrl_spectrum1D_get_flux(self);
421
422 return hdrl_image_get_pixel(flx, idx + 1, 1, rej);
423}
424
432/* ---------------------------------------------------------------------------*/
433hdrl_data_t
434hdrl_spectrum1D_get_wavelength_value(const hdrl_spectrum1D * self, int idx, int * rej){
435
436 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, 0.0);
437
438 const hdrl_spectrum1D_wavelength lambdas =
440
441 const cpl_array * wlengs = lambdas.wavelength;
442 const hdrl_data_t to_ret = (hdrl_data_t) cpl_array_get(wlengs, idx, NULL);
443
444 if(rej){
445 const cpl_mask * msk = lambdas.bpm;
446 if(msk)
447 *rej = cpl_mask_get(msk, idx + 1, 1);
448 else
449 *rej = CPL_BINARY_0;
450 }
451
452 return to_ret;
453}
454
464/* ---------------------------------------------------------------------------*/
465hdrl_spectrum1D *
466hdrl_spectrum1D_div_spectrum_create(const hdrl_spectrum1D * num,
467 const hdrl_spectrum1D * den){
468 return operate_spectra_flux_create(num, den, hdrl_image_div_image);
469}
470
480/* ---------------------------------------------------------------------------*/
481hdrl_spectrum1D *
482hdrl_spectrum1D_mul_spectrum_create(const hdrl_spectrum1D * f1,
483 const hdrl_spectrum1D * f2){
484 return operate_spectra_flux_create(f1, f2, hdrl_image_mul_image);
485}
486
496/* ---------------------------------------------------------------------------*/
497hdrl_spectrum1D *
498hdrl_spectrum1D_add_spectrum_create(const hdrl_spectrum1D * f1,
499 const hdrl_spectrum1D * f2){
500 return operate_spectra_flux_create(f1, f2, hdrl_image_add_image);
501}
502
503
513/* ---------------------------------------------------------------------------*/
514hdrl_spectrum1D *
515hdrl_spectrum1D_sub_spectrum_create(const hdrl_spectrum1D * f1,
516 const hdrl_spectrum1D * f2){
517 return operate_spectra_flux_create(f1, f2, hdrl_image_sub_image);
518}
519
520
527/* ---------------------------------------------------------------------------*/
528cpl_error_code hdrl_spectrum1D_div_spectrum(hdrl_spectrum1D * self,
529 const hdrl_spectrum1D * other){
530 return operate_spectra_flux_mutate(self, other, hdrl_image_div_image);
531}
532
539/* ---------------------------------------------------------------------------*/
540cpl_error_code hdrl_spectrum1D_mul_spectrum(hdrl_spectrum1D * self,
541 const hdrl_spectrum1D * other){
542 return operate_spectra_flux_mutate(self, other, hdrl_image_mul_image);
543}
544
551/* ---------------------------------------------------------------------------*/
552cpl_error_code hdrl_spectrum1D_add_spectrum(hdrl_spectrum1D * self,
553 const hdrl_spectrum1D * other){
554 return operate_spectra_flux_mutate(self, other, hdrl_image_add_image);
555}
556
557
564/* ---------------------------------------------------------------------------*/
565cpl_error_code hdrl_spectrum1D_sub_spectrum(hdrl_spectrum1D * self,
566 const hdrl_spectrum1D * other){
567 return operate_spectra_flux_mutate(self, other, hdrl_image_sub_image);
568}
569
579/* ---------------------------------------------------------------------------*/
580hdrl_spectrum1D *
581hdrl_spectrum1D_div_scalar_create(const hdrl_spectrum1D * self,
582 hdrl_value scalar_operator){
583 return
584 operate_spectra_scalar_flux_create(self, scalar_operator, hdrl_image_div_scalar);
585}
586
596/* ---------------------------------------------------------------------------*/
597hdrl_spectrum1D *
598hdrl_spectrum1D_mul_scalar_create(const hdrl_spectrum1D * self,
599 hdrl_value scalar_operator){
600 return
601 operate_spectra_scalar_flux_create(self, scalar_operator, hdrl_image_mul_scalar);
602}
603
613/* ---------------------------------------------------------------------------*/
614hdrl_spectrum1D *
615hdrl_spectrum1D_add_scalar_create(const hdrl_spectrum1D * self,
616 hdrl_value scalar_operator){
617 return
618 operate_spectra_scalar_flux_create(self, scalar_operator, hdrl_image_add_scalar);
619}
620
630/* ---------------------------------------------------------------------------*/
631hdrl_spectrum1D *
632hdrl_spectrum1D_sub_scalar_create(const hdrl_spectrum1D * self,
633 hdrl_value scalar_operator){
634 return
635 operate_spectra_scalar_flux_create(self, scalar_operator, hdrl_image_sub_scalar);
636}
637
647/* ---------------------------------------------------------------------------*/
648hdrl_spectrum1D *
649hdrl_spectrum1D_pow_scalar_create(const hdrl_spectrum1D * self,
650 hdrl_value scalar_operator){
651 return
652 operate_spectra_scalar_flux_create(self, scalar_operator, hdrl_image_pow_scalar);
653}
654
664/* ---------------------------------------------------------------------------*/
665hdrl_spectrum1D *
666hdrl_spectrum1D_exp_scalar_create(const hdrl_spectrum1D * self,
667 hdrl_value scalar_operator){
668 return
669 operate_spectra_scalar_flux_create(self, scalar_operator, hdrl_image_exp_scalar);
670}
671
679/* ---------------------------------------------------------------------------*/
680cpl_error_code hdrl_spectrum1D_div_scalar(hdrl_spectrum1D * self,
681 hdrl_value scalar_operator){
682 return
683 operate_spectra_scalar_flux_mutate(self, scalar_operator, hdrl_image_div_scalar);
684}
685
686
694/* ---------------------------------------------------------------------------*/
695cpl_error_code hdrl_spectrum1D_mul_scalar(hdrl_spectrum1D * self,
696 hdrl_value scalar_operator){
697 return
698 operate_spectra_scalar_flux_mutate(self, scalar_operator, hdrl_image_mul_scalar);
699}
700
708/* ---------------------------------------------------------------------------*/
709cpl_error_code hdrl_spectrum1D_add_scalar(hdrl_spectrum1D * self,
710 hdrl_value scalar_operator){
711 return
712 operate_spectra_scalar_flux_mutate(self, scalar_operator, hdrl_image_add_scalar);
713}
714
722/* ---------------------------------------------------------------------------*/
723cpl_error_code hdrl_spectrum1D_sub_scalar(hdrl_spectrum1D * self,
724 hdrl_value scalar_operator){
725 return
726 operate_spectra_scalar_flux_mutate(self, scalar_operator, hdrl_image_sub_scalar);
727}
728
736/* ---------------------------------------------------------------------------*/
737cpl_error_code hdrl_spectrum1D_pow_scalar(hdrl_spectrum1D * self,
738 hdrl_value scalar_operator){
739 return
740 operate_spectra_scalar_flux_mutate(self, scalar_operator, hdrl_image_pow_scalar);
741}
742
750/* ---------------------------------------------------------------------------*/
751cpl_error_code hdrl_spectrum1D_exp_scalar(hdrl_spectrum1D * self,
752 hdrl_value scalar_operator){
753 return
754 operate_spectra_scalar_flux_mutate(self, scalar_operator, hdrl_image_exp_scalar);
755}
756
766/* ---------------------------------------------------------------------------*/
767cpl_error_code hdrl_spectrum1D_wavelength_mult_scalar_linear(hdrl_spectrum1D * self,
768 hdrl_data_t scale_linear)
769{
770 cpl_ensure_code(scale_linear > 0, CPL_ERROR_INCOMPATIBLE_INPUT);
771
772 if(self == NULL) return CPL_ERROR_NONE;
773
774 if(self->wave_scale == hdrl_spectrum1D_wave_scale_linear)
775 return cpl_array_multiply_scalar(self->wavelength, scale_linear);
776
777 return cpl_array_add_scalar(self->wavelength, log(scale_linear));
778}
779
791/* ---------------------------------------------------------------------------*/
792hdrl_spectrum1D *
794 hdrl_data_t scale_linear)
795{
796 if(!self) return NULL;
797
798 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_duplicate(self);
799
800 cpl_error_code fail =
802 if(fail){
803 hdrl_spectrum1D_delete(&to_ret);
804 }
805 return to_ret;
806}
807
815/* ---------------------------------------------------------------------------*/
816cpl_error_code hdrl_spectrum1D_wavelength_shift(hdrl_spectrum1D * self,
817 hdrl_data_t shift)
818{
819 if(!self) return CPL_ERROR_NONE;
820
821 return cpl_array_add_scalar(self->wavelength, shift);
822}
823
833/* ---------------------------------------------------------------------------*/
834hdrl_spectrum1D *
835hdrl_spectrum1D_wavelength_shift_create(const hdrl_spectrum1D * self,
836 hdrl_data_t shift){
837
838 if(!self) return NULL;
839
840 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_duplicate(self);
841
842 cpl_error_code fail = hdrl_spectrum1D_wavelength_shift(to_ret, shift);
843
844 if(fail){
845 hdrl_spectrum1D_delete(&to_ret);
846 }
847
848 return to_ret;
849}
850
858/* ---------------------------------------------------------------------------*/
859cpl_error_code hdrl_spectrum1D_wavelength_convert_to_linear(hdrl_spectrum1D * self){
860
861 if(self == NULL || self->wave_scale == hdrl_spectrum1D_wave_scale_linear)
862 return CPL_ERROR_NONE;
863
864 cpl_error_code fail = cpl_array_exponential(self->wavelength, CPL_MATH_E);
865 self->wave_scale = hdrl_spectrum1D_wave_scale_linear;
866 return fail;
867}
868
878/* ---------------------------------------------------------------------------*/
879hdrl_spectrum1D *
881
882 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_duplicate(self);
883 cpl_error_code fail = hdrl_spectrum1D_wavelength_convert_to_linear(to_ret);
884
885 if(fail){
886 hdrl_spectrum1D_delete(&to_ret);
887 }
888 return to_ret;
889}
890
897/* ---------------------------------------------------------------------------*/
898cpl_error_code hdrl_spectrum1D_wavelength_convert_to_log(hdrl_spectrum1D * self){
899
900 if(self == NULL || self->wave_scale == hdrl_spectrum1D_wave_scale_log)
901 return CPL_ERROR_NONE;
902
903 cpl_error_code fail = cpl_array_logarithm(self->wavelength, CPL_MATH_E);
904 self->wave_scale = hdrl_spectrum1D_wave_scale_log;
905 return fail;
906}
907
919/* ---------------------------------------------------------------------------*/
920hdrl_spectrum1D *
922
923 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_duplicate(self);
924 cpl_error_code fail = hdrl_spectrum1D_wavelength_convert_to_log(to_ret);
925
926 if(fail){
927 hdrl_spectrum1D_delete(&to_ret);
928 }
929 return to_ret;
930}
931
952/* ---------------------------------------------------------------------------*/
953hdrl_spectrum1D *
954hdrl_spectrum1D_select_wavelengths(const hdrl_spectrum1D * self,
955 const cpl_bivector * windows, const cpl_boolean is_internal){
956
957 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
958 cpl_ensure(windows != NULL, CPL_ERROR_NULL_INPUT, NULL);
959
960 const cpl_size sz = hdrl_spectrum1D_get_size(self);
961 cpl_size num_selected = 0;
962
963 for(cpl_size i = 0; i < sz; ++i){
964 const hdrl_data_t w = hdrl_spectrum1D_get_wavelength_value(self, i, NULL);
965 if(is_wlen_selected(windows, is_internal, w))
966 num_selected++;
967 }
968
969 if(num_selected == sz)
970 return hdrl_spectrum1D_duplicate(self);
971
972 cpl_ensure(num_selected > 0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
973
974 cpl_image * flux = cpl_image_new(num_selected, 1, HDRL_TYPE_DATA);
975 cpl_image * flux_e = cpl_image_new(num_selected, 1, HDRL_TYPE_ERROR);
976 cpl_array * wavs = cpl_array_new(num_selected, HDRL_TYPE_DATA);
977
978 cpl_size idx_this = 0;
979 for(cpl_size i = 0; i < sz; ++i){
980
981 int rej = 0;
982 const hdrl_data_t w = hdrl_spectrum1D_get_wavelength_value(self, i, NULL);
983 if(!is_wlen_selected(windows, is_internal, w)) continue;
984
985 hdrl_value v = hdrl_spectrum1D_get_flux_value(self, i, &rej);
986
987 if(!rej){
988 cpl_image_set(flux, idx_this + 1, 1, v.data);
989 cpl_image_set(flux_e, idx_this + 1, 1, v.error);
990 }
991 else{
992 cpl_image_reject(flux, idx_this + 1, 1);
993 cpl_image_reject(flux_e, idx_this + 1, 1);
994 }
995
996 cpl_array_set(wavs, idx_this, w);
997
998 idx_this++;
999 }
1000
1001 const hdrl_spectrum1D_wave_scale scale = hdrl_spectrum1D_get_scale(self);
1002 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_create(flux,flux_e, wavs, scale);
1003
1004 cpl_image_delete(flux);
1005 cpl_image_delete(flux_e);
1006 cpl_array_delete(wavs);
1007
1008 return to_ret;
1009}
1010
1024/* ---------------------------------------------------------------------------*/
1025hdrl_spectrum1D *
1026hdrl_spectrum1D_reject_pixels(const hdrl_spectrum1D * self,
1027 const cpl_array * bad_samples){
1028
1029 const cpl_size sz = cpl_array_get_size(bad_samples);
1030
1031 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1032 cpl_ensure(bad_samples != NULL, CPL_ERROR_NULL_INPUT, NULL);
1033 cpl_ensure(sz == hdrl_spectrum1D_get_size(self), CPL_ERROR_ILLEGAL_INPUT, NULL);
1034
1035 hdrl_image * flux = hdrl_image_duplicate(hdrl_spectrum1D_get_flux(self));
1036
1037 for(cpl_size i = 0; i < sz; ++i){
1038
1039 if(cpl_array_get_int(bad_samples, i, NULL))
1040 hdrl_image_reject(flux, i + 1, 1);
1041 }
1042
1043 const cpl_image * flx_cpl = hdrl_image_get_image(flux);
1044 const cpl_image * flx_e_cpl = hdrl_image_get_error(flux);
1045 hdrl_spectrum1D_wavelength wlen = hdrl_spectrum1D_get_wavelength(self);
1046
1047 hdrl_spectrum1D * to_ret =
1048 hdrl_spectrum1D_create(flx_cpl, flx_e_cpl,
1049 wlen.wavelength, wlen.scale);
1050
1051 hdrl_image_delete(flux);
1052 return to_ret;
1053}
1054
1072/* ---------------------------------------------------------------------------*/
1074 const hdrl_spectrum1D * self, const char * flux_col_name,
1075 const char* wavelength_col_name, const char * flux_e_col_name,
1076 const char * flux_bpm_col_name){
1077
1078 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1079 cpl_ensure(flux_col_name != NULL || wavelength_col_name != NULL,
1080 CPL_ERROR_NULL_INPUT, NULL);
1081
1082 cpl_size sz = hdrl_spectrum1D_get_size(self);
1083
1084 cpl_table * tb = cpl_table_new(sz);
1085 cpl_ensure(tb != NULL, CPL_ERROR_NULL_INPUT, NULL);
1086
1087 cpl_error_code fail = hdrl_spectrum1D_append_to_table
1088 (self, tb, flux_col_name, wavelength_col_name, flux_e_col_name,
1089 flux_bpm_col_name);
1090
1091 if(fail){
1092 cpl_table_delete(tb);
1093 tb = NULL;
1094 }
1095 return tb;
1096}
1097
1113/* ---------------------------------------------------------------------------*/
1115(const hdrl_spectrum1D * self, cpl_table * dest,
1116const char * flux_col_name, const char* wavelength_col_name,
1117const char * flux_e_col_name, const char * flux_bpm_col_name){
1118
1119 cpl_ensure_code(self != NULL && dest != NULL,CPL_ERROR_NULL_INPUT);
1120 cpl_ensure_code(flux_col_name != NULL || wavelength_col_name != NULL,
1121 CPL_ERROR_NULL_INPUT);
1122
1123 cpl_size cl_sz = cpl_table_get_nrow(dest);
1124 cpl_size sz = hdrl_spectrum1D_get_size(self);
1125
1126 cpl_ensure_code(sz == cl_sz, CPL_ERROR_INCOMPATIBLE_INPUT);
1127
1128 if(wavelength_col_name){
1129 double * lambdas = cpl_calloc(sz ,sizeof(double));
1130 for(cpl_size i = 0; i < sz; i++){
1131 lambdas[i] = hdrl_spectrum1D_get_wavelength_value(self, i, NULL);
1132 }
1133 cpl_error_code fail =
1134 cpl_table_wrap_double(dest, lambdas, wavelength_col_name);
1135
1136 if(fail){
1137 cpl_free(lambdas);
1138 return fail;
1139 }
1140 }
1141
1142 if(flux_col_name){
1143 double * flux = cpl_calloc(sz ,sizeof(double));
1144 for(cpl_size i = 0; i < sz; i++){
1145 flux[i] = hdrl_spectrum1D_get_flux_value(self, i, NULL).data;
1146 }
1147
1148 cpl_error_code fail = cpl_table_wrap_double(dest, flux, flux_col_name);
1149 if(fail){
1150 cpl_free(flux);
1151 return fail;
1152 }
1153 }
1154
1155 if(flux_e_col_name){
1156 double * e_flux = cpl_calloc(sz ,sizeof(double));
1157 for(cpl_size i = 0; i < sz; i++){
1158 e_flux[i] = hdrl_spectrum1D_get_flux_value(self, i, NULL).error;
1159 }
1160 cpl_error_code fail =
1161 cpl_table_wrap_double(dest, e_flux, flux_e_col_name);
1162
1163 if(fail){
1164 cpl_free(e_flux);
1165 return fail;
1166 }
1167 }
1168
1169 if(flux_bpm_col_name){
1170 int * bpm_flux = cpl_calloc(sz ,sizeof(int));
1171 for(cpl_size i = 0; i < sz; i++){
1172 hdrl_spectrum1D_get_flux_value(self, i, &bpm_flux[i]);
1173 }
1174 cpl_error_code fail =
1175 cpl_table_wrap_int(dest, bpm_flux, flux_bpm_col_name);
1176 if(fail){
1177 cpl_free(bpm_flux);
1178 return fail;
1179 }
1180 }
1181
1182 return CPL_ERROR_NONE;
1183}
1184
1198/* ---------------------------------------------------------------------------*/
1200(const cpl_table * self, const char * flux_col_name,
1201const char* wavelength_col_name, const char * flux_e_col_name,
1202const char * flux_bpm_col_name, hdrl_spectrum1D_wave_scale scale){
1203
1204 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
1205 cpl_ensure(flux_col_name != NULL, CPL_ERROR_NULL_INPUT, NULL);
1206 cpl_ensure(wavelength_col_name != NULL, CPL_ERROR_NULL_INPUT, NULL);
1207
1208 cpl_size sz = cpl_table_get_nrow(self);
1209
1210 cpl_ensure(sz > 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1211
1212 cpl_image * flux = cpl_image_new(sz, 1, HDRL_TYPE_DATA);
1213 cpl_image * flux_e = cpl_image_new(sz, 1, HDRL_TYPE_ERROR);
1214 cpl_array * lambdas = cpl_array_new(sz, HDRL_TYPE_DATA);
1215
1216
1217 for(cpl_size i = 0; i < sz; ++i){
1218 const double fx = cpl_table_get(self, flux_col_name, i, NULL);
1219 const double l = cpl_table_get(self, wavelength_col_name, i, NULL);
1220
1221 double fx_e = 0;
1222 if(flux_e_col_name)
1223 fx_e = cpl_table_get(self, flux_e_col_name, i, NULL);
1224
1225 int rej = 0;
1226 if(flux_bpm_col_name)
1227 rej = cpl_table_get_int(self, flux_bpm_col_name, i, NULL);
1228
1229 cpl_image_set(flux, i + 1, 1, fx);
1230
1231 if(rej)
1232 cpl_image_reject(flux, i + 1, 1);
1233
1234 cpl_image_set(flux_e, i + 1, 1, fx_e);
1235 cpl_array_set(lambdas, i, l);
1236 }
1237
1238 hdrl_spectrum1D * sp = hdrl_spectrum1D_create(flux, flux_e, lambdas, scale);
1239
1240 cpl_image_delete(flux);
1241 cpl_image_delete(flux_e);
1242 cpl_array_delete(lambdas);
1243 return sp;
1244}
1245
1246void hdrl_spectrum1D_save(const hdrl_spectrum1D * s, const char * fname){
1247 if(s == NULL) return;
1248 cpl_table * tb = hdrl_spectrum1D_convert_to_table(s, "FLX", "WLN", "FLX_E",
1249 "FLX_BPM");
1250 cpl_table_save(tb, NULL, NULL, fname, CPL_IO_CREATE);
1251 cpl_table_delete(tb);
1252}
1253
1260/* ---------------------------------------------------------------------------*/
1261cpl_boolean
1263 const cpl_array * w2){
1264 if(w1 == NULL && w2 == NULL) return CPL_TRUE;
1265
1266 if(w1 == NULL) return CPL_FALSE;
1267
1268 if(w2 == NULL) return CPL_FALSE;
1269
1270 cpl_size sz = cpl_array_get_size(w1);
1271 if(sz != cpl_array_get_size(w2)) return CPL_FALSE;
1272 for(cpl_size i = 0; i < sz; i++){
1273 const double wa = cpl_array_get(w1, i, NULL);
1274 const double wb = cpl_array_get(w2, i, NULL);
1275
1276 const double d = wa - wb;
1277 if(fabs(d) > 1e-10 * CPL_MIN(wa, wb)){
1278 return CPL_FALSE;
1279 }
1280 }
1281
1282 return CPL_TRUE;
1283}
1284
1291/* ---------------------------------------------------------------------------*/
1292cpl_boolean
1293hdrl_spectrum1D_are_spectra_compatible(const hdrl_spectrum1D_wavelength* s1,
1294 const hdrl_spectrum1D_wavelength* s2){
1295
1296 if(s1 == NULL && s2 == NULL) return CPL_TRUE;
1297
1298 if(s1 == NULL) return CPL_FALSE;
1299
1300 if(s2 == NULL) return CPL_FALSE;
1301
1302 if(s1->scale != s2->scale) return CPL_FALSE;
1303
1304 return hdrl_spectrum1D_are_wavelengths_compatible(s1->wavelength,
1305 s2->wavelength);
1306}
1307
1316/* ---------------------------------------------------------------------------*/
1317cpl_boolean hdrl_spectrum1D_is_uniformly_sampled(const hdrl_spectrum1D * self,
1318 double * bin){
1319
1320 *bin = 0.0;
1321
1322 if(self == NULL) return CPL_FALSE;
1323
1324 const cpl_size sz = hdrl_spectrum1D_get_size(self);
1325
1326 if(sz <= 2) return CPL_TRUE;
1327
1328 double * vd = cpl_calloc(sz, sizeof(double));
1329
1330 for(cpl_size i = 0; i < sz; ++i){
1331 vd[i] = hdrl_spectrum1D_get_wavelength_value(self, i, NULL);
1332 }
1333
1334 qsort(vd, sz, sizeof(double), compare_double);
1335
1336 cpl_boolean to_ret = is_uniformly_sampled(vd, sz, bin);
1337
1338 cpl_free(vd);
1339
1340 return to_ret;
1341
1342}
1343
1344/*-----------------------------------------------------------------------------
1345 Private Functions Implementation
1346 -----------------------------------------------------------------------------*/
1356/* ---------------------------------------------------------------------------*/
1357static inline cpl_error_code operate_spectra_flux_mutate(hdrl_spectrum1D * self,
1358 const hdrl_spectrum1D * other,
1359 operate_image_mutable func){
1360 cpl_ensure_code(self != NULL && other != NULL,
1361 CPL_ERROR_NULL_INPUT);
1362
1363 hdrl_spectrum1D_wavelength w_self = hdrl_spectrum1D_get_wavelength(self);
1364 hdrl_spectrum1D_wavelength w_other = hdrl_spectrum1D_get_wavelength(other);
1365 cpl_ensure_code(hdrl_spectrum1D_are_spectra_compatible(&w_self, &w_other),
1366 CPL_ERROR_INCOMPATIBLE_INPUT);
1367
1368 hdrl_image * f1 = self->flux;
1369 const hdrl_image * f2 = other->flux;
1370
1371 cpl_ensure_code(f1 != NULL && f2 != NULL,
1372 CPL_ERROR_NULL_INPUT);
1373
1374 func(f1, f2);
1375
1376 return CPL_ERROR_NONE;
1377}
1378
1388/* ---------------------------------------------------------------------------*/
1389static inline hdrl_spectrum1D *
1390operate_spectra_flux_create(const hdrl_spectrum1D * self,
1391 const hdrl_spectrum1D * other,
1392 operate_image_mutable func){
1393
1394 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_duplicate(self);
1395
1396 cpl_error_code fail = operate_spectra_flux_mutate(to_ret, other, func);
1397
1398 if(fail){
1399 hdrl_spectrum1D_delete(&to_ret);
1400 }
1401 return to_ret;
1402}
1403
1413/* ---------------------------------------------------------------------------*/
1414static inline cpl_error_code
1415operate_spectra_scalar_flux_mutate(hdrl_spectrum1D * self,
1416 hdrl_value scalar,
1417 operate_image_scalar_mutable func){
1418
1419 if(!self) return CPL_ERROR_NONE;
1420
1421 hdrl_image * f1 = self->flux;
1422
1423 cpl_ensure_code(f1 != NULL, CPL_ERROR_NULL_INPUT);
1424
1425 func(f1, scalar);
1426
1427 return CPL_ERROR_NONE;
1428}
1429
1439/* ---------------------------------------------------------------------------*/
1440static inline hdrl_spectrum1D *
1441operate_spectra_scalar_flux_create(const hdrl_spectrum1D * self,
1442 hdrl_value scalar,
1443 operate_image_scalar_mutable func){
1444
1445 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_duplicate(self);
1446
1447 cpl_error_code fail =
1448 operate_spectra_scalar_flux_mutate(to_ret, scalar, func);
1449
1450 if(fail){
1451 hdrl_spectrum1D_delete(&to_ret);
1452 }
1453
1454 return to_ret;
1455}
1456
1457static inline
1458hdrl_spectrum1D * hdrl_spectrum1D_wrap(hdrl_image * arg_flux,
1459 cpl_array * wavelength,
1460 hdrl_spectrum1D_wave_scale scale){
1461
1462 hdrl_spectrum1D * to_ret = cpl_calloc(1, sizeof(*to_ret));
1463
1464 to_ret->flux = arg_flux;
1465 to_ret->wavelength = wavelength;
1466 to_ret->wave_scale = scale;
1467 return to_ret;
1468}
1469
1470static inline
1471int compare_double(const void * a, const void * b){
1472 const double ad = *((const double *)a);
1473 const double bd = *((const double *)b);
1474 const double delta = ad - bd;
1475 if(delta > 0.0) return 1;
1476 if(delta < 0.0) return -1;
1477 return 0;
1478}
1479
1480#if HDRL_SIZEOF_DATA == 4
1481 const double wave_delta = 1.e-5;
1482#else
1483 const double wave_delta = 1.e-6;
1484#endif
1485
1486static inline
1487cpl_boolean is_uniformly_sampled(const double * v, cpl_size sz, double * bin){
1488
1489 const double d = v[1] - v[0];
1490 *bin = d;
1491 for(cpl_size i = 1; i < sz - 1; ++i){
1492 const double d2 = (v[i + 1] - v[i]);
1493 const double eps = (fabs(d2 - d) / d);
1494 if(eps > wave_delta){
1495 return CPL_FALSE;
1496 }
1497 }
1498
1499 return CPL_TRUE;
1500}
1501
1502
1503static inline cpl_boolean
1504is_contained_in_at_least_one_window(const cpl_bivector * windows, const hdrl_data_t w){
1505 const cpl_size sz = cpl_bivector_get_size(windows);
1506
1507 for(cpl_size i = 0; i < sz; ++i){
1508 const double wmin = cpl_vector_get(cpl_bivector_get_x_const(windows), i);
1509 const double wmax = cpl_vector_get(cpl_bivector_get_y_const(windows), i);
1510
1511 if(w >= wmin && w <= wmax) return CPL_TRUE;
1512 }
1513
1514 return CPL_FALSE;
1515}
1516
1517static inline cpl_boolean
1518is_wlen_selected(const cpl_bivector * windows, const cpl_boolean is_internal,
1519 const hdrl_data_t w){
1520
1521 if(is_internal) return is_contained_in_at_least_one_window(windows, w);
1522
1523 return !is_contained_in_at_least_one_window(windows, w);
1524
1525}
1526
hdrl_value hdrl_image_get_pixel(const hdrl_image *self, cpl_size xpos, cpl_size ypos, int *pis_rejected)
get pixel values of hdrl_image
Definition hdrl_image.c:559
cpl_error_code hdrl_image_sub_image(hdrl_image *self, const hdrl_image *other)
Subtract two images, store the result in the first image.
cpl_error_code hdrl_image_div_scalar(hdrl_image *self, hdrl_value value)
Elementwise division of an image with a scalar.
cpl_error_code hdrl_image_pow_scalar(hdrl_image *self, const hdrl_value exponent)
computes the power of an image by a scalar
cpl_error_code hdrl_image_add_image(hdrl_image *self, const hdrl_image *other)
Add two images, store the result in the first image.
cpl_error_code hdrl_image_div_image(hdrl_image *self, const hdrl_image *other)
Divide two images, store the result in the first image.
cpl_error_code hdrl_image_mul_scalar(hdrl_image *self, hdrl_value value)
Elementwise multiplication of an image with a scalar.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
Definition hdrl_image.c:391
cpl_error_code hdrl_image_add_scalar(hdrl_image *self, hdrl_value value)
Elementwise addition of a scalar to an image.
cpl_error_code hdrl_image_mul_image(hdrl_image *self, const hdrl_image *other)
Multiply two images, store the result in the first image.
cpl_error_code hdrl_image_exp_scalar(hdrl_image *self, const hdrl_value base)
computes the exponential of an image by a scalar
cpl_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
Definition hdrl_image.c:131
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition hdrl_image.c:105
cpl_error_code hdrl_image_reject(hdrl_image *self, cpl_size xpos, cpl_size ypos)
mark pixel as bad
Definition hdrl_image.c:427
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
Definition hdrl_image.c:118
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition hdrl_image.c:379
cpl_error_code hdrl_image_sub_scalar(hdrl_image *self, hdrl_value value)
Elementwise subtraction of a scalar from an image.
hdrl_spectrum1D * hdrl_spectrum1D_pow_scalar_create(const hdrl_spectrum1D *self, hdrl_value scalar_operator)
subtract a scalar from a spectrum
const hdrl_image * hdrl_spectrum1D_get_flux(const hdrl_spectrum1D *self)
hdrl_spectrum1D getter flux
cpl_error_code hdrl_spectrum1D_mul_scalar(hdrl_spectrum1D *self, hdrl_value scalar_operator)
computes the elementwise multiplication of a spectrum by a scalar, the self parameter is modified
cpl_error_code hdrl_spectrum1D_wavelength_mult_scalar_linear(hdrl_spectrum1D *self, hdrl_data_t scale_linear)
computes the elementwise multiplication of the scalar for the wavelength. The scalar is assumed to be...
cpl_error_code hdrl_spectrum1D_wavelength_convert_to_linear(hdrl_spectrum1D *self)
converts the wavelength scale to linear.
hdrl_spectrum1D * hdrl_spectrum1D_sub_spectrum_create(const hdrl_spectrum1D *f1, const hdrl_spectrum1D *f2)
subtract two spectra
cpl_error_code hdrl_spectrum1D_wavelength_shift(hdrl_spectrum1D *self, hdrl_data_t shift)
computes the elementwise shift of the wavelength by the shift parameter. The self parameter is modifi...
cpl_error_code hdrl_spectrum1D_div_spectrum(hdrl_spectrum1D *self, const hdrl_spectrum1D *other)
divide one spectrum by another spectrum
cpl_error_code hdrl_spectrum1D_pow_scalar(hdrl_spectrum1D *self, hdrl_value scalar_operator)
computes the elementwise power of the flux to the scalar, the self parameter is modified
hdrl_spectrum1D * hdrl_spectrum1D_mul_spectrum_create(const hdrl_spectrum1D *f1, const hdrl_spectrum1D *f2)
multiply one spectrum by another spectrum
hdrl_spectrum1D * hdrl_spectrum1D_duplicate(const hdrl_spectrum1D *self)
hdrl_spectrum1D copy constructor
cpl_size hdrl_spectrum1D_get_size(const hdrl_spectrum1D *self)
hdrl_spectrum1D getter for size
void hdrl_spectrum1D_delete(hdrl_spectrum1D **p_self)
hdrl_spectrum1D destructor
cpl_error_code hdrl_spectrum1D_mul_spectrum(hdrl_spectrum1D *self, const hdrl_spectrum1D *other)
multiply one spectrum by another spectrum
cpl_error_code hdrl_spectrum1D_wavelength_convert_to_log(hdrl_spectrum1D *self)
converts the wavelength scale to log. If the spectrum is already in log scale nothing is done.
hdrl_spectrum1D * hdrl_spectrum1D_div_spectrum_create(const hdrl_spectrum1D *num, const hdrl_spectrum1D *den)
divide one spectrum by another spectrum
cpl_error_code hdrl_spectrum1D_exp_scalar(hdrl_spectrum1D *self, hdrl_value scalar_operator)
computes the elementwise power of the scalar to the flux, the self parameter is modified
hdrl_spectrum1D * hdrl_spectrum1D_mul_scalar_create(const hdrl_spectrum1D *self, hdrl_value scalar_operator)
multiply a spectrum by a scalar
cpl_error_code hdrl_spectrum1D_sub_spectrum(hdrl_spectrum1D *self, const hdrl_spectrum1D *other)
subtract two spectra
hdrl_spectrum1D * hdrl_spectrum1D_wavelength_shift_create(const hdrl_spectrum1D *self, hdrl_data_t shift)
computes the elementwise shift of the wavelength by the shift parameter.
hdrl_spectrum1D * hdrl_spectrum1D_div_scalar_create(const hdrl_spectrum1D *self, hdrl_value scalar_operator)
divide a spectrum by a scalar
hdrl_spectrum1D * hdrl_spectrum1D_create_error_DER_SNR(const cpl_image *arg_flux, cpl_size half_window, const cpl_array *wavelength, hdrl_spectrum1D_wave_scale scale)
hdrl_spectrum1D constructor when no error information is available, in this case we use DER_SNR to es...
hdrl_spectrum1D * hdrl_spectrum1D_convert_from_table(const cpl_table *self, const char *flux_col_name, const char *wavelength_col_name, const char *flux_e_col_name, const char *flux_bpm_col_name, hdrl_spectrum1D_wave_scale scale)
convert a table to a spectrum
hdrl_spectrum1D * hdrl_spectrum1D_wavelength_convert_to_log_create(const hdrl_spectrum1D *self)
converts the wavelength scale to log. It returns a modified version of self. self is not modified....
cpl_boolean hdrl_spectrum1D_are_wavelengths_compatible(const cpl_array *w1, const cpl_array *w2)
checks if two wavelengths array are defined on the same wavelengths.
cpl_error_code hdrl_spectrum1D_sub_scalar(hdrl_spectrum1D *self, hdrl_value scalar_operator)
computes the elementwise subtraction of a spectrum by a scalar, the self parameter is modified
cpl_boolean hdrl_spectrum1D_is_uniformly_sampled(const hdrl_spectrum1D *self, double *bin)
checks if the spectrum is defined on uniformly sampled wavelengths.
hdrl_spectrum1D * hdrl_spectrum1D_create(const cpl_image *arg_flux, const cpl_image *arg_flux_e, const cpl_array *wavelength, hdrl_spectrum1D_wave_scale wave_scale)
hdrl_spectrum1D default constructor
cpl_error_code hdrl_spectrum1D_add_scalar(hdrl_spectrum1D *self, hdrl_value scalar_operator)
computes the elementwise addition of a spectrum by a scalar, the self parameter is modified
cpl_error_code hdrl_spectrum1D_add_spectrum(hdrl_spectrum1D *self, const hdrl_spectrum1D *other)
sum two spectra
hdrl_spectrum1D * hdrl_spectrum1D_exp_scalar_create(const hdrl_spectrum1D *self, hdrl_value scalar_operator)
subtract a scalar from a spectrum
hdrl_spectrum1D * hdrl_spectrum1D_sub_scalar_create(const hdrl_spectrum1D *self, hdrl_value scalar_operator)
subtract a scalar from a spectrum
hdrl_spectrum1D * hdrl_spectrum1D_wavelength_mult_scalar_linear_create(const hdrl_spectrum1D *self, hdrl_data_t scale_linear)
computes the elementwise multiplication of the scalar for the wavelength. The scalar is assumed to be...
hdrl_spectrum1D_wave_scale hdrl_spectrum1D_get_scale(const hdrl_spectrum1D *self)
hdrl_spectrum1D getter for scale
hdrl_spectrum1D_wavelength hdrl_spectrum1D_get_wavelength(const hdrl_spectrum1D *self)
hdrl_spectrum1D getter for wavelengths
hdrl_spectrum1D * hdrl_spectrum1D_create_error_free(const cpl_image *arg_flux, const cpl_array *wavelength, hdrl_spectrum1D_wave_scale scale)
hdrl_spectrum1D constructor in the case of error-free spectrum (i.e. the error on the flux is zero fo...
hdrl_spectrum1D * hdrl_spectrum1D_add_scalar_create(const hdrl_spectrum1D *self, hdrl_value scalar_operator)
add a scalar to a spectrum
hdrl_data_t hdrl_spectrum1D_get_wavelength_value(const hdrl_spectrum1D *self, int idx, int *rej)
hdrl_spectrum1D getter for a wavelength value
hdrl_spectrum1D * hdrl_spectrum1D_create_analytic(calculate_analytic_spectrum_point func, const cpl_array *wavelength, hdrl_spectrum1D_wave_scale scale)
hdrl_spectrum1D constructor in the case of a spectrum defined by an analytical function
cpl_error_code hdrl_spectrum1D_append_to_table(const hdrl_spectrum1D *self, cpl_table *dest, const char *flux_col_name, const char *wavelength_col_name, const char *flux_e_col_name, const char *flux_bpm_col_name)
append a spectrum to a table.
hdrl_spectrum1D * hdrl_spectrum1D_wavelength_convert_to_linear_create(const hdrl_spectrum1D *self)
converts the wavelength scale to linear.
cpl_table * hdrl_spectrum1D_convert_to_table(const hdrl_spectrum1D *self, const char *flux_col_name, const char *wavelength_col_name, const char *flux_e_col_name, const char *flux_bpm_col_name)
converts a spectrum in a table.
hdrl_spectrum1D * hdrl_spectrum1D_select_wavelengths(const hdrl_spectrum1D *self, const cpl_bivector *windows, const cpl_boolean is_internal)
the function selects or discards flux values according to whether the value of the corresponding wave...
hdrl_spectrum1D * hdrl_spectrum1D_add_spectrum_create(const hdrl_spectrum1D *f1, const hdrl_spectrum1D *f2)
sum one spectrum to another spectrum
cpl_error_code hdrl_spectrum1D_div_scalar(hdrl_spectrum1D *self, hdrl_value scalar_operator)
computes the elementwise division of a spectrum by a scalar, the self parameter is modified
cpl_image * estimate_noise_DER_SNR(const hdrl_data_t *flux_in, const cpl_binary *msk_in, const cpl_array *wavelengths, const cpl_size length, const cpl_size half_window)
For every pixel in position i in img_arg, the function estimates the noise using the pixels in the wi...
cpl_boolean hdrl_spectrum1D_are_spectra_compatible(const hdrl_spectrum1D_wavelength *s1, const hdrl_spectrum1D_wavelength *s2)
checks if two spectrum wavelengths are equal.
hdrl_spectrum1D * hdrl_spectrum1D_reject_pixels(const hdrl_spectrum1D *self, const cpl_array *bad_samples)
For every i-th element in bad_samples having value CPL_TRUE, the i-th pixel in the 1D spectrum is mar...
hdrl_value hdrl_spectrum1D_get_flux_value(const hdrl_spectrum1D *self, int idx, int *rej)
hdrl_spectrum1D getter for a flux value