678 long tel, diode, side;
682 double x0, y0, x1, y1, xc, yc, delta_phase, sum_cos, sum_sin, new_phase, sq1, rms, tmp, speed;
684 int flag, comb_flag, sum_flag;
686 double cos_delta_phase, sin_delta_phase;
693 long buffer_idx_avg =((sample_number - 1) % tacConfiguration->
number_to_average);
694 long prev_idx_avg = buffer_idx_avg - 1;
695 if(prev_idx_avg < 0) {
699 long buffer_idx_rms = ((sample_number - 1) % tacConfiguration->
number_for_rms);
700 long buffer_idx_speed = ((sample_number - 1) % tacConfiguration->
number_for_speed);
702 long prev_idx_speed = buffer_idx_speed - 1;
703 if(prev_idx_speed < 0) {
711 for (tel = 0; tel < 4; tel++) {
712 for (side =
FT; side <=
SC; side++) {
723 xc = x1 * x0 + y1 * y0;
724 yc = x1 * y0 - y1 * x0;
729 sq1 = sqrt(x1*x1+y1*y1);
735 xc = x1 * x0 + y1 * y0;
736 yc = x1 * y0 - y1 * x0;
744 for(diode = 0; diode < 4; diode++) {
755 xc = x1 * x0 + y1 * y0;
756 yc = x1 * y0 - y1 * x0;
762 sq1 = sqrt(x1*x1+y1*y1);
768 xc = x1 * x0 + y1 * y0;
769 yc = x1 * y0 - y1 * x0;
784 for (tel = 0; tel < 4; tel++) {
785 for (side =
FT; side <=
SC; side++) {
793 for(diode = 0; diode < 4; diode++) {
806 for (tel = 0; tel < 4; tel++) {
807 for (side =
FT; side <=
SC; side++) {
808 if(sample_number == 1) {
820 if(sample_number < tacConfiguration->number_to_average) {
825 for(diode = 0; diode < 4; diode++) {
826 if(sample_number == 1) {
836 if(sample_number < tacConfiguration->number_to_average) {
846 for (tel = 0; tel < 4; tel++) {
847 for (side =
FT; side <=
SC; side++) {
858 xc = x1 * x0 + y1 * y0;
859 yc = x1 * y0 - y1 * x0;
910 cos_delta_phase = cos(delta_phase);
911 sin_delta_phase = sin(delta_phase);
916 idx = buffer_idx_avg;
925 sum_cos += x0 * x1 - y0 * y1;
926 sum_sin += x0 * y1 + x1 * y0;
931 tmp = x1 * cos_delta_phase - y1 * sin_delta_phase;
932 y1 = x1 * sin_delta_phase + y1 * cos_delta_phase;
937 new_phase =
myAtan(sum_cos, sum_sin, &flag) + delta_phase;
958 for(diode = 0; diode < 4; diode++) {
969 xc = x1 * x0 + y1 * y0;
970 yc = x1 * y0 - y1 * x0;
1019 idx = buffer_idx_avg;
1023 cos_delta_phase = cos(delta_phase);
1024 sin_delta_phase = sin(delta_phase);
1034 sum_cos += x0 * x1 - y0 * y1;
1035 sum_sin += x0 * y1 + x1 * y0;
1040 tmp = x1 * cos_delta_phase - y1 * sin_delta_phase;
1041 y1 = x1 * sin_delta_phase + y1 * cos_delta_phase;
1046 new_phase =
myAtan(sum_cos, sum_sin, &flag) + delta_phase;
1069 for (tel = 0; tel < 4; tel++) {
1070 for (side =
FT; side <=
SC; side++) {
1072 for(diode = 0; diode < 4; diode++) {
1104 for (tel = 0; tel < 4; tel++) {
1105 for (side =
FT; side <=
SC; side++) {
1108 for (diode = 0; diode < 4; diode++) {
1111 xc = x0 * x1 + y0 * y1;
1112 yc = x0 * y1 - y0 * x1;
1124 flux = sqrt(sqflux);
1125 tacData->
flux_diff[tel][diode][side] = flux;
1166 for (tel = 0; tel < 4; tel++) {
1167 for (side =
FT; side <=
SC; side++) {
1168 for (diode = 0; diode < 4; diode++) {
1170 if(sample_number <= tacConfiguration->number_to_smooth_for_telescope) {
1188 for (tel = 0; tel < 4; tel++) {
1189 for (side =
FT; side <=
SC; side++) {
1190 for (diode = 0; diode < 4; diode++) {
1204 for (tel = 0; tel < 4; tel++) {
1205 for (side =
FT; side <=
SC; side++) {
1208 for (diode = 0; diode < 4; diode++) {
1235 for (tel = 0; tel < 4; tel++) {
1236 for (side =
FT; side <=
SC; side++) {
1266 printf(
"After freezing: speed predictor too far from where phase is, pred: %f, phase: %f\n",
1288 for (tel = 0; tel < 4; tel++) {
1290 for (diode = 0; diode < 4; diode++) {
1299 for (tel = 0; tel < 4; tel++) {
1300 for (diode = 0; diode < 4; diode++) {
1958 cpl_table * vismet_table,
1959 cpl_propertylist *
header,
1960 const cpl_parameterlist * parlist)
1963 cpl_ensure_code (metrology_table, CPL_ERROR_NULL_INPUT);
1964 cpl_ensure_code (
header, CPL_ERROR_NULL_INPUT);
1969 double timer1_start=0;
1970 double timer2_start=0;
1976 double preswitch_delay =
gravi_param_get_int(parlist,
"gravity.metrology.preswitch-delay");
1977 double postswitch_delay =
gravi_param_get_int(parlist,
"gravity.metrology.postswitch-delay");
1983 rate1 = 1e6*cpl_vector_get(faint_params,0);
1984 repeat1 = cpl_vector_get(faint_params,1);
1985 rate2 = 1e6*cpl_vector_get(faint_params,3);
1986 repeat2 = cpl_vector_get(faint_params,4);
1989 cpl_msg_debug(cpl_func,
"ESO INS ANLO3 REPEAT1: %g",repeat1);
1990 cpl_msg_debug(cpl_func,
"ESO INS ANLO3 TIMER1: %g",cpl_vector_get(faint_params,2));
1992 cpl_msg_debug(cpl_func,
"ESO INS ANLO3 REPEAT2: %g",repeat2);
1993 cpl_msg_debug(cpl_func,
"ESO INS ANLO3 TIMER2: %g",cpl_vector_get(faint_params,5));
2002 timer1_start = 1e6*(cpl_vector_get(faint_params,2) - time_ref);
2003 timer2_start = 1e6*(cpl_vector_get(faint_params,5) - time_ref);
2006 cpl_msg_debug(cpl_func,
"FAINT TIMER1 phase ref: %g",time_ref);
2007 cpl_msg_debug(cpl_func,
"FAINT TIMER1 start: %g",timer1_start);
2008 cpl_msg_debug(cpl_func,
"FAINT TIMER2 start: %g",timer2_start);
2011 cpl_vector_delete(faint_params);
2017 int ind_sintel_FT[4][4]={{0,2,4,6},
2021 int ind_costel_FT[4][4]={{1,3,5,7},
2025 int ind_sintel_SC[4][4]={{32,34,36,38},
2029 int ind_costel_SC[4][4]={{33,35,37,39},
2033 int ind_sinfc_FT[4]={64,66,68,70};
2034 int ind_cosfc_FT[4]={65,67,69,71};
2035 int ind_sinfc_SC[4]={72,74,76,78};
2036 int ind_cosfc_SC[4]={73,75,77,79};
2038 cpl_array ** raw_met=cpl_table_get_data_array(metrology_table,
"VOLT");
2039 cpl_size nbrow_met = cpl_table_get_nrow (metrology_table);
2049 cpl_array * bright_array = cpl_array_new(nbrow_met,CPL_TYPE_DOUBLE);
2050 cpl_array_fill_window (bright_array, 0, nbrow_met, 1);
2052 cpl_array * good_met_array = cpl_array_new(nbrow_met,CPL_TYPE_DOUBLE);
2053 cpl_array_fill_window (good_met_array, 0, nbrow_met, 1);
2055 int Nbefore=(int) (preswitch_delay*0.5);
2056 int Nafter=(int) (postswitch_delay*0.5);
2060 if (cpl_table_has_column (metrology_table,
"FLAG"))
2062 cpl_msg_info(cpl_func,
"Now reading the metrology flag to check the bright/faint status");
2063 for (cpl_size row = 0; row < nbrow_met; row ++)
2065 int flag = cpl_table_get_int (metrology_table,
"FLAG", row, NULL);
2067 cpl_array_set_double(bright_array,row,0.0);
2070 cpl_msg_warning(cpl_func,
"Using theoretical information to check the bright/faint status");
2071 for (cpl_size row = 0; row < nbrow_met; row ++)
2073 int time_met = cpl_table_get_int (metrology_table,
"TIME", row, NULL);
2074 for (
int repeat_counter = 0; repeat_counter < repeat1; repeat_counter ++)
2076 if ( time_met > timer1_start+rate1*repeat_counter &&
2077 time_met < timer2_start+rate2*repeat_counter)
2078 cpl_array_set_double(bright_array,row,0.0);
2083 cpl_msg_info(cpl_func,
"Removing part of the metrology that correspond to brigthnesse change ...");
2084 cpl_msg_info(cpl_func,
"this means removing %.1fms before and %.1fms after (%i,%i DITs)",preswitch_delay,postswitch_delay,Nbefore,Nafter);
2086 for (cpl_size row = 0; row < nbrow_met-1; row ++)
2088 if (((cpl_array_get(bright_array,row, NULL) > 0.1)&&(cpl_array_get(bright_array,row+1, NULL) < 0.1))||
2089 ((cpl_array_get(bright_array,row, NULL) < 0.1)&&(cpl_array_get(bright_array,row+1, NULL) > 0.1)))
2092 cpl_array_fill_window (good_met_array, 0, row+Nafter, 0);
2093 else if (row+Nafter >=nbrow_met)
2094 cpl_array_fill_window (good_met_array, row-Nbefore, nbrow_met-1-row+Nbefore, 0);
2096 cpl_array_fill_window (good_met_array, row-Nbefore, Nbefore+Nafter, 0);
2100 cpl_array_multiply (bright_array, good_met_array);
2111 int DIT_smooth_faint = DIT_smooth + Nbefore + Nafter;
2113 cpl_msg_info (cpl_func,
"Smoothing volts of the FC diodes by %d metrology DITS",DIT_smooth*2+1);
2115 for (cpl_size diode = 64; diode < 80; diode ++) {
2117 cpl_array * volt_array = cpl_array_new(nbrow_met,CPL_TYPE_DOUBLE);
2119 for (cpl_size row = 0; row < nbrow_met; row ++)
2120 cpl_array_set_double(volt_array,row,cpl_array_get (raw_met[row], diode, NULL) );
2122 cpl_array_multiply (volt_array, good_met_array);
2126 cpl_array * volts_smooth_array_faint=
gravi_array_smooth (volt_array, DIT_smooth_faint);
2131 for (cpl_size row = 0; row < nbrow_met; row ++)
2133 if (cpl_array_get(bright_array,row, NULL) < 0.1)
2134 cpl_array_set_float(raw_met[row],diode,cpl_array_get_double (volts_smooth_array_faint, row, NULL) );
2136 cpl_array_set_float(raw_met[row],diode,cpl_array_get_double (volts_smooth_array, row, NULL) );
2140 cpl_array_delete(volt_array);
2141 cpl_array_delete(volts_smooth_array);
2142 cpl_array_delete(volts_smooth_array_faint);
2146 cpl_msg_info (cpl_func,
"Smoothing volts of the FC diodes done");
2156 cpl_msg_info (cpl_func,
"Smoothing volts of the TEL diodes by %d metrology DITS",DIT_smooth*2+1);
2158 for (cpl_size diode = 0; diode < 64; diode ++) {
2160 cpl_array * volt_array = cpl_array_new(nbrow_met,CPL_TYPE_DOUBLE);
2162 for (cpl_size row = 0; row < nbrow_met; row ++)
2163 cpl_array_set_double(volt_array,row,cpl_array_get (raw_met[row], diode, NULL) );
2169 for (cpl_size row = 0; row < nbrow_met; row ++)
2170 cpl_array_set_float(raw_met[row],diode,cpl_array_get_double (volts_smooth_array, row, NULL) );
2173 cpl_array_delete(volt_array);
2174 cpl_array_delete(volts_smooth_array);
2179 cpl_msg_info (cpl_func,
"Smoothing volts of the TEL diodes done");
2187 cpl_msg_info (cpl_func,
"Fill the OI_VIS_MET table with the DRS algorithm");
2192 cpl_table_new_column (vismet_table,
"PHASE_FC_DRS", CPL_TYPE_DOUBLE);
2193 cpl_table_set_column_unit (vismet_table,
"PHASE_FC_DRS",
"rad");
2194 cpl_table_new_column (vismet_table,
"PHASE_FCFT_DRS", CPL_TYPE_DOUBLE);
2195 cpl_table_set_column_unit (vismet_table,
"PHASE_FCFT_DRS",
"rad");
2196 cpl_table_new_column (vismet_table,
"PHASE_FCSC_DRS", CPL_TYPE_DOUBLE);
2197 cpl_table_set_column_unit (vismet_table,
"PHASE_FCSC_DRS",
"rad");
2198 cpl_table_new_column_array (vismet_table,
"PHASE_TEL_DRS", CPL_TYPE_DOUBLE,
ndiode);
2199 cpl_table_set_column_unit (vismet_table,
"PHASE_TEL_DRS",
"rad");
2200 cpl_table_new_column_array (vismet_table,
"AMPLITUDE_TEL", CPL_TYPE_DOUBLE,
ndiode);
2201 cpl_table_set_column_unit (vismet_table,
"AMPLITUDE_TEL",
"Volts");
2202 cpl_table_new_column (vismet_table,
"FLAG_DRS", CPL_TYPE_INT);
2203 cpl_table_set_column_unit (vismet_table,
"FLAG_DRS",
"0/1");
2218 int met_date_row = -1;
2219 for (cpl_size row = 1; row < nbrow_met; row ++) {
2221 int time_met = cpl_table_get_int (metrology_table,
"TIME", row, NULL);
2222 int time_met_minus = cpl_table_get_int (metrology_table,
"TIME", row-1, NULL);
2223 CPLCHECK_MSG(
"Cannot get Time for Metrology phase date");
2224 if ((time_met > met_mjd) && (time_met_minus < met_mjd)) met_date_row = row;
2226 cpl_msg_info(cpl_func,
"Found DIT corresponding to metrology phase date at number %i",met_date_row);
2230 sprintf (qc_name,
"ESO QC MET REF ROW");
2231 cpl_msg_info (cpl_func,
"%s = %i", qc_name, met_date_row);
2232 cpl_propertylist_update_int (
header, qc_name,met_date_row);
2233 cpl_propertylist_set_comment (
header, qc_name,
"met row at unwraped phase ref");
2236 if (met_date_row == -1){
2237 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
2238 "The metrology phase date is not within"
2239 " the boundaries of RMN acquisition");
2240 return CPL_ERROR_ILLEGAL_INPUT;
2248 for (
int tel = 0; tel <
ntel; tel++) {
2252 cpl_array * phasor_array_ft = cpl_array_new(nbrow_met,CPL_TYPE_DOUBLE_COMPLEX);
2253 cpl_array * phasor_array_sc = cpl_array_new(nbrow_met,CPL_TYPE_DOUBLE_COMPLEX);
2255 for (cpl_size row = 0; row < nbrow_met; row ++)
2257 double complex phasor_ft =
2258 cpl_array_get (raw_met[row],ind_cosfc_FT[tel], NULL)
2259 + I*cpl_array_get (raw_met[row],ind_sinfc_FT[tel], NULL);
2260 double complex phasor_sc =
2261 cpl_array_get (raw_met[row],ind_cosfc_SC[tel], NULL)
2262 + I*cpl_array_get (raw_met[row],ind_sinfc_SC[tel], NULL);
2264 cpl_array_set_double_complex(phasor_array_ft,row,phasor_ft);
2265 cpl_array_set_double_complex(phasor_array_sc,row,phasor_sc);
2269 cpl_array * phase_array_ft = cpl_array_duplicate (phasor_array_ft);
2270 cpl_array * phase_array_sc = cpl_array_duplicate (phasor_array_sc);
2271 cpl_array_arg(phase_array_ft);
2272 cpl_array_arg(phase_array_sc);
2277 double phase_reference_ft = cpl_array_get_double(phase_array_ft, met_date_row, NULL);
2278 double phase_reference_sc = cpl_array_get_double(phase_array_sc, met_date_row, NULL);
2281 sprintf (name,
"ESO OCS MET PH_FC%d_FT", tel+1);
2282 double k_phase_ft = cpl_propertylist_get_double (
header, name) - phase_reference_ft;
2283 sprintf (name,
"ESO ADD MET PH_FC%d_FT", tel+1);
2284 if (cpl_propertylist_has(
header, name))
2287 k_phase_ft += cpl_propertylist_get_int (
header, name) *
TWOPI;
2288 cpl_msg_warning( cpl_func,
"Adding to FC FT metrology %i 2pi rad from header", cpl_propertylist_get_int (
header, name));
2291 sprintf (name,
"ESO OCS MET PH_FC%d_SC", tel+1);
2292 double k_phase_sc = cpl_propertylist_get_double (
header, name) - phase_reference_sc;
2293 sprintf (name,
"ESO ADD MET PH_FC%d_SC", tel+1);
2294 if (cpl_propertylist_has(
header, name))
2297 k_phase_sc += cpl_propertylist_get_int (
header, name) *
TWOPI;
2298 cpl_msg_warning( cpl_func,
"Adding to FC SC metrology %i 2pi rad from header", cpl_propertylist_get_int (
header, name));
2302 k_phase_ft = floor(k_phase_ft/(2*M_PI)+0.5)*2*M_PI;
2303 k_phase_sc = floor(k_phase_sc/(2*M_PI)+0.5)*2*M_PI;
2304 cpl_array_add_scalar (phase_array_ft, k_phase_ft);
2305 cpl_array_add_scalar (phase_array_sc, k_phase_sc);
2308 for (cpl_size row = 0; row < nbrow_met; row ++)
2310 cpl_table_set (vismet_table,
"PHASE_FC_DRS", row*
ntel+tel, cpl_array_get_double (phase_array_ft, row, NULL)
2311 - cpl_array_get_double (phase_array_sc, row, NULL) );
2312 cpl_table_set (vismet_table,
"PHASE_FCFT_DRS", row*
ntel+tel, cpl_array_get_double (phase_array_ft, row, NULL));
2313 cpl_table_set (vismet_table,
"PHASE_FCSC_DRS", row*
ntel+tel, cpl_array_get_double (phase_array_sc, row, NULL));
2316 cpl_array_delete(phasor_array_ft);
2317 cpl_array_delete(phasor_array_sc);
2318 cpl_array_delete(phase_array_ft);
2319 cpl_array_delete(phase_array_sc);
2320 CPLCHECK_MSG(
"Error while computing the metrology phase at FC");
2324 cpl_msg_info(cpl_func,
"Finished computing phase (stored in PHASE_FC_DRS)");
2331 for (
int tel = 0; tel <
ntel; tel++){
2334 cpl_array ** tel_phase = cpl_malloc (nbrow_met *
sizeof(cpl_array *)) ;
2335 for (cpl_size row = 0; row < nbrow_met; row ++)
2336 tel_phase[row]=cpl_array_new (
ndiode, CPL_TYPE_DOUBLE);
2337 cpl_array ** tel_amplitude = cpl_malloc (nbrow_met *
sizeof(cpl_array *)) ;
2338 for (cpl_size row = 0; row < nbrow_met; row ++)
2339 tel_amplitude[row]=cpl_array_new (
ndiode, CPL_TYPE_DOUBLE);
2341 for (
int diode = 0; diode <
ndiode; diode++){
2344 cpl_array * phasor_array = cpl_array_new(nbrow_met,CPL_TYPE_DOUBLE_COMPLEX);
2346 for (cpl_size row = 0; row < nbrow_met; row ++)
2348 double complex phasor_ft =
2349 cpl_array_get(raw_met[row],ind_costel_FT[tel][diode], NULL)
2350 +I*cpl_array_get(raw_met[row],ind_sintel_FT[tel][diode], NULL);
2351 double complex conj_phasor_sc =
2352 cpl_array_get(raw_met[row],ind_costel_SC[tel][diode], NULL)
2353 -I*cpl_array_get(raw_met[row],ind_sintel_SC[tel][diode], NULL);
2355 cpl_array_set_double_complex(phasor_array,row,phasor_ft*conj_phasor_sc);
2361 cpl_array * phase_array = cpl_array_duplicate(abs_array);
2363 cpl_array_arg(phase_array);
2366 cpl_array_abs(abs_array);
2369 double phase_reference = cpl_array_get_double(phase_array, met_date_row, NULL);
2372 sprintf (name,
"ESO OCS MET PH_T%d_D%d_FT", tel+1,diode+1);
2373 double phase_rtc = cpl_propertylist_get_double (
header, name);
2374 sprintf (name,
"ESO OCS MET PH_T%d_D%d_SC", tel+1,diode+1);
2375 phase_rtc = phase_rtc - cpl_propertylist_get_double (
header, name);
2376 double k_phase = phase_rtc - phase_reference;
2378 k_phase = floor(k_phase/(2*M_PI)+0.5)*2*M_PI;
2379 cpl_array_add_scalar (phase_array, k_phase);
2380 CPLCHECK_MSG(
"could not get met phase offset from headers");
2382 for (cpl_size row = 0; row < nbrow_met; row ++)
2384 cpl_array_set_double(tel_phase[row],diode,cpl_array_get_double (phase_array, row, NULL));
2385 cpl_array_set_double(tel_amplitude[row],diode,cpl_array_get_double (abs_array, row, NULL));
2388 cpl_array_delete(phasor_array);
2389 cpl_array_delete(phase_array);
2390 cpl_array_delete(abs_array);
2391 CPLCHECK_MSG(
"Computing the metrology phase for TEL diodes failed");
2394 for (cpl_size row = 0; row < nbrow_met; row ++){
2395 cpl_table_set_array (vismet_table,
"PHASE_TEL_DRS", row*
ntel+tel, tel_phase[row]);
2396 cpl_table_set_array (vismet_table,
"AMPLITUDE_TEL", row*
ntel+tel, tel_amplitude[row]);
2397 cpl_table_set (vismet_table,
"FLAG_DRS", row*
ntel+tel, cpl_array_get (bright_array, row, NULL));
2398 cpl_array_delete(tel_phase[row]);
2399 cpl_array_delete(tel_amplitude[row]);
2401 FREE (cpl_free, tel_phase);
2402 FREE (cpl_free, tel_amplitude);
2405 cpl_msg_info(cpl_func,
"Finished computing phase (stored in PHASE_TEL_DRS)");
2413 cpl_table_new_column_array (vismet_table,
"PHASOR_TELFC_DRS", CPL_TYPE_DOUBLE_COMPLEX,
ndiode);
2414 cpl_table_set_column_unit (vismet_table,
"PHASOR_TELFC_DRS",
"V^4");
2415 cpl_array ** phasor_telfc = cpl_table_get_data_array (vismet_table,
"PHASOR_TELFC_DRS");
2417 for (cpl_size row = 0; row < nbrow_met; row++) {
2418 for (
int tel = 0; tel <
ntel; tel++) {
2419 phasor_telfc[row*
ntel+tel] = cpl_array_new (
ndiode, CPL_TYPE_DOUBLE_COMPLEX);
2421 double complex V_fc;
2422 V_fc = (cpl_array_get (raw_met[row],ind_cosfc_FT[tel], NULL) +
2423 cpl_array_get (raw_met[row],ind_sinfc_FT[tel], NULL) * I) *
2424 (cpl_array_get (raw_met[row],ind_cosfc_SC[tel], NULL) -
2425 cpl_array_get (raw_met[row],ind_sinfc_SC[tel], NULL) * I);
2428 for (
int diode = 0; diode < 4; diode++) {
2429 double complex V_tel;
2430 V_tel = (cpl_array_get (raw_met[row],ind_costel_FT[tel][diode], NULL) +
2431 cpl_array_get (raw_met[row],ind_sintel_FT[tel][diode], NULL) * I) *
2432 (cpl_array_get (raw_met[row],ind_costel_SC[tel][diode], NULL) -
2433 cpl_array_get (raw_met[row],ind_sintel_SC[tel][diode], NULL) * I);
2434 cpl_array_set_complex (phasor_telfc[row*
ntel+tel], diode,
2435 V_tel * conj (V_fc) );
2442 cpl_array_delete(bright_array);
2443 cpl_array_delete(good_met_array);
2446 return CPL_ERROR_NONE;
2715 cpl_table * vismet_table,
2717 cpl_propertylist *
header,
2718 const cpl_parameterlist * parlist)
2724 cpl_size nrow_met = cpl_table_get_nrow (metrology_table);
2738 double * phase_fc_2;
2739 double ** phase_tel;
2740 double ** amplitude_tel;
2743 if (use_met_rtc == 0) {
2744 cpl_msg_info (cpl_func,
"Using DRS metrology algorithm");
2746 phase_fc = cpl_table_get_data_double (vismet_table,
"PHASE_FC_DRS");
2747 CPLCHECK_MSG (
"Cannot get PHASE_FC_DRS from vismet_table");
2749 phase_fc_2 = cpl_table_get_data_double (vismet_table,
"PHASE_FC_TAC");
2750 CPLCHECK_MSG (
"Cannot get PHASE_FC_TAC from vismet_table");
2753 CPLCHECK_MSG (
"Cannot get PHASE_TEL_DRS from vismet_table");
2756 cpl_msg_info (cpl_func,
"Using RTC (TAC) metrology algorithm");
2758 phase_fc = cpl_table_get_data_double (vismet_table,
"PHASE_FC_TAC");
2759 CPLCHECK_MSG (
"Cannot get PHASE_FC_DRS from vismet_table");
2761 phase_fc_2 = cpl_table_get_data_double (vismet_table,
"PHASE_FC_DRS");
2762 CPLCHECK_MSG (
"Cannot get PHASE_FC_TAC from vismet_table");
2765 CPLCHECK_MSG (
"Cannot get PHASE_TEL_DRS from vismet_table");
2769 CPLCHECK_MSG (
"Cannot get AMPLITUDE_TEL from vismet_table");
2771 cpl_msg_info (cpl_func,
"G-FAINT: create flagged amplitude");
2772 met_flag = cpl_table_get_data_int (vismet_table,
"FLAG_DRS");
2773 CPLCHECK_MSG (
"Cannot get FLAG_DRS from vismet_table");
2777 for (cpl_size row = 0; row < nrow_met*
ntel; row++) {
2778 for (
int diode = 0; diode <
ndiode; diode++)
2779 amplitude_tel_flagged[row][diode]= amplitude_tel[row][diode] * met_flag[row];
2785 cpl_msg_info (cpl_func,
"Lambda met mean :%f nm", lambda_met_mean*1e9);
2790 for (
int tel = 0; tel <
ntel; tel++) {
2791 double phase_diff = 0;
2792 for (cpl_size row = 0; row < nrow_met; row++)
2793 phase_diff += phase_fc[row*
ntel+tel] - phase_fc_2[row*
ntel+tel];
2794 phase_diff /= nrow_met;
2795 sprintf (qc_name,
"ESO QC MET DRS DIFF%i", tel+1);
2796 if (phase_diff<0.02)
2797 cpl_msg_info (cpl_func,
"%s = %f", qc_name, phase_diff);
2799 cpl_msg_warning (cpl_func,
"%s = %f", qc_name, phase_diff);
2801 cpl_propertylist_set_comment (
header, qc_name,
"[rad] TAC and DRS phase difference");
2815 double * opd_fc = cpl_table_get_data_double (vismet_table,
"OPD_FC");
2820 for (cpl_size row = 0; row < nrow_met*
ntel; row++) {
2821 opd_fc[row]= - lambda_met_mean / CPL_MATH_2PI * phase_fc[row];
2822 for (
int diode = 0; diode <
ndiode; diode++)
2823 opd_tel[row][diode]= - lambda_met_mean / CPL_MATH_2PI * phase_tel[row][diode];
2835 cpl_msg_info (cpl_func,
"Calculate OPD_FC_CORR from OPD_PUPIL and pickup/defocus.");
2839 double * opd_fc_corr = cpl_table_get_data_double (vismet_table,
"OPD_FC_CORR");
2842 double * opd_pupil = NULL;
2843 if ( cpl_table_has_column(vismet_table,
"OPD_PUPIL") ) {
2844 opd_pupil = cpl_table_get_data_double (vismet_table,
"OPD_PUPIL");
2847 cpl_msg_warning(cpl_func,
"Cannot get the OPD_PUPIL (not computed) so will"
2848 "not correct for pupil opd (check the --reduce-acq-cam option)");
2854 double rho_in = sqrt(dx_in*dx_in + dy_in*dy_in);
2860 cpl_msg_info(cpl_func,
"X and Y OFFSET from gvctu = %.2f, %.2f mas",dx_gvctu,dy_gvctu);
2861 cpl_msg_info(cpl_func,
"X and Y OFFSET from header = %.2f, %.2f mas",dx_in,dy_in);
2865 cpl_msg_info (cpl_func,
"Mode SINGLE thus separation forced to 0.0");
2868 cpl_msg_info (cpl_func,
"FE: separation in mas: %g ", rho_in );
2871 for (
int tel = 0; tel <
ntel; tel++) {
2877 cpl_msg_info (cpl_func,
"FE: Tel %d Pupil %g Focus %g Shift %g",
2879 (opd_pupil?opd_pupil[0*
ntel+tel]:0)*1e9,
2883 for (cpl_size row = 0; row < nrow_met; row++) {
2884 opd_fc_corr[row*
ntel+tel] = (opd_pupil?opd_pupil[row*
ntel+tel]:0)
2901 cpl_msg_info (cpl_func,
"Deproject telescope diodes to center of telescope in OPD_TEL_CORR.");
2913 double rec_az[4][4];
2914 double rec_zd[4][4];
2915 for (
int tel=0;tel<4;tel++) {
2916 for (
int diode=0;diode<4;diode++) {
2921 CPLCHECK_MSG (
"Cannot read metrology reciever position from MET_POS");
2928 double deproject, northangle, field_dU, field_dV;
2932 cpl_array * northangle_array = cpl_array_new(4,CPL_TYPE_DOUBLE);
2936 cpl_array_set_double (northangle_array,0,north_angle_tmp);
2939 for (cpl_size tel=1;tel < 4; tel++)
2942 if (north_angle_tmp2-north_angle_tmp >= 180) north_angle_tmp2 -= 360.0;
2943 if (north_angle_tmp2-north_angle_tmp < -180) north_angle_tmp2 += 360.0;
2944 cpl_array_set_double (northangle_array,tel,north_angle_tmp2);
2949 cpl_vector * rec = cpl_vector_new (3);
2950 cpl_vector * sobj = cpl_vector_new (3);
2953 cpl_array ** E_U = cpl_table_get_data_array (vismet_table,
"E_U");
2954 cpl_array ** E_V = cpl_table_get_data_array (vismet_table,
"E_V");
2955 cpl_array ** E_AZ = cpl_table_get_data_array (vismet_table,
"E_AZ");
2956 cpl_array ** E_ZD = cpl_table_get_data_array (vismet_table,
"E_ZD");
2960 double * field_dX = NULL;
2961 double * field_dY = NULL;
2962 if ( cpl_table_has_column (vismet_table,
"FIELD_FIBER_DX")
2963 && cpl_table_has_column (vismet_table,
"FIELD_FIBER_DY") ) {
2964 field_dX = cpl_table_get_data_double (vismet_table,
"FIELD_FIBER_DX");
2965 field_dY = cpl_table_get_data_double (vismet_table,
"FIELD_FIBER_DY");
2971 cpl_array_get (E_U[0*
ntel+0], 0, NULL),
2972 cpl_array_get (E_U[0*
ntel+0], 1, NULL),
2973 cpl_array_get (E_U[0*
ntel+0], 2, NULL));
2975 cpl_array_get (E_V[0*
ntel+0], 0, NULL),
2976 cpl_array_get (E_V[0*
ntel+0], 1, NULL),
2977 cpl_array_get (E_V[0*
ntel+0], 2, NULL));
2979 cpl_array_get (E_AZ[0*
ntel+0], 0, NULL),
2980 cpl_array_get (E_AZ[0*
ntel+0], 1, NULL),
2981 cpl_array_get (E_AZ[0*
ntel+0], 2, NULL));
2983 cpl_array_get (E_ZD[0*
ntel+0], 0, NULL),
2984 cpl_array_get (E_ZD[0*
ntel+0], 1, NULL),
2985 cpl_array_get (E_ZD[0*
ntel+0], 2, NULL));
2990 double dx_sep_diode = dx_gvctu;
2991 double dy_sep_diode = dy_gvctu;
2992 if (cpl_propertylist_has (
header,
"ESO FT KAL SEPTRK"))
2994 if (cpl_propertylist_get_int (
header,
"ESO FT KAL SEPTRK") == 1)
2996 dx_sep_diode = dx_in;
2997 dy_sep_diode = dy_in;
2998 cpl_msg_info (cpl_func,
"Using X/Y offset from header");
3008 cpl_msg_info (cpl_func,
"Use fiber dxy is set to %s", use_fiber_dxy ?
"TRUE" :
"FALSE");
3011 for (
int tel = 0; tel <
ntel; tel++) {
3015 for (
int diode = 0; diode <
ndiode; diode++) {
3016 RA+=rec_az[tel][diode];
3017 RZ+=rec_zd[tel][diode];
3019 cpl_msg_info (cpl_func,
"Tel %i; diodes RA=%g, RZ=%g, ABS=%g", tel, RA, RZ, sqrt(RA*RA+RZ*RZ));
3022 northangle = cpl_array_get_double(northangle_array,tel,NULL);
3027 sprintf (card,
"ESO QC ACQ FIELD%d SCALE", tel+1);
3028 if (cpl_propertylist_has (
header, card))
3029 scale = cpl_propertylist_get_double (
header, card);
3032 for (cpl_size row = 0; row < nrow_met; row++) {
3036 if ((field_dX && field_dY) && use_fiber_dxy != 0) {
3037 field_dU = (field_dX[row*
ntel+tel] * sin( (northangle+90.) * CPL_MATH_RAD_DEG )
3038 +field_dY[row*
ntel+tel] * cos( (northangle+90.) * CPL_MATH_RAD_DEG ))*scale;
3039 field_dV = (field_dX[row*
ntel+tel] * sin( (northangle ) * CPL_MATH_RAD_DEG )
3040 +field_dY[row*
ntel+tel] * cos( (northangle ) * CPL_MATH_RAD_DEG ))*scale;
3046 for (
int diode = 0; diode <
ndiode; diode++) {
3049 cpl_vector_set (rec, 0, rec_az[tel][diode] * cpl_array_get (E_AZ[row*
ntel+tel], 0, NULL)
3050 +rec_zd[tel][diode] * cpl_array_get (E_ZD[row*
ntel+tel], 0, NULL));
3051 cpl_vector_set (rec, 1, rec_az[tel][diode] * cpl_array_get (E_AZ[row*
ntel+tel], 1, NULL)
3052 +rec_zd[tel][diode] * cpl_array_get (E_ZD[row*
ntel+tel], 1, NULL));
3053 cpl_vector_set (rec, 2, rec_az[tel][diode] * cpl_array_get (E_AZ[row*
ntel+tel], 2, NULL)
3054 +rec_zd[tel][diode] * cpl_array_get (E_ZD[row*
ntel+tel], 2, NULL));
3055 cpl_vector_set (sobj, 0, (dx_sep_diode-field_dU) * cpl_array_get (E_U[row*
ntel+tel], 0, NULL)
3056 +(dy_sep_diode-field_dV) * cpl_array_get (E_V[row*
ntel+tel], 0, NULL));
3057 cpl_vector_set (sobj, 1, (dx_sep_diode-field_dU) * cpl_array_get (E_U[row*
ntel+tel], 1, NULL)
3058 +(dy_sep_diode-field_dV) * cpl_array_get (E_V[row*
ntel+tel], 1, NULL));
3059 cpl_vector_set (sobj, 2, (dx_sep_diode-field_dU) * cpl_array_get (E_U[row*
ntel+tel], 2, NULL)
3060 +(dy_sep_diode-field_dV) * cpl_array_get (E_V[row*
ntel+tel], 2, NULL));
3063 deproject = cpl_vector_product(rec, sobj);
3064 deproject = deproject / 1000. / 3600. / 360. *
TWOPI;
3067 if (row == 0 && tel == 0 && diode == 0) {
3068 cpl_msg_debug (cpl_func,
"FE: Julien deproject diode 0 in nm: %g", deproject*1e9);
3070 if (row == 0 && tel == 0 && diode == 1) {
3071 cpl_msg_debug (cpl_func,
"FE: Julien deproject diode 1 in nm: %g", deproject*1e9);
3073 if (row == 0 && tel == 0 && diode == 2) {
3074 cpl_msg_debug (cpl_func,
"FE: Julien deproject diode 2 in nm: %g", deproject*1e9);
3076 if (row == 0 && tel == 0 && diode == 3) {
3077 cpl_msg_debug (cpl_func,
"FE: Julien deproject diode 3 in nm: %g", deproject*1e9);
3081 opd_tel_corr[row*
ntel+tel][diode] = deproject;
3087 FREE (cpl_vector_delete, rec);
3088 FREE (cpl_vector_delete, sobj);
3089 CPLCHECK_MSG (
"Cannot calculate OPD_TEL_CORR (SX and SY)");
3094 double AstigmAmplitude;
3096 double AstigmRadius;
3104 double parang1 = cpl_propertylist_get_double(
header,
"ESO ISS PARANG START") * (
TWOPI/360.0);
3105 double parang2 = cpl_propertylist_get_double(
header,
"ESO ISS PARANG END" ) * (
TWOPI/360.0);
3106 if (parang2-parang1 >
TWOPI/2) parang2-=
TWOPI;
3107 if (parang2-parang1 < -
TWOPI/2) parang2+=
TWOPI;
3109 double parang = (parang1 + parang2) / 2;
3111 cpl_msg_info (cpl_func,
"FE: paralactic angle in degrees: %g ", parang * (360.0/
TWOPI) );
3118 for (
int tel = 0; tel <
ntel; tel++) {
3122 cpl_msg_info (cpl_func,
"Astigmatism params GV%i : %5g [nm], %5g [deg]", tel, AstigmAmplitude ,AstigmTheta);
3124 for (cpl_size row = 0; row < nrow_met; row++) {
3125 for (
int diode = 0; diode <
ndiode; diode++) {
3126 diodeang =
myAtan(-rec_zd[tel][diode],-rec_az[tel][diode], &flag);
3127 double parang3 = parang1 + (parang2-parang1) * row / nrow_met;
3128 astang = (AstigmTheta - cpl_array_get_double(northangle_array,tel,NULL)) * (
TWOPI/360.) - parang3 - diodeang ;
3129 astradius = sqrt(rec_az[tel][diode]*rec_az[tel][diode] + rec_zd[tel][diode]*rec_zd[tel][diode]) / AstigmRadius;
3130 astigm = (AstigmAmplitude*1e-9) * sqrt(6) * astradius * astradius * sin(2. * astang);
3133 if (row == 0 && tel == 0 && diode == 0) {
3135 cpl_msg_debug (cpl_func,
"FE: Frank astigmatism angle [deg]: %g", astang /
TWOPI * 360.);
3136 cpl_msg_debug (cpl_func,
"FE: Frank normalized astradius: %g", astradius);
3137 cpl_msg_debug (cpl_func,
"FE: Frank astigmatism diode 0 in nm: %g", astigm*1e9);
3139 if (row == 0 && tel == 0 && diode == 1) {
3140 cpl_msg_debug (cpl_func,
"FE: Frank astigmatism diode 1 in nm: %g", astigm*1e9);
3142 if (row == 0 && tel == 0 && diode == 2) {
3143 cpl_msg_debug (cpl_func,
"FE: Frank astigmatism diode 2 in nm: %g", astigm*1e9);
3145 if (row == 0 && tel == 0 && diode == 3) {
3146 cpl_msg_debug (cpl_func,
"FE: Frank astigmatism diode 3 in nm: %g", astigm*1e9);
3151 opd_tel_corr[row*
ntel+tel][diode] -= astigm;
3155 CPLCHECK_MSG (
"Cannot calculate OPD_TEL_CORR (Astigmatism part)");
3165 cpl_msg_info (cpl_func,
"Calculate difference between corrected telescope diodes and fiber coupler in OPD_TELFC_CORR.");
3179 double complex phasor;
3180 double complex phasorfc;
3181 double complex dphasor;
3183 for (
int tel = 0; tel <
ntel; tel++) {
3184 for (cpl_size row = 0; row < nrow_met; row++) {
3185 phifc = - phase_fc[row*
ntel+tel]
3186 + opd_fc_corr[row*
ntel+tel] / lambda_met_mean *
TWOPI;
3187 phasorfc = cos(phifc) + sin(phifc) * I;
3188 for (
int diode = 0; diode <
ndiode; diode++) {
3189 phi = - phase_tel[row*
ntel+tel][diode] + (opd_tel_corr[row*
ntel+tel][diode])
3190 / lambda_met_mean *
TWOPI;
3191 phasor = cos(phi) + sin(phi) * I;
3192 dphasor = phasor*conj(phasorfc);
3193 phase_telfc_corr[row*
ntel+tel][diode] = carg(dphasor);
3212 double tilt_mean[4];
3214 double astig_mean[4];
3221 int Nsmooth_astig = 2500;
3222 int Nsmooth_sep = 1250;
3223 int Nsmooth_tel = 50;
3229 Nsmooth_astig = (int) 250 * 4 * (dit_sc +1.0);
3230 Nsmooth_sep = (int) 250 * 2 * (dit_sc + 1.0);
3231 if ( use_faint_met == 1) {
3234 Nsmooth_tel = (int) 250 * 2* (dit_sc + 1.0);
3238 for (
int tel = 0; tel <
ntel; tel++)
3240 cpl_msg_info (cpl_func,
"G-FAINT: Use flagged amplitude for astigmatism");
3241 cpl_msg_info (cpl_func,
"Smoothing astigmatism by %d metrology DITS (tel=%i)",Nsmooth_astig*2+1,tel);
3242 cpl_array * phasor_array = cpl_array_new(nrow_met,CPL_TYPE_DOUBLE_COMPLEX);
3243 for (cpl_size row = 0; row < nrow_met; row++)
3245 double amplitude_ast = amplitude_tel_flagged[row*
ntel+tel][3] *
3246 amplitude_tel_flagged[row*
ntel+tel][2] *
3247 amplitude_tel_flagged[row*
ntel+tel][1] *
3248 amplitude_tel_flagged[row*
ntel+tel][0];
3249 double phase_ast = phase_telfc_corr[row*
ntel+tel][3] -
3250 phase_telfc_corr[row*
ntel+tel][2] +
3251 phase_telfc_corr[row*
ntel+tel][1] -
3252 phase_telfc_corr[row*
ntel+tel][0];
3253 double complex complex_ast = amplitude_ast * (cos(phase_ast)+I*sin(phase_ast));
3255 cpl_array_set_double_complex(phasor_array,row,complex_ast);
3259 double complex mean_phasor = cpl_array_get_mean_complex (phasor_array);
3260 cpl_array_multiply_scalar_complex (phasor_array, conj(mean_phasor));
3261 cpl_array * phase_astig_corr_array =
gravi_array_smooth (phasor_array, Nsmooth_astig);
3262 cpl_array_arg(phase_astig_corr_array);
3263 cpl_array_add_scalar(phase_astig_corr_array, carg(mean_phasor));
3265 astig_mean[tel]=carg(mean_phasor);
3266 cpl_msg_info(cpl_func,
"Mean astigmatism for tel %i : %.2f radians",tel,carg(mean_phasor));
3269 cpl_array_delete(phasor_array);
3272 cpl_array * phasor_array_X = cpl_array_new(nrow_met,CPL_TYPE_DOUBLE_COMPLEX);
3273 cpl_array * phasor_array_Y = cpl_array_new(nrow_met,CPL_TYPE_DOUBLE_COMPLEX);
3276 cpl_msg_info (cpl_func,
"G-FAINT: Use flagged amplitude for sep. angle");
3277 cpl_msg_info (cpl_func,
"Smoothing X and Y sep by %d metrology DITS (tel=%i)",Nsmooth_sep*2+1,tel);
3278 for (cpl_size row = 0; row < nrow_met; row++)
3280 double phase_ast_2=cpl_array_get_double(phase_astig_corr_array,row,NULL)/2.;
3282 double amplitude_sep = amplitude_tel_flagged[row*
ntel+tel][3] *
3283 amplitude_tel_flagged[row*
ntel+tel][2] *
3284 amplitude_tel_flagged[row*
ntel+tel][1] *
3285 amplitude_tel_flagged[row*
ntel+tel][0];
3287 double phase_sepX1 = phase_telfc_corr[row*
ntel+tel][3] -
3288 phase_telfc_corr[row*
ntel+tel][2] - phase_ast_2;
3289 double phase_sepX2 = phase_telfc_corr[row*
ntel+tel][0] -
3290 phase_telfc_corr[row*
ntel+tel][1] + phase_ast_2;
3292 double phase_sepY1 = phase_telfc_corr[row*
ntel+tel][3] -
3293 phase_telfc_corr[row*
ntel+tel][0] - phase_ast_2;
3294 double phase_sepY2 = phase_telfc_corr[row*
ntel+tel][2] -
3295 phase_telfc_corr[row*
ntel+tel][1] + phase_ast_2;
3297 double complex phase_sepX = amplitude_sep * (cos(phase_sepX1) + cos(phase_sepX2)
3298 + I*( sin(phase_sepX1) + sin(phase_sepX2) ));
3299 double complex phase_sepY = amplitude_sep * (cos(phase_sepY1) + cos(phase_sepY2)
3300 + I*( sin(phase_sepY1) + sin(phase_sepY2) ));
3302 cpl_array_set_double_complex(phasor_array_X,row,phase_sepX);
3303 cpl_array_set_double_complex(phasor_array_Y,row,phase_sepY);
3307 double complex mean_phasor_X = cpl_array_get_mean_complex (phasor_array_X);
3308 cpl_array_multiply_scalar_complex (phasor_array_X, conj(mean_phasor_X));
3309 cpl_array * phase_sepX_corr_array =
gravi_array_smooth (phasor_array_X, Nsmooth_sep);
3310 cpl_array_arg(phase_sepX_corr_array);
3311 cpl_array_add_scalar(phase_sepX_corr_array, carg(mean_phasor_X));
3313 double complex mean_phasor_Y = cpl_array_get_mean_complex (phasor_array_Y);
3314 cpl_array_multiply_scalar_complex (phasor_array_Y, conj(mean_phasor_Y));
3315 cpl_array * phase_sepY_corr_array =
gravi_array_smooth (phasor_array_Y, Nsmooth_sep);
3316 cpl_array_arg(phase_sepY_corr_array);
3317 cpl_array_add_scalar(phase_sepY_corr_array, carg(mean_phasor_Y));
3319 tip_mean[tel]=carg(mean_phasor_X);
3320 tilt_mean[tel]=carg(mean_phasor_Y);
3321 cpl_msg_info(cpl_func,
"Mean X separation for tel %i : %.2f radians",tel,carg(mean_phasor_X));
3322 cpl_msg_info(cpl_func,
"Mean Y separation for tel %i : %.2f radians",tel,carg(mean_phasor_Y));
3325 CPLCHECK_MSG (
"Failed when smoothing separation vectors");
3326 cpl_array_delete(phasor_array_X);
3327 cpl_array_delete(phasor_array_Y);
3332 cpl_array * phasor_telfc_corr_array[
ndiode];
3333 for (
int diode = 0; diode <
ndiode; diode++)
3334 phasor_telfc_corr_array[diode] = cpl_array_new(nrow_met,CPL_TYPE_DOUBLE_COMPLEX);
3336 cpl_msg_info(cpl_func,
"Computing the PHASE_TELFC_CORR_XY column");
3337 if ( use_faint_met == 1) {
3338 cpl_msg_info(cpl_func,
"G-FAINT: Use faint amplitude for PHASE_TELFC_CORR_XY");
3340 cpl_msg_info(cpl_func,
"G-FAINT: Use flagged amplitude for PHASE_TELFC_CORR_XY");
3342 for (cpl_size row = 0; row < nrow_met; row++)
3344 double amplitude_diodes;
3345 if ( use_faint_met == 1) {
3346 amplitude_diodes = amplitude_tel[row*
ntel+tel][3] +
3347 amplitude_tel[row*
ntel+tel][2] +
3348 amplitude_tel[row*
ntel+tel][1] +
3349 amplitude_tel[row*
ntel+tel][0];
3351 amplitude_diodes = amplitude_tel_flagged[row*
ntel+tel][3] +
3352 amplitude_tel_flagged[row*
ntel+tel][2] +
3353 amplitude_tel_flagged[row*
ntel+tel][1] +
3354 amplitude_tel_flagged[row*
ntel+tel][0];
3356 phase_telfc_corr_xy[row*
ntel+tel][0]=
3357 -cpl_array_get_double(phase_astig_corr_array,row,NULL)/4
3358 +cpl_array_get_double(phase_sepX_corr_array,row,NULL)/2
3359 -cpl_array_get_double(phase_sepY_corr_array,row,NULL)/2;
3360 phase_telfc_corr_xy[row*
ntel+tel][1]=
3361 cpl_array_get_double(phase_astig_corr_array,row,NULL)/4
3362 -cpl_array_get_double(phase_sepX_corr_array,row,NULL)/2
3363 -cpl_array_get_double(phase_sepY_corr_array,row,NULL)/2;
3364 phase_telfc_corr_xy[row*
ntel+tel][2]=
3365 -cpl_array_get_double(phase_astig_corr_array,row,NULL)/4
3366 -cpl_array_get_double(phase_sepX_corr_array,row,NULL)/2
3367 +cpl_array_get_double(phase_sepY_corr_array,row,NULL)/2;
3368 phase_telfc_corr_xy[row*
ntel+tel][3]=
3369 cpl_array_get_double(phase_astig_corr_array,row,NULL)/4
3370 +cpl_array_get_double(phase_sepX_corr_array,row,NULL)/2
3371 +cpl_array_get_double(phase_sepY_corr_array,row,NULL)/2;
3373 for (
int diode = 0; diode <
ndiode; diode++) {
3374 double phase_telfc_tmp = phase_telfc_corr[row*
ntel+tel][diode]-phase_telfc_corr_xy[row*
ntel+tel][diode];
3375 double complex amp_telfc_corr = amplitude_diodes*(cos(phase_telfc_tmp)+I*sin(phase_telfc_tmp));
3376 cpl_array_set_double_complex(phasor_telfc_corr_array[diode],row,amp_telfc_corr);
3380 for (
int diode = 0; diode <
ndiode; diode++) {
3381 phase_telfc_corr_xy[row*
ntel+tel][diode]*=lambda_met_mean /
TWOPI ;
3384 CPLCHECK_MSG (
"Failed when computing phasor for PHASE_TELFC_CORR_XY");
3386 cpl_msg_info (cpl_func,
"Smoothing phase_telfc_corr by %d metrology DITS (tel=%i)",Nsmooth_tel*2+1,tel);
3388 for (
int diode = 0; diode <
ndiode; diode++) {
3389 double complex mean_phasor = cpl_array_get_mean_complex (phasor_telfc_corr_array[diode]);
3390 cpl_array_multiply_scalar_complex (phasor_telfc_corr_array[diode], conj(mean_phasor));
3391 cpl_array * phase_telfc_corr_array =
gravi_array_smooth (phasor_telfc_corr_array[diode], Nsmooth_tel);
3392 cpl_array_arg(phase_telfc_corr_array);
3393 cpl_array_add_scalar(phase_telfc_corr_array, carg(mean_phasor));
3395 for (cpl_size row = 0; row < nrow_met; row++)
3397 phase_telfc_corr[row*
ntel+tel][diode] = cpl_array_get_double(phase_telfc_corr_array,row,NULL);
3398 opd_telfc_corr[row*
ntel+tel][diode] = phase_telfc_corr[row*
ntel+tel][diode] /
TWOPI * lambda_met_mean ;
3400 cpl_array_delete(phase_telfc_corr_array);
3401 cpl_array_delete(phasor_telfc_corr_array[diode]);
3404 CPLCHECK_MSG (
"Failed when smoothing PHASE_TELFC_CORR_XY");
3405 cpl_array_delete(phase_astig_corr_array);
3406 cpl_array_delete(phase_sepX_corr_array);
3407 cpl_array_delete(phase_sepY_corr_array);
3414 cpl_vector * tmp_vector;
3415 tmp_vector = cpl_vector_new (nrow_met);
3420 for (
int tel = 0; tel <
ntel; tel++) {
3421 for (
int diode = 0; diode <
ndiode; diode++) {
3423 for (cpl_size row = 0; row < nrow_met; row++) {
3424 cpl_vector_set (tmp_vector, row, opd_telfc_corr[row*
ntel+tel][diode]);
3427 tmp_median = cpl_vector_get_median_const(tmp_vector);
3428 cpl_msg_info (cpl_func,
"Median TEL-FC in nm for Tel %d Diode %d : %g ",
3429 tel, diode, tmp_median*1e9);
3431 mmet[tel][diode] = tmp_median;
3449 for (
int tel=0; tel<
ntel; tel++) {
3451 sprintf (qc_name,
"ESO QC MET OFF%i", tel+1);
3452 cpl_msg_info (cpl_func,
"%s = %f [nm]", qc_name, (mmet[tel][0]+mmet[tel][1]+mmet[tel][2]+mmet[tel][3])/4.*1e9);
3454 cpl_propertylist_set_comment (
header, qc_name,
"[nm] residual metrology offset");
3455 sprintf (qc_name,
"ESO QC MET TIP%i", tel+1);
3456 cpl_msg_info (cpl_func,
"%s = %f [nm]", qc_name, (mmet[tel][0]-mmet[tel][2])/2.*1e9);
3457 sprintf (qc_name,
"ESO QC MET TILT%i", tel+1);
3458 cpl_msg_info (cpl_func,
"%s = %f [nm]", qc_name, (mmet[tel][1]-mmet[tel][3])/2.*1e9);
3459 sprintf (qc_name,
"ESO QC MET ASTIG%i", tel+1);
3460 cpl_msg_info (cpl_func,
"%s = %f [nm]", qc_name,(mmet[tel][0]-mmet[tel][1]+mmet[tel][2]-mmet[tel][3])/4.*1e9);
3462 sprintf (qc_name,
"ESO QC MET TIP%i", tel+1);
3463 cpl_msg_info (cpl_func,
"%s = %f [nm]", qc_name, tip_mean[tel]*lambda_met_mean*1e9/
TWOPI);
3465 cpl_propertylist_set_comment (
header, qc_name,
"[nm] residual metrology tip");
3466 sprintf (qc_name,
"ESO QC MET TILT%i", tel+1);
3467 cpl_msg_info (cpl_func,
"%s = %f [nm]", qc_name, tilt_mean[tel]*lambda_met_mean*1e9/
TWOPI);
3469 cpl_propertylist_set_comment (
header, qc_name,
"[nm] residual metrology tilt");
3470 sprintf (qc_name,
"ESO QC MET ASTIG%i", tel+1);
3471 cpl_msg_info (cpl_func,
"%s = %f [nm]", qc_name,astig_mean[tel]*lambda_met_mean*1e9/
TWOPI);
3473 cpl_propertylist_set_comment (
header, qc_name,
"[nm] residual metrology astigmatism");
3487 for (
int tel = 0; tel <
ntel; tel++) {
3488 mttx[tel] = (mmet[tel][3]*rec_az[tel][3]*pow(rec_zd[tel][0],2) - mmet[tel][0]*rec_az[tel][1]*rec_zd[tel][0]*rec_zd[tel][1] + mmet[tel][0]*rec_az[tel][0]*pow(rec_zd[tel][1],2) +
3489 mmet[tel][3]*rec_az[tel][3]*pow(rec_zd[tel][1],2) - mmet[tel][0]*rec_az[tel][2]*rec_zd[tel][0]*rec_zd[tel][2] + mmet[tel][0]*rec_az[tel][0]*pow(rec_zd[tel][2],2) +
3490 mmet[tel][3]*rec_az[tel][3]*pow(rec_zd[tel][2],2) - mmet[tel][3]*rec_az[tel][0]*rec_zd[tel][0]*rec_zd[tel][3] - mmet[tel][0]*rec_az[tel][3]*rec_zd[tel][0]*rec_zd[tel][3] -
3491 mmet[tel][3]*rec_az[tel][1]*rec_zd[tel][1]*rec_zd[tel][3] - mmet[tel][3]*rec_az[tel][2]*rec_zd[tel][2]*rec_zd[tel][3] + mmet[tel][0]*rec_az[tel][0]*pow(rec_zd[tel][3],2) -
3492 mmet[tel][2]*rec_zd[tel][2]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][1]*rec_zd[tel][1] + rec_az[tel][3]*rec_zd[tel][3]) -
3493 mmet[tel][1]*rec_zd[tel][1]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][2]*rec_zd[tel][2] + rec_az[tel][3]*rec_zd[tel][3]) +
3494 mmet[tel][2]*rec_az[tel][2]*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][1],2) + pow(rec_zd[tel][3],2)) +
3495 mmet[tel][1]*rec_az[tel][1]*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][2],2) + pow(rec_zd[tel][3],2))) /
3496 (pow(rec_az[tel][3],2)*pow(rec_zd[tel][0],2) + pow(rec_az[tel][0],2)*pow(rec_zd[tel][1],2) +
3497 pow(rec_az[tel][3],2)*pow(rec_zd[tel][1],2) + pow(rec_az[tel][0],2)*pow(rec_zd[tel][2],2) +
3498 pow(rec_az[tel][3],2)*pow(rec_zd[tel][2],2) - 2*rec_az[tel][0]*rec_az[tel][3]*rec_zd[tel][0]*rec_zd[tel][3] +
3499 pow(rec_az[tel][0],2)*pow(rec_zd[tel][3],2) - 2*rec_az[tel][2]*rec_zd[tel][2]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][3]*rec_zd[tel][3]) -
3500 2*rec_az[tel][1]*rec_zd[tel][1]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][2]*rec_zd[tel][2] + rec_az[tel][3]*rec_zd[tel][3]) +
3501 pow(rec_az[tel][2],2)*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][1],2) + pow(rec_zd[tel][3],2)) +
3502 pow(rec_az[tel][1],2)*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][2],2) + pow(rec_zd[tel][3],2)));
3503 mtty[tel] = (-(mmet[tel][2]*rec_az[tel][0]*rec_az[tel][2]*rec_zd[tel][0]) - mmet[tel][3]*rec_az[tel][0]*rec_az[tel][3]*rec_zd[tel][0] - mmet[tel][2]*rec_az[tel][1]*rec_az[tel][2]*rec_zd[tel][1] -
3504 mmet[tel][3]*rec_az[tel][1]*rec_az[tel][3]*rec_zd[tel][1] + mmet[tel][2]*pow(rec_az[tel][0],2)*rec_zd[tel][2] + mmet[tel][2]*pow(rec_az[tel][1],2)*rec_zd[tel][2] -
3505 mmet[tel][3]*rec_az[tel][2]*rec_az[tel][3]*rec_zd[tel][2] + mmet[tel][2]*pow(rec_az[tel][3],2)*rec_zd[tel][2] + mmet[tel][3]*pow(rec_az[tel][0],2)*rec_zd[tel][3] +
3506 mmet[tel][3]*pow(rec_az[tel][1],2)*rec_zd[tel][3] + mmet[tel][3]*pow(rec_az[tel][2],2)*rec_zd[tel][3] - mmet[tel][2]*rec_az[tel][2]*rec_az[tel][3]*rec_zd[tel][3] +
3507 mmet[tel][0]*(pow(rec_az[tel][1],2)*rec_zd[tel][0] + pow(rec_az[tel][2],2)*rec_zd[tel][0] + pow(rec_az[tel][3],2)*rec_zd[tel][0] -
3508 rec_az[tel][0]*rec_az[tel][1]*rec_zd[tel][1] - rec_az[tel][0]*rec_az[tel][2]*rec_zd[tel][2] - rec_az[tel][0]*rec_az[tel][3]*rec_zd[tel][3]) +
3509 mmet[tel][1]*(-(rec_az[tel][0]*rec_az[tel][1]*rec_zd[tel][0]) + pow(rec_az[tel][0],2)*rec_zd[tel][1] + pow(rec_az[tel][2],2)*rec_zd[tel][1] +
3510 pow(rec_az[tel][3],2)*rec_zd[tel][1] - rec_az[tel][1]*rec_az[tel][2]*rec_zd[tel][2] - rec_az[tel][1]*rec_az[tel][3]*rec_zd[tel][3]))/
3511 (pow(rec_az[tel][3],2)*pow(rec_zd[tel][0],2) + pow(rec_az[tel][0],2)*pow(rec_zd[tel][1],2) +
3512 pow(rec_az[tel][3],2)*pow(rec_zd[tel][1],2) + pow(rec_az[tel][0],2)*pow(rec_zd[tel][2],2) +
3513 pow(rec_az[tel][3],2)*pow(rec_zd[tel][2],2) - 2*rec_az[tel][0]*rec_az[tel][3]*rec_zd[tel][0]*rec_zd[tel][3] +
3514 pow(rec_az[tel][0],2)*pow(rec_zd[tel][3],2) - 2*rec_az[tel][2]*rec_zd[tel][2]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][3]*rec_zd[tel][3]) -
3515 2*rec_az[tel][1]*rec_zd[tel][1]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][2]*rec_zd[tel][2] + rec_az[tel][3]*rec_zd[tel][3]) +
3516 pow(rec_az[tel][2],2)*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][1],2) + pow(rec_zd[tel][3],2)) +
3517 pow(rec_az[tel][1],2)*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][2],2) + pow(rec_zd[tel][3],2)));
3519 mttx[tel] = mttx[tel] /
TWOPI * 360. * 3600. * 1000.;
3520 mtty[tel] = mtty[tel] /
TWOPI * 360. * 3600. * 1000.;
3524 double scale = 18.0;
3525 sprintf (card,
"ESO QC ACQ FIELD%d SCALE", tel+1);
3526 if (cpl_propertylist_has (
header, card))
3527 scale = cpl_propertylist_get_double (
header, card);
3533 if (telname == NULL) {
3538 mttx[tel] = mttx[tel] / scale;
3539 mtty[tel] = mtty[tel] / scale;
3541 mtte[tel] = mttx[tel]*cos(parang) + mtty[tel]*sin(parang);
3542 mttn[tel] = - mttx[tel]*sin(parang) + mtty[tel]*cos(parang);
3544 northangle = cpl_array_get_double(northangle_array,tel,NULL);
3545 mttdx[tel] = mttn[tel]*sin(northangle * CPL_MATH_RAD_DEG ) + mtte[tel]*cos(northangle * CPL_MATH_RAD_DEG );
3546 mttdy[tel] = mttn[tel]*cos(northangle * CPL_MATH_RAD_DEG ) - mtte[tel]*sin(northangle * CPL_MATH_RAD_DEG );
3550 cpl_msg_debug (cpl_func,
"FE: mttx, mtty in telescope coordinates of GV1: %g %g pixel", mttx[0], mtty[0]);
3551 cpl_msg_debug (cpl_func,
"FE: mttx, mtty in telescope coordinates of GV2: %g %g pixel", mttx[1], mtty[1]);
3552 cpl_msg_debug (cpl_func,
"FE: mttx, mtty in telescope coordinates of GV3: %g %g pixel", mttx[2], mtty[2]);
3553 cpl_msg_debug (cpl_func,
"FE: mttx, mtty in telescope coordinates of GV4: %g %g pixel", mttx[3], mtty[3]);
3554 cpl_msg_debug (cpl_func,
"FE: mttx, mtty in RA DEC coordinates of GV1: %g %g pixel", mtte[0], mttn[0]);
3555 cpl_msg_debug (cpl_func,
"FE: mttx, mtty in RA DEC coordinates of GV2: %g %g pixel", mtte[1], mttn[1]);
3556 cpl_msg_debug (cpl_func,
"FE: mttx, mtty in RA DEC coordinates of GV3: %g %g pixel", mtte[2], mttn[2]);
3557 cpl_msg_debug (cpl_func,
"FE: mttx, mtty in RA DEC coordinates of GV4: %g %g pixel", mtte[3], mttn[3]);
3558 cpl_msg_debug (cpl_func,
"FE: correction for dxy of GV1: %g %g pixel", mttdx[0], mttdy[0]);
3559 cpl_msg_debug (cpl_func,
"FE: correction for dxy of GV2: %g %g pixel", mttdx[1], mttdy[1]);
3560 cpl_msg_debug (cpl_func,
"FE: correction for dxy of GV3: %g %g pixel", mttdx[2], mttdy[2]);
3561 cpl_msg_debug (cpl_func,
"FE: correction for dxy of GV4: %g %g pixel", mttdx[3], mttdy[3]);
3566 for (
int tel=0; tel<
ntel; tel++) {
3567 sprintf (qc_name,
"ESO QC MET FIBER SC%iDX", tel+1);
3568 cpl_msg_info (cpl_func,
"%s = %f", qc_name, mttdx[tel]);
3570 cpl_propertylist_set_comment (
header, qc_name,
"[pix] SC fiber offset measured by tel metrology");
3571 sprintf (qc_name,
"ESO QC MET FIBER SC%iDY", tel+1);
3572 cpl_msg_info (cpl_func,
"%s = %f", qc_name, mttdy[tel]);
3574 cpl_propertylist_set_comment (
header, qc_name,
"[pix] SC fiber offset measured by tel metrology");
3588 double sobj_ddec[4];
3589 double sc_fiber_dx[4];
3590 double sc_fiber_dy[4];
3592 for (
int tel=0; tel<
ntel; tel++) {
3596 sprintf (card,
"ESO QC ACQ FIELD%d SC_FIBER_DX", tel+1);
3597 if (cpl_propertylist_has (
header, card) && use_fiber_dxy != 0) {
3598 sc_fiber_dx[tel] = cpl_propertylist_get_double (
header, card);
3599 sobj_dx[tel] = sc_fiber_dx[tel] - mttdx[tel];
3601 sobj_dx[tel] = - mttdx[tel];
3603 sprintf (card,
"ESO QC ACQ FIELD%d SC_FIBER_DY", tel+1);
3604 if (cpl_propertylist_has (
header, card) && use_fiber_dxy != 0) {
3605 sc_fiber_dy[tel] = cpl_propertylist_get_double (
header, card);
3606 sobj_dy[tel] = sc_fiber_dy[tel] - mttdy[tel];
3608 sobj_dy[tel] = - mttdy[tel];
3611 sprintf (qc_name,
"ESO QC MET SOBJ DX%i", tel+1);
3612 cpl_msg_info (cpl_func,
"%s = %f", qc_name, sobj_dx[tel]);
3614 cpl_propertylist_set_comment (
header, qc_name,
"[pixel] x offset from SOBJ");
3615 sprintf (qc_name,
"ESO QC MET SOBJ DY%i", tel+1);
3616 cpl_msg_info (cpl_func,
"%s = %f", qc_name, sobj_dy[tel]);
3618 cpl_propertylist_set_comment (
header, qc_name,
"[pixel] y offset from SOBJ");
3624 northangle = cpl_array_get_double(northangle_array,tel,NULL);
3625 sobj_dra[tel] = sobj_dx[tel]*cos(northangle * CPL_MATH_RAD_DEG ) - sobj_dy[tel]*sin(northangle * CPL_MATH_RAD_DEG );
3626 sobj_ddec[tel] = sobj_dx[tel]*sin(northangle * CPL_MATH_RAD_DEG ) + sobj_dy[tel]*cos(northangle * CPL_MATH_RAD_DEG );
3629 double scale = 18.0;
3630 sprintf (card,
"ESO QC ACQ FIELD%d SCALE", tel+1);
3631 if (cpl_propertylist_has (
header, card))
3632 scale = cpl_propertylist_get_double (
header, card);
3633 sobj_dra[tel] = sobj_dra[tel] * scale;
3634 sobj_ddec[tel] = sobj_ddec[tel] * scale;
3636 sprintf (qc_name,
"ESO QC MET SOBJ DRA%i", tel+1);
3637 cpl_msg_info (cpl_func,
"%s = %f", qc_name, sobj_dra[tel]);
3639 cpl_propertylist_set_comment (
header, qc_name,
"[mas] RA offset from SOBJ");
3640 sprintf (qc_name,
"ESO QC MET SOBJ DDEC%i", tel+1);
3641 cpl_msg_info (cpl_func,
"%s = %f", qc_name, sobj_ddec[tel]);
3643 cpl_propertylist_set_comment (
header, qc_name,
"[mas] DEC offset from SOBJ");
3661 double * opd_telfc_mcorr = cpl_table_get_data_double (vismet_table,
"OPD_TELFC_MCORR");
3664 for (
int tel = 0; tel <
ntel; tel++) {
3665 for (cpl_size row = 0; row < nrow_met; row++) {
3666 opd_telfc_mcorr[row*
ntel+tel] =
3667 (opd_telfc_corr[row*
ntel+tel][0]
3668 + opd_telfc_corr[row*
ntel+tel][1]
3669 + opd_telfc_corr[row*
ntel+tel][2]
3670 + opd_telfc_corr[row*
ntel+tel][3]) / 4. ;
3675 FREE (cpl_vector_delete, tmp_vector);
3687 double * fiber_du = cpl_table_get_data_double (vismet_table,
"FIBER_DU");
3689 double * fiber_dv = cpl_table_get_data_double (vismet_table,
"FIBER_DV");
3690 double met_ttx, met_tty;
3693 float sparang = sin(parang);
3694 float cparang = cos(parang);
3696 for (
int tel = 0; tel <
ntel; tel++) {
3697 for (cpl_size row = 0; row < nrow_met; row++) {
3699 met_ttx = (opd_telfc_corr[row*
ntel+tel][3]*rec_az[tel][3]*pow(rec_zd[tel][0],2) - opd_telfc_corr[row*
ntel+tel][0]*rec_az[tel][1]*rec_zd[tel][0]*rec_zd[tel][1] + opd_telfc_corr[row*
ntel+tel][0]*rec_az[tel][0]*pow(rec_zd[tel][1],2) +
3700 opd_telfc_corr[row*
ntel+tel][3]*rec_az[tel][3]*pow(rec_zd[tel][1],2) - opd_telfc_corr[row*
ntel+tel][0]*rec_az[tel][2]*rec_zd[tel][0]*rec_zd[tel][2] + opd_telfc_corr[row*
ntel+tel][0]*rec_az[tel][0]*pow(rec_zd[tel][2],2) +
3701 opd_telfc_corr[row*
ntel+tel][3]*rec_az[tel][3]*pow(rec_zd[tel][2],2) - opd_telfc_corr[row*
ntel+tel][3]*rec_az[tel][0]*rec_zd[tel][0]*rec_zd[tel][3] - opd_telfc_corr[row*
ntel+tel][0]*rec_az[tel][3]*rec_zd[tel][0]*rec_zd[tel][3] -
3702 opd_telfc_corr[row*
ntel+tel][3]*rec_az[tel][1]*rec_zd[tel][1]*rec_zd[tel][3] - opd_telfc_corr[row*
ntel+tel][3]*rec_az[tel][2]*rec_zd[tel][2]*rec_zd[tel][3] + opd_telfc_corr[row*
ntel+tel][0]*rec_az[tel][0]*pow(rec_zd[tel][3],2) -
3703 opd_telfc_corr[row*
ntel+tel][2]*rec_zd[tel][2]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][1]*rec_zd[tel][1] + rec_az[tel][3]*rec_zd[tel][3]) -
3704 opd_telfc_corr[row*
ntel+tel][1]*rec_zd[tel][1]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][2]*rec_zd[tel][2] + rec_az[tel][3]*rec_zd[tel][3]) +
3705 opd_telfc_corr[row*
ntel+tel][2]*rec_az[tel][2]*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][1],2) + pow(rec_zd[tel][3],2)) +
3706 opd_telfc_corr[row*
ntel+tel][1]*rec_az[tel][1]*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][2],2) + pow(rec_zd[tel][3],2))) /
3707 (pow(rec_az[tel][3],2)*pow(rec_zd[tel][0],2) + pow(rec_az[tel][0],2)*pow(rec_zd[tel][1],2) +
3708 pow(rec_az[tel][3],2)*pow(rec_zd[tel][1],2) + pow(rec_az[tel][0],2)*pow(rec_zd[tel][2],2) +
3709 pow(rec_az[tel][3],2)*pow(rec_zd[tel][2],2) - 2*rec_az[tel][0]*rec_az[tel][3]*rec_zd[tel][0]*rec_zd[tel][3] +
3710 pow(rec_az[tel][0],2)*pow(rec_zd[tel][3],2) - 2*rec_az[tel][2]*rec_zd[tel][2]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][3]*rec_zd[tel][3]) -
3711 2*rec_az[tel][1]*rec_zd[tel][1]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][2]*rec_zd[tel][2] + rec_az[tel][3]*rec_zd[tel][3]) +
3712 pow(rec_az[tel][2],2)*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][1],2) + pow(rec_zd[tel][3],2)) +
3713 pow(rec_az[tel][1],2)*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][2],2) + pow(rec_zd[tel][3],2)));
3714 met_tty = (-(opd_telfc_corr[row*
ntel+tel][2]*rec_az[tel][0]*rec_az[tel][2]*rec_zd[tel][0]) - opd_telfc_corr[row*
ntel+tel][3]*rec_az[tel][0]*rec_az[tel][3]*rec_zd[tel][0] - opd_telfc_corr[row*
ntel+tel][2]*rec_az[tel][1]*rec_az[tel][2]*rec_zd[tel][1] -
3715 opd_telfc_corr[row*
ntel+tel][3]*rec_az[tel][1]*rec_az[tel][3]*rec_zd[tel][1] + opd_telfc_corr[row*
ntel+tel][2]*pow(rec_az[tel][0],2)*rec_zd[tel][2] + opd_telfc_corr[row*
ntel+tel][2]*pow(rec_az[tel][1],2)*rec_zd[tel][2] -
3716 opd_telfc_corr[row*
ntel+tel][3]*rec_az[tel][2]*rec_az[tel][3]*rec_zd[tel][2] + opd_telfc_corr[row*
ntel+tel][2]*pow(rec_az[tel][3],2)*rec_zd[tel][2] + opd_telfc_corr[row*
ntel+tel][3]*pow(rec_az[tel][0],2)*rec_zd[tel][3] +
3717 opd_telfc_corr[row*
ntel+tel][3]*pow(rec_az[tel][1],2)*rec_zd[tel][3] + opd_telfc_corr[row*
ntel+tel][3]*pow(rec_az[tel][2],2)*rec_zd[tel][3] - opd_telfc_corr[row*
ntel+tel][2]*rec_az[tel][2]*rec_az[tel][3]*rec_zd[tel][3] +
3718 opd_telfc_corr[row*
ntel+tel][0]*(pow(rec_az[tel][1],2)*rec_zd[tel][0] + pow(rec_az[tel][2],2)*rec_zd[tel][0] + pow(rec_az[tel][3],2)*rec_zd[tel][0] -
3719 rec_az[tel][0]*rec_az[tel][1]*rec_zd[tel][1] - rec_az[tel][0]*rec_az[tel][2]*rec_zd[tel][2] - rec_az[tel][0]*rec_az[tel][3]*rec_zd[tel][3]) +
3720 opd_telfc_corr[row*
ntel+tel][1]*(-(rec_az[tel][0]*rec_az[tel][1]*rec_zd[tel][0]) + pow(rec_az[tel][0],2)*rec_zd[tel][1] + pow(rec_az[tel][2],2)*rec_zd[tel][1] +
3721 pow(rec_az[tel][3],2)*rec_zd[tel][1] - rec_az[tel][1]*rec_az[tel][2]*rec_zd[tel][2] - rec_az[tel][1]*rec_az[tel][3]*rec_zd[tel][3]))/
3722 (pow(rec_az[tel][3],2)*pow(rec_zd[tel][0],2) + pow(rec_az[tel][0],2)*pow(rec_zd[tel][1],2) +
3723 pow(rec_az[tel][3],2)*pow(rec_zd[tel][1],2) + pow(rec_az[tel][0],2)*pow(rec_zd[tel][2],2) +
3724 pow(rec_az[tel][3],2)*pow(rec_zd[tel][2],2) - 2*rec_az[tel][0]*rec_az[tel][3]*rec_zd[tel][0]*rec_zd[tel][3] +
3725 pow(rec_az[tel][0],2)*pow(rec_zd[tel][3],2) - 2*rec_az[tel][2]*rec_zd[tel][2]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][3]*rec_zd[tel][3]) -
3726 2*rec_az[tel][1]*rec_zd[tel][1]*(rec_az[tel][0]*rec_zd[tel][0] + rec_az[tel][2]*rec_zd[tel][2] + rec_az[tel][3]*rec_zd[tel][3]) +
3727 pow(rec_az[tel][2],2)*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][1],2) + pow(rec_zd[tel][3],2)) +
3728 pow(rec_az[tel][1],2)*(pow(rec_zd[tel][0],2) + pow(rec_zd[tel][2],2) + pow(rec_zd[tel][3],2)));
3730 fiber_du[row*
ntel+tel] = met_ttx*cparang + met_tty*sparang;
3731 fiber_dv[row*
ntel+tel] = - met_ttx*sparang + met_tty*cparang;
3739 double * pupil_u = NULL;
3740 double * pupil_v = NULL;
3741 if ( cpl_table_has_column(vismet_table,
"PUPIL_U") && cpl_table_has_column(vismet_table,
"PUPIL_V") ) {
3742 pupil_u = cpl_table_get_data_double (vismet_table,
"PUPIL_U");
3743 pupil_v = cpl_table_get_data_double (vismet_table,
"PUPIL_V");
3746 cpl_msg_warning(cpl_func,
"Cannot get the PUPIL_U/V (not computed) so will"
3747 "not correct for pupil opd (check the --reduce-acq-cam option)");
3752 double * opd_ttpup = cpl_table_get_data_double (vismet_table,
"OPD_TTPUP");
3754 for (
int tel = 0; tel <
ntel; tel++) {
3755 for (cpl_size row = 0; row < nrow_met; row++) {
3756 opd_ttpup[row*
ntel+tel] = (pupil_u && pupil_v) ?
3757 fiber_du[row*
ntel+tel] * pupil_u[row*
ntel+tel] +
3758 fiber_dv[row*
ntel+tel] * pupil_v[row*
ntel+tel] : 0. ;
3767 CPLCHECK_MSG (
"Cannot fill result of TEL vs FC computation");
3770 cpl_array_delete(northangle_array);
3771 FREE (cpl_free, phase_tel);
3772 FREE (cpl_free, amplitude_tel);
3773 FREE (cpl_free, amplitude_tel_flagged);
3774 FREE (cpl_free, opd_tel);
3775 FREE (cpl_free, opd_tel_corr);
3776 FREE (cpl_free, opd_telfc_corr);
3777 FREE (cpl_free, phase_telfc_corr);
3778 FREE (cpl_free, phase_telfc_corr_xy);
3781 return CPL_ERROR_NONE;
3833 cpl_ensure (metrology_table, CPL_ERROR_NULL_INPUT, NULL);
3835 cpl_vector * vectA, * vectB,
3836 * y_sigma, * init_val, *opl_vect;
3837 const cpl_array * volt;
3838 cpl_array * coherence_fit, * phase_fit;
3839 cpl_matrix * opd_matrix;
3842 int val_to_fit2[] = {1,1,1,0}, nv;
3843 double mse, red_chisq;
3850 cpl_size nrow = cpl_table_get_nrow (metrology_table);
3854 cpl_table * p2vm_met = cpl_table_new (
ntel * 2);
3855 cpl_table_new_column_array (p2vm_met,
"TRANSMISSION", CPL_TYPE_DOUBLE, 2);
3856 cpl_table_new_column_array (p2vm_met,
"COHERENCE", CPL_TYPE_DOUBLE, 2);
3857 cpl_table_new_column_array (p2vm_met,
"PHASE", CPL_TYPE_DOUBLE, 2);
3862 for (
int gravi_type = 0; gravi_type < 2; gravi_type++ ){
3863 int comb = (gravi_type ==
GRAVI_SC ? 1 : 2);
3866 for (
int tel = 0; tel <
ntel; tel++){
3869 vectA = cpl_vector_new (nrow);
3870 vectB = cpl_vector_new (nrow);
3872 for (cpl_size row = 0; row < nrow; row ++){
3873 volt = cpl_table_get_array ( metrology_table,
"VOLT", row);
3874 cpl_vector_set (vectA, row, cpl_array_get (volt , n_diode - 2*(comb*
ntel - tel), &nv));
3875 cpl_vector_set (vectB, row, cpl_array_get (volt , n_diode - 2*(comb*
ntel - tel) + 1, &nv));
3880 cpl_vector_multiply_scalar (opl_vect, wave_met/(2.0*M_PI));
3884 opd_matrix = cpl_matrix_new(nrow, 1);
3885 for (cpl_size row = 0; row < nrow; row++){
3886 cpl_matrix_set (opd_matrix, row, 0, cpl_vector_get (opl_vect, row));
3889 cpl_vector_delete (opl_vect);
3893 vect = cpl_malloc (2*
sizeof(cpl_vector*));
3896 phase_fit = cpl_array_new (2, CPL_TYPE_DOUBLE);
3897 coherence_fit = cpl_array_new (2, CPL_TYPE_DOUBLE);
3898 trans = cpl_array_new (2, CPL_TYPE_DOUBLE);
3900 for (
int i = 0; i < 2; i++){
3903 y_sigma = cpl_vector_new(nrow);
3904 cpl_vector_fill(y_sigma, 1);
3909 init_val = cpl_vector_new(4);
3910 cpl_vector_set(init_val, 0, 1);
3911 cpl_vector_set(init_val, 1, 1);
3912 cpl_vector_set(init_val, 2, 1);
3913 cpl_vector_set(init_val, 3, wave_met);
3915 cpl_errorstate prestate = cpl_errorstate_get();
3916 cpl_fit_lvmq(opd_matrix, NULL, vect[i],
3918 &
dfda_sin, CPL_FIT_LVMQ_TOLERANCE, CPL_FIT_LVMQ_COUNT,
3919 CPL_FIT_LVMQ_MAXITER, &mse, &red_chisq, NULL);
3921 if (cpl_error_get_code()){
3922 printf(
"error %f %s and %s \n", 6.0, cpl_error_get_message(), cpl_error_get_where());
3926 if (!strcmp(
"The iterative process did not converge",
3927 cpl_error_get_message())){
3930 "did not converge");
3931 cpl_errorstate_set (prestate);
3935 "%g chi2 %g", tel, mse, red_chisq);
3939 cpl_array_set_double (coherence_fit, i,
3940 sqrt( pow( cpl_vector_get(init_val, 2), 2) +
3941 pow( cpl_vector_get(init_val, 1), 2)));
3943 cpl_array_set_double (phase_fit, i, atan2( cpl_vector_get(init_val, 2),
3944 cpl_vector_get(init_val, 1)));
3946 cpl_array_set_double (trans, i, cpl_vector_get(init_val, 0));
3948 if (cpl_error_get_code()){
3949 printf(
"error %f %s and %s \n", 7.0, cpl_error_get_message(), cpl_error_get_where());
3953 cpl_vector_delete(init_val);
3954 cpl_vector_delete(y_sigma);
3955 cpl_vector_delete (vect[i]);
3958 FREE (cpl_free, vect);
3959 FREE (cpl_matrix_delete, opd_matrix);
3961 cpl_table_set_array (p2vm_met,
"COHERENCE",
ntel*(1-gravi_type) + tel, coherence_fit);
3962 cpl_array_subtract_scalar (phase_fit,
3963 cpl_array_get_double (phase_fit, 0, &nv));
3964 cpl_table_set_array (p2vm_met,
"PHASE",
ntel*(1-gravi_type) + tel, phase_fit);
3965 cpl_table_set_array (p2vm_met,
"TRANSMISSION",
ntel*(1-gravi_type) + tel, trans);
3967 FREE (cpl_array_delete, trans);
3968 FREE (cpl_array_delete, coherence_fit);
3969 FREE (cpl_array_delete, phase_fit);