28#include "hdrl_response.h"
29#include "hdrl_spectrum_resample.h"
30#include "hdrl_efficiency.h"
31#include "hdrl_utils.h"
39static inline cpl_array *
40get_uniform_wavs(
const hdrl_spectrum1D * s,
const hdrl_data_t w_step,
41 const hdrl_data_t lmin,
const hdrl_data_t lmax);
43static inline hdrl_xcorrelation_result *
44correlate_obs_with_telluric(
const hdrl_spectrum1D * obs_s,
45 const hdrl_spectrum1D * telluric_s,
46 const hdrl_data_t w_step,
48 const cpl_boolean normalize,
49 const hdrl_data_t lmin,
50 const hdrl_data_t lmax);
52static inline hdrl_spectrum1D *
53shift_and_convolve_telluric_model(
const hdrl_spectrum1D * obs,
54 const hdrl_spectrum1D * telluric,
55 const hdrl_data_t w_step,
56 const cpl_size half_win,
57 const cpl_boolean normalize,
58 const hdrl_data_t lmin,
59 const hdrl_data_t lmax,
60 double * telluric_shift);
62static inline cpl_size get_lower_odd(
const cpl_size sz);
64static inline hdrl_spectrum1D *
65convolve_with_kernel_symmetrically(
const hdrl_spectrum1D * s,
67 const hdrl_data_t w_step);
69static inline cpl_matrix *
70create_symmetrical_gaussian_kernel(
const double slitw,
const double fwhm,
71 const cpl_size max_sz);
73static inline hdrl_spectrum1D *
74convolve_spectrum_with_kernel(
const hdrl_spectrum1D * s,
75 const cpl_matrix * kernel);
78erf_antideriv(
const double x,
const double sigma);
82static inline hdrl_spectrum1D *
83compute_corrected_obs_spectrum(
84 const hdrl_spectrum1D * obs_s_arg,
85 const hdrl_spectrum1D * telluric_s_arg,
86 const hdrl_data_t w_step,
87 const cpl_size half_win,
88 const cpl_boolean normalize,
89 const cpl_boolean shift_in_log_scale,
90 const hdrl_data_t lmin,
const hdrl_data_t lmax,
91 double * telluric_shift);
93static inline hdrl_spectrum1D *
94compute_interpolated_spectrum(
const hdrl_spectrum1D * wlength_source,
95 const hdrl_spectrum1D * sampled_points,
96 const hdrl_spectrum1D_interpolation_method method);
99compute_quality(
const hdrl_spectrum1D * s,
100 const cpl_bivector * quality_areas,
double * mean_abs_difference_from_1,
104free_spectrum_array(hdrl_spectrum1D ** s,
const cpl_size sz);
106static inline cpl_error_code
107get_first_error_code(
const cpl_error_code * codes,
const cpl_size sz);
109static inline hdrl_spectrum1D *
110select_win(
const hdrl_spectrum1D * s,
const hdrl_data_t wmin,
111 const hdrl_data_t wmax);
113static inline hdrl_spectrum1D *
114select_obs_wlen(
const hdrl_spectrum1D * s,
115 const hdrl_spectrum1D * wlens_source);
117static inline hdrl_spectrum1D *
118correct_spectrum_for_doppler_shift(
const hdrl_spectrum1D * s,
119 const hdrl_data_t offset);
121static inline hdrl_spectrum1D *
122filter_spectrum_median(
const hdrl_spectrum1D * resp,
const cpl_size radius);
124static inline hdrl_image *
125compute_median_on_hdrl_image(
const hdrl_image * img,
const cpl_size radius);
127static inline hdrl_spectrum1D *
128resample_on_medians_skip_abs_regions(
const hdrl_spectrum1D * s,
129 const cpl_array * fit_points,
const cpl_bivector * high_abs_regions,
130 const hdrl_data_t wrange);
132static inline cpl_array *
133remove_regions_and_outliers_from_array(
const cpl_array * fit_points,
134 const cpl_bivector * high_abs_regions,
135 const hdrl_data_t wmin,
const hdrl_data_t wmax);
137static inline cpl_boolean
138contained_in_any_region(
const hdrl_data_t w,
const cpl_bivector * high_abs_regions);
140static inline hdrl_spectrum1D *
141get_median_on_fit_points(
const hdrl_spectrum1D * s_input,
142 const cpl_array * fit_points,
const hdrl_data_t wrange);
144static inline hdrl_spectrum1D *
145remove_bad_data(
const hdrl_spectrum1D * s);
147static inline const hdrl_spectrum1Dlist *
148hdrl_response_telluric_evaluation_parameter_get_telluric_models(
149 const hdrl_parameter * par);
151static inline hdrl_data_t
152hdrl_response_telluric_evaluation_parameter_get_w_step(
153 const hdrl_parameter * par);
155static inline cpl_size
156hdrl_response_telluric_evaluation_parameter_get_half_win(
157 const hdrl_parameter * par);
159static inline cpl_boolean
160hdrl_response_telluric_evaluation_parameter_get_normalize(
161 const hdrl_parameter * par);
163static inline cpl_boolean
164hdrl_response_telluric_evaluation_parameter_get_shift_in_log_scale(
165 const hdrl_parameter * par);
167static inline const cpl_bivector *
168hdrl_response_telluric_evaluation_parameter_get_quality_areas(
169 const hdrl_parameter * par);
171static inline const cpl_bivector *
172hdrl_response_telluric_evaluation_parameter_get_fit_areas(
173 const hdrl_parameter * par);
175static inline hdrl_data_t
176hdrl_response_telluric_evaluation_parameter_get_lmin(
177 const hdrl_parameter * par);
179static inline hdrl_data_t
180hdrl_response_telluric_evaluation_parameter_get_lmax(
181 const hdrl_parameter * par);
183static inline const cpl_array *
184hdrl_response_parameter_get_fit_points(
185 const hdrl_parameter * par);
187static inline const cpl_bivector *
188hdrl_response_parameter_get_high_abs_regions(
189 const hdrl_parameter * par);
191static inline cpl_size
192hdrl_response_parameter_get_radius(
193 const hdrl_parameter * par);
195static inline hdrl_data_t
196hdrl_response_parameter_get_wrange(
197 const hdrl_parameter * par);
199static inline hdrl_spectrum1D *
200 hdrl_spectrum1D_extract_fit_regions(
const hdrl_spectrum1D * s,
201 const cpl_bivector * areas);
208 hdrl_spectrum1Dlist * telluric_models;
211 cpl_boolean normalize;
212 cpl_boolean shift_in_log_scale;
213 cpl_bivector * quality_areas;
214 cpl_bivector * fit_areas;
217}hdrl_response_telluric_evaluation_parameter;
220hdrl_response_telluric_evaluation_parameter_delete(
221 hdrl_parameter * ev){
223 if(ev == NULL)
return;
225 if(hdrl_parameter_get_parameter_enum(ev)
226 != HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION)
229 hdrl_response_telluric_evaluation_parameter * par =
230 (hdrl_response_telluric_evaluation_parameter *)ev;
233 cpl_bivector_delete(par->quality_areas);
234 cpl_bivector_delete(par->fit_areas);
238static hdrl_parameter_typeobj
239hdrl_telluric_eval_parameters_type = {
240 HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
241 (hdrl_alloc *)&cpl_malloc,
242 (hdrl_free *)&hdrl_response_telluric_evaluation_parameter_delete,
244 sizeof(hdrl_response_telluric_evaluation_parameter),
251 cpl_array * fit_points;
252 cpl_bivector * high_abs_regions;
254}response_fit_parameter;
257hdrl_response_fit_parameter_delete(
258 hdrl_parameter * ev){
260 if(ev == NULL)
return;
262 if(hdrl_parameter_get_parameter_enum(ev)
263 != HDRL_PARAMETER_RESPONSE_FIT)
266 response_fit_parameter * par =
267 (response_fit_parameter *)ev;
269 cpl_bivector_delete(par->high_abs_regions);
270 cpl_array_delete(par->fit_points);
274static hdrl_parameter_typeobj
275hdrl_response_parameters_type = {
276 HDRL_PARAMETER_RESPONSE_FIT,
277 (hdrl_alloc *)&cpl_malloc,
278 (hdrl_free *)&hdrl_response_fit_parameter_delete,
280 sizeof(response_fit_parameter),
284static inline hdrl_spectrum1D *
285hdrl_spectrum1D_create_from_buffers(
double * flux,
double * wlens, cpl_size sz,
286 hdrl_spectrum1D_wave_scale scale);
288static inline hdrl_response_result *
289hdrl_response_result_wrap(hdrl_spectrum1D * final_response,
290 hdrl_spectrum1D * selected_response,
291 hdrl_spectrum1D * raw_response,
293 hdrl_spectrum1D * corrected_observed_spectrum,
294 cpl_size best_telluric_model_idx,
295 hdrl_data_t telluric_shift,
296 hdrl_data_t avg_diff_from_1,
299 hdrl_data_t doppler_shift);
348 const hdrl_spectrum1Dlist * telluric_models,
351 cpl_boolean normalize,
352 cpl_boolean shift_in_log_scale,
353 const cpl_bivector * quality_areas,
354 const cpl_bivector * fit_areas,
358 cpl_ensure(quality_areas != NULL, CPL_ERROR_NULL_INPUT, NULL);
359 cpl_ensure(telluric_models != NULL, CPL_ERROR_NULL_INPUT, NULL);
360 cpl_ensure(fit_areas != NULL, CPL_ERROR_NULL_INPUT, NULL);
361 cpl_ensure(w_step > 0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
362 cpl_ensure(half_win > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
363 cpl_ensure(lmin < lmax, CPL_ERROR_ILLEGAL_INPUT, NULL);
365 hdrl_response_telluric_evaluation_parameter * ev
366 = (hdrl_response_telluric_evaluation_parameter *)
367 hdrl_parameter_new(&hdrl_telluric_eval_parameters_type);
371 ev->half_win = half_win;
372 ev->normalize = normalize;
373 ev->shift_in_log_scale = shift_in_log_scale;
374 ev->quality_areas = cpl_bivector_duplicate(quality_areas);
375 ev->fit_areas = cpl_bivector_duplicate(fit_areas);
379 return (hdrl_parameter *)ev;
404 const cpl_size radius,
const cpl_array * fit_points,
405 const hdrl_data_t wrange,
const cpl_bivector * high_abs_regions){
407 cpl_ensure(radius > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
408 cpl_ensure(wrange > 0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
409 cpl_ensure(fit_points != NULL, CPL_ERROR_NULL_INPUT, NULL);
411 response_fit_parameter * p
412 = (response_fit_parameter *)
413 hdrl_parameter_new(&hdrl_response_parameters_type);
415 p->fit_points = cpl_array_duplicate(fit_points);
416 p->high_abs_regions = NULL;
419 p->high_abs_regions = cpl_bivector_duplicate(high_abs_regions);
424 return (hdrl_parameter *) p;
458hdrl_response_result *
460 const hdrl_spectrum1D * obs_s,
461 const hdrl_spectrum1D * ref_s,
462 const hdrl_spectrum1D * E_x,
463 const hdrl_parameter * telluric_par,
464 const hdrl_parameter * velocity_par,
465 const hdrl_parameter * calc_par,
466 const hdrl_parameter * fit_par){
468 cpl_ensure(calc_par != NULL, CPL_ERROR_NULL_INPUT, NULL);
469 cpl_ensure(hdrl_parameter_get_parameter_enum(calc_par) ==
470 HDRL_PARAMETER_EFFICIENCY, CPL_ERROR_ILLEGAL_INPUT, NULL);
473 cpl_ensure(hdrl_parameter_get_parameter_enum(telluric_par) ==
474 HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
475 CPL_ERROR_ILLEGAL_INPUT, NULL);
478 cpl_ensure(hdrl_parameter_get_parameter_enum(velocity_par) ==
479 HDRL_PARAMETER_SPECTRUM1D_SHIFT,
480 CPL_ERROR_ILLEGAL_INPUT, NULL);
482 cpl_ensure(fit_par != NULL, CPL_ERROR_NULL_INPUT, NULL);
483 cpl_ensure(hdrl_parameter_get_parameter_enum(fit_par) ==
484 HDRL_PARAMETER_RESPONSE_FIT, CPL_ERROR_ILLEGAL_INPUT, NULL);
486 cpl_ensure(obs_s != NULL, CPL_ERROR_NULL_INPUT, NULL);
487 cpl_ensure(ref_s != NULL, CPL_ERROR_NULL_INPUT, NULL);
488 cpl_ensure(E_x != NULL, CPL_ERROR_NULL_INPUT, NULL);
490 hdrl_data_t best_mean_minus1 = 0, best_stddev = 0;
491 hdrl_data_t best_telluric_shift = 0;
492 cpl_size best_idx = -1;
494 hdrl_spectrum1D * corrected_obs =
495 hdrl_response_evaluate_telluric_models(obs_s, telluric_par,
496 &best_telluric_shift, &best_mean_minus1, &best_stddev, &best_idx);
498 cpl_ensure(best_idx >= 0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
499 cpl_ensure(corrected_obs != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
501 cpl_ensure(cpl_error_get_code() == CPL_ERROR_NONE,
502 CPL_ERROR_ILLEGAL_OUTPUT, NULL);
504 hdrl_data_t velocity_shift = 0.0;
505 if(velocity_par != NULL){
510 cpl_ensure(cpl_error_get_code() == CPL_ERROR_NONE,
511 CPL_ERROR_ILLEGAL_OUTPUT, NULL);
513 hdrl_spectrum1D * ref_shifted =
514 correct_spectrum_for_doppler_shift(ref_s,
517 cpl_ensure(ref_shifted != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
518 cpl_ensure(cpl_error_get_code() == CPL_ERROR_NONE,
519 CPL_ERROR_ILLEGAL_OUTPUT, NULL);
521 hdrl_spectrum1D * resp_raw =
524 cpl_ensure(resp_raw != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
525 cpl_ensure(cpl_error_get_code() == CPL_ERROR_NONE,
526 CPL_ERROR_ILLEGAL_OUTPUT, NULL);
528 const cpl_size radius = hdrl_response_parameter_get_radius(fit_par);
529 const cpl_bivector * high_abs_regions =
530 hdrl_response_parameter_get_high_abs_regions(fit_par);
531 const cpl_array * fit_points =
532 hdrl_response_parameter_get_fit_points(fit_par);
533 const hdrl_data_t wrange =
534 hdrl_response_parameter_get_wrange(fit_par);
536 cpl_ensure(cpl_error_get_code() == CPL_ERROR_NONE,
537 CPL_ERROR_ILLEGAL_OUTPUT, NULL);
539 hdrl_spectrum1D * resp_smoothed =
540 filter_spectrum_median(resp_raw, radius);
542 cpl_ensure(resp_smoothed != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
543 cpl_ensure(cpl_error_get_code() == CPL_ERROR_NONE, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
545 hdrl_spectrum1D * resp_on_fit_points =
546 resample_on_medians_skip_abs_regions(resp_smoothed, fit_points,
547 high_abs_regions, wrange);
549 cpl_ensure(resp_on_fit_points != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
550 cpl_ensure(cpl_error_get_code() == CPL_ERROR_NONE,
551 CPL_ERROR_ILLEGAL_OUTPUT, NULL);
554 hdrl_parameter * par =
557 hdrl_spectrum1D * resp_final =
567 return hdrl_response_result_wrap(resp_final, resp_on_fit_points,
568 resp_raw, corrected_obs, best_idx, best_telluric_shift,
569 best_mean_minus1, best_stddev, velocity_shift);
585const hdrl_spectrum1D *
587 cpl_ensure(res != NULL, CPL_ERROR_NULL_INPUT, NULL);
588 return res->final_response;
605const hdrl_spectrum1D *
607 cpl_ensure(res != NULL, CPL_ERROR_NULL_INPUT, NULL);
608 return res->selected_response;
624const hdrl_spectrum1D *
626 cpl_ensure(res != NULL, CPL_ERROR_NULL_INPUT, NULL);
627 return res->raw_response;
642const hdrl_spectrum1D *
644 cpl_ensure(res != NULL, CPL_ERROR_NULL_INPUT, NULL);
645 return res->corrected_observed_spectrum;
663 cpl_ensure(res != NULL, CPL_ERROR_NULL_INPUT, -1);
664 return res->best_telluric_model_idx;
685 cpl_ensure(res != NULL, CPL_ERROR_NULL_INPUT, NAN);
686 return res->avg_diff_from_1;
707 cpl_ensure(res != NULL, CPL_ERROR_NULL_INPUT, NAN);
727 cpl_ensure(res != NULL, CPL_ERROR_NULL_INPUT, NAN);
728 return res->telluric_shift;
745 cpl_ensure(res != NULL, CPL_ERROR_NULL_INPUT, NAN);
746 return res->doppler_shift;
776hdrl_response_evaluate_telluric_models(
777 const hdrl_spectrum1D * obs_s,
778 const hdrl_parameter * ev,
779 hdrl_data_t * telluric_shift,
780 hdrl_data_t * mean_minus_1, hdrl_data_t * stddev,
781 cpl_size * best_model_index){
783 cpl_ensure(mean_minus_1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
784 cpl_ensure(stddev != NULL, CPL_ERROR_NULL_INPUT, NULL);
785 cpl_ensure(best_model_index != NULL, CPL_ERROR_NULL_INPUT, NULL);
786 cpl_ensure(obs_s != NULL, CPL_ERROR_NULL_INPUT, NULL);
788 *mean_minus_1 = (hdrl_data_t)0.0;
789 *stddev = (hdrl_data_t)0.0;
790 *best_model_index = -1;
793 *best_model_index = 0;
796 *telluric_shift = NAN;
800 cpl_ensure(hdrl_parameter_get_parameter_enum(ev)
801 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
802 CPL_ERROR_ILLEGAL_INPUT, NULL);
804 const hdrl_spectrum1Dlist * telluric_models =
805 hdrl_response_telluric_evaluation_parameter_get_telluric_models(ev);
806 const hdrl_data_t w_step =
807 hdrl_response_telluric_evaluation_parameter_get_w_step(ev);
808 const cpl_size half_win =
809 hdrl_response_telluric_evaluation_parameter_get_half_win(ev);
810 const cpl_boolean normalize =
811 hdrl_response_telluric_evaluation_parameter_get_normalize(ev);
812 const cpl_boolean shift_in_log_scale =
813 hdrl_response_telluric_evaluation_parameter_get_shift_in_log_scale(ev);
814 const cpl_bivector * quality_areas =
815 hdrl_response_telluric_evaluation_parameter_get_quality_areas(ev);
816 const cpl_bivector * fit_areas =
817 hdrl_response_telluric_evaluation_parameter_get_fit_areas(ev);
818 const hdrl_data_t lmin =
819 hdrl_response_telluric_evaluation_parameter_get_lmin(ev);
820 const hdrl_data_t lmax =
821 hdrl_response_telluric_evaluation_parameter_get_lmax(ev);
823 hdrl_spectrum1D * to_ret = NULL;
826 cpl_ensure(sz > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
828 cpl_array * calc_std_devs = cpl_array_new(sz, CPL_TYPE_DOUBLE);
829 cpl_array * calc_means_minus_1 = cpl_array_new(sz, CPL_TYPE_DOUBLE);
830 cpl_array * calc_telluric_shift = cpl_array_new(sz, CPL_TYPE_DOUBLE);
832 cpl_array_fill_window(calc_std_devs, 0, sz, 0);
833 cpl_array_fill_window(calc_means_minus_1, 0, sz, 0);
834 cpl_array_fill_window(calc_telluric_shift, 0, sz, 0);
836 double * p_stddevs = cpl_array_get_data_double(calc_std_devs);
837 double * p_means = cpl_array_get_data_double(calc_means_minus_1);
838 double * p_telluric_shift = cpl_array_get_data_double(calc_telluric_shift);
840 hdrl_spectrum1D ** l = cpl_calloc(sz,
sizeof(hdrl_spectrum1D*));
841 cpl_error_code * codes = cpl_calloc(sz,
sizeof(cpl_error_code));
843 HDRL_OMP(omp parallel
for)
844 for(cpl_size i = 0; i < sz; ++i){
845 const hdrl_spectrum1D * this_model =
848 l[i] = hdrl_response_evaluate_telluric_model(obs_s, this_model, w_step,
849 half_win, normalize, shift_in_log_scale, quality_areas, fit_areas,
850 lmin, lmax, p_means + i, p_stddevs + i,p_telluric_shift + i);
851 codes[i] = cpl_error_get_code();
853 if(l[i] == NULL && codes[i] == CPL_ERROR_NONE)
854 codes[i] = CPL_ERROR_ILLEGAL_OUTPUT;
857 cpl_error_code err = get_first_error_code(codes, sz);
860 cpl_size best_idx = 0;
861 err = cpl_array_get_minpos(calc_means_minus_1, &best_idx);
863 *stddev = cpl_array_get(calc_std_devs, best_idx, NULL);
864 *mean_minus_1 = cpl_array_get(calc_means_minus_1, best_idx, NULL);
865 *telluric_shift = cpl_array_get(calc_telluric_shift, best_idx, NULL);
866 to_ret = l[best_idx];
868 *best_model_index = best_idx;
872 cpl_array_delete(calc_std_devs);
873 cpl_array_delete(calc_means_minus_1);
874 cpl_array_delete(calc_telluric_shift);
876 free_spectrum_array(l, sz);
878 cpl_ensure(err == CPL_ERROR_NONE, err, NULL);
888hdrl_response_evaluate_telluric_model(
const hdrl_spectrum1D * obs_s_arg,
889 const hdrl_spectrum1D * telluric_s_arg,
890 const hdrl_data_t w_step,
891 const cpl_size half_win,
892 const cpl_boolean normalize,
893 const cpl_boolean shift_in_log_scale,
894 const cpl_bivector * quality_areas,
895 const cpl_bivector * fit_areas,
896 const hdrl_data_t lmin,
const hdrl_data_t lmax,
897 double * mean_minus_1,
double * stddev,
898 double * telluric_shift){
900 cpl_ensure(obs_s_arg != NULL, CPL_ERROR_NULL_INPUT, NULL);
901 cpl_ensure(telluric_s_arg != NULL, CPL_ERROR_NULL_INPUT, NULL);
902 cpl_ensure(quality_areas != NULL, CPL_ERROR_NULL_INPUT, NULL);
903 cpl_ensure(fit_areas != NULL, CPL_ERROR_NULL_INPUT, NULL);
904 cpl_ensure(mean_minus_1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
905 cpl_ensure(stddev != NULL, CPL_ERROR_NULL_INPUT, NULL);
906 cpl_ensure(w_step > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
907 cpl_ensure(half_win > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
911 *telluric_shift = 0.0;
913 hdrl_spectrum1D * corrected_spectrum =
914 compute_corrected_obs_spectrum(obs_s_arg,
915 telluric_s_arg, w_step, half_win, normalize,
916 shift_in_log_scale, lmin, lmax, telluric_shift);
918 cpl_ensure(corrected_spectrum != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
920 hdrl_spectrum1D * corr_spectrum_extracted =
921 hdrl_spectrum1D_extract_fit_regions(corrected_spectrum, fit_areas);
923 if(corr_spectrum_extracted == NULL) {
925 cpl_ensure(CPL_FALSE, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
928 hdrl_spectrum1D * smoothed_fit =
929 compute_interpolated_spectrum(corrected_spectrum,
930 corr_spectrum_extracted, hdrl_spectrum1D_interp_akima);
932 hdrl_spectrum1D * quality_ratio =
935 compute_quality(quality_ratio, quality_areas, mean_minus_1, stddev);
941 return corrected_spectrum;
952compute_quality(
const hdrl_spectrum1D * s,
953 const cpl_bivector * quality_areas,
double * mean_abs_difference_from_1,
956 hdrl_spectrum1D * s_new =
969static inline hdrl_spectrum1D *
970compute_interpolated_spectrum(
const hdrl_spectrum1D * wlength_source,
971 const hdrl_spectrum1D * sampled_points,
972 const hdrl_spectrum1D_interpolation_method method){
974 hdrl_parameter * par =
979 hdrl_spectrum1D * continuum_fit =
983 return continuum_fit;
991static inline hdrl_spectrum1D *
992compute_corrected_obs_spectrum(
993 const hdrl_spectrum1D * obs_s_arg,
994 const hdrl_spectrum1D * telluric_s_arg,
995 const hdrl_data_t w_step,
const cpl_size half_win,
996 const cpl_boolean normalize,
997 const cpl_boolean shift_in_log_scale,
998 const hdrl_data_t lmin,
const hdrl_data_t lmax,
999 double * telluric_shift){
1001 cpl_ensure(obs_s_arg != NULL, CPL_ERROR_NULL_INPUT, NULL);
1002 cpl_ensure(telluric_s_arg != NULL, CPL_ERROR_NULL_INPUT, NULL);
1009 if(shift_in_log_scale){
1014 hdrl_spectrum1D * telluric_s_shifted_convolved=
1015 shift_and_convolve_telluric_model(obs_s, telluric_s_cp, w_step,
1016 half_win, normalize, lmin, lmax, telluric_shift);
1019 if(telluric_s_shifted_convolved != NULL){
1024 hdrl_spectrum1D * telluric_s_shifted_convolved_downsampled =
1026 hdrl_spectrum1D * corrected =
1039static inline hdrl_spectrum1D *
1040select_obs_wlen(
const hdrl_spectrum1D * s,
1041 const hdrl_spectrum1D * wlens_source){
1045 const hdrl_data_t wmin = cpl_array_get_min(wlens);
1046 const hdrl_data_t wmax = cpl_array_get_max(wlens);
1048 return select_win(s, wmin, wmax);
1054static inline hdrl_spectrum1D *
1055shift_and_convolve_telluric_model(
const hdrl_spectrum1D * obs,
1056 const hdrl_spectrum1D * telluric,
1057 const hdrl_data_t w_step,
1058 const cpl_size half_win,
1059 const cpl_boolean normalize,
1060 const hdrl_data_t lmin,
1061 const hdrl_data_t lmax,
1062 double * telluric_shift){
1064 hdrl_spectrum1D * telluric_s = select_win(telluric, lmin, lmax);
1066 cpl_ensure(telluric_s != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
1068 hdrl_xcorrelation_result * res =
1069 correlate_obs_with_telluric(obs, telluric_s,
1070 w_step, half_win, normalize, lmin, lmax);
1073 cpl_ensure(res != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
1075 hdrl_data_t shift = (hdrl_data_t)
1079 *telluric_shift = shift;
1081 hdrl_spectrum1D * telluric_selected_obs =
1082 select_obs_wlen(telluric, obs);
1084 hdrl_spectrum1D * telluric_s_shifted =
1090 cpl_ensure(telluric_s_shifted != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
1092 hdrl_spectrum1D * telluric_s_shifted_convolved =
1093 convolve_with_kernel_symmetrically(telluric_s_shifted, sigma, w_step);
1098 return telluric_s_shifted_convolved;
1107static inline hdrl_xcorrelation_result *
1108correlate_obs_with_telluric(
const hdrl_spectrum1D * obs_s,
1109 const hdrl_spectrum1D * telluric_s,
1110 const hdrl_data_t w_step,
1111 const cpl_size half_win,
1112 const cpl_boolean normalize,
1113 const hdrl_data_t lmin,
1114 const hdrl_data_t lmax){
1116 cpl_ensure(obs_s != NULL, CPL_ERROR_NULL_INPUT, NULL);
1117 cpl_ensure(telluric_s != NULL, CPL_ERROR_NULL_INPUT, NULL);
1122 hdrl_spectrum1D * tell_for_sel = select_win(telluric_s, wmin, wmax);
1124 hdrl_spectrum1D * telluric_s_res = NULL;
1125 hdrl_spectrum1D * obs_s_res = NULL;
1127 cpl_array * new_lambdas = get_uniform_wavs(tell_for_sel, w_step, lmin, lmax);
1133 hdrl_parameter * par =
1135 (hdrl_spectrum1D_interp_akima);
1144 cpl_array_delete(new_lambdas);
1147 cpl_ensure(obs_s_res != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
1148 cpl_ensure(telluric_s_res != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
1150 hdrl_xcorrelation_result * gshift =
1152 half_win, normalize);
1164static inline cpl_array *
1165get_uniform_wavs(
const hdrl_spectrum1D * s,
const hdrl_data_t w_step,
1166 const hdrl_data_t lmin,
const hdrl_data_t lmax){
1168 const hdrl_data_t w_min = CPL_MAX(lmin,
1170 const hdrl_data_t w_max = CPL_MIN(lmax,
1173 const cpl_size sz_new_spectrum = (w_max - w_min)/w_step;
1174 cpl_array * new_w_lengths = cpl_array_new(sz_new_spectrum, HDRL_TYPE_DATA);
1176 for(cpl_size i = 0; i < sz_new_spectrum; ++i){
1177 cpl_array_set(new_w_lengths, i, i * w_step + w_min);
1180 return new_w_lengths;
1186static inline hdrl_spectrum1D *
1187convolve_spectrum_with_kernel(
const hdrl_spectrum1D * s,
1188 const cpl_matrix * kernel){
1193 cpl_image * dest = cpl_image_new(sz, 1, HDRL_TYPE_DATA);
1195 const cpl_error_code cd =
1196 cpl_image_filter(dest, img, kernel, CPL_FILTER_LINEAR, CPL_BORDER_FILTER);
1199 hdrl_spectrum1D * to_ret = NULL;
1200 if(cd == CPL_ERROR_NONE){
1207 cpl_image_delete(dest);
1209 cpl_ensure(cd == CPL_ERROR_NONE, cd, NULL);
1214static inline cpl_size get_lower_odd(
const cpl_size sz){
1216 if(sz == 0)
return 0;
1218 if(sz % 2 == 1)
return sz;
1224static inline hdrl_spectrum1D *
1225convolve_with_kernel_symmetrically(
const hdrl_spectrum1D * s,
1227 const hdrl_data_t w_step){
1229 const double fwhm = CPL_MATH_FWHM_SIG * sigma;
1230 int fwhm_pix = (int) (fwhm / w_step + 0.5);
1232 cpl_matrix * kernel =
1233 create_symmetrical_gaussian_kernel(fwhm_pix / CPL_MATH_FWHM_SIG,
1234 fwhm_pix / CPL_MATH_FWHM_SIG,
1237 hdrl_spectrum1D * convolved =
1238 convolve_spectrum_with_kernel(s, kernel);
1239 cpl_matrix_delete(kernel);
1241 cpl_ensure(convolved != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
1248static inline cpl_matrix *
1249create_symmetrical_gaussian_kernel(
const double slitw,
const double fwhm,
1250 const cpl_size max_sz){
1252 cpl_ensure(slitw > 0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1253 cpl_ensure(fwhm > 0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1255 const double sigma = fwhm * CPL_MATH_SIG_FWHM;
1256 cpl_size size = 1 + (cpl_size)(5.0 * sigma + 0.5*slitw);
1262 size = CPL_MIN(size, max_sz);
1264 cpl_matrix * kernel = cpl_matrix_new(1, size);
1267 cpl_matrix_set(kernel, 0, size/2,
1268 (erf_antideriv(0.5*slitw + 0.5, sigma) -
1269 erf_antideriv(0.5*slitw - 0.5, sigma)) / slitw);
1271 for (cpl_size i = 1; i < size / 2; i++) {
1273 const double x1p = (double)i + 0.5 * slitw + 0.5;
1274 const double x1n = (double)i - 0.5 * slitw + 0.5;
1275 const double x0p = (double)i + 0.5 * slitw - 0.5;
1276 const double x0n = (double)i - 0.5 * slitw - 0.5;
1277 const double val = 0.5 / slitw *
1278 (erf_antideriv(x1p, sigma) - erf_antideriv(x1n, sigma) -
1279 erf_antideriv(x0p, sigma) + erf_antideriv(x0n, sigma));
1281 cpl_matrix_set(kernel, 0, size/2 + i, val);
1282 cpl_matrix_set(kernel, 0, size/2 - i, val);
1290erf_antideriv(
const double x,
const double sigma)
1292 return x * erf( x / (sigma * CPL_MATH_SQRT2))
1293 + 2.0 * sigma/CPL_MATH_SQRT2PI * exp(-0.5 * x * x / (sigma * sigma));
1299free_spectrum_array(hdrl_spectrum1D ** s,
const cpl_size sz){
1306static inline cpl_error_code
1307get_first_error_code(
const cpl_error_code * codes,
const cpl_size sz){
1308 for(cpl_size i = 0; i < sz; ++i){
1309 if(codes[i])
return codes[i];
1311 return CPL_ERROR_NONE;
1315static inline hdrl_spectrum1D *
1316select_win(
const hdrl_spectrum1D * s,
const hdrl_data_t wmin,
1317 const hdrl_data_t wmax){
1319 cpl_bivector * bv = cpl_bivector_new(1);
1321 cpl_vector_set(cpl_bivector_get_x(bv), 0, wmin);
1322 cpl_vector_set(cpl_bivector_get_y(bv), 0, wmax);
1326 cpl_bivector_delete(bv);
1331static inline hdrl_spectrum1D *
1332correct_spectrum_for_doppler_shift(
const hdrl_spectrum1D * s,
1333 const hdrl_data_t offset){
1342 for(cpl_size i = 0; i < cpl_array_get_size(wavs); ++i){
1343 const double d = cpl_array_get(wavs, i, NULL) * (1. + offset);
1344 cpl_array_set(wavs, i, d);
1352 cpl_array_delete(wavs);
1356static inline hdrl_spectrum1D *
1357filter_spectrum_median(
const hdrl_spectrum1D * resp,
const cpl_size radius){
1359 hdrl_image * flx_smoothed = compute_median_on_hdrl_image(flx_total, radius);
1373static inline hdrl_image *
1374compute_median_on_hdrl_image(
const hdrl_image * img,
const cpl_size radius){
1378 for(cpl_size i = 1; i <= sz; ++i){
1379 cpl_size start = CPL_MAX(i - radius, 1);
1380 cpl_size stop = CPL_MIN(i + radius, sz);
1390static inline hdrl_spectrum1D *
1391remove_bad_data(
const hdrl_spectrum1D * s){
1394 double * flx = cpl_calloc(sz,
sizeof(
double));
1395 double * flx_e = cpl_calloc(sz,
sizeof(
double));
1396 double * wlen = cpl_calloc(sz,
sizeof(
double));
1398 cpl_size true_size = 0;
1399 for(cpl_size i = 0; i < sz; ++i){
1402 if(rej || isnan(v.data) || isinf(v.data))
continue;
1404 flx[true_size] = v.data;
1405 flx_e[true_size] = v.error;
1418 cpl_image * img_flx = cpl_image_wrap_double(true_size, 1, flx);
1419 cpl_image * img_flx_e = cpl_image_wrap_double(true_size, 1, flx_e);
1420 cpl_array * arr_wlens= cpl_array_wrap_double(wlen, true_size);
1424 cpl_image_delete(img_flx);
1425 cpl_image_delete(img_flx_e);
1426 cpl_array_delete(arr_wlens);
1427 return good_spectrum;
1433static inline hdrl_spectrum1D *
1434get_median_on_fit_points(
const hdrl_spectrum1D * s_input,
1435 const cpl_array * fit_points,
const hdrl_data_t wrange){
1437 cpl_size final_fit_points_size = cpl_array_get_size(fit_points);
1439 cpl_array * wlens_fit = cpl_array_new(final_fit_points_size,
1441 hdrl_image * flux_fit =
hdrl_image_new(final_fit_points_size, 1);
1443 for(cpl_size i = 0; i < final_fit_points_size; ++i){
1444 const double w_fit = cpl_array_get(fit_points, i, NULL);
1445 cpl_array_set(wlens_fit, i, w_fit);
1446 hdrl_spectrum1D * f_s =
1447 select_win(s_input, w_fit - wrange, w_fit + wrange);
1468 cpl_array_delete(wlens_fit);
1473static inline hdrl_spectrum1D *
1474select_regions_and_good_value(
const hdrl_spectrum1D * s,
const cpl_bivector * areas){
1476 hdrl_spectrum1D * filted = NULL;
1482 hdrl_spectrum1D * to_ret = remove_bad_data(filted);
1492static inline hdrl_spectrum1D *
1493resample_on_medians_skip_abs_regions(
const hdrl_spectrum1D * s,
1494 const cpl_array * fit_points,
const cpl_bivector * high_abs_regions,
1495 const hdrl_data_t wrange){
1497 cpl_ensure(s != NULL, CPL_ERROR_NULL_INPUT, NULL);
1498 cpl_ensure(fit_points != NULL, CPL_ERROR_NULL_INPUT, NULL);
1500 hdrl_spectrum1D * filter_s =
1501 select_regions_and_good_value(s, high_abs_regions);
1503 cpl_ensure(filter_s != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
1505 const hdrl_data_t wmin=
1507 const hdrl_data_t wmax=
1510 cpl_array * filter_fit_points =
1511 remove_regions_and_outliers_from_array(fit_points, high_abs_regions, wmin, wmax);
1513 if(filter_fit_points == NULL || cpl_array_get_size(filter_fit_points) == 0){
1515 cpl_array_delete(filter_fit_points);
1516 cpl_ensure(CPL_FALSE, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
1519 hdrl_spectrum1D * selected_s_median_points =
1520 get_median_on_fit_points(filter_s, filter_fit_points, wrange);
1522 cpl_array_delete(filter_fit_points);
1525 return selected_s_median_points;
1529static inline cpl_boolean
1530contained_in_any_region(
const hdrl_data_t w,
const cpl_bivector * high_abs_regions){
1532 if(!high_abs_regions)
return CPL_FALSE;
1534 const cpl_size sz = cpl_bivector_get_size(high_abs_regions);
1536 for(cpl_size i = 0; i < sz; ++i){
1538 cpl_vector_get(cpl_bivector_get_x_const(high_abs_regions), i);
1540 cpl_vector_get(cpl_bivector_get_y_const(high_abs_regions), i);
1541 if(w >= wmin && w <= wmax)
return CPL_TRUE;
1548static inline cpl_array *
1549remove_regions_and_outliers_from_array(
const cpl_array * fit_points,
1550 const cpl_bivector * high_abs_regions,
1551 const hdrl_data_t wmin,
const hdrl_data_t wmax){
1553 const cpl_size sz = cpl_array_get_size(fit_points);
1554 double * filter = cpl_calloc(sz,
sizeof(*filter));
1556 for(cpl_size i = 0; i < sz; ++i){
1557 const double w = cpl_array_get(fit_points, i, NULL);
1558 if(w > wmax)
continue;
1559 if(w < wmin)
continue;
1560 if(contained_in_any_region(w, high_abs_regions))
continue;
1571 return cpl_array_wrap_double(filter, k);
1574static inline const hdrl_spectrum1Dlist *
1575hdrl_response_telluric_evaluation_parameter_get_telluric_models(
1576 const hdrl_parameter * par){
1578 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, NULL);
1579 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1580 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
1581 CPL_ERROR_ILLEGAL_INPUT, NULL);
1583 const hdrl_response_telluric_evaluation_parameter * p =
1584 (
const hdrl_response_telluric_evaluation_parameter *)par;
1585 return p->telluric_models;
1588static inline hdrl_data_t
1589hdrl_response_telluric_evaluation_parameter_get_w_step(
1590 const hdrl_parameter * par){
1592 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, 0.0);
1593 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1594 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
1595 CPL_ERROR_ILLEGAL_INPUT, 0.0);
1597 const hdrl_response_telluric_evaluation_parameter * p =
1598 (
const hdrl_response_telluric_evaluation_parameter *)par;
1602static inline cpl_size
1603hdrl_response_telluric_evaluation_parameter_get_half_win(
1604 const hdrl_parameter * par){
1606 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, 0);
1607 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1608 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
1609 CPL_ERROR_ILLEGAL_INPUT, 0);
1611 const hdrl_response_telluric_evaluation_parameter * p =
1612 (
const hdrl_response_telluric_evaluation_parameter *)par;
1616static inline cpl_boolean
1617hdrl_response_telluric_evaluation_parameter_get_normalize(
1618 const hdrl_parameter * par){
1620 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
1621 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1622 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
1623 CPL_ERROR_ILLEGAL_INPUT, CPL_FALSE);
1625 const hdrl_response_telluric_evaluation_parameter * p =
1626 (
const hdrl_response_telluric_evaluation_parameter *)par;
1627 return p->normalize;
1630static inline cpl_boolean
1631hdrl_response_telluric_evaluation_parameter_get_shift_in_log_scale(
1632 const hdrl_parameter * par){
1634 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
1635 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1636 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
1637 CPL_ERROR_ILLEGAL_INPUT, CPL_FALSE);
1639 const hdrl_response_telluric_evaluation_parameter * p =
1640 (
const hdrl_response_telluric_evaluation_parameter *)par;
1641 return p->shift_in_log_scale;
1644static inline const cpl_bivector *
1645hdrl_response_telluric_evaluation_parameter_get_quality_areas(
1646 const hdrl_parameter * par){
1648 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, NULL);
1649 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1650 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
1651 CPL_ERROR_ILLEGAL_INPUT, NULL);
1653 const hdrl_response_telluric_evaluation_parameter * p =
1654 (
const hdrl_response_telluric_evaluation_parameter *)par;
1655 return p->quality_areas;
1658static inline const cpl_bivector *
1659hdrl_response_telluric_evaluation_parameter_get_fit_areas(
1660 const hdrl_parameter * par){
1662 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, NULL);
1663 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1664 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
1665 CPL_ERROR_ILLEGAL_INPUT, NULL);
1667 const hdrl_response_telluric_evaluation_parameter * p =
1668 (
const hdrl_response_telluric_evaluation_parameter *)par;
1669 return p->fit_areas;
1672static inline hdrl_data_t
1673hdrl_response_telluric_evaluation_parameter_get_lmin(
1674 const hdrl_parameter * par){
1676 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, 0.0);
1677 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1678 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
1679 CPL_ERROR_ILLEGAL_INPUT, 0.0);
1681 const hdrl_response_telluric_evaluation_parameter * p =
1682 (
const hdrl_response_telluric_evaluation_parameter *)par;
1686static inline hdrl_data_t
1687hdrl_response_telluric_evaluation_parameter_get_lmax(
1688 const hdrl_parameter * par){
1690 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, 0.0);
1691 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1692 == HDRL_PARAMETER_RESPONSE_TELLURIC_EVALUATION,
1693 CPL_ERROR_ILLEGAL_INPUT, 0.0);
1695 const hdrl_response_telluric_evaluation_parameter * p =
1696 (
const hdrl_response_telluric_evaluation_parameter *)par;
1700static inline const cpl_array *
1701hdrl_response_parameter_get_fit_points(
1702 const hdrl_parameter * par){
1704 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, NULL);
1705 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1706 == HDRL_PARAMETER_RESPONSE_FIT,
1707 CPL_ERROR_ILLEGAL_INPUT, NULL);
1709 const response_fit_parameter * p =
1710 (
const response_fit_parameter *)par;
1711 return p->fit_points;
1714static inline const cpl_bivector *
1715hdrl_response_parameter_get_high_abs_regions(
1716 const hdrl_parameter * par){
1718 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, NULL);
1719 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1720 == HDRL_PARAMETER_RESPONSE_FIT,
1721 CPL_ERROR_ILLEGAL_INPUT, NULL);
1723 const response_fit_parameter * p =
1724 (
const response_fit_parameter *)par;
1725 return p->high_abs_regions;
1728static inline cpl_size
1729hdrl_response_parameter_get_radius(
1730 const hdrl_parameter * par){
1732 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, 0);
1733 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1734 == HDRL_PARAMETER_RESPONSE_FIT,
1735 CPL_ERROR_ILLEGAL_INPUT, 0);
1737 const response_fit_parameter * p =
1738 (
const response_fit_parameter *)par;
1742static inline hdrl_data_t
1743hdrl_response_parameter_get_wrange(
1744 const hdrl_parameter * par){
1746 cpl_ensure(par != NULL, CPL_ERROR_NULL_INPUT, 0.0);
1747 cpl_ensure(hdrl_parameter_get_parameter_enum(par)
1748 == HDRL_PARAMETER_RESPONSE_FIT,
1749 CPL_ERROR_ILLEGAL_INPUT, 0.0);
1751 const response_fit_parameter * p =
1752 (
const response_fit_parameter *)par;
1757static inline hdrl_spectrum1D *
1758hdrl_spectrum1D_create_from_buffers(
double * flux,
double * wlens, cpl_size sz,
1759 hdrl_spectrum1D_wave_scale scale){
1761 cpl_array * w = cpl_array_wrap_double(wlens, sz);
1762 cpl_image * fl = cpl_image_wrap_double(sz, 1, flux);
1766 cpl_array_unwrap(w);
1767 cpl_image_unwrap(fl);
1773static inline hdrl_spectrum1D *
1774 hdrl_spectrum1D_extract_fit_regions(
const hdrl_spectrum1D * s,
1775 const cpl_bivector * areas){
1777 const double step = 1.0;
1779 cpl_size sz = cpl_bivector_get_size(areas);
1780 const cpl_vector * l_min = cpl_bivector_get_x_const(areas);
1781 const cpl_vector * l_max = cpl_bivector_get_y_const(areas);
1783 double * flux = cpl_calloc(sz + 2,
sizeof(
double));
1784 double * wlens = cpl_calloc(sz + 2,
sizeof(
double));
1786 const hdrl_data_t wmin =
1788 const hdrl_data_t wmax =
1791 hdrl_spectrum1D * s_sel =
1792 select_win(s, wmin - step, wmin + step);
1801 cpl_size size_sel = 1;
1802 for(cpl_size i = 0; i < sz; ++i){
1803 const double lambda_min = cpl_vector_get(l_min, i);
1804 const double lambda_max = cpl_vector_get(l_max, i);
1806 hdrl_spectrum1D * s_sel =
1807 select_win(s, lambda_min, lambda_max);
1813 wlens[size_sel] = .5 * (lambda_max + lambda_min);
1822 hdrl_spectrum1D * s_sel =
1823 select_win(s, wmax - step, wmax + step);
1826 wlens[size_sel] = wmax;
1831 hdrl_spectrum1D * sel_s = NULL;
1835 sel_s = hdrl_spectrum1D_create_from_buffers(flux, wlens, size_sel, scale);
1847static inline hdrl_response_result *
1848hdrl_response_result_wrap(hdrl_spectrum1D * final_response,
1849 hdrl_spectrum1D * selected_response,
1850 hdrl_spectrum1D * raw_response,
1852 hdrl_spectrum1D * corrected_observed_spectrum,
1853 cpl_size best_telluric_model_idx,
1854 hdrl_data_t telluric_shift,
1855 hdrl_data_t avg_diff_from_1,
1858 hdrl_data_t doppler_shift){
1860 hdrl_response_result * to_ret = cpl_calloc(1,
sizeof(*to_ret));
1862 to_ret->final_response = final_response;
1863 to_ret->raw_response = raw_response;
1864 to_ret->selected_response = selected_response;
1866 to_ret->corrected_observed_spectrum = corrected_observed_spectrum;
1867 to_ret->best_telluric_model_idx = best_telluric_model_idx;
1868 to_ret->telluric_shift = telluric_shift;
1869 to_ret->avg_diff_from_1 = avg_diff_from_1;
1870 to_ret->stddev = stddev;
1872 to_ret->doppler_shift = doppler_shift;
void hdrl_xcorrelation_result_delete(hdrl_xcorrelation_result *self)
Destructor for hdrl_xcorrelation_result.
cpl_size hdrl_xcorrelation_result_get_half_window(const hdrl_xcorrelation_result *self)
Get the half_window used to calculate the cross-correlation.
double hdrl_xcorrelation_result_get_peak_subpixel(const hdrl_xcorrelation_result *self)
Get the index where the cross correlation reaches its maximum, with sub-pixel precision.
double hdrl_xcorrelation_result_get_sigma(const hdrl_xcorrelation_result *self)
Get the estimated standard deviation of the correlation.
hdrl_spectrum1D * hdrl_response_core_compute(const hdrl_spectrum1D *I_std_arg, const hdrl_spectrum1D *I_std_ref, const hdrl_spectrum1D *E_x, const hdrl_parameter *pars)
core response calculation
cpl_error_code hdrl_image_set_pixel(hdrl_image *self, cpl_size xpos, cpl_size ypos, hdrl_value value)
set pixel values of hdrl_image
hdrl_value hdrl_image_get_median(const hdrl_image *self)
computes the median and associated error of an image.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
double hdrl_image_get_stdev(const hdrl_image *self)
computes the standard deviation of the data of an image
hdrl_image * hdrl_image_extract(const hdrl_image *self, cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury)
extract copy of window from image
cpl_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
hdrl_value hdrl_image_get_mean(const hdrl_image *self)
computes mean pixel value and associated error of an image.
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
const cpl_image * hdrl_image_get_error_const(const hdrl_image *himg)
get error as cpl image
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
cpl_error_code hdrl_image_reject(hdrl_image *self, cpl_size xpos, cpl_size ypos)
mark pixel as bad
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
hdrl_image * hdrl_image_new(cpl_size nx, cpl_size ny)
create new zero filled hdrl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter
hdrl_data_t hdrl_response_result_get_stddev(const hdrl_response_result *res)
Getter of the standard deviation of the ratio between the corrected observed spectrum and its smoothe...
const hdrl_spectrum1D * hdrl_response_result_get_final_response(const hdrl_response_result *res)
Getter for the final response contained inside the hdrl_response_result.
const hdrl_spectrum1D * hdrl_response_result_get_selected_response(const hdrl_response_result *res)
Getter for the selected response contained inside the hdrl_response_result.
hdrl_parameter * hdrl_response_fit_parameter_create(const cpl_size radius, const cpl_array *fit_points, const hdrl_data_t wrange, const cpl_bivector *high_abs_regions)
ctor for the hdrl_parameter for the final interpolation of the response
cpl_size hdrl_response_result_get_best_telluric_model_idx(const hdrl_response_result *res)
Getter of the index of the telluric model used for telluric correction contained in hdrl_response_res...
hdrl_data_t hdrl_response_result_get_doppler_shift(const hdrl_response_result *res)
Getter of the doppler shift used to correct the model.
void hdrl_response_result_delete(hdrl_response_result *res)
Destructor for hdrl_response_result.
hdrl_response_result * hdrl_response_compute(const hdrl_spectrum1D *obs_s, const hdrl_spectrum1D *ref_s, const hdrl_spectrum1D *E_x, const hdrl_parameter *telluric_par, const hdrl_parameter *velocity_par, const hdrl_parameter *calc_par, const hdrl_parameter *fit_par)
Computation of the response.
hdrl_parameter * hdrl_response_telluric_evaluation_parameter_create(const hdrl_spectrum1Dlist *telluric_models, hdrl_data_t w_step, cpl_size half_win, cpl_boolean normalize, cpl_boolean shift_in_log_scale, const cpl_bivector *quality_areas, const cpl_bivector *fit_areas, hdrl_data_t lmin, hdrl_data_t lmax)
ctor for the hdrl_parameter for the telluric evaluation
const hdrl_spectrum1D * hdrl_response_result_get_raw_response(const hdrl_response_result *res)
Getter for the raw response contained inside the hdrl_response_result.
hdrl_data_t hdrl_response_result_get_avg_diff_from_1(const hdrl_response_result *res)
Getter of the value |mean - 1|, where mean is the average of the ratio between the corrected observed...
hdrl_data_t hdrl_response_result_get_telluric_shift(const hdrl_response_result *res)
Getter of the shift applied to the telluric model.
const hdrl_spectrum1D * hdrl_response_result_get_corrected_obs_spectrum(const hdrl_response_result *res)
Getter for the corrected observed spectrum contained in hdrl_response_result.
const hdrl_image * hdrl_spectrum1D_get_flux(const hdrl_spectrum1D *self)
hdrl_spectrum1D getter flux
cpl_error_code hdrl_spectrum1D_wavelength_convert_to_linear(hdrl_spectrum1D *self)
converts the wavelength scale to linear.
hdrl_data_t hdrl_spectrum1D_compute_shift_fit(const hdrl_spectrum1D *obs, const hdrl_parameter *par)
The function compute the shift due to radial velocity. If wguess is the reference line and wfound is ...
cpl_size hdrl_spectrum1Dlist_get_size(const hdrl_spectrum1Dlist *l)
hdrl_spectrum1Dlist getter for size
hdrl_spectrum1D * hdrl_spectrum1D_resample(const hdrl_spectrum1D *self, const hdrl_spectrum1D_wavelength *waves, const hdrl_parameter *par)
resample a hdrl_spectrum1D on the wavelengths contained in waves
hdrl_parameter * hdrl_spectrum1D_resample_interpolate_parameter_create(const hdrl_spectrum1D_interpolation_method method)
constructor for the hdrl_parameter in the case of interpolation
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_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
hdrl_xcorrelation_result * hdrl_spectrum1D_compute_shift_xcorrelation(const hdrl_spectrum1D *s1, const hdrl_spectrum1D *s2, cpl_size half_win, const cpl_boolean normalize)
The function computes the shift between the two spectra.
void hdrl_spectrum1Dlist_delete(hdrl_spectrum1Dlist *l)
hdrl_spectrum1Dlist destructor
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.
const hdrl_spectrum1D * hdrl_spectrum1Dlist_get_const(const hdrl_spectrum1Dlist *self, const cpl_size idx)
hdrl_spectrum1Dlist getter of the i-th element
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
hdrl_spectrum1D * hdrl_spectrum1D_resample_on_array(const hdrl_spectrum1D *self, const cpl_array *waves, const hdrl_parameter *par)
resample a hdrl_spectrum1D on the wavelengths contained in waves
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_data_t hdrl_spectrum1D_get_wavelength_value(const hdrl_spectrum1D *self, int idx, int *rej)
hdrl_spectrum1D getter for a wavelength value
hdrl_spectrum1Dlist * hdrl_spectrum1Dlist_duplicate(const hdrl_spectrum1Dlist *l)
hdrl_spectrum1Dlist copy-constructor
hdrl_spectrum1Dlist * hdrl_spectrum1Dlist_wrap(hdrl_spectrum1D **self, const cpl_size sz)
hdrl_spectrum1Dlist wrapper
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_parameter * hdrl_spectrum1D_resample_integrate_parameter_create(void)
constructor for the hdrl_parameter in the case of integration
hdrl_value hdrl_spectrum1D_get_flux_value(const hdrl_spectrum1D *self, int idx, int *rej)
hdrl_spectrum1D getter for a flux value