116 cpl_ensure (vis_data, CPL_ERROR_NULL_INPUT, NULL);
127 cpl_size nrow = cpl_table_get_nrow (oiflux_table) /
ntel;
128 cpl_msg_info (cpl_func,
"Input vis_data has %lld observation",nrow);
132 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
133 "Not enough observations to compute"
134 "a dispersion model. Check input SOF");
145 cpl_propertylist_append (disp_header, vis_header);
148 cpl_propertylist_append (disp_header_extra, vis_header_extra);
151 const char * qc_name =
"ESO QC DISP NEXP";
152 cpl_propertylist_update_int (disp_header, qc_name, nrow);
153 cpl_propertylist_set_comment (disp_header, qc_name,
"Number of exposures used");
160 cpl_table * linearity_table;
169 cpl_table * dispwave_table;
170 double GDrms = 0.0, Amin = 1e4, Amax = -1e4;
173 for (
int pol = 0; pol < npol; pol++) {
184 cpl_table * dispwave_table0;
186 oiwave_table, &GDrms,
193 dispwave_table = dispwave_table0;
200 cpl_table_delete (dispwave_table0);
206 qc_name =
"ESO QC DISP GDELAY_RMS";
208 cpl_propertylist_set_comment (disp_header, qc_name,
"[m] GDELAY rms over files");
210 qc_name =
"ESO QC DISP BETA_CORRECTION MIN";
212 cpl_propertylist_set_comment (disp_header, qc_name,
"Fine correction");
214 qc_name =
"ESO QC DISP BETA_CORRECTION MAX";
216 cpl_propertylist_set_comment (disp_header, qc_name,
"Fine correction");
218 qc_name =
"ESO QC DISP BETA_CORRECTION RANGE";
220 cpl_propertylist_set_comment (disp_header, qc_name,
"Fine correction");
230 cpl_table * dispth_table = cpl_table_duplicate (pos_table);
231 cpl_size nline = cpl_table_get_nrow (dispth_table);
234 dispwave_table,
"EFF_WAVE",
"BETA");
237 dispwave_table,
"EFF_WAVE",
"GAMMA");
247 cpl_table_duplicate_column (dispth_table,
"N_MEAN", dispth_table,
"BETA");
248 cpl_table_duplicate_column (dispth_table,
"N_DIFF", dispth_table,
"GAMMA");
250 for (cpl_size line = 0; line < nline; line++) {
251 double value = cpl_table_get (dispth_table,
"WAVE_TH", line, NULL) /
LAMBDA_MET;
252 cpl_array_multiply_scalar (cpl_table_get_data_array (dispth_table,
"N_MEAN")[line], value);
253 cpl_array_multiply_scalar (cpl_table_get_data_array (dispth_table,
"N_DIFF")[line], value);
260 cpl_table * disp_table = linearity_table;
269 cpl_size mindeg = 0, maxdeg = 3;
277 cpl_matrix * matrix = cpl_matrix_new (1, nline);
278 cpl_vector * vector = cpl_vector_new (nline);
279 cpl_polynomial * poly = cpl_polynomial_new (1);
280 cpl_array * coeff = cpl_array_new (maxdeg+1, CPL_TYPE_DOUBLE);
283 double wave0 = 2.2e-6;
284 for (cpl_size line = 0; line < nline; line++) {
285 double wave_th = cpl_table_get (dispth_table,
"WAVE_TH", line, NULL);
286 cpl_matrix_set (matrix, 0, line, wave0/wave_th - 1.);
289 for (cpl_size tel = 0; tel <
ntel; tel++) {
290 cpl_table_set (disp_table,
"WAVE0", tel, wave0);
293 for (cpl_size line = 0; line < nline; line++)
295 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
296 for (cpl_size order = 0; order <= maxdeg; order ++)
297 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
298 cpl_table_set_array (disp_table,
"BETA", tel, coeff);
301 for (cpl_size line = 0; line < nline; line++)
303 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
304 for (cpl_size order = 0; order <= maxdeg; order ++)
305 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
306 cpl_table_set_array (disp_table,
"GAMMA", tel, coeff);
309 for (cpl_size line = 0; line < nline; line++)
311 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
312 for (cpl_size order = 0; order <= maxdeg; order ++)
313 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
314 cpl_table_set_array (disp_table,
"N_MEAN", tel, coeff);
317 for (cpl_size line = 0; line < nline; line++)
319 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
320 for (cpl_size order = 0; order <= maxdeg; order ++)
321 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
322 cpl_table_set_array (disp_table,
"N_DIFF", tel, coeff);
324 CPLCHECK_NUL (
"Cannot fit the dispersion coefficients");
326 FREE (cpl_vector_delete, vector);
327 FREE (cpl_matrix_delete, matrix);
328 FREE (cpl_polynomial_delete, poly);
329 FREE (cpl_array_delete, coeff);
367 cpl_ensure_code (vis_data, CPL_ERROR_NULL_INPUT);
369 cpl_size nbase = 6,
ntel = 4, nclo = 4;
378 cpl_size nrow = cpl_table_get_nrow (oivis_table) / nbase;
381 cpl_array * flag_array = cpl_array_new (nrow, CPL_TYPE_INT);
382 cpl_array_fill_window (flag_array, 0, nrow, 0);
388 for (cpl_size row = 0; row < nrow; row++) {
389 for (cpl_size base = 0; base < nbase; base++) {
390 cpl_size
id = row * nbase + base;
391 double vis = cpl_array_get_median (cpl_table_get_array (oivis_table,
"VISAMP",
id));
393 if ( vis < 0.35) cpl_array_set (flag_array, row, 1);
403 cpl_size first = 0, nobs = 0;
407 for (cpl_size row = 0; row < nrow; row++) {
408 if (row < first || row >= first+nobs)
409 cpl_array_set (flag_array, row, 1);
413 cpl_msg_warning (cpl_func,
"LKDT not stable over all files "
414 "(keep %lld over %lld)", nobs, nrow);
423 for (
int type_data = 0; type_data < 2; type_data ++) {
425 for (
int pol = 0; pol < npol; pol ++) {
433 FREE (cpl_array_delete, flag_array);
436 cpl_size nrow_new = cpl_table_get_nrow (oivis_table) / nbase;
437 cpl_msg_info (cpl_func,
"Initial data had %lld obs, now %lld", nrow, nrow_new);
440 return CPL_ERROR_NONE;
471 cpl_ensure (oiflux_table, CPL_ERROR_NULL_INPUT, NULL);
473 cpl_size
ntel = 4, nbase = 6;
474 cpl_size nrow = cpl_table_get_nrow (oiflux_table) /
ntel;
477 cpl_matrix * rhs_matrix = cpl_matrix_new (nrow * nbase, 1);
478 cpl_matrix * model_matrix = cpl_matrix_new (nrow * nbase, nbase + 4 *
ntel);
480 for (
int base = 0; base < nbase; base++) {
484 for (cpl_size row=0; row<nrow; row++) {
485 int id = row * nbase + base;
486 int idi = row *
ntel + i;
487 int idj = row *
ntel + j;
490 double meti = cpl_table_get (oiflux_table,
"OPD_MET_FC", idi, NULL);
491 double metj = cpl_table_get (oiflux_table,
"OPD_MET_FC", idj, NULL);
492 cpl_matrix_set (rhs_matrix,
id, 0, (meti - metj)*1e6);
495 cpl_matrix_set (model_matrix,
id, base, 1.0);
498 double ft_posi = cpl_table_get (oiflux_table,
"FT_POS", idi, NULL);
499 double ft_posj = cpl_table_get (oiflux_table,
"FT_POS", idj, NULL);
500 cpl_matrix_set (model_matrix,
id, 6 +i, ft_posi);
501 cpl_matrix_set (model_matrix,
id, 6 +j, -1*ft_posj);
502 cpl_matrix_set (model_matrix,
id, 10+i, ft_posi*ft_posi);
503 cpl_matrix_set (model_matrix,
id, 10+j, -1*ft_posj*ft_posj);
506 double sc_posi = cpl_table_get (oiflux_table,
"SC_POS", idi, NULL);
507 double sc_posj = cpl_table_get (oiflux_table,
"SC_POS", idj, NULL);
508 cpl_matrix_set (model_matrix,
id, 14+i, -1*sc_posi);
509 cpl_matrix_set (model_matrix,
id, 14+j, sc_posj);
510 cpl_matrix_set (model_matrix,
id, 18+i, -1*sc_posi*sc_posi);
511 cpl_matrix_set (model_matrix,
id, 18+j, sc_posj*sc_posj);
516 cpl_matrix * res_matrix = cpl_matrix_solve_normal (model_matrix, rhs_matrix);
517 FREE (cpl_matrix_delete, model_matrix);
518 FREE (cpl_matrix_delete, rhs_matrix);
524 cpl_table * lin_table = cpl_table_new (
ntel);
528 cpl_array * coeff = cpl_array_new (3, CPL_TYPE_DOUBLE);
529 for (cpl_size tel = 0; tel <
ntel; tel++) {
530 cpl_array_set (coeff, 0, 0);
531 cpl_array_set (coeff, 1, cpl_matrix_get (res_matrix, 6 +tel, 0));
532 cpl_array_set (coeff, 2, cpl_matrix_get (res_matrix, 10+tel, 0));
533 cpl_table_set_array (lin_table,
"LIN_FDDL_FT", tel, coeff);
534 cpl_array_set (coeff, 0, 0);
535 cpl_array_set (coeff, 1, cpl_matrix_get (res_matrix, 14+tel, 0));
536 cpl_array_set (coeff, 2, cpl_matrix_get (res_matrix, 18+tel, 0));
537 cpl_table_set_array (lin_table,
"LIN_FDDL_SC", tel, coeff);
542 FREE (cpl_matrix_delete, res_matrix);
543 FREE (cpl_array_delete, coeff);
590 cpl_table * oivis_table,
591 cpl_table * oiwave_table,
597 cpl_ensure (oiflux_table, CPL_ERROR_NULL_INPUT, NULL);
598 cpl_ensure (oivis_table, CPL_ERROR_NULL_INPUT, NULL);
599 cpl_ensure (oiwave_table, CPL_ERROR_NULL_INPUT, NULL);
601 cpl_size nbase = 6,
ntel = 4;
602 cpl_size nrow = cpl_table_get_nrow (oiflux_table) / 4;
603 cpl_size nwave = cpl_table_get_column_depth (oiflux_table,
"FLUXDATA");
609 double beta0 = 0.8651, beta1 = 0.8814;
611 cpl_table_new_column (oiwave_table,
"BETA", CPL_TYPE_DOUBLE);
612 for (cpl_size wave = 0; wave < nwave; wave ++) {
613 double lbd = cpl_table_get (oiwave_table,
"EFF_WAVE", wave, NULL);
614 double beta = beta0 + beta1 * (2.2e-6/lbd - 1.0);
615 cpl_table_set (oiwave_table,
"BETA", wave, beta);
620 double * metdata = cpl_table_get_data_double (oivis_table,
"OPD_MET_FC");
622 double * beta = cpl_table_get_data_double (oiwave_table,
"BETA");
623 float * effwave = cpl_table_get_data_float (oiwave_table,
"EFF_WAVE");
634 for (cpl_size base = 0; base < nbase ; base ++) {
635 for (cpl_size row = 0; row < nrow ; row ++) {
636 int id = row * nbase + base;
637 for (cpl_size wave = 0; wave < nwave; wave ++) {
638 visdata[id][wave] *= cexp (- 2*I*CPL_MATH_PI * beta[wave] * metdata[
id] /
LAMBDA_MET);
655 cpl_vector * GDb = cpl_vector_new (nbase);
657 for (cpl_size base = 0; base < nbase ; base ++) {
660 cpl_vector_set (GDb, base, mean);
663 for (cpl_size row = 0; row < nrow ; row ++) {
664 int id = row * nbase + base;
665 for (cpl_size wave = 0; wave < nwave; wave ++) {
666 visdata[id][wave] *= cexp (-2*I*CPL_MATH_PI * mean / effwave[wave]);
674 *GDrms = CPL_MAX (std, *GDrms);
691 double complex * phasor = cpl_calloc (nrow * nA,
sizeof (
double complex));
695 cpl_matrix * Abl = cpl_matrix_new (nbase, nwave);
698 for (cpl_size base = 0; base < nbase ; base ++) {
699 for (cpl_size wave = 0; wave < nwave ; wave ++) {
704 for (cpl_size iA = 0; iA < nA; iA++) {
709 double complex currentV = 0.0;
710 for (cpl_size row = 0; row < nrow; row++) {
711 if (wave==0) phasor[row*nA+iA] = cexp (-2.* CPL_MATH_PI * I * A *
712 metdata[row*nbase+base] /
714 currentV += phasor[row*nA+iA] * visdata[row*nbase+base][wave];
720 if (cabs (currentV) > maxV) {
721 cpl_matrix_set (Abl, base, wave, A);
723 maxV = cabs (currentV);
729 for (cpl_size row = 0; row < nrow; row++) {
730 visdata[row*nbase+base][wave] *= phasor[row*nA+iAmax];
735 FREE (cpl_free, phasor);
738 cpl_msg_info (cpl_func,
"Abl range = %g (beta correction)",
740 cpl_msg_info (cpl_func,
"Abl mean = %g (beta correction)",
741 cpl_matrix_get_mean (Abl));
742 cpl_msg_info (cpl_func,
"Abl std = %g (beta correction)",
743 cpl_matrix_get_stdev (Abl));
745 *Amax = CPL_MAX (*Amax, cpl_matrix_get_max (Abl));
746 *Amin = CPL_MIN (*Amin, cpl_matrix_get_min (Abl));
761 cpl_matrix * Obl = cpl_matrix_new (nbase, nwave);
764 for (cpl_size base = 0; base < nbase ; base ++) {
765 for (cpl_size wave = 0; wave < nwave ; wave ++) {
768 double complex currentV = 0.0;
769 for (cpl_size row = 0; row < nrow; row++) {
770 currentV += visdata[row*nbase+base][wave];
772 cpl_matrix_set (Obl, base, wave, carg (currentV));
776 for (cpl_size row = 0; row < nrow; row++) {
777 visdata[row*nbase+base][wave] *= conj (currentV);
794 cpl_matrix * disp_fits = cpl_matrix_new (nbase +
ntel * 2, nwave);
795 cpl_matrix * residuals_fits = cpl_matrix_new (nrow*nbase, nwave);
798 cpl_matrix * rhs_matrix = cpl_matrix_new (nrow * nbase, 1);
799 cpl_matrix * model_matrix = cpl_matrix_new (nrow * nbase, nbase +
ntel * 2);
801 for (cpl_size wave = 0; wave < nwave; wave ++) {
803 for (
int base = 0; base < nbase; base++) {
807 for (cpl_size row=0; row<nrow; row++) {
808 int id = row * nbase + base;
809 int idi = row *
ntel + i;
810 int idj = row *
ntel + j;
815 double phi = carg (visdata[
id][wave]);
816 phi += cpl_matrix_get (Obl, base, wave);
817 phi += CPL_MATH_2PI * cpl_matrix_get (Abl, base, wave) * metdata[id] /
LAMBDA_MET;
818 phi += CPL_MATH_2PI * cpl_vector_get (GDb, base) / effwave[wave];
819 phi += CPL_MATH_2PI * beta[wave] * metdata[id] /
LAMBDA_MET;
820 cpl_matrix_set (rhs_matrix,
id, 0, phi *
LAMBDA_MET / CPL_MATH_2PI);
823 cpl_matrix_set (model_matrix,
id, base, 1);
826 double fddli = cpl_table_get (oiflux_table,
"FDDL", idi, NULL);
827 double fddlj = cpl_table_get (oiflux_table,
"FDDL", idj, NULL);
828 cpl_matrix_set (model_matrix,
id, 6+i, fddli);
829 cpl_matrix_set (model_matrix,
id, 6+j, -1*fddlj);
832 double meti = cpl_table_get (oiflux_table,
"OPD_MET_FC", idi, NULL);
833 double metj = cpl_table_get (oiflux_table,
"OPD_MET_FC", idj, NULL);
834 cpl_matrix_set (model_matrix,
id, 10+i, meti);
835 cpl_matrix_set (model_matrix,
id, 10+j, -1*metj);
840 cpl_matrix * res_matrix = cpl_matrix_solve_normal (model_matrix, rhs_matrix);
843 cpl_matrix * residual_matrix = cpl_matrix_product_create ( model_matrix, res_matrix);
844 cpl_matrix_subtract(residual_matrix, rhs_matrix);
847 for (cpl_size param = 0; param < nbase +
ntel * 2; param++)
848 cpl_matrix_set (disp_fits, param, wave, cpl_matrix_get (res_matrix,param,0));
849 for (cpl_size param = 0; param < nrow * nbase; param++)
850 cpl_matrix_set (residuals_fits, param, wave, cpl_matrix_get (residual_matrix,param,0));
851 FREE (cpl_matrix_delete, res_matrix);
852 FREE (cpl_matrix_delete, residual_matrix);
855 FREE (cpl_matrix_delete, model_matrix);
856 FREE (cpl_matrix_delete, rhs_matrix);
859 FREE (cpl_free, visdata);
863 FREE (cpl_vector_delete, GDb);
864 FREE (cpl_matrix_delete, Abl);
865 FREE (cpl_matrix_delete, Obl);
870 cpl_table * dispwave_table = cpl_table_duplicate (oiwave_table);
878 for (cpl_size tel = 0; tel <
ntel; tel++) {
879 for (cpl_size wave = 0; wave < nwave; wave ++) {
881 cpl_matrix_get (disp_fits, 10+tel, wave));
883 cpl_matrix_get (disp_fits, 6+tel, wave));
889 for (cpl_size tel = 0; tel < nrow * nbase; tel++) {
890 for (cpl_size wave = 0; wave < nwave; wave ++) {
892 cpl_matrix_get (residuals_fits, tel, wave));
898 FREE (cpl_matrix_delete, disp_fits);
899 FREE (cpl_matrix_delete, residuals_fits);
902 return dispwave_table;
925 cpl_ensure_code (preproc_data, CPL_ERROR_NULL_INPUT);
939 cpl_ensure_code (spectrum_table, CPL_ERROR_ILLEGAL_INPUT);
940 cpl_ensure_code (oi_wave, CPL_ERROR_ILLEGAL_INPUT);
946 const cpl_array * array_data;
947 cpl_array * argon = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
948 cpl_array_fill_window (argon, 0, nwave, 0.0);
951 for (cpl_size region = 0; region < n_region; region ++) {
952 array_data = cpl_table_get_array (spectrum_table,
GRAVI_DATA[region], 0);
953 cpl_array_add (argon, array_data);
956 cpl_array_divide_scalar (argon, n_region);
965 if ( cpl_table_has_column (line_wave_table ,
"ARGON_LINES") ) {
967 line_wave = cpl_table_get_data_double (line_wave_table,
"ARGON_LINES");
968 nlines = cpl_table_get_nrow (line_wave_table);
970 cpl_msg_info (cpl_func,
"line_wave [0] : %e", line_wave[0]);
971 cpl_msg_info (cpl_func,
"line_wave [1] : %e", line_wave[1]);
972 cpl_msg_info (cpl_func,
"line_wave [2] : %e", line_wave[2]);
973 cpl_msg_info (cpl_func,
"line_wave [3] : %e", line_wave[3]);
974 cpl_msg_info (cpl_func,
"line_wave [4] : %e", line_wave[4]);
975 cpl_msg_info (cpl_func,
"line_wave [5] : %e", line_wave[5]);
976 cpl_msg_info (cpl_func,
"line_wave [6] : %e", line_wave[6]);
977 cpl_msg_info (cpl_func,
"line_wave [7] : %e", line_wave[7]);
978 cpl_msg_info (cpl_func,
"line_wave [8] : %e", line_wave[8]);
979 cpl_msg_info (cpl_func,
"line_wave [9] : %e", line_wave[9]);
984 cpl_msg_error(cpl_func,
"Cannot get the default values for Argon line_wave");
985 return CPL_ERROR_ILLEGAL_INPUT;
993 int fitwidth = nwave > 500 ? 10 : 3;
994 int nfitwidth = fitwidth * 2;
997 cpl_table * outTable = cpl_table_new (nlines);
1006 cpl_vector * vector_x = cpl_vector_new (nfitwidth);
1007 cpl_vector * vector_y = cpl_vector_new (nfitwidth);
1009 for (cpl_size list = 0; list < nlines; list ++) {
1012 double waveI = line_wave[list];
1016 while ( cpl_table_get (oi_wave,
"EFF_WAVE", pixI, NULL) < waveI) {
1022 for (cpl_size i = 0; i < nfitwidth; i++) {
1023 cpl_size w = pixI - fitwidth + i;
1024 cpl_vector_set (vector_x, i, cpl_table_get (oi_wave,
"EFF_WAVE", w, NULL));
1025 cpl_vector_set (vector_y, i, cpl_array_get (argon, w, NULL));
1029 cpl_errorstate prestate = cpl_errorstate_get();
1030 double w0 = waveI, sigma, area, offset, mse;
1031 cpl_vector_fit_gaussian (vector_x, NULL, vector_y, NULL,
1032 CPL_FIT_ALL, &w0, &sigma, &area,
1033 &offset, &mse, NULL, NULL);
1035 if (cpl_error_get_code() == CPL_ERROR_CONTINUE){
1036 cpl_errorstate_set (prestate);
1037 cpl_msg_warning(cpl_func,
"The gaussian fit did not converge");
1038 cpl_vector_multiply (vector_x, vector_y);
1039 w0 = cpl_vector_get_mean (vector_x) /
1040 cpl_vector_get_mean (vector_y);
1045 double diff = w0 - waveI;
1046 double scale = (cpl_vector_get_max (vector_x) - cpl_vector_get_min (vector_x)) / (nfitwidth - 1);
1047 double diff_pix = diff / scale;
1050 cpl_msg_info (cpl_func,
"Argon line %lld: %.3g [nm] %.3g [pix] (over %i)",
1051 list, 1e9*diff, diff_pix, fitwidth);
1054 cpl_table_set (outTable,
"WAVE_TH", list, waveI);
1055 cpl_table_set (outTable,
"WAVE", list, w0);
1056 cpl_table_set (outTable,
"SIGMA", list, sigma);
1057 cpl_table_set (outTable,
"DIFF", list, diff);
1058 cpl_table_set (outTable,
"DIFF_PIX", list, diff_pix);
1061 cpl_array * tmp_array = cpl_array_wrap_double (cpl_vector_get_data (vector_y), nfitwidth);
1062 cpl_table_set_array (outTable,
"DATA_MEAN", list, tmp_array);
1063 FREE (cpl_array_unwrap, tmp_array);
1069 FREE (cpl_vector_delete, vector_y);
1070 FREE (cpl_vector_delete, vector_x);
1071 FREE (cpl_array_delete, argon);
1077 cpl_table_get_column_min (outTable,
"DIFF") * 1e9,
1078 cpl_table_get_column_max (outTable,
"DIFF") * 1e9,
1079 cpl_table_get_column_stdev (outTable,
"DIFF") * 1e9);
1085 return CPL_ERROR_NONE;