45 #define GRAVI_ACOEFF_RANGE 0.02 62 #include "gravi_data.h" 63 #include "gravi_dfs.h" 64 #include "gravi_pfits.h" 65 #include "gravi_cpl.h" 67 #include "gravi_utils.h" 68 #include "gravi_signal.h" 70 #include "gravi_vis.h" 71 #include "gravi_disp.h" 80 cpl_table * oivis_table,
81 cpl_table * oiwave_table,
115 gravi_msg_function_start(1);
116 cpl_ensure (vis_data, CPL_ERROR_NULL_INPUT, NULL);
120 cpl_propertylist * vis_header = gravi_data_get_header (vis_data);
121 cpl_size npol = gravi_pfits_get_pola_num (vis_header, GRAVI_SC);
122 cpl_table * oiflux_table = gravi_data_get_oi_flux (vis_data, GRAVI_SC, 0, npol);
123 CPLCHECK_NUL (
"Cannot get data");
126 cpl_size nrow = cpl_table_get_nrow (oiflux_table) / ntel;
127 cpl_msg_info (cpl_func,
"Input vis_data has %lld observation",nrow);
131 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
132 "Not enough observations to compute" 133 "a dispersion model. Check input SOF");
143 cpl_propertylist * disp_header = gravi_data_get_header (disp_map);
144 cpl_propertylist_append (disp_header, vis_header);
147 const char * qc_name =
"ESO QC DISP NEXP";
148 cpl_propertylist_update_int (disp_header, qc_name, nrow);
149 cpl_propertylist_set_comment (disp_header, qc_name,
"Number of exposures used");
156 cpl_table * linearity_table;
158 CPLCHECK_NUL (
"Cannot compute the FDDL linearity");
165 cpl_table * dispwave_table;
166 double GDrms = 0.0, Amin = 1e4, Amax = -1e4;
169 for (
int pol = 0; pol < npol; pol++) {
172 cpl_table * oiflux_table = gravi_data_get_oi_flux (vis_data, GRAVI_SC, pol, npol);
173 cpl_table * oivis_table = gravi_data_get_oi_vis (vis_data, GRAVI_SC, pol, npol);
174 cpl_table * oiwave_table = gravi_data_get_oi_wave (vis_data, GRAVI_SC, pol, npol);
180 cpl_table * dispwave_table0;
182 oiwave_table, &GDrms,
184 CPLCHECK_NUL (
"Cannot compute dispersion");
189 dispwave_table = dispwave_table0;
191 gravi_msg_warning (
"FIXME",
"Assumes same OI_WAVE for both polar of SC");
192 gravi_table_add_columns (dispwave_table,
"BETA", dispwave_table0,
"BETA");
194 gravi_table_add_columns (dispwave_table,
"GAMMA", dispwave_table0,
"GAMMA");
196 cpl_table_delete (dispwave_table0);
202 qc_name =
"ESO QC DISP GDELAY_RMS";
203 cpl_propertylist_update_double (disp_header, qc_name, GDrms);
204 cpl_propertylist_set_comment (disp_header, qc_name,
"[m] GDELAY rms over files");
206 qc_name =
"ESO QC DISP BETA_CORRECTION MIN";
207 cpl_propertylist_update_double (disp_header, qc_name, Amin);
208 cpl_propertylist_set_comment (disp_header, qc_name,
"Fine correction");
210 qc_name =
"ESO QC DISP BETA_CORRECTION MAX";
211 cpl_propertylist_update_double (disp_header, qc_name, Amax);
212 cpl_propertylist_set_comment (disp_header, qc_name,
"Fine correction");
214 qc_name =
"ESO QC DISP BETA_CORRECTION RANGE";
215 cpl_propertylist_update_double (disp_header, qc_name, GRAVI_ACOEFF_RANGE);
216 cpl_propertylist_set_comment (disp_header, qc_name,
"Fine correction");
226 cpl_table * dispth_table = cpl_table_duplicate (pos_table);
227 cpl_size nline = cpl_table_get_nrow (dispth_table);
229 gravi_table_interpolate_column (dispth_table,
"WAVE",
"BETA",
230 dispwave_table,
"EFF_WAVE",
"BETA");
232 gravi_table_interpolate_column (dispth_table,
"WAVE",
"GAMMA",
233 dispwave_table,
"EFF_WAVE",
"GAMMA");
235 CPLCHECK_NUL (
"Cannot interpolate into argon lines");
243 cpl_table_duplicate_column (dispth_table,
"N_MEAN", dispth_table,
"BETA");
244 cpl_table_duplicate_column (dispth_table,
"N_DIFF", dispth_table,
"GAMMA");
246 for (cpl_size line = 0; line < nline; line++) {
247 double value = cpl_table_get (dispth_table,
"WAVE_TH", line, NULL) / LAMBDA_MET;
248 cpl_array_multiply_scalar (cpl_table_get_data_array (dispth_table,
"N_MEAN")[line], value);
249 cpl_array_multiply_scalar (cpl_table_get_data_array (dispth_table,
"N_DIFF")[line], value);
256 cpl_table * disp_table = linearity_table;
264 cpl_size mindeg = 0, maxdeg = 2;
265 gravi_table_new_column_array (disp_table,
"N_MEAN", NULL, CPL_TYPE_DOUBLE, maxdeg+1);
266 gravi_table_new_column_array (disp_table,
"N_DIFF", NULL, CPL_TYPE_DOUBLE, maxdeg+1);
267 gravi_table_new_column (disp_table,
"WAVE0",
"m", CPL_TYPE_DOUBLE);
268 gravi_table_new_column_array (disp_table,
"BETA", NULL, CPL_TYPE_DOUBLE, maxdeg+1);
269 gravi_table_new_column_array (disp_table,
"GAMMA", NULL, CPL_TYPE_DOUBLE, maxdeg+1);
272 cpl_matrix * matrix = cpl_matrix_new (1, nline);
273 cpl_vector * vector = cpl_vector_new (nline);
274 cpl_polynomial * poly = cpl_polynomial_new (1);
275 cpl_array * coeff = cpl_array_new (maxdeg+1, CPL_TYPE_DOUBLE);
278 double wave0 = 2.2e-6;
279 for (cpl_size line = 0; line < nline; line++) {
280 double wave_th = cpl_table_get (dispth_table,
"WAVE_TH", line, NULL);
281 cpl_matrix_set (matrix, 0, line, wave0/wave_th - 1.);
284 for (cpl_size tel = 0; tel < ntel; tel++) {
285 cpl_table_set (disp_table,
"WAVE0", tel, wave0);
288 for (cpl_size line = 0; line < nline; line++)
289 cpl_vector_set (vector, line, gravi_table_get_value (dispth_table,
"BETA", line, tel));
290 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
291 for (cpl_size order = 0; order <= maxdeg; order ++)
292 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
293 cpl_table_set_array (disp_table,
"BETA", tel, coeff);
296 for (cpl_size line = 0; line < nline; line++)
297 cpl_vector_set (vector, line, gravi_table_get_value (dispth_table,
"GAMMA", line, tel));
298 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
299 for (cpl_size order = 0; order <= maxdeg; order ++)
300 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
301 cpl_table_set_array (disp_table,
"GAMMA", tel, coeff);
304 for (cpl_size line = 0; line < nline; line++)
305 cpl_vector_set (vector, line, gravi_table_get_value (dispth_table,
"N_MEAN", line, tel));
306 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
307 for (cpl_size order = 0; order <= maxdeg; order ++)
308 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
309 cpl_table_set_array (disp_table,
"N_MEAN", tel, coeff);
312 for (cpl_size line = 0; line < nline; line++)
313 cpl_vector_set (vector, line, gravi_table_get_value (dispth_table,
"N_DIFF", line, tel));
314 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
315 for (cpl_size order = 0; order <= maxdeg; order ++)
316 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
317 cpl_table_set_array (disp_table,
"N_DIFF", tel, coeff);
319 CPLCHECK_NUL (
"Cannot fit the dispersion coefficients");
321 FREE (cpl_vector_delete, vector);
322 FREE (cpl_matrix_delete, matrix);
323 FREE (cpl_polynomial_delete, poly);
324 FREE (cpl_array_delete, coeff);
341 gravi_msg_function_exit(1);
361 gravi_msg_function_start(1);
362 cpl_ensure_code (vis_data, CPL_ERROR_NULL_INPUT);
364 cpl_size nbase = 6, ntel = 4, nclo = 4;
366 cpl_propertylist * header = gravi_data_get_header (vis_data);
367 cpl_size npol_sc = gravi_pfits_get_pola_num (header, GRAVI_SC);
368 cpl_size npol_ft = gravi_pfits_get_pola_num (header, GRAVI_FT);
371 cpl_table * oivis_table = gravi_data_get_oi_vis (vis_data, GRAVI_FT, 0, npol_ft);
372 cpl_table * oiflux_table = gravi_data_get_oi_flux (vis_data, GRAVI_SC, 0, npol_sc);
373 cpl_size nrow = cpl_table_get_nrow (oivis_table) / nbase;
376 cpl_array * flag_array = cpl_array_new (nrow, CPL_TYPE_INT);
377 cpl_array_fill_window (flag_array, 0, nrow, 0);
383 for (cpl_size row = 0; row < nrow; row++) {
384 for (cpl_size base = 0; base < nbase; base++) {
385 cpl_size
id = row * nbase + base;
386 double vis = cpl_array_get_median (cpl_table_get_array (oivis_table,
"VISAMP",
id));
387 cpl_msg_debug (
"TEST",
"vis = %g", vis);
388 if ( vis < 0.35) cpl_array_set (flag_array, row, 1);
391 CPLCHECK_MSG (
"Cannot compute flag_array");
398 cpl_size first = 0, nobs = 0;
402 for (cpl_size row = 0; row < nrow; row++) {
403 if (row < first || row >= first+nobs)
404 cpl_array_set (flag_array, row, 1);
408 cpl_msg_warning (cpl_func,
"LKDT not stable over all files " 409 "(keep %lld over %lld)", nobs, nrow);
411 cpl_msg_info (cpl_func,
"LKDT stable over all files");
418 for (
int type_data = 0; type_data < 2; type_data ++) {
419 cpl_size npol = gravi_pfits_get_pola_num (header, type_data);
420 for (
int pol = 0; pol < npol; pol ++) {
421 gravi_vis_erase_obs (gravi_data_get_oi_flux (vis_data, type_data, pol, npol), flag_array, ntel);
422 gravi_vis_erase_obs (gravi_data_get_oi_vis (vis_data, type_data, pol, npol), flag_array, nbase);
423 gravi_vis_erase_obs (gravi_data_get_oi_vis2 (vis_data, type_data, pol, npol), flag_array, nbase);
424 gravi_vis_erase_obs (gravi_data_get_oi_t3 (vis_data, type_data, pol, npol), flag_array, nclo);
425 CPLCHECK_MSG (
"Cannot erase flagged observations");
428 FREE (cpl_array_delete, flag_array);
431 cpl_size nrow_new = cpl_table_get_nrow (oivis_table) / nbase;
432 cpl_msg_info (cpl_func,
"Initial data had %lld obs, now %lld", nrow, nrow_new);
434 gravi_msg_function_exit(1);
435 return CPL_ERROR_NONE;
465 gravi_msg_function_start(1);
466 cpl_ensure (oiflux_table, CPL_ERROR_NULL_INPUT, NULL);
468 cpl_size ntel = 4, nbase = 6;
469 cpl_size nrow = cpl_table_get_nrow (oiflux_table) / ntel;
472 cpl_matrix * rhs_matrix = cpl_matrix_new (nrow * nbase, 1);
473 cpl_matrix * model_matrix = cpl_matrix_new (nrow * nbase, nbase + 4 * ntel);
475 for (
int base = 0; base < nbase; base++) {
476 int i = GRAVI_BASE_TEL[base][0];
477 int j = GRAVI_BASE_TEL[base][1];
479 for (cpl_size row=0; row<nrow; row++) {
480 int id = row * nbase + base;
481 int idi = row * ntel + i;
482 int idj = row * ntel + j;
485 double meti = cpl_table_get (oiflux_table,
"OPD_MET_FC", idi, NULL);
486 double metj = cpl_table_get (oiflux_table,
"OPD_MET_FC", idj, NULL);
487 cpl_matrix_set (rhs_matrix,
id, 0, (meti - metj)*1e6);
490 cpl_matrix_set (model_matrix,
id, base, 1.0);
493 double ft_posi = cpl_table_get (oiflux_table,
"FT_POS", idi, NULL);
494 double ft_posj = cpl_table_get (oiflux_table,
"FT_POS", idj, NULL);
495 cpl_matrix_set (model_matrix,
id, 6 +i, ft_posi);
496 cpl_matrix_set (model_matrix,
id, 6 +j, -1*ft_posj);
497 cpl_matrix_set (model_matrix,
id, 10+i, ft_posi*ft_posi);
498 cpl_matrix_set (model_matrix,
id, 10+j, -1*ft_posj*ft_posj);
501 double sc_posi = cpl_table_get (oiflux_table,
"SC_POS", idi, NULL);
502 double sc_posj = cpl_table_get (oiflux_table,
"SC_POS", idj, NULL);
503 cpl_matrix_set (model_matrix,
id, 14+i, -1*sc_posi);
504 cpl_matrix_set (model_matrix,
id, 14+j, sc_posj);
505 cpl_matrix_set (model_matrix,
id, 18+i, -1*sc_posi*sc_posi);
506 cpl_matrix_set (model_matrix,
id, 18+j, sc_posj*sc_posj);
511 cpl_matrix * res_matrix = cpl_matrix_solve_normal (model_matrix, rhs_matrix);
512 FREE (cpl_matrix_delete, model_matrix);
513 FREE (cpl_matrix_delete, rhs_matrix);
519 cpl_table * lin_table = cpl_table_new (ntel);
520 gravi_table_new_column_array (lin_table,
"LIN_FDDL_SC",
"um/V^i", CPL_TYPE_DOUBLE, 3);
521 gravi_table_new_column_array (lin_table,
"LIN_FDDL_FT",
"um/V^i", CPL_TYPE_DOUBLE, 3);
523 cpl_array * coeff = cpl_array_new (3, CPL_TYPE_DOUBLE);
524 for (cpl_size tel = 0; tel < ntel; tel++) {
525 cpl_array_set (coeff, 0, 0);
526 cpl_array_set (coeff, 1, cpl_matrix_get (res_matrix, 6 +tel, 0));
527 cpl_array_set (coeff, 2, cpl_matrix_get (res_matrix, 10+tel, 0));
528 cpl_table_set_array (lin_table,
"LIN_FDDL_FT", tel, coeff);
529 cpl_array_set (coeff, 0, 0);
530 cpl_array_set (coeff, 1, cpl_matrix_get (res_matrix, 14+tel, 0));
531 cpl_array_set (coeff, 2, cpl_matrix_get (res_matrix, 18+tel, 0));
532 cpl_table_set_array (lin_table,
"LIN_FDDL_SC", tel, coeff);
533 CPLCHECK_NUL (
"Cannot set dispersion coeff");
537 FREE (cpl_matrix_delete, res_matrix);
538 FREE (cpl_array_delete, coeff);
540 gravi_msg_function_exit(1);
585 cpl_table * oivis_table,
586 cpl_table * oiwave_table,
591 gravi_msg_function_start(1);
592 cpl_ensure (oiflux_table, CPL_ERROR_NULL_INPUT, NULL);
593 cpl_ensure (oivis_table, CPL_ERROR_NULL_INPUT, NULL);
594 cpl_ensure (oiwave_table, CPL_ERROR_NULL_INPUT, NULL);
596 cpl_size nbase = 6, ntel = 4;
597 cpl_size nrow = cpl_table_get_nrow (oiflux_table) / 4;
598 cpl_size nwave = cpl_table_get_column_depth (oiflux_table,
"FLUX");
599 CPLCHECK_NUL (
"Cannot get data");
604 double beta0 = 0.8651, beta1 = 0.8814;
606 cpl_table_new_column (oiwave_table,
"BETA", CPL_TYPE_DOUBLE);
607 for (cpl_size wave = 0; wave < nwave; wave ++) {
608 double lbd = cpl_table_get (oiwave_table,
"EFF_WAVE", wave, NULL);
609 double beta = beta0 + beta1 * (2.2e-6/lbd - 1.0);
610 cpl_table_set (oiwave_table,
"BETA", wave, beta);
612 CPLCHECK_NUL (
"Cannot create BETA column");
615 double * metdata = cpl_table_get_data_double (oivis_table,
"OPD_MET_FC");
616 double complex ** visdata = gravi_table_get_data_array_double_complex (oivis_table,
"VISDATA");
617 double * beta = cpl_table_get_data_double (oiwave_table,
"BETA");
618 float * effwave = cpl_table_get_data_float (oiwave_table,
"EFF_WAVE");
619 CPLCHECK_NUL (
"Cannot get data");
626 cpl_msg_info (cpl_func,
"Correction #1");
629 for (cpl_size base = 0; base < nbase ; base ++) {
630 for (cpl_size row = 0; row < nrow ; row ++) {
631 int id = row * nbase + base;
632 for (cpl_size wave = 0; wave < nwave; wave ++) {
633 visdata[id][wave] *= cexp (- 2*I*CPL_MATH_PI * beta[wave] * metdata[
id] / LAMBDA_MET);
644 cpl_msg_info (cpl_func,
"Correction #2");
647 gravi_table_compute_group_delay (oivis_table,
"VISDATA",
"GDELAY", oiwave_table);
650 cpl_vector * GDb = cpl_vector_new (nbase);
652 for (cpl_size base = 0; base < nbase ; base ++) {
653 double mean = gravi_table_get_column_mean (oivis_table,
"GDELAY", base, nbase);
654 double std = gravi_table_get_column_std (oivis_table,
"GDELAY", base, nbase);
655 cpl_vector_set (GDb, base, mean);
658 for (cpl_size row = 0; row < nrow ; row ++) {
659 int id = row * nbase + base;
660 for (cpl_size wave = 0; wave < nwave; wave ++) {
661 visdata[id][wave] *= cexp (-2*I*CPL_MATH_PI * mean / effwave[wave]);
665 cpl_msg_info (cpl_func,
"GD mean = %g [um]", mean*1e6);
666 cpl_msg_info (cpl_func,
"GD std = %g [um]", std*1e6);
669 *GDrms = CPL_MAX (std, *GDrms);
682 cpl_msg_info (cpl_func,
"Correction #3");
686 double complex * phasor = cpl_calloc (nrow * nA,
sizeof (
double complex));
690 cpl_matrix * Abl = cpl_matrix_new (nbase, nwave);
693 for (cpl_size base = 0; base < nbase ; base ++) {
694 for (cpl_size wave = 0; wave < nwave ; wave ++) {
699 for (cpl_size iA = 0; iA < nA; iA++) {
700 double A = GRAVI_ACOEFF_RANGE * (2.* iA / nA - 1.0);
704 double complex currentV = 0.0;
705 for (cpl_size row = 0; row < nrow; row++) {
706 if (wave==0) phasor[row*nA+iA] = cexp (-2.* CPL_MATH_PI * I * A *
707 metdata[row*nbase+base] /
709 currentV += phasor[row*nA+iA] * visdata[row*nbase+base][wave];
715 if (cabs (currentV) > maxV) {
716 cpl_matrix_set (Abl, base, wave, A);
718 maxV = cabs (currentV);
724 for (cpl_size row = 0; row < nrow; row++) {
725 visdata[row*nbase+base][wave] *= phasor[row*nA+iAmax];
730 FREE (cpl_free, phasor);
733 cpl_msg_info (cpl_func,
"Abl range = %g (beta correction)",
735 cpl_msg_info (cpl_func,
"Abl mean = %g (beta correction)",
736 cpl_matrix_get_mean (Abl));
737 cpl_msg_info (cpl_func,
"Abl std = %g (beta correction)",
738 cpl_matrix_get_stdev (Abl));
740 *Amax = CPL_MAX (*Amax, cpl_matrix_get_max (Abl));
741 *Amin = CPL_MIN (*Amin, cpl_matrix_get_min (Abl));
753 cpl_msg_info (cpl_func,
"Correction #4");
756 cpl_matrix * Obl = cpl_matrix_new (nbase, nwave);
759 for (cpl_size base = 0; base < nbase ; base ++) {
760 for (cpl_size wave = 0; wave < nwave ; wave ++) {
763 double complex currentV = 0.0;
764 for (cpl_size row = 0; row < nrow; row++) {
765 currentV += visdata[row*nbase+base][wave];
767 cpl_matrix_set (Obl, base, wave, carg (currentV));
771 for (cpl_size row = 0; row < nrow; row++) {
772 visdata[row*nbase+base][wave] *= conj (currentV);
786 cpl_msg_info (cpl_func,
"Fit dispersion model");
789 cpl_matrix * disp_fits = cpl_matrix_new (nbase + ntel * 2, nwave);
792 cpl_matrix * rhs_matrix = cpl_matrix_new (nrow * nbase, 1);
793 cpl_matrix * model_matrix = cpl_matrix_new (nrow * nbase, nbase + ntel * 2);
795 for (cpl_size wave = 0; wave < nwave; wave ++) {
797 for (
int base = 0; base < nbase; base++) {
798 int i = GRAVI_BASE_TEL[base][0];
799 int j = GRAVI_BASE_TEL[base][1];
801 for (cpl_size row=0; row<nrow; row++) {
802 int id = row * nbase + base;
803 int idi = row * ntel + i;
804 int idj = row * ntel + j;
809 double phi = carg (visdata[
id][wave]);
810 phi += cpl_matrix_get (Obl, base, wave);
811 phi += CPL_MATH_2PI * cpl_matrix_get (Abl, base, wave) * metdata[id] / LAMBDA_MET;
812 phi += CPL_MATH_2PI * cpl_vector_get (GDb, base) / effwave[wave];
813 phi += CPL_MATH_2PI * beta[wave] * metdata[id] / LAMBDA_MET;
814 cpl_matrix_set (rhs_matrix,
id, 0, phi * LAMBDA_MET / CPL_MATH_2PI);
817 cpl_matrix_set (model_matrix,
id, base, 1);
820 double fddli = cpl_table_get (oiflux_table,
"FDDL", idi, NULL);
821 double fddlj = cpl_table_get (oiflux_table,
"FDDL", idj, NULL);
822 cpl_matrix_set (model_matrix,
id, 6+i, fddli);
823 cpl_matrix_set (model_matrix,
id, 6+j, -1*fddlj);
826 double meti = cpl_table_get (oiflux_table,
"OPD_MET_FC", idi, NULL);
827 double metj = cpl_table_get (oiflux_table,
"OPD_MET_FC", idj, NULL);
828 cpl_matrix_set (model_matrix,
id, 10+i, meti);
829 cpl_matrix_set (model_matrix,
id, 10+j, -1*metj);
834 cpl_matrix * res_matrix = cpl_matrix_solve_normal (model_matrix, rhs_matrix);
837 for (cpl_size param = 0; param < nbase + ntel * 2; param++)
838 cpl_matrix_set (disp_fits, param, wave, cpl_matrix_get (res_matrix,param,0));
839 FREE (cpl_matrix_delete, res_matrix);
842 FREE (cpl_matrix_delete, model_matrix);
843 FREE (cpl_matrix_delete, rhs_matrix);
846 FREE (cpl_free, visdata);
850 FREE (cpl_vector_delete, GDb);
851 FREE (cpl_matrix_delete, Abl);
852 FREE (cpl_matrix_delete, Obl);
857 cpl_table * dispwave_table = cpl_table_duplicate (oiwave_table);
860 gravi_table_init_column_array (dispwave_table,
"BETA", NULL, CPL_TYPE_DOUBLE, ntel);
861 gravi_table_init_column_array (dispwave_table,
"GAMMA", NULL, CPL_TYPE_DOUBLE, ntel);
864 for (cpl_size tel = 0; tel < ntel; tel++) {
865 for (cpl_size wave = 0; wave < nwave; wave ++) {
866 gravi_table_set_value (dispwave_table,
"BETA",wave,tel,
867 cpl_matrix_get (disp_fits, 10+tel, wave));
868 gravi_table_set_value (dispwave_table,
"GAMMA",wave,tel,
869 cpl_matrix_get (disp_fits, 6+tel, wave));
870 CPLCHECK_NUL (
"Cannot fill the dispwave_table");
875 FREE (cpl_matrix_delete, disp_fits);
877 gravi_msg_function_exit (1);
878 return dispwave_table;
900 gravi_msg_function_start(1);
901 cpl_ensure_code (preproc_data, CPL_ERROR_NULL_INPUT);
904 cpl_table * spectrum_table = gravi_data_get_spectrum_data (preproc_data, GRAVI_SC);
905 cpl_size n_region = gravi_spectrum_get_nregion (spectrum_table);
906 cpl_size npol = gravi_spectrum_get_npol (spectrum_table);
907 cpl_size nwave = gravi_spectrum_get_nwave (spectrum_table);
908 CPLCHECK_MSG (
"Cannot get data");
911 gravi_msg_warning (
"FIXME",
"Assumes same OI_WAVE for both polar of SC");
912 cpl_table * oi_wave = gravi_data_get_oi_wave (preproc_data, GRAVI_SC, 0, npol);
915 cpl_ensure_code (spectrum_table, CPL_ERROR_ILLEGAL_INPUT);
916 cpl_ensure_code (oi_wave, CPL_ERROR_ILLEGAL_INPUT);
922 const cpl_array * array_data;
923 cpl_array * argon = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
924 cpl_array_fill_window (argon, 0, nwave, 0.0);
927 for (cpl_size region = 0; region < n_region; region ++) {
928 array_data = cpl_table_get_array (spectrum_table, GRAVI_DATA[region], 0);
929 cpl_array_add (argon, array_data);
932 cpl_array_divide_scalar (argon, n_region);
940 double line_wave[] = {
958 cpl_msg_info(cpl_func,
"Vor line_wave2" );
961 if ( cpl_table_has_column(line_wave_table ,
"ARGON_LINES") ) {
962 line_wave = cpl_table_get_data_double (line_wave_table,
"ARGON_LINES");
963 nlines = cpl_table_get_nrow (line_wave_table);
965 cpl_msg_info(cpl_func,
"line_wave [0] : %e", line_wave[0] );
966 cpl_msg_info(cpl_func,
"line_wave [1] : %e", line_wave[1] );
967 cpl_msg_info(cpl_func,
"line_wave [2] : %e", line_wave[2] );
968 cpl_msg_info(cpl_func,
"line_wave [3] : %e", line_wave[3] );
969 cpl_msg_info(cpl_func,
"line_wave [4] : %e", line_wave[4] );
970 cpl_msg_info(cpl_func,
"line_wave [5] : %e", line_wave[5] );
971 cpl_msg_info(cpl_func,
"line_wave [6] : %e", line_wave[6] );
972 cpl_msg_info(cpl_func,
"line_wave [7] : %e", line_wave[7] );
973 cpl_msg_info(cpl_func,
"line_wave [8] : %e", line_wave[8] );
974 cpl_msg_info(cpl_func,
"line_wave [9] : %e", line_wave[9] );
975 cpl_msg_info(cpl_func,
"nlines : %d", nlines );
978 cpl_msg_error(cpl_func,
"Cannot get the default values for Argon line_wave");
987 int fitwidth = nwave > 500 ? 10 : 3;
988 int nfitwidth = fitwidth * 2;
991 cpl_table * outTable = cpl_table_new (nlines);
992 gravi_table_new_column (outTable,
"WAVE_TH",
"m", CPL_TYPE_DOUBLE);
993 gravi_table_new_column (outTable,
"WAVE",
"m", CPL_TYPE_DOUBLE);
994 gravi_table_new_column (outTable,
"SIGMA",
"m", CPL_TYPE_DOUBLE);
995 gravi_table_new_column (outTable,
"DIFF",
"m", CPL_TYPE_DOUBLE);
996 gravi_table_new_column (outTable,
"DIFF_PIX",
"pix", CPL_TYPE_DOUBLE);
997 gravi_table_new_column_array (outTable,
"DATA_MEAN",
"adu", CPL_TYPE_DOUBLE, nfitwidth);
1000 cpl_vector * vector_x = cpl_vector_new (nfitwidth);
1001 cpl_vector * vector_y = cpl_vector_new (nfitwidth);
1003 for (cpl_size list = 0; list < nlines; list ++) {
1006 double waveI = line_wave[list];
1010 while ( cpl_table_get (oi_wave,
"EFF_WAVE", pixI, NULL) < waveI) {
1011 CPLCHECK_MSG (
"Cannot get the expected position");
1016 for (cpl_size i = 0; i < nfitwidth; i++) {
1017 cpl_size w = pixI - fitwidth + i;
1018 cpl_vector_set (vector_x, i, cpl_table_get (oi_wave,
"EFF_WAVE", w, NULL));
1019 cpl_vector_set (vector_y, i, cpl_array_get (argon, w, NULL));
1023 cpl_errorstate prestate = cpl_errorstate_get();
1024 double w0 = waveI, sigma, area, offset, mse;
1025 cpl_vector_fit_gaussian (vector_x, NULL, vector_y, NULL,
1026 CPL_FIT_ALL, &w0, &sigma, &area,
1027 &offset, &mse, NULL, NULL);
1029 if (cpl_error_get_code() == CPL_ERROR_CONTINUE){
1030 cpl_errorstate_set (prestate);
1031 cpl_msg_warning(cpl_func,
"The gaussian fit did not converge");
1032 cpl_vector_multiply (vector_x, vector_y);
1033 w0 = cpl_vector_get_mean (vector_x) /
1034 cpl_vector_get_mean (vector_y);
1039 double diff = w0 - waveI;
1040 double scale = (cpl_vector_get_max (vector_x) - cpl_vector_get_min (vector_x)) / (nfitwidth - 1);
1041 double diff_pix = diff / scale;
1044 cpl_msg_info (cpl_func,
"Argon line %lld: %.3g [nm] %.3g [pix] (over %i)",
1045 list, 1e9*diff, diff_pix, fitwidth);
1048 cpl_table_set (outTable,
"WAVE_TH", list, waveI);
1049 cpl_table_set (outTable,
"WAVE", list, w0);
1050 cpl_table_set (outTable,
"SIGMA", list, sigma);
1051 cpl_table_set (outTable,
"DIFF", list, diff);
1052 cpl_table_set (outTable,
"DIFF_PIX", list, diff_pix);
1055 cpl_array * tmp_array = cpl_array_wrap_double (cpl_vector_get_data (vector_y), nfitwidth);
1056 cpl_table_set_array (outTable,
"DATA_MEAN", list, tmp_array);
1057 FREE (cpl_array_unwrap, tmp_array);
1059 CPLCHECK_MSG (
"Error during the computation");
1063 FREE (cpl_vector_delete, vector_y);
1064 FREE (cpl_vector_delete, vector_x);
1065 FREE (cpl_array_delete, argon);
1070 cpl_msg_info (cpl_func,
"MIN=%e MAX=%e RMS=%e [nm]",
1071 cpl_table_get_column_min (outTable,
"DIFF") * 1e9,
1072 cpl_table_get_column_max (outTable,
"DIFF") * 1e9,
1073 cpl_table_get_column_stdev (outTable,
"DIFF") * 1e9);
1077 cpl_msg_error(cpl_func,
"Ekki und raus hier");
1078 gravi_msg_function_exit(1);
1079 return CPL_ERROR_NONE;
gravi_data * gravi_data_new(int nb_ext)
Create an empty gravi_data.
gravi_data * gravi_compute_disp(gravi_data *vis_data)
Compute the DISP_MODEL calibration map.
cpl_error_code gravi_lkdt_get_sequence(cpl_table *oi_table, cpl_size ntel, cpl_size *first, cpl_size *nobs)
Return the longuest sequence with constant LKDT.
cpl_error_code gravi_compute_argon_pos(gravi_data *preproc_data, gravi_data *wave_param)
Compute position of argon lines in SC spectrum.
cpl_table * gravi_fit_fddl_lin(cpl_table *oiflux_table)
Compute the linearity coefficient of FDDLs.
cpl_error_code gravi_table_multiply_scalar(cpl_table *table, const char *name, int base, int nbase, double value)
Multiply scalar or array column by scalar.
cpl_table * gravi_data_get_table(gravi_data *self, const char *extname)
Return a pointer on a table extension by its EXTNAME.
cpl_error_code gravi_vis_erase_obs(cpl_table *oi_table, cpl_array *flag_array, cpl_size ntel)
Erase observation from an OIFITS table.
cpl_error_code gravi_flux_create_fddllin_sc(cpl_table *flux_SC, cpl_table *disp_table)
Compute the (FDDL_SC + FDDL_FT)/2 position in [m].
cpl_error_code gravi_disp_cleanup(gravi_data *vis_data)
Cleanup a VIS gravi_data before calibrating the dispersion.
cpl_table * gravi_fit_dispersion(cpl_table *oiflux_table, cpl_table *oivis_table, cpl_table *oiwave_table, double *GDrms, double *Amin, double *Amax)
Compute the dispersion coefficient of FDDLs.
cpl_error_code gravi_data_add_table(gravi_data *self, cpl_propertylist *plist, const char *extname, cpl_table *table)
Add a BINTABLE extension in gravi_data.