80 cpl_table * detector_table,
107 cpl_ensure (detector_table, CPL_ERROR_NULL_INPUT, NULL);
108 cpl_ensure (nwave>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
112 int n_region = cpl_table_get_nrow (detector_table);
115 cpl_table * p2vm_table = cpl_table_new (n_region);
118 cpl_table_duplicate_column (p2vm_table,
"REGNAME",
119 detector_table,
"REGNAME");
121 cpl_table_new_column_array (p2vm_table,
"TRANSMISSION", CPL_TYPE_FLOAT,
124 cpl_table_new_column_array (p2vm_table,
"COHERENCE", CPL_TYPE_FLOAT,
127 cpl_table_new_column_array (p2vm_table,
"PHASE", CPL_TYPE_FLOAT,
130 cpl_table_new_column_array (p2vm_table,
"C_MATRIX", CPL_TYPE_FLOAT,
134 cpl_array * zero_array_transmission, * zero_array;
135 zero_array_transmission = cpl_array_new (nwave*
ntel, CPL_TYPE_FLOAT);
136 cpl_array_fill_window_float (zero_array_transmission, 0, nwave*
ntel, 0);
138 zero_array = cpl_array_new (nwave*(
ntel*(
ntel-1)/2),
140 cpl_array_fill_window_float (zero_array, 0,
141 nwave * (
ntel * (
ntel - 1) / 2), 0);
144 for (
int i = 0; i < n_region; i++){
145 cpl_table_set_array (p2vm_table,
"TRANSMISSION", i, zero_array_transmission);
146 cpl_table_set_array (p2vm_table,
"COHERENCE", i, zero_array);
147 cpl_table_set_array (p2vm_table,
"PHASE", i, zero_array);
148 cpl_table_set_array (p2vm_table,
"C_MATRIX", i, zero_array);
151 cpl_array * dimensions;
152 dimensions = cpl_array_new (2, CPL_TYPE_INT);
155 cpl_array_set_int (dimensions, 0, nwave);
156 cpl_array_set_int (dimensions, 1,
ntel);
157 cpl_table_set_column_dimensions (p2vm_table,
"TRANSMISSION", dimensions);
160 cpl_array_set_int (dimensions, 1, (
ntel*(
ntel-1)/2));
161 cpl_table_set_column_dimensions (p2vm_table,
"COHERENCE", dimensions);
164 cpl_array_set_int (dimensions, 1, (
ntel*(
ntel-1)/2));
165 cpl_table_set_column_dimensions (p2vm_table,
"PHASE", dimensions);
167 cpl_table_set_column_dimensions (p2vm_table,
"C_MATRIX", dimensions);
169 FREE (cpl_array_delete, zero_array_transmission);
170 FREE (cpl_array_delete, zero_array);
171 FREE (cpl_array_delete, dimensions);
192 cpl_propertylist *
header,
196 cpl_ensure (wave_table, CPL_ERROR_NULL_INPUT, NULL);
197 cpl_ensure (
header, CPL_ERROR_NULL_INPUT, NULL);
224 double * calib_eff_wave;
228 if ( cpl_table_has_column(calib_eff_table ,
"FBAND_WAVE") == 1 ) {
229 calib_eff_wave = cpl_table_get_data_double (calib_eff_table,
"FBAND_WAVE");
230 cpl_msg_info(cpl_func,
"calib_eff_wave [0] : %e", calib_eff_wave[0] );
231 cpl_msg_info(cpl_func,
"calib_eff_wave [1] : %e", calib_eff_wave[1] );
232 cpl_msg_info(cpl_func,
"calib_eff_wave [2] : %e", calib_eff_wave[2] );
233 cpl_msg_info(cpl_func,
"calib_eff_wave [3] : %e", calib_eff_wave[3] );
236 cpl_msg_error(cpl_func,
"Cannot get the default values for calib_eff_wave");
237 cpl_msg_error(cpl_func,
"WAVE_TAB table in WAVE_PARAM input does not have FBAND_WAVE column");
244 cpl_msg_info (cpl_func,
"gravi_high_lbd_min : %e", gravi_high_lbd_min);
247 cpl_msg_info (cpl_func,
"gravi_high_lbd_max : %e", gravi_high_lbd_max);
250 cpl_msg_info (cpl_func,
"gravi_med_lbd_min : %e", gravi_med_lbd_min);
253 cpl_msg_info (cpl_func,
"gravi_med_lbd_max : %e", gravi_med_lbd_max);
256 cpl_msg_info (cpl_func,
"gravi_low_lbd_min : %e", gravi_low_lbd_min);
259 cpl_msg_info (cpl_func,
"gravi_low_lbd_max : %e", gravi_low_lbd_max);
271 int n_element = cpl_table_get_column_depth (wave_table,
"DATA1");
273 double max_wave ,min_wave ;
278 max_wave = gravi_low_lbd_max;
279 min_wave = gravi_low_lbd_min;
280 cpl_msg_info (cpl_func,
"Using Low resolution wavelength table");
282 }
else if (n_element<500)
286 max_wave = gravi_med_lbd_max;
287 min_wave = gravi_med_lbd_min;
288 cpl_msg_info (cpl_func,
"Using Med resolution wavelength table");
294 max_wave = gravi_high_lbd_max;
295 min_wave = gravi_high_lbd_min;
296 cpl_msg_info (cpl_func,
"Using High resolution wavelength table");
305 cpl_table * oiwave_table = cpl_table_new (nwave);
307 cpl_table_new_column (oiwave_table,
"EFF_WAVE", CPL_TYPE_FLOAT);
308 cpl_table_set_column_unit (oiwave_table,
"EFF_WAVE",
"m");
310 cpl_table_new_column (oiwave_table,
"EFF_BAND", CPL_TYPE_FLOAT);
311 cpl_table_set_column_unit (oiwave_table,
"EFF_BAND",
"m");
315 for (cpl_size wave = 0; wave < nwave; wave++){
316 double lambda = min_wave + wave * (max_wave-min_wave)/(nwave-1);
317 cpl_table_set (oiwave_table,
"EFF_WAVE", wave, lambda);
319 cpl_table_set (oiwave_table,
"EFF_BAND", wave, (max_wave-min_wave)/(nwave-1)*2);
321 if (nwave == 14) cpl_table_set (oiwave_table,
"EFF_BAND", wave, calib_eff_wave[wave]);
346 cpl_table * detector_table,
350 cpl_ensure (wave_table, CPL_ERROR_NULL_INPUT, NULL);
351 cpl_ensure (detector_table, CPL_ERROR_NULL_INPUT, NULL);
352 cpl_ensure (pol == 0 || pol == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
356 cpl_size nreg = cpl_table_get_nrow (detector_table);
359 cpl_table * oiwave_table = cpl_table_new (nwave);
361 cpl_table_new_column (oiwave_table,
"EFF_WAVE", CPL_TYPE_FLOAT);
362 cpl_table_set_column_unit (oiwave_table,
"EFF_WAVE",
"m");
364 cpl_table_new_column (oiwave_table,
"EFF_BAND", CPL_TYPE_FLOAT);
365 cpl_table_set_column_unit (oiwave_table,
"EFF_BAND",
"m");
368 for (cpl_size wave = 0; wave < nwave; wave++) {
369 double lambda = (wave == nwave-1) ? 1.0 : 0.0;
372 for (
int reg = 0; reg < nreg; reg++) {
376 if (wave == 0) lambda = CPL_MAX (lambda, value + 0.00001e-6);
377 else if (wave == nwave-1) lambda = CPL_MIN (lambda, value - 0.00001e-6);
378 else lambda += value / 24.0;
380 cpl_msg_info (cpl_func,
"lbd[%lld] = %g [um]", wave, lambda*1e6);
382 cpl_table_set (oiwave_table,
"EFF_WAVE", wave, lambda);
383 cpl_table_set (oiwave_table,
"EFF_BAND", wave, 8.5e-8);
415 cpl_table * oiwave_table;
419 cpl_ensure (wave_map, CPL_ERROR_NULL_INPUT, NULL);
432 for (
int type_data = 0; type_data < 2 ; type_data++) {
455 for (
int pol = 0 ; pol<n_pol ; pol++) {
470 cpl_propertylist * oiwave_plist = cpl_propertylist_new ();
471 cpl_propertylist_append_int (oiwave_plist,
"NWAVE", cpl_table_get_nrow (oiwave_table));
472 cpl_propertylist_update_int (oiwave_plist,
"OI_REVN", 1);
473 cpl_propertylist_append_string (oiwave_plist,
"INSNAME",
GRAVI_INSNAME(type_data,pol,n_pol));
474 cpl_propertylist_append_int (oiwave_plist,
"EXTVER",
GRAVI_EXTVER(type_data,pol,n_pol));
485 cpl_size n_wave = cpl_table_get_nrow (oiwave_table);
488 cpl_table * p2vm_table;
492 cpl_propertylist * p2vm_plist = cpl_propertylist_new();
547 int ** valid_trans,
int ** valid_pair,
551 cpl_ensure_code (p2vm_map, CPL_ERROR_NULL_INPUT);
552 cpl_ensure_code (preproc_data, CPL_ERROR_NULL_INPUT);
559 int init_type_data = 1;
560 int end_type_data = 1;
565 for (
int type_data = init_type_data; type_data <= end_type_data; type_data++ ) {
577 cpl_table * detector_table, * spectrum_table, * p2vm_table;
582 cpl_ensure_code (detector_table, CPL_ERROR_ILLEGAL_INPUT);
583 cpl_ensure_code (spectrum_table, CPL_ERROR_ILLEGAL_INPUT);
584 cpl_ensure_code (p2vm_table, CPL_ERROR_ILLEGAL_INPUT);
587 int n_region = cpl_table_get_nrow (detector_table);
588 int npol = n_region > 24 ? npol = 2 : 1;
594 int nwave = cpl_table_get_nrow (oiwave_tables[0]);
597 cpl_array ** transmission, ** coherence, ** phase, ** norma_m;
598 coherence = cpl_table_get_data_array (p2vm_table,
"COHERENCE");
599 phase = cpl_table_get_data_array (p2vm_table,
"PHASE");
600 norma_m = cpl_table_get_data_array (p2vm_table,
"C_MATRIX");
601 transmission = cpl_table_get_data_array (p2vm_table,
"TRANSMISSION");
604 int tel = -1, base = -1;
615 cpl_ensure_code (tel>=0 || base>=0, CPL_ERROR_ILLEGAL_INPUT);
621 valid_trans[type_data][tel] = 1;
624 "tel %d for %s", tel+1,
GRAVI_TYPE(type_data));
627 cpl_image * imgflux = NULL;
628 cpl_image ** spectrum_img;
629 spectrum_img = cpl_calloc (n_region,
sizeof(cpl_image*));
631 for (cpl_size region = 0; region < n_region; region++){
634 cpl_imagelist * spectrum_imglist;
638 spectrum_img[region] = cpl_imagelist_collapse_median_create (spectrum_imglist);
644 imgflux = cpl_image_duplicate (spectrum_img[region]);
646 cpl_image_add (imgflux, spectrum_img[region]);
650 double max_flux = cpl_image_get_flux (imgflux);
653 for (cpl_size region = 0; region < n_region; region++){
656 cpl_image_divide_scalar (spectrum_img[region], max_flux);
659 for (cpl_size wave = 0; wave < nwave; wave++) {
660 double value = cpl_image_get (spectrum_img[region], wave+1, 1, &nv);
661 cpl_array_set (transmission[region],
662 wave + nwave * tel, value);
680 valid_pair[type_data][base] = 1;
683 "phase of pair (%d,%d) for %s", tel1+1,
687 int nrow = cpl_table_get_nrow (spectrum_table);
694 cpl_vector * mean_opd;
696 oiwave_tables, NULL, base);
702 double residuals_avg = 0;
704 for (cpl_size wave = 0; wave < nwave; wave++){
714 cpl_matrix ** inv_matrixes = cpl_calloc (npol,
sizeof(cpl_matrix *));
715 cpl_matrix ** model_matrices = cpl_calloc (npol,
sizeof(cpl_matrix *));
717 for (
int pol = 0; pol < npol; pol ++) {
718 model_matrices[pol] = cpl_matrix_new (nrow, 3);
720 for (cpl_size row = 0; row < nrow; row++) {
721 cpl_matrix_set (model_matrices[pol], row, 0, 1.0);
722 double lambda = cpl_table_get (oiwave_tables[pol],
"EFF_WAVE", wave, NULL);
723 double phi = cpl_vector_get (mean_opd, row) / lambda * CPL_MATH_2PI;
724 double enveloppe = cpl_vector_get (envelope_vector, row);
725 cpl_matrix_set (model_matrices[pol], row, 1, sin(phi)*enveloppe);
726 cpl_matrix_set (model_matrices[pol], row, 2, cos(phi)*enveloppe);
734 for (cpl_size region = 0; region < n_region; region ++){
738 cpl_vector * y_window;
748 cpl_vector * init_val = cpl_vector_new(3);
750 for (cpl_size j = 0; j < 3; j++){
752 for (cpl_size i = 0; i < nrow; i++){
753 comp += cpl_matrix_get (inv_matrixes[pol], j, i) * cpl_vector_get (y_window, i);
755 cpl_vector_set (init_val, j, comp);
759 double residuals_sum=0;
763 for (cpl_size i = 0; i < nrow; i++){
765 for (cpl_size j = 0; j < 3; j++){
766 comp += cpl_matrix_get (model_matrices[pol], i, j) * cpl_vector_get (init_val, j);
768 if (cpl_vector_get (yerr_window, i) > 0.001 ) {
769 residuals_sum += pow((cpl_vector_get (y_window, i)-comp)/cpl_vector_get (yerr_window, i) , 2);
788 if (count > 0) residuals_avg += residuals_sum/count;
791 double coherence_fit =
792 sqrt( pow (cpl_vector_get(init_val, 2), 2) +
793 pow (cpl_vector_get(init_val, 1), 2));
795 cpl_array_set (coherence[region], wave + nwave *
796 base, coherence_fit);
800 phase_fit = atan2( cpl_vector_get(init_val, 2),
801 cpl_vector_get(init_val, 1));
803 cpl_array_set (phase[region], wave + nwave * base,
807 cpl_array_set (norma_m[region], wave + nwave * base,
808 cpl_vector_get (init_val,0));
810 FREE (cpl_vector_delete, init_val);
811 FREE (cpl_vector_delete, y_window);
812 FREE (cpl_vector_delete, yerr_window);
815 FREELOOP (cpl_matrix_delete, inv_matrixes, npol);
816 FREELOOP (cpl_matrix_delete, model_matrices, npol);
817 FREE (cpl_vector_delete, envelope_vector);
823 cpl_msg_info (cpl_func,
"Averaged of CHI2 of p2vm fit for %s base %i = %f",
GRAVI_TYPE(type_data), base+1, residuals_avg / (nwave*n_region));
824 sprintf (qc_name,
"ESO QC P2VM%s%i CHI2",
GRAVI_TYPE(type_data), base+1);
825 cpl_propertylist_append_double (p2vm_header, qc_name, residuals_avg / (nwave*n_region));
826 cpl_propertylist_set_comment (p2vm_header, qc_name,
"Chi2 avg. of p2vm fit");
828 FREE (cpl_vector_delete, mean_opd);
831 FREE (cpl_free, oiwave_tables);
839 return CPL_ERROR_NONE;
884 int ntel = 4, n_base = 6;
889 cpl_ensure_code (p2vm_map, CPL_ERROR_NULL_INPUT);
890 cpl_ensure_code (valid_trans, CPL_ERROR_NULL_INPUT);
891 cpl_ensure_code (valid_pair, CPL_ERROR_NULL_INPUT);
898 for (
int type_data = 0; type_data < 2; type_data ++){
910 cpl_table * p2vm_table, * detector_table;
915 cpl_size n_region = cpl_table_get_nrow (detector_table);
916 int n_pol = n_region > 24 ? 2 : 1;
919 cpl_table * oiwave_table;
921 cpl_size nwave = cpl_table_get_nrow (oiwave_table);
922 cpl_ensure_code (nwave, CPL_ERROR_ILLEGAL_INPUT);
925 cpl_array ** transmission, ** coherence, ** phase;
926 coherence = cpl_table_get_data_array (p2vm_table,
"COHERENCE");
927 phase = cpl_table_get_data_array (p2vm_table,
"PHASE");
928 transmission = cpl_table_get_data_array (p2vm_table,
"TRANSMISSION");
935 for (
int pol = 0; pol < n_pol; pol++) {
936 for (
int base = 0; base < 6; base++){
939 if ( !valid_pair[type_data][base])
continue;
947 for (cpl_size i = 0; i < cpl_array_get_size(phase[0]); i++){
949 double valA = cpl_array_get (phase[iA], i, NULL);
950 cpl_array_set (phase[iA], i, 0.0);
952 double valB = cpl_array_get (phase[iB], i, NULL) - valA;
953 if (valB < 0) valB += CPL_MATH_2PI;
954 cpl_array_set (phase[iB], i, valB);
956 double valC = cpl_array_get (phase[iC], i, NULL) - valA;
957 if (valC < 0) valC += CPL_MATH_2PI;
958 cpl_array_set (phase[iC], i, valC);
960 double valD = cpl_array_get (phase[iD], i, NULL) - valA;
961 if (valD < 0) valD += CPL_MATH_2PI;
962 cpl_array_set (phase[iD], i, valD);
976 int ntrans = cpl_array_get_size (transmission[0]);
977 cpl_array * mean_transmission = cpl_array_new (ntrans, CPL_TYPE_FLOAT);
978 cpl_array_fill_window (mean_transmission, 0, ntrans, 0.);
980 for (cpl_size region = 0; region < n_region; region++) {
981 cpl_array_add (mean_transmission,transmission[region]);
983 cpl_array_divide_scalar (mean_transmission, n_region);
986 for (cpl_size region = 0; region < n_region; region++){
987 cpl_array_divide (transmission[region], mean_transmission);
989 FREE (cpl_array_delete, mean_transmission);
996 double mean_flux[4] = {0.0,0.0,0.0,0.0};
997 int n_flux[4] = {0,0,0,0};
1000 for (
int base = 0; base < 6; base++) {
1005 for (cpl_size wave = 0; wave < nwave; wave++){
1008 cpl_matrix * matrix_T = cpl_matrix_new (n_region, 4);
1012 cpl_matrix * matrix_c = cpl_matrix_new (n_region, 1);
1013 for(cpl_size region = 0; region < n_region; region++) {
1014 cpl_matrix_set (matrix_c, region, 0, cpl_vector_get (vector_c, region));
1015 for (
int tel = 0; tel <
ntel; tel++){
1016 cpl_matrix_set (matrix_T, region, tel,
1017 cpl_array_get (transmission[region],
1018 tel*nwave+wave ,&nv));
1021 FREE (cpl_vector_delete, vector_c);
1024 cpl_errorstate prestate = cpl_errorstate_get();
1026 cpl_matrix * matrix_I = cpl_matrix_solve_normal (matrix_T, matrix_c);
1029 if (! strcmp(
"Singular matrix", cpl_error_get_message())){
1030 cpl_msg_warning(cpl_func,
"matrix_c or matrix_T "
1031 "are singular for tel1 = %d tel2 = %d and wave = %lld",
1033 cpl_errorstate_set (prestate);
1034 cpl_matrix_delete (matrix_T);
1035 cpl_matrix_delete (matrix_I);
1036 cpl_matrix_delete (matrix_c);
1041 mean_flux[tel0] += cpl_matrix_get (matrix_I, tel0, 0);
1042 mean_flux[tel1] += cpl_matrix_get (matrix_I, tel1, 0);
1047 double F0 = cpl_matrix_get (matrix_I, tel0, 0);
1048 double F1 = cpl_matrix_get (matrix_I, tel1, 0);
1049 double coeff = sqrt (fabs(F0*F1));
1053 for (cpl_size region = 0; region < n_region; region++){
1054 double value = cpl_array_get (coherence[region],
1055 wave+nwave*base, &nv);
1056 cpl_array_set (coherence[region],
1062 FREE (cpl_matrix_delete, matrix_c);
1063 FREE (cpl_matrix_delete, matrix_I);
1064 FREE (cpl_matrix_delete, matrix_T);
1075 for (
int tel = 0; tel<4; tel++ ) {
1076 cpl_msg_info (cpl_func,
"Mean flux tel%i = %f (n=%i)", tel, mean_flux[tel] / n_flux[tel], n_flux[tel]);
1077 sprintf (qc_name,
"ESO QC FLUX_%s%i AVG",
GRAVI_TYPE(type_data), tel);
1078 cpl_propertylist_append_double (p2vm_header, qc_name, mean_flux[tel] / n_flux[tel]);
1079 cpl_propertylist_set_comment (p2vm_header, qc_name,
"[e/DIT/chanel/output/file] mean flux");
1089 cpl_array * sig_phi_arr = cpl_array_new(n_region, CPL_TYPE_DOUBLE);
1090 cpl_array * sig_coh_arr = cpl_array_new(n_region, CPL_TYPE_DOUBLE);
1091 cpl_array * mean_coh_arr = cpl_array_new(n_region, CPL_TYPE_DOUBLE);
1092 cpl_array * mean_coh_base_arr = cpl_array_new(n_base, CPL_TYPE_DOUBLE);
1093 cpl_array * min_coh_base_arr = cpl_array_new(n_base, CPL_TYPE_DOUBLE);
1094 cpl_array * max_coh_base_arr = cpl_array_new(n_base, CPL_TYPE_DOUBLE);
1095 cpl_array * mean_trans_arr = cpl_array_new(n_region, CPL_TYPE_DOUBLE);
1096 cpl_array * sig_transdiff_arr = cpl_array_new(n_region, CPL_TYPE_DOUBLE);
1098 cpl_array_fill_window (mean_coh_base_arr, 0, n_base, 0);
1099 cpl_array_fill_window (min_coh_base_arr, 0, n_base, 10);
1100 cpl_array_fill_window (max_coh_base_arr, 0, n_base, 0);
1103 for (cpl_size region = 0; region < n_region; region ++ ) {
1111 cpl_array * coh_region = cpl_array_extract (coherence[region],
1113 cpl_array * trans_tel1 = cpl_array_extract (transmission[region],
1115 cpl_array * trans_tel2 = cpl_array_extract (transmission[region],
1117 cpl_array * ph_region = cpl_array_extract (phase[region],
1121 cpl_array_set (mean_coh_arr, region,
1122 cpl_array_get_mean (coh_region));
1124 cpl_array_set (sig_coh_arr, region,
1125 cpl_array_get_stdev (coh_region));
1127 cpl_array_set (mean_trans_arr, region,
1128 (cpl_array_get_mean (trans_tel1) +
1129 cpl_array_get_mean (trans_tel2)) /2);
1131 cpl_array_set (sig_phi_arr, region,
1132 cpl_array_get_stdev (ph_region));
1134 cpl_array * diff_trans;
1135 diff_trans = cpl_array_duplicate (trans_tel1);
1136 cpl_array_subtract (diff_trans, trans_tel2);
1137 cpl_array_set (sig_transdiff_arr, region,
1138 cpl_array_get_stdev (diff_trans));
1139 cpl_array_delete (diff_trans);
1142 cpl_array_power (trans_tel1, 0.5);
1143 cpl_array_power (trans_tel2, 0.5);
1144 cpl_array_divide (coh_region, trans_tel1);
1145 cpl_array_divide (coh_region, trans_tel2);
1146 cpl_array_divide_scalar (coh_region, 2.);
1149 cpl_array_set (mean_coh_base_arr, base,
1150 cpl_array_get (mean_coh_base_arr, base, NULL) +
1151 cpl_array_get_mean (coh_region)/(n_region/6));
1157 if (cpl_array_get(min_coh_base_arr, base, NULL) > min_percentile)
1158 cpl_array_set(min_coh_base_arr, base, min_percentile);
1160 if (cpl_array_get(max_coh_base_arr, base, NULL) < max_percentile)
1161 cpl_array_set(max_coh_base_arr, base, max_percentile);
1164 cpl_array_delete (coh_region);
1165 cpl_array_delete (trans_tel2);
1166 cpl_array_delete (trans_tel1);
1167 cpl_array_delete (ph_region);
1171 CPLCHECK_MSG (
"Cannot compute_the averages values per region");
1174 double mean_coh, sig_coh, sig_phi, min_trans, mean_trans, max_trans;
1175 mean_coh = cpl_array_get_mean (mean_coh_arr) /
1176 (2*cpl_array_get_mean (mean_trans_arr));
1177 sig_coh = cpl_array_get_mean (sig_coh_arr) /
1178 (2*cpl_array_get_mean (mean_trans_arr));
1179 sig_phi = cpl_array_get_mean (sig_phi_arr);
1180 min_trans = cpl_array_get_min (mean_trans_arr)/2.;
1181 max_trans = cpl_array_get_max (mean_trans_arr)/2.;
1182 mean_trans = cpl_array_get_mean (mean_trans_arr)/2.;
1199 cpl_msg_info (cpl_func,
"QC %s COH_AVG = %e COH_RMS %e PHASE_RMS = %e TRANS_AVG %e TRANS_MIN = %e TRANS_MAX = %e",
1200 GRAVI_TYPE(type_data), mean_coh, (sig_coh), sig_phi, min_trans, mean_trans, max_trans);
1205 for (
int base=0; base< n_base; base++){
1209 cpl_array_get (mean_coh_base_arr, base, NULL));
1210 cpl_propertylist_set_comment (p2vm_header, qc_name,
1211 "Avg coh. over lbd per baseline");
1216 cpl_array_get (min_coh_base_arr, base, NULL));
1217 cpl_propertylist_set_comment (p2vm_header, qc_name,
1218 "Min coh. (5 perc) over lbd per baseline");
1223 cpl_array_get (max_coh_base_arr, base, NULL));
1224 cpl_propertylist_set_comment (p2vm_header, qc_name,
1225 "Max coh. (95 perc) over lbd per baseline");
1229 FREE (cpl_array_delete, sig_phi_arr);
1230 FREE (cpl_array_delete, sig_coh_arr);
1231 FREE (cpl_array_delete, mean_coh_arr);
1232 FREE (cpl_array_delete, mean_trans_arr);
1233 FREE (cpl_array_delete, sig_transdiff_arr);
1234 FREE (cpl_array_delete, mean_coh_base_arr);
1235 FREE (cpl_array_delete, min_coh_base_arr);
1236 FREE (cpl_array_delete, max_coh_base_arr);
1241 return CPL_ERROR_NONE;
1272 cpl_ensure_code (p2vm_map, CPL_ERROR_NULL_INPUT);
1273 cpl_ensure_code (p2vmred_data, CPL_ERROR_NULL_INPUT);
1283 for (
int type_data = 0; type_data < 2; type_data ++) {
1291 cpl_msg_info (cpl_func,
"Calibrate the internal phase of %s (%s)",
1292 GRAVI_TYPE(type_data),full_phase?
"full phases":
"closure phases");
1295 cpl_array ** visphase = cpl_calloc (12,
sizeof(cpl_array*));
1299 for (
int pol= 0 ; pol < npol ; pol++ ) {
1301 cpl_msg_info (cpl_func,
"Compute correction for pol %i over %i", pol+1, npol);
1307 cpl_size nrow = cpl_table_get_nrow (oi_vis) / 6;
1310 cpl_array ** visdata = cpl_table_get_data_array (oi_vis,
"VISDATA");
1311 float * wavedata = cpl_table_get_data_float (oi_wave,
"EFF_WAVE");
1312 cpl_size nwave = cpl_array_get_size (visdata[0]);
1313 cpl_size wave0 = nwave/2;
1321 double ** opl = cpl_malloc (
sizeof(
double*) * nrow);
1322 for (cpl_size row=0 ; row<nrow ; row++) {
1323 opl[row] = cpl_malloc (
sizeof(
double) * 4);
1325 for (
int base= 1 ; base < 4 ; base++ ) {
1326 opl[row][base] = carg (cpl_array_get_complex (visdata[row * 6 + base-1], wave0, &nv));
1331 for (
int base= 1 ; base < 4 ; base++ ) {
1332 double wrap = 0.0, ref = opl[0][base];
1333 for (cpl_size row=1 ; row<nrow ; row++) {
1334 if ( (opl[row][base] - ref) < -CPL_MATH_PI ) wrap += 2.*CPL_MATH_PI;
1335 if ( (opl[row][base] - ref) > CPL_MATH_PI ) wrap -= 2.*CPL_MATH_PI;
1336 ref = opl[row][base];
1337 opl[row][base] += wrap;
1342 for (
int base= 1 ; base < 4 ; base++ ) {
1344 for (cpl_size row=0 ; row<nrow ; row++) mean += opl[row][base];
1345 for (cpl_size row=0 ; row<nrow ; row++) opl[row][base] -= mean / nrow;
1353 cpl_msg_debug (cpl_func,
"Compute coherent integration of VISDATA");
1355 for (
int base = 0 ; base < 6 ; base++ ) {
1357 visphase[base + pol*6] = cpl_array_new (nwave, CPL_TYPE_FLOAT_COMPLEX);
1358 cpl_array_fill_window_complex (visphase[base + pol*6], 0, nwave, 0.0 * I + 0.0);
1361 for (cpl_size row=0 ; row<nrow ; row++) {
1363 for (cpl_size wave=0; wave<nwave; wave++)
1364 cpl_array_set_complex (visphase[base + pol*6], wave,
1365 cpl_array_get_complex (visphase[base + pol*6], wave, &nv) +
1366 cpl_array_get_complex (visdata[row * 6 + base], wave, &nv) *
1367 cexp (-1.*I * x * wavedata[wave0] / wavedata[wave]) );
1383 cpl_array ** ref = cpl_malloc (4 *
sizeof(cpl_array*));
1384 ref[0] = cpl_array_new (nwave, CPL_TYPE_DOUBLE_COMPLEX);
1385 cpl_array_fill_window_complex (ref[0], 0, nwave, 0.0 * I + 1.0);
1387 if (full_phase == 0) {
1389 cpl_msg_info (cpl_func,
"Force phiA(lbd) to be zero for baselines (01,02,03) = keep only closures");
1391 for (
int base = 0; base<3 ; base++)
1392 ref[base+1] = cpl_array_duplicate (visphase[base + pol*6]);
1394 }
else if (full_phase == 1) {
1396 cpl_msg_info (cpl_func,
"Force phiA(lbd) to have zero mean and minimum GD for baselines (01,02,03)");
1398 for (
int base = 0; base<3 ; base++) {
1401 &gd, 1, 2e-3, CPL_FALSE);
1402 cpl_array * tmp = cpl_array_duplicate (visphase[base + pol*6]);
1404 gd += carg (cpl_array_get_mean_complex (tmp)) / CPL_MATH_2PI / cpl_array_get_mean (sigma);
1405 cpl_array_delete (tmp);
1409 }
else if (full_phase == 2) {
1411 cpl_msg_info (cpl_func,
"Force phiA(lbd) to have zero-GD for baselines (01,02,03)");
1413 for (
int base = 0; base<3 ; base++) {
1416 &gd, 1, 2e-3, CPL_FALSE);
1420 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
"Option for phase calibration out of range");
1425 for (
int base = 0 ; base < 6 ; base++ ) {
1426 cpl_array_multiply (visphase[base + pol*6], ref[
GRAVI_BASE_TEL[base][0]]);
1435 for (
int base = 0 ; base < 6 ; base++ ) {
1437 cpl_msg_info (cpl_func,
"Performing wiggle removal on baseline %i (pol %i over %i)",
1438 base+1, pol+1, npol);
1441 cpl_size mindeg = 0, maxdeg = 6;
1442 cpl_polynomial * fit = cpl_polynomial_new (1);
1446 cpl_array * phase_unwraped = cpl_array_cast (visphase[base + pol*6], CPL_TYPE_DOUBLE_COMPLEX);
1451 &gd, 1, 2e-3, CPL_FALSE);
1455 double mean_phase = carg (cpl_array_get_mean_complex (phase_unwraped));
1456 cpl_array_multiply_scalar_complex (phase_unwraped, cexp(- I * mean_phase));
1459 cpl_array_arg (phase_unwraped);
1461 cpl_array_add_scalar (phase_unwraped, mean_phase);
1465 double sigma0 = cpl_array_get_mean (sigma);
1466 double delta0 = cpl_array_get_max (sigma)-cpl_array_get_min (sigma);
1468 cpl_matrix * sigma_matrix = cpl_matrix_new (1,nwave);
1469 for (cpl_size wave = 0; wave < nwave; wave ++) {
1470 cpl_matrix_set (sigma_matrix, 0, wave, (cpl_array_get (sigma,wave,&nv) - sigma0)/delta0 );
1474 cpl_vector * input = cpl_vector_wrap (nwave, cpl_array_get_data_double (phase_unwraped));
1475 cpl_polynomial_fit (fit, sigma_matrix, NULL, input, NULL, CPL_FALSE, &mindeg, &maxdeg);
1476 cpl_vector_unwrap (input);
1477 cpl_array_delete (phase_unwraped);
1480 for (cpl_size wave=0; wave<nwave;wave++) {
1481 cpl_array_set_complex (visphase[base + pol*6], wave, cexp( I * cpl_polynomial_eval_1d (fit, cpl_matrix_get (sigma_matrix,0,wave), NULL)));
1484 FREE (cpl_polynomial_delete, fit);
1485 FREE (cpl_matrix_delete, sigma_matrix);
1488 FREELOOP (cpl_array_delete, ref, 4);
1490 FREE (cpl_array_delete, sigma);
1502 cpl_msg_info (cpl_func,
"Apply correction to P2VM phases");
1505 cpl_array ** phase = cpl_table_get_data_array (p2vm,
"PHASE");
1506 cpl_size nreg = cpl_table_get_nrow (p2vm);
1507 cpl_size nwave = cpl_array_get_size (visphase[0]);
1510 for (cpl_size reg=0; reg<nreg; reg++) {
1517 for (cpl_size wave=0; wave<nwave;wave++) {
1518 double phi = carg ( cexp (1.*I*cpl_array_get (phase[reg], wave + nwave * base, &nv)) *
1519 conj(cpl_array_get_complex (visphase[base + pol*6], wave, &nv) ));
1520 cpl_array_set (phase[reg], wave + nwave * base, (phi>=0.0?phi:phi+CPL_MATH_2PI));
1526 FREELOOP (cpl_array_delete, visphase, 12);
1531 return CPL_ERROR_NONE;
1553 cpl_ensure_code (p2vm_map, CPL_ERROR_NULL_INPUT);
1554 cpl_ensure_code (p2vmred_data, CPL_ERROR_NULL_INPUT);
1559 for (
int type_data = 0; type_data < 2; type_data ++) {
1563 for (
int pol = 0; pol < npol; pol++) {
1565 cpl_msg_info (cpl_func,
"Compute the internal transmission of %s (pol %i over %i)",
1570 cpl_array ** flux = cpl_table_get_data_array (flux_tbl,
"FLUX");
1571 cpl_size nwave = cpl_array_get_size (flux[0]);
1572 cpl_size nrow = cpl_table_get_nrow (flux_tbl) / 4;
1576 cpl_array * flux_mean = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
1580 for (
int tel = 0; tel < 4; tel++) {
1583 cpl_array_fill_window (flux_mean, 0, nwave, 0.0);
1584 for (cpl_size row = 0; row < nrow; row++) {
1585 cpl_array_add (flux_mean, flux[tel + row*4]);
1589 cpl_array_divide_scalar (flux_mean, cpl_array_get_mean (flux_mean));
1592 cpl_table_set_array (oi_flux,
"FLUX", tel, flux_mean);
1595 cpl_array_fill_window (flux_mean, 0, nwave, 0.0);
1596 cpl_table_set_array (oi_flux,
"FLUXERR", tel, flux_mean);
1600 FREE (cpl_array_delete, flux_mean);
1613 return CPL_ERROR_NONE;
#define GRAVI_PRIMARY_HDR_EXT
#define gravi_table_get_value(table, name, row, value)
typedefCPL_BEGIN_DECLS struct _gravi_data_ gravi_data
#define gravi_data_has_wave(data, type)
#define gravi_data_has_p2vm(data, type)
#define gravi_data_get_spectrum_data(data, type)
#define gravi_data_get_wave_data(data, type)
#define gravi_data_get_oi_flux(data, type, pol, npol)
#define gravi_data_get_header(data)
#define gravi_data_get_oi_wave(data, type, pol, npol)
#define gravi_data_get_oi_flux_plist(data, type, pol, npol)
#define gravi_data_get_p2vm_data(data, type)
#define gravi_data_has_spectrum(data, type)
#define gravi_data_get_imaging_detector(data, type)
#define gravi_data_get_oi_vis(data, type, pol, npol)
cpl_msg_debug(cpl_func, "Spectra has <50 pixels -> don't flat")
cpl_propertylist * header
cpl_msg_info(cpl_func, "Compute WAVE_SCAN for %s", GRAVI_TYPE(type_data))
cpl_propertylist_update_double(header, "ESO QC MINWAVE SC", cpl_propertylist_get_double(plist, "ESO QC MINWAVE SC"))
cpl_image_delete(flat_profiled)
#define GRAVI_INSNAME(type, pol, npol)
#define GRAVI_P2VM_DATA_FT_EXT
#define GRAVI_OI_FLUX_EXT
#define GRAVI_P2VM_DATA_SC_EXT
#define GRAVI_EXTVER(type, pol, npol)
#define GRAVI_P2VM_MET_EXT
#define GRAVI_IMAGING_DETECTOR_EXT(type)
#define GRAVI_OI_WAVELENGTH_EXT
#define gravi_spectrum_get_npol(table)
#define gravi_msg_function_exit(flag)
#define FREE(function, variable)
#define CPLCHECK_NUL(msg)
#define gravi_msg_function_start(flag)
#define CPLCHECK_MSG(msg)
#define FREELOOP(function, variable, n)
cpl_array * gravi_array_cexp(double complex factor, const cpl_array *input)
Compute the complex exponention of an array: cexp (factor * input)
cpl_matrix * gravi_matrix_invertSV_create(cpl_matrix *a_in)
Invers a matrix with singular value decomposition.
cpl_error_code gravi_array_add_phase(cpl_array *input, double factor, cpl_array *phase)
Add a REAL phase to a REAL phase array, in-place: input = input + factor * phase.
cpl_imagelist * gravi_imagelist_wrap_column(cpl_table *table_data, const char *data_x)
Wrap a column array of a table into an imagelist.
double gravi_array_get_quantile(cpl_array *arr, double thr)
Compute the value of the vector corresponding to the quantile 'thr' (0 < thr < 1)
cpl_error_code gravi_imagelist_unwrap_images(cpl_imagelist *imglist)
Unwrap an imagelist an all its images.
cpl_error_code gravi_array_get_group_delay_loop(cpl_array **input, cpl_array **flag, cpl_array *sigma, double *gd, cpl_size nrow, double max_width, int verbose)
Optimized computation of GDELAY for a list of arrays.
cpl_vector * gravi_table_get_vector(cpl_table *spectrum_data, cpl_size index, const char *regname)
Create a vector from the row index of the column regname.
cpl_array * gravi_table_create_sigma_array(cpl_table *oi_wave)
cpl_error_code gravi_array_multiply_phasor(cpl_array *input, double complex factor, cpl_array *phase)
Multiply a REAL phase to a COMPLEX array, in-place: input = input * cexp (factor * phase)
cpl_error_code gravi_array_multiply_conj(cpl_array *input1, cpl_array *input2)
cpl_propertylist * gravi_data_get_plist(gravi_data *self, const char *extname)
Get the propertylist from EXTNAME.
gravi_data * gravi_data_new(int nb_ext)
Create an empty gravi_data.
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.
cpl_table ** gravi_data_get_oiwave_tables(gravi_data *data, int type_data, int npol)
Get pointer to the OI_WAVELENGTH tables of both polarisations.
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_data_copy_ext(gravi_data *output, gravi_data *input, const char *name)
Copy extensions from one data to another.
cpl_vector * gravi_ellipse_meanopd_create(cpl_table *spectrum_table, cpl_table *detector_table, cpl_table **oiwave_tables, cpl_vector *guess_vector, int base)
Compute the OPD modulation of a baseline from spectrum.
cpl_error_code gravi_p2vm_phase_correction(gravi_data *p2vm_map, gravi_data *p2vmred_data, int full_phase)
Correct the phase of the P2VM from internal closure-phases.
cpl_error_code gravi_p2vm_normalisation(gravi_data *p2vm_map, int **valid_trans, int **valid_pair)
The given output FITS file contain a p2vm table with the values of the transmission,...
cpl_table * gravi_create_oiwave_table_sc(cpl_table *wave_table, cpl_propertylist *header, gravi_data *wave_param)
Create a new oiwave table for SC.
cpl_error_code gravi_compute_p2vm(gravi_data *p2vm_map, gravi_data *preproc_data, int **valid_trans, int **valid_pair, enum gravi_detector_type det_type)
The given output FITS file contain a p2vm table with the values of the transmission,...
cpl_table * gravi_create_oiwave_table_ft(cpl_table *wave_table, cpl_table *detector_table, int pol)
Create a new oiwave table for FT.
cpl_error_code gravi_p2vm_transmission(gravi_data *p2vm_map, gravi_data *p2vmred_data)
Compute the flux normalisation in the P2VM.
gravi_data * gravi_create_p2vm(gravi_data *wave_map, gravi_data *wave_param)
Create a new P2VM map.
cpl_table * gravi_create_p2vm_table(cpl_table *detector_table, int nwave)
Create a new p2vm table.
int gravi_pfits_get_pola_num(const cpl_propertylist *plist, int type_data)
int gravi_region_get_pol(cpl_table *imaging_detector, int region)
Return the polarisation id of a region.
int gravi_region_get_base(cpl_table *imaging_detector, int region)
Return the base of a region.
char GRAVI_BASE_NAME[6][3]
cpl_size gravi_spectrum_get_nwave(const cpl_table *table)
int gravi_check_shutter(cpl_propertylist *header, int t0, int t1, int t2, int t3)
char GRAVI_DATAERR[50][10]
cpl_vector * gravi_compute_envelope(const cpl_vector *opd, int wave, int nwave)
Compute the envelope value.
int GRAVI_BASE_TEL[GRAVI_NBASE][2]
int gravi_get_region(cpl_table *img_det, int base, char phase, int pol)
Find the region matching base, phase and pol.
cpl_table * gravi_table_oi_create(int nwave, int nrow, const char *oi_name)
Create the oi table (oi_vis, oi_vis2, oi_t3)
int gravi_wave_get_nlambda(cpl_table *wave_data, double lambda_min, double lambda_max)
Get the number of spectral element between lambdamin et lambdamax.