33#include "eris_ifu_lambda_corr.h"
34#include "eris_ifu_jitter_static.h"
35#include "eris_ifu_error.h"
62 const cpl_propertylist *header,
66 cpl_polynomial *lcorr_coeffs = NULL;
67 cpl_imagelist *tmpCube = NULL;
68 cpl_image *tmpImg = NULL;
69 cpl_bivector *obj_spectrum = NULL,
72 const int format_width = 14,
74 char *coeff_string = NULL,
75 coeff_dump[format_width * max_coeffs + 1];
77 ifsBand bandId = UNDEFINED_BAND;
84 ASSURE(cube != NULL || hdrlCube != NULL,
85 CPL_ERROR_ILLEGAL_INPUT,
"One of cube or hdrlCube must be not NULL");
86 ASSURE(!(cube != NULL && hdrlCube != NULL),
87 CPL_ERROR_ILLEGAL_INPUT,
"One of cube or hdrlCube must be NULL");
89 CPL_ERROR_NULL_INPUT,
"Not all input data is provided!");
119 tmpCube = cpl_imagelist_new();
122 cpl_imagelist_set(tmpCube, cpl_image_duplicate(tmpImg), sx);
141 cpl_imagelist_delete(tmpCube);
144 peaks, bandId, pfit_order));
148 for (ic = 0; ic <= cpl_polynomial_get_degree(lcorr_coeffs) && ic < max_coeffs; ic++) {
150 coeff_string = cpl_sprintf(
" %*g,", format_width-2, cpl_polynomial_get_coeff(lcorr_coeffs,pows));
151 strncat(coeff_dump, coeff_string, format_width);
152 cpl_free(coeff_string); coeff_string = NULL;
154 cpl_msg_debug(cpl_func,
"Lambda correction coeffs %s", coeff_dump);
158 cpl_polynomial_delete(lcorr_coeffs); lcorr_coeffs = NULL;
161 cpl_bivector_delete(ref_spectrum); ref_spectrum = NULL;
162 cpl_bivector_delete(obj_spectrum); obj_spectrum = NULL;
163 cpl_free(coeff_string); coeff_string = NULL;
185 const cpl_propertylist *header,
186 const double min_frac,
187 const cpl_vector *range) {
189 cpl_bivector *result = NULL;
190 cpl_vector *spectrum = NULL,
192 cpl_image *obj_mask = NULL;
195 ASSURE(cube != NULL && header != NULL,
196 CPL_ERROR_NULL_INPUT,
197 "Not all input data is provided!");
211 eris_ifu_extract_spec(cube, NULL, obj_mask, &spectrum, NULL));
214 result = cpl_bivector_wrap_vectors(lambda, spectrum));
221 if (obj_mask != NULL) {cpl_image_delete(obj_mask);}
222 if (result == NULL) {
223 if (lambda != NULL) {cpl_vector_delete(lambda);}
224 if (spectrum != NULL) {cpl_vector_delete(spectrum);}
260 const cpl_vector *lambda,
261 const cpl_vector *range) {
263 cpl_image *mask = NULL;
264 cpl_imagelist *rcube = NULL;
265 const cpl_image *slice = NULL;
266 cpl_imagelist *icube = NULL;
267 cpl_image *tmp_img = NULL,
269 cpl_vector *sum = NULL,
272 cpl_mask *empty_mask = NULL;
275 int nx, ny, nz, nr, px, cnz= 0;
276 int check4range = FALSE;
277 const double *lambda_data = NULL;
278 double l_low, l_up = 0.0;
279 double max_value = 0.0;
281 double *m_data = NULL;
282 float *mask_data = NULL;
287 CPL_ERROR_NULL_INPUT,
288 "Not all input data is provided!");
290 ASSURE(((lambda != NULL) && (range != NULL)) ||
291 ((lambda == NULL) && (range == NULL)) ,
292 CPL_ERROR_NULL_INPUT,
293 "Not all input data is provided!");
296 ASSURE(cpl_vector_get_size(range)%2 == 0,
297 CPL_ERROR_ILLEGAL_INPUT,
298 "Range vector size must be a multiple of 2");
300 nr = cpl_vector_get_size(range) / 2;
303 if (lambda != NULL) {
304 ASSURE(cpl_vector_get_size(lambda) == cpl_imagelist_get_size(cube),
305 CPL_ERROR_ILLEGAL_INPUT,
306 "Size of lambda vector must be the number of images in the input cube");
308 lambda_data = cpl_vector_get_data_const(lambda));
312 slice = cpl_imagelist_get_const(cube, 0));
313 nx = cpl_image_get_size_x(slice);
314 ny = cpl_image_get_size_y(slice);
315 nz = cpl_imagelist_get_size(cube);
322 rcube = cpl_imagelist_new());
323 for (z=0; z<nz; z++) {
325 for (r=0; r<nr; r++) {
326 l_low = cpl_vector_get(range, r*2);
327 l_up = cpl_vector_get(range, r*2+1);
328 if ((lambda_data[z] >= l_low) && (lambda_data[z] <= l_up)) {
335 slice = cpl_imagelist_get_const(cube, z));
337 cpl_imagelist_set(rcube, cpl_image_duplicate(slice), cnz));
343 icube = (cpl_imagelist*) cube;
348 tmp_img = cpl_imagelist_collapse_median_create(icube));
350 m_img = cpl_image_cast(tmp_img, CPL_TYPE_DOUBLE));
352 m_data = cpl_image_get_data_double(m_img));
354 m_vector = cpl_vector_wrap(nx * ny, m_data));
356 sorted_sum = cpl_vector_duplicate(m_vector));
357 cpl_vector_sort(sorted_sum, CPL_SORT_ASCENDING);
358 max_value = cpl_vector_get(sorted_sum, nx*ny*min_frac);
360 mask = cpl_image_new(nx,ny,CPL_TYPE_FLOAT);
362 mask_data = cpl_image_get_data_float(mask));
363 for (x=0; x<nx; x++) {
364 for (y=0; y<ny; y++) {
366 if (m_data[px] <= max_value) {
378 if (mask != NULL) {cpl_image_delete(mask);}
381 if (rcube != NULL) {cpl_imagelist_delete(rcube);}
382 if (tmp_img != NULL) {cpl_image_delete(tmp_img);}
383 if (m_img != NULL) {cpl_image_delete(m_img);}
384 if (m_vector != NULL) {cpl_vector_unwrap(m_vector);}
385 if (sum != NULL) {cpl_vector_delete(sum);}
386 if (cnts != NULL) {cpl_free(cnts);}
387 if (sorted_sum != NULL) {cpl_vector_delete(sorted_sum);}
388 if (empty_mask != NULL) {cpl_mask_delete(empty_mask);}
410 cpl_vector *lambda_vector = NULL;
412 double crval3, cdelt3, crpix3 = 0.0;
413 double *lambda = NULL;
417 CPL_ERROR_NULL_INPUT,
418 "Not all input data is provided!");
419 ASSURE(cpl_propertylist_has(header,NAXIS3) &&
420 cpl_propertylist_has(header,CRVAL3) &&
421 cpl_propertylist_has(header,CDELT3) &&
422 cpl_propertylist_has(header,CRPIX3),
423 CPL_ERROR_ILLEGAL_INPUT,
424 "missing WCS keywords in header");
426 naxis3 = cpl_propertylist_get_int(header, NAXIS3);
427 crval3 = cpl_propertylist_get_double(header, CRVAL3);
428 cdelt3 = cpl_propertylist_get_double(header, CDELT3);
429 crpix3 = cpl_propertylist_get_double(header, CRPIX3);
432 lambda_vector = cpl_vector_new(naxis3));
434 lambda = cpl_vector_get_data(lambda_vector));
436 for (z=0; z<naxis3; z++) {
437 lambda[z] = (z+1 - crpix3) * cdelt3 + crval3;
443 if (lambda_vector != NULL) {
444 cpl_vector_delete(lambda_vector);
445 lambda_vector = NULL;
449 return lambda_vector;
469 cpl_size ext_number) {
471 cpl_bivector *result = NULL;
472 cpl_vector *lambda = NULL,
474 cpl_propertylist *header = NULL;
475 double *lambda_data = NULL;
476 double crpix, crval, cdelt = 0.0;
481 CPL_ERROR_NULL_INPUT,
482 "Not all input data is provided!");
484 cpl_msg_info(__func__,
485 "Using file %s as OH reference spectrum for lambda correction",
488 spec = cpl_vector_load(filename, ext_number);
489 if (cpl_error_get_code() != CPL_ERROR_NONE) {
490 if (cpl_error_get_code() == CPL_ERROR_FILE_IO) {
491 cpl_msg_error(
"",
"File not found: %s", filename);
493 cpl_msg_error(
"",
"Problem loading file '%s' (%s --> Code %d)",
494 filename, cpl_error_get_message(),
495 cpl_error_get_code());
500 header = cpl_propertylist_load(filename, ext_number));
502 naxis1 = cpl_propertylist_get_int(header, NAXIS1);
504 crval = cpl_propertylist_get_double(header, CRVAL1);
506 cdelt = cpl_propertylist_get_double(header, CDELT1);
508 switch (cpl_propertylist_get_type(header, CRPIX1)) {
510 crpix = cpl_propertylist_get_int(header, CRPIX1);
512 case CPL_TYPE_DOUBLE:
513 crpix = cpl_propertylist_get_double(header, CRPIX1);
516 crpix = cpl_propertylist_get_float(header, CRPIX1);
520 "CRPIX1 is of wrong type!");
525 lambda = cpl_vector_new(naxis1));
527 lambda_data = cpl_vector_get_data(lambda));
529 for (i = 0; i < naxis1; i++) {
530 lambda_data[i] = crval + (i + 1-crpix)*cdelt;
534 result = cpl_bivector_wrap_vectors(lambda, spec));
541 if (header != NULL) {cpl_propertylist_delete(header);}
566 cpl_array *positions = NULL;
568 cpl_vector *copied_spectrum = NULL;
578 double *spec_data = NULL,
580 const double *lambda_data = NULL;
583 ASSURE(spectrum != NULL && cpl_bivector_get_y_const(spectrum) != NULL,
584 CPL_ERROR_NULL_INPUT,
585 "Not all input data is provided!");
588 ASSURE(cpl_bivector_get_x_const(spectrum) != NULL,
589 CPL_ERROR_NULL_INPUT,
590 "Not all input data is provided!");
591 ASSURE(cpl_vector_get_size(range)%2 == 0,
592 CPL_ERROR_ILLEGAL_INPUT,
593 "Range vector size must be a multiple of 2");
595 lambda_data = cpl_vector_get_data_const(cpl_bivector_get_x_const(spectrum)));
596 nr = cpl_vector_get_size(range) / 2;
600 copied_spectrum = cpl_vector_duplicate(cpl_bivector_get_y_const(spectrum)));
603 spec_data = cpl_vector_get_data(copied_spectrum));
605 spec_size = cpl_vector_get_size(copied_spectrum);
608 for (i = 0; i < (spec_size-1); i++) {
610 for (r = 0; r < nr; r++) {
611 l_low = cpl_vector_get(range, r*2);
612 l_up = cpl_vector_get(range, r*2+1);
613 if ((lambda_data[i] >= l_low) && (lambda_data[i] <= l_up)) {
625 diff_data = cpl_malloc((spec_size-1) *
sizeof(
double)));
628 positions = cpl_array_new(spec_size, CPL_TYPE_INT));
630 min = cpl_vector_get_max(copied_spectrum) * min_frac;
632 if (spec_data[0] < min) {
635 for (i = 0; i < (spec_size-1); i++) {
636 if (spec_data[i+1] < min) {
639 diff_data[i] = spec_data[i+1] - spec_data[i];
643 for (i = 0; i < (spec_size-2); i++) {
644 if ((diff_data[i] > 0) && (diff_data[i+1] < 0)) {
646 cpl_array_set_int(positions, peak_cnt, i+1));
651 cpl_array_set_size(positions, peak_cnt));
656 if (positions != NULL) {cpl_array_delete(positions);}
660 if (diff_data != NULL) {cpl_free(diff_data);}
661 if (copied_spectrum != NULL) {cpl_vector_delete(copied_spectrum);}
684 cpl_vector *peaks = NULL,
686 cpl_array *positions = NULL;
687 cpl_size no_peaks = 0,
689 const int *pos_data = NULL;
690 const double *spec_data = NULL;
691 double *lambda_data = NULL;
693 cpl_vector *ref_fit = NULL,
698 int *invalid_index = NULL;
699 cpl_size peak_idx = 0;
700 double delta_lambda = 0.0,
710 int validPeaksCnt = 0;
712 const int halfwidth = 5;
715 ASSURE(spectrum != NULL &&
716 cpl_bivector_get_x_const(spectrum) != NULL &&
717 cpl_bivector_get_y_const(spectrum) != NULL,
718 CPL_ERROR_NULL_INPUT,
719 "Not all input data is provided!");
723 no_peaks = cpl_array_get_size(positions);
726 peaks = cpl_vector_new(no_peaks));
729 pos_data = cpl_array_get_data_int_const(positions));
731 spec_data = cpl_vector_get_data_const(cpl_bivector_get_x_const(spectrum)));
733 lambda_data = cpl_vector_get_data(peaks));
735 spec_size = cpl_bivector_get_size(spectrum);
738 for (i = 0; i < no_peaks; i++) {
739 if (pos_data[i] >= spec_size) {
742 lambda_data[i] = spec_data[pos_data[i]];
747 invalid_index = cpl_calloc(no_peaks,
sizeof(
int)));
750 delta_lambda = 1.93 / 11200.;
752 for (i = 0; i < no_peaks-1; i++) {
753 if ((cpl_vector_get(peaks,i+1) - cpl_vector_get(peaks,i)) < 2. * delta_lambda) {
754 invalid_index[i] = 1;
755 invalid_index[i+1] = 1;
756 cpl_msg_debug(cpl_func,
757 "Pair of peaks are rejected because they are too close: %lld - %lld, %f - %f",
758 i, i+1, cpl_vector_get(peaks,i), cpl_vector_get(peaks,i+1));
765 ref_fit = cpl_vector_new(no_peaks));
767 sigma_fit = cpl_vector_new(no_peaks));
769 lambda_ref = cpl_vector_new(no_peaks));
771 lambda_tmp = cpl_vector_new(no_peaks));
773 sigma_tmp = cpl_vector_new(no_peaks));
777 if (IDL !=NULL ) fprintf(IDL,
"%20s: %s\n",
"xcorr spectrum type", stype);
778 for (i = 0 ; i < no_peaks; i++) {
779 lambda_in = cpl_vector_get(peaks,i);
781 lambda_out =
fit_peak (spectrum, spec_size, lambda_in, halfwidth, &sigma);
782 if (invalid_index[i] == 0) {
783 if (lambda_out > 0.) {
785 cpl_vector_set(ref_fit, i, lambda_out));
787 cpl_vector_set(sigma_fit, i, sigma));
789 cpl_vector_set(lambda_ref, peak_idx, lambda_in));
791 cpl_vector_set(lambda_tmp, peak_idx, lambda_out));
793 cpl_vector_set(sigma_tmp, peak_idx, sigma));
796 invalid_index[i] = 2;
797 cpl_msg_debug(cpl_func,
798 "Gaussian fit failed for %s spectrum, wavelenght %f, peak index %lld",
799 stype, lambda_in, i);
804 cpl_vector_set_size(lambda_ref,peak_idx));
806 cpl_vector_set_size(lambda_tmp,peak_idx));
808 cpl_vector_set_size(sigma_tmp,peak_idx));
810 fprintf(IDL,
"%20s: %lld ",
"xcorr lambda_ref", peak_idx); cpl_vector_dump(lambda_ref, IDL);
811 fprintf(IDL,
"%20s: %lld ",
"xcorr lambda_tmp", peak_idx); cpl_vector_dump(lambda_tmp, IDL);
812 fprintf(IDL,
"%20s: %lld ",
"xcorr sigma_tmp", peak_idx); cpl_vector_dump(sigma_tmp, IDL);
816 cpl_vector_subtract(lambda_tmp,lambda_ref));
817 l_median = cpl_vector_get_median_const(lambda_tmp);
818 l_stdev = cpl_vector_get_stdev(lambda_tmp);
819 s_median = cpl_vector_get_median_const(sigma_tmp);
820 s_stdev = cpl_vector_get_stdev(sigma_tmp);
821 l_limit = 3. * l_stdev;
822 s_limit = 3. * s_stdev;
823 if (IDL !=NULL ) fprintf(IDL,
"%20s: %f %f %f %f %f %f\n",
"xcorr limits", l_median, l_stdev, l_limit, s_median, s_stdev, s_limit);
825 for (i = 0; i < no_peaks; i++){
826 if (invalid_index[i] == 0) {
827 double tmp_lambda = cpl_vector_get(ref_fit,i) - cpl_vector_get(peaks,i);
828 double tmp_sigma = cpl_vector_get(sigma_fit,i);
829 if (fabs(tmp_lambda - l_median) > l_limit) {
830 invalid_index[i] = 3;
831 cpl_msg_debug(cpl_func,
832 "Peak rejected due lambda outlier, %s spectrum, wavelength %f, index %lld, limit %f, value %f",
833 stype, cpl_vector_get(peaks,i), i, l_limit, fabs(tmp_lambda - l_median));
834 }
else if (fabs(tmp_sigma - s_median) > s_limit) {
835 cpl_msg_debug(cpl_func,
836 "Peak rejected due sigma outlier, %s spectrum, wavelength %f, index %lld, limit %f, value %f",
837 stype, cpl_vector_get(peaks,i), i, s_limit,fabs(tmp_sigma - s_median));
838 invalid_index[i] = 4;
844 for (i = 0; i < no_peaks; i++) {
845 if (invalid_index[i] == 0) {
849 final_peaks = cpl_vector_new(validPeaksCnt);
851 for (i = 0; i < no_peaks; i++) {
852 if (invalid_index[i] == 0) {
853 cpl_vector_set(final_peaks, validPeaksCnt,
854 cpl_vector_get(ref_fit,i));
866 if (positions != NULL) {cpl_array_delete(positions);}
891int gauss1d_fnc(
const double x[],
const double a[],
double *result)
896 double offset = a[3];
901 double z = (x[0]- mean)/sigma;
902 double ez = exp(-z*z/2.);
903 *result = offset + peak * ez;
930 double z = (x[0]- mean)/sigma;
931 double ez = exp(-z*z/2.);
937 result[1] = peak * ez * z/sigma;
940 result[2] = result[1] * z;
963double fit_peak (
const cpl_bivector *spectrum,
const cpl_size size,
964 double lambda_in,
int half_width,
double *sigma_par) {
967 double x0 = 0., sigma = 0., area = 0., offset = 0., mserr = 0.;
968 cpl_size pos_found = 0, low_bound = 0, high_bound = 0;
969 cpl_vector *vx = NULL,
971 cpl_fit_mode fit_mode = CPL_FIT_ALL;
972 cpl_error_code cpl_err;
974 const double sqrt2pi = sqrt(2. * 3.14159265358979323846);
977 if (IDL !=NULL ) fprintf(IDL,
"%20s: %f %d %lld %f\n",
"fitpeak input", lambda_in, half_width, size, sigma);
979 if ((lambda_in < cpl_vector_get(cpl_bivector_get_x_const(spectrum), 0)) ||
980 (lambda_in > cpl_vector_get(cpl_bivector_get_x_const(spectrum),size-1))) {
983 pos_found = cpl_vector_find(cpl_bivector_get_x_const(spectrum), lambda_in);
987 low_bound = pos_found - half_width;
988 high_bound = pos_found + half_width;
992 if (high_bound >= size) {
993 high_bound = size - 1;
996 vx = cpl_vector_extract(cpl_bivector_get_x_const(spectrum), low_bound, high_bound, 1);
997 vy = cpl_vector_extract(cpl_bivector_get_y_const(spectrum), low_bound, high_bound, 1);
1000 fprintf(IDL,
"%20s: %lld %lld %lld\n",
"fitpeak selection", low_bound, high_bound, cpl_vector_get_size(vx));
1001 fprintf(IDL,
"%20s: %lld",
"fitpeak vx", cpl_vector_get_size(vx)); cpl_vector_dump(vx, IDL);
1002 fprintf(IDL,
"%20s: %lld",
"fitpeak vy", cpl_vector_get_size(vx)); cpl_vector_dump(vy, IDL);
1004 if (high_bound-low_bound < 4) {
1005 if (vx != NULL) {cpl_vector_delete(vx);}
1006 if (vy != NULL) {cpl_vector_delete(vy);}
1011 fit_mode = CPL_FIT_ALL;
1013 fit_mode = CPL_FIT_CENTROID | CPL_FIT_AREA | CPL_FIT_OFFSET;
1016 cpl_err = cpl_vector_fit_gaussian(vx, NULL, vy, NULL,
1017 fit_mode, &x0, &sigma, &area, &offset, &mserr, NULL, NULL);
1020 if (cpl_err != CPL_ERROR_NONE) {
1023 if (IDL !=NULL ) fprintf(IDL,
"%20s: %d %f %f %f %f\n",
"fitpeak vectorfit", cpl_err, area/sigma/sqrt2pi, x0, sigma, offset);
1027 cpl_matrix *mx = cpl_matrix_wrap(cpl_vector_get_size(vx), 1, cpl_vector_get_data(vx));
1028 cpl_vector *fit_par = cpl_vector_new(4);
1029 cpl_vector_set(fit_par,0,cpl_vector_get_max(vy));
1030 cpl_vector_set(fit_par,1,lambda_in);
1031 cpl_vector_set(fit_par,2,(cpl_vector_get(vx,cpl_vector_get_size(vx)-1)-cpl_vector_get(vx,0))/9.);
1032 cpl_vector_set(fit_par,3,cpl_vector_get_min(vy));
1033 cpl_error_code cpl_err_tmp = cpl_fit_lvmq(mx, NULL,
1037 CPL_FIT_LVMQ_TOLERANCE / 10000.,
1039 CPL_FIT_LVMQ_MAXITER * 1000,
1043 if (cpl_err_tmp != CPL_ERROR_NONE) {
1054 fprintf(IDL,
"%20s: %d %f %f %f %f\n",
"fitpeak LVMQfit",
1055 cpl_err_tmp, cpl_vector_get(fit_par,0), cpl_vector_get(fit_par,1),
1056 cpl_vector_get(fit_par,2),cpl_vector_get(fit_par,3));
1057 if (mx != NULL) cpl_matrix_unwrap(mx);
1058 if (fit_par != NULL) cpl_vector_delete(fit_par);
1061 cpl_vector_delete(vx);
1062 cpl_vector_delete(vy);
1064 if (cpl_err != CPL_ERROR_NONE) {
1065 if (cpl_err != CPL_ERROR_CONTINUE) {
1066 cpl_msg_error(
"",
"%s\n",cpl_error_get_message_default(cpl_err));
1091 cpl_bivector *
object,
1094 const int pfit_order) {
1096 cpl_vector *lambda_fit = NULL,
1102 *final_obj_in = NULL,
1103 *final_obj_fit = NULL,
1104 *final_obj_diff = NULL;
1105 cpl_polynomial *coeffs = NULL;
1106 cpl_matrix * samppos = NULL;
1108 int halfwidth_obj = 0,
1110 cpl_size obj_size = 0,
1115 int *invalid_index = NULL;
1117 double lambda_in = 0.0,
1129 const char *stype = NULL;
1134 CPL_ERROR_NULL_INPUT,
1135 "Not all input data is provided!");
1139 obj_size = cpl_bivector_get_size(
object);
1140 no_peaks = cpl_vector_get_size(peaks);
1142 fprintf(IDL,
"%20s: %lld %lld %f\n",
"xcorr input", obj_size, no_peaks, resolution);
1143 fprintf(IDL,
"%20s: %lld ",
"xcorr object_l", obj_size); cpl_vector_dump(cpl_bivector_get_x_const(
object), IDL);
1144 fprintf(IDL,
"%20s: %lld ",
"xcorr object_v", obj_size); cpl_vector_dump(cpl_bivector_get_y_const(
object), IDL);
1145 fprintf(IDL,
"%20s: %lld ",
"xcorr peaks", no_peaks); cpl_vector_dump(peaks, IDL);
1148 ASSURE(obj_size > 1 && no_peaks > 1 ,
1149 CPL_ERROR_ILLEGAL_INPUT,
1150 "Input spectra must have more than one value");
1153 invalid_index = cpl_calloc(no_peaks,
sizeof(
int)));
1156 cpl_vector_get(cpl_bivector_get_x_const(
object), cpl_bivector_get_size(
object) / 2) /
1160 halfwidth_obj = delta_lambda / (cpl_vector_get(cpl_bivector_get_x_const(
object),1) -
1161 cpl_vector_get(cpl_bivector_get_x_const(
object),0));
1169 lambda_fit = cpl_vector_new(no_peaks));
1171 sigma_fit = cpl_vector_new(no_peaks));
1173 lambda_ref = cpl_vector_new(no_peaks));
1175 lambda_tmp = cpl_vector_new(no_peaks));
1177 sigma_tmp = cpl_vector_new(no_peaks));
1181 if (IDL !=NULL ) fprintf(IDL,
"%20s: %s\n",
"xcorr spectrum type", stype);
1182 for (i = 0; i < no_peaks; i++) {
1183 lambda_in = cpl_vector_get(peaks,i);
1185 lambda_out =
fit_peak (
object, obj_size, lambda_in, halfwidth_obj, &sigma);
1186 if (invalid_index[i] == 0) {
1187 if (lambda_out > 0.) {
1189 cpl_vector_set(lambda_fit, i, lambda_out));
1191 cpl_vector_set(sigma_fit, i, sigma));
1193 cpl_vector_set(lambda_ref, peak_idx, lambda_in));
1195 cpl_vector_set(lambda_tmp, peak_idx, lambda_out));
1197 cpl_vector_set(sigma_tmp, peak_idx, sigma));
1200 invalid_index[i] = 5;
1201 cpl_msg_debug(cpl_func,
1202 "Gaussian fit failed for %s spectrum, wavelenght %f, peak index %d",
1203 stype, lambda_in, i);
1208 cpl_vector_set_size(lambda_ref,peak_idx));
1210 cpl_vector_set_size(lambda_tmp,peak_idx));
1212 cpl_vector_set_size(sigma_tmp,peak_idx));
1214 fprintf(IDL,
"%20s: %lld ",
"xcorr lambda_ref", peak_idx); cpl_vector_dump(lambda_ref, IDL);
1215 fprintf(IDL,
"%20s: %lld ",
"xcorr lambda_tmp", peak_idx); cpl_vector_dump(lambda_tmp, IDL);
1216 fprintf(IDL,
"%20s: %lld ",
"xcorr sigma_tmp", peak_idx); cpl_vector_dump(sigma_tmp, IDL);
1220 cpl_vector_subtract(lambda_tmp,lambda_ref));
1221 l_median = cpl_vector_get_median_const(lambda_tmp);
1222 l_stdev = cpl_vector_get_stdev(lambda_tmp);
1223 s_median = cpl_vector_get_median_const(sigma_tmp);
1224 s_stdev = cpl_vector_get_stdev(sigma_tmp);
1225 l_limit = 2. * l_stdev;
1226 s_limit = 2. * s_stdev;
1227 cpl_vector_delete(lambda_ref);
1228 cpl_vector_delete(lambda_tmp);
1229 cpl_vector_delete(sigma_tmp);
1230 if (IDL !=NULL ) fprintf(IDL,
"%20s: %f %f %f %f %f %f\n",
"xcorr limits", l_median, l_stdev, l_limit, s_median, s_stdev, s_limit);
1232 for (i = 0; i < no_peaks; i++){
1233 if (invalid_index[i] == 0) {
1234 double tmp_lambda = cpl_vector_get(lambda_fit,i) - cpl_vector_get(peaks,i);
1235 double tmp_sigma = cpl_vector_get(sigma_fit,i);
1236 if (fabs(tmp_lambda - l_median) > l_limit) {
1237 invalid_index[i] = 6;
1238 cpl_msg_debug(cpl_func,
1239 "Peak rejected due lambda outlier, %s spectrum, wavelength %f, index %d, limit %f, value %f",
1240 stype, cpl_vector_get(peaks,i), i, l_limit, fabs(tmp_lambda - l_median));
1241 }
else if (fabs(tmp_sigma - s_median) > s_limit) {
1242 cpl_msg_debug(cpl_func,
1243 "Peak rejected due sigma outlier, %s spectrum, wavelength %f, index %d, limit %f, value %f",
1244 stype, cpl_vector_get(peaks,i), i, s_limit,fabs(tmp_sigma - s_median));
1245 invalid_index[i] = 7;
1249 cpl_vector_delete(sigma_fit);
1254 dbg_msg = cpl_malloc((no_peaks * 2 + 1) *
sizeof(
char)));
1255 dbg_msg[no_peaks*2] =
'\0';
1256 if (IDL !=NULL ) fprintf(IDL,
"%20s: %lld",
"xcorr invalid peaks", no_peaks);
1257 for (i = 0; i < no_peaks; i++){
1258 sprintf(&dbg_msg[2*i],
"%2d", invalid_index[i]);
1259 if (invalid_index[i] == 0) {
1262 if (IDL !=NULL ) fprintf(IDL,
" %d", invalid_index[i]);
1267 cpl_msg_debug(__func__,
"%d valid ones of %d peaks: %s", (
int) no_valid_peaks, (
int) no_peaks, dbg_msg);
1270 if (no_valid_peaks == 0) {
1271 cpl_msg_error(cpl_func,
" |-----------------------------------------------------|");
1272 cpl_msg_error(cpl_func,
" | No OH lines could be fitted. Aborting. |");
1273 cpl_msg_error(cpl_func,
" | Run again with parameter --skip_oh_align |");
1274 cpl_msg_error(cpl_func,
" | |");
1275 cpl_msg_error(cpl_func,
" | WARNING: the spectral calibration of the outputs |");
1276 cpl_msg_error(cpl_func,
" | is expected to be off for several pixels |");
1277 cpl_msg_error(cpl_func,
" | due to flexure of the instrument |");
1278 cpl_msg_error(cpl_func,
" |-----------------------------------------------------|");
1280 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT);
1285 final_obj_in = cpl_vector_new(no_valid_peaks));
1287 final_obj_fit = cpl_vector_new(no_valid_peaks));
1289 final_obj_diff = cpl_vector_new(no_valid_peaks));
1291 for (i = 0; i < no_peaks; i++){
1292 if (invalid_index[i] == 0) {
1293 double in = cpl_vector_get(peaks,i);
1294 double fit = cpl_vector_get(lambda_fit,i);
1296 cpl_vector_set(final_obj_in, v_idx, in));
1298 cpl_vector_set(final_obj_fit, v_idx, fit));
1300 cpl_vector_set(final_obj_diff, v_idx, fit-in));
1305 fprintf(IDL,
"%20s: %lld ",
"xcorr final_obj_in", no_valid_peaks); cpl_vector_dump(final_obj_in, IDL);
1306 fprintf(IDL,
"%20s: %lld ",
"xcorr final_obj_fit", no_valid_peaks); cpl_vector_dump(final_obj_fit, IDL);
1307 fprintf(IDL,
"%20s: %lld ",
"xcorr final_obj_diff", no_valid_peaks); cpl_vector_dump(final_obj_diff, IDL);
1315 cpl_size degree[1] = {0};
1316 degree[0] = pfit_order;
1317 cpl_msg_info(cpl_func,
"Use poly deg: %lld to determine OH correction",degree[0]);
1319 coeffs = cpl_polynomial_new(1));
1321 if (cpl_vector_get_size(final_obj_in) > (degree[0] + 3)) {
1323 samppos = cpl_matrix_wrap(1,cpl_vector_get_size(final_obj_in),
1324 cpl_vector_get_data(final_obj_in)));
1326 cpl_polynomial_fit(coeffs, samppos, NULL, final_obj_diff, NULL, CPL_FALSE,
1329 cpl_msg_warning(NULL,
"Too few valid peaks for lambda correction using OH lines");
1334 cpl_polynomial_set_coeff (coeffs, pows, 0.));
1339 fprintf(IDL,
"%20s: %lld",
"xcorr polyfit", cpl_polynomial_get_degree(coeffs));
1340 for (i = 0; i <= cpl_polynomial_get_degree(coeffs); i++) {
1342 fprintf(IDL,
" %f", cpl_polynomial_get_coeff(coeffs,pows));
1350 if (coeffs != NULL) {
1351 cpl_polynomial_delete(coeffs);
1356 if (ref_fit != NULL) cpl_vector_delete(ref_fit);
1357 if (lambda_fit != NULL) cpl_vector_delete(lambda_fit);
1358 if (final_obj_in != NULL) cpl_vector_delete(final_obj_in);
1359 if (final_obj_fit != NULL) cpl_vector_delete(final_obj_fit);
1360 if (final_obj_diff != NULL) cpl_vector_delete(final_obj_diff);
1361 if (invalid_index != NULL) cpl_free(invalid_index);
1362 if (samppos != NULL) cpl_matrix_unwrap(samppos);
1375 IDL = fopen(filename,
"w");
ifsBand eris_ifu_get_band(const cpl_propertylist *header)
Determine preoptic band.
#define BRK_WITH_ERROR(code)
Set a new CPL error, and exit the try-block.
#define ASSURE(condition, error,...)
error handling macro (from fors-pipeline)
#define BRK_IF_ERROR(function)
If function is or returns an error != CPL_ERROR_NONE, then the try-block is exited.
#define CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
#define BRK_WITH_ERROR_MSG(code,...)
Set a new CPL error, and exit the try-block.
#define CATCH_MSG()
Displays an error message.
#define TRY
Beginning of a TRY-block.
#define CATCH
End of a TRY-block, beginning of a CATCH-block.
#define BRK_IF_NULL(function)
If function is or returns a NULL pointer, then the try-block is exited.
cpl_image * eris_ifu_lcorr_create_object_mask(const cpl_imagelist *cube, double min_frac, const cpl_vector *lambda, const cpl_vector *range)
Creates a mask of the cube.
cpl_bivector * eris_ifu_lcorr_extract_spectrum(const cpl_imagelist *cube, const cpl_propertylist *header, const double min_frac, const cpl_vector *range)
Creates a vector containing the spectrum of all marked spaxels.
cpl_polynomial * eris_ifu_lcorr_get(cpl_imagelist *cube, hdrl_imagelist *hdrlCube, const cpl_propertylist *header, cpl_vector *peaks, const int pfit_order)
Main function to create the lcal-correction.
void eris_ifu_lcorr_close_debug_file(void)
close ASCII file that hold debug results
cpl_vector * eris_ifu_lcorr_create_lambda_vector(const cpl_propertylist *header)
Creates a wavelength vector from an input cube.
void eris_ifu_lcorr_open_debug_file(const char *filename)
open ASCII file to hold debug results
cpl_array * eris_ifu_lcorr_get_peak_positions(const cpl_bivector *spectrum, double min_frac, cpl_vector *range)
Get peaks of position of lines used in wavelength calibration.
int gauss1d_fncd(const double x[], const double a[], double result[])
define a Gaussian profile
cpl_vector * eris_ifu_lcorr_get_peak_lambdas(const cpl_bivector *spectrum, double min_frac, cpl_vector *range)
Get peaks of position of lines used in wavelength calibration.
double fit_peak(const cpl_bivector *spectrum, const cpl_size size, double lambda_in, int half_width, double *sigma_par)
fit a peak
int gauss1d_fnc(const double x[], const double a[], double *result)
define a Gaussian profile
cpl_polynomial * eris_ifu_lcorr_crosscorrelate_spectra(cpl_bivector *object, cpl_vector *peaks, ifsBand bandId, const int pfit_order)
cross-correlate two input spectra
cpl_bivector * eris_ifu_lcorr_read_OH_reference_spectrum(const char *filename, cpl_size ext_number)
Creates a spectrum bivector (x: lambda) from an input FITS file.
void eris_ifu_free_vector(cpl_vector **item)
free memory and set pointer to null
void eris_ifu_free_int_array(int **item)
free memory and set pointer to null
cpl_error_code eris_ifu_mask_nans_in_cube(cpl_imagelist *cube)
mask NANs in input data cube
double eris_ifu_get_band_resolution(ifsBand band)
eris_ifu_get_band_resolution
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.