def test_two_important_number(some_numbers): errors = np.ones(10) errors[2:] = np.inf assert stats.circular_mean( some_numbers, errors=errors) == stats.circular_mean(some_numbers[:2]) assert stats.circular_error(some_numbers, errors=errors, t_value_corr=False) ==\ stats.circular_error(some_numbers[:2], errors=np.ones(2), t_value_corr=False)
def test_nanhandling(): vector = np.array([355., 0., 5., np.nan]) assert stats.circular_nanmean(vector) == stats.circular_mean(vector[:-1]) assert stats.weighted_nanmean(vector) == stats.weighted_mean(vector[:-1]) assert stats.weighted_nanrms(vector) == stats.weighted_rms(vector[:-1]) vector = np.array([[355., 0., 5., 0.], [355., 0., 5., 0.], [355., 0., 5., np.nan]]) assert np.all( stats.circular_nanerror(vector, axis=1) == stats.circular_error( vector[:, :-1], axis=1))
def _process_rdt(meas_input, input_files, phase_data, invariants, plane, rdt): df = pd.DataFrame(phase_data) second_bpms = df.loc[:, "NAME2"].to_numpy() df["S2"] = df.loc[second_bpms, "S"].to_numpy() df["COUNT"] = len(input_files.dpp_frames(plane, 0)) line = _determine_line(rdt, plane) phase_sign, suffix = get_line_sign_and_suffix(line, input_files, plane) comp_coeffs1 = to_complex( input_files.joined_frame(plane, [f"AMP{suffix}"], dpp_value=0).loc[df.index, :].to_numpy(), phase_sign * input_files.joined_frame(plane, [f"PHASE{suffix}"], dpp_value=0).loc[df.index, :].to_numpy()) # Multiples of tunes needs to be added to phase at second BPM if that is in second turn phase2 = phase_sign * input_files.joined_frame( plane, [f"PHASE{suffix}"], dpp_value=0).loc[second_bpms, :].to_numpy() comp_coeffs2 = to_complex( input_files.joined_frame(plane, [f"AMP{suffix}"], dpp_value=0).loc[second_bpms, :].to_numpy(), _add_tunes_if_in_second_turn(df, input_files, line, phase2)) # Get amplitude and phase of the line from linx/liny file line_amp, line_phase, line_amp_e, line_phase_e = complex_secondary_lines( # TODO use the errors df.loc[:, "MEAS"].to_numpy()[:, np.newaxis] * meas_input.accelerator.beam_direction, df.loc[:, "ERRMEAS"].to_numpy()[:, np.newaxis], comp_coeffs1, comp_coeffs2) rdt_phases_per_file = _calculate_rdt_phases_from_line_phases( df, input_files, line, line_phase) rdt_angles = stats.circular_mean(rdt_phases_per_file, period=1, axis=1) % 1 df[f"PHASE"] = rdt_angles df[f"{ERR}PHASE"] = stats.circular_error(rdt_phases_per_file, period=1, axis=1) df[AMPLITUDE], df[f"{ERR}{AMPLITUDE}"] = _fit_rdt_amplitudes( invariants, line_amp, plane, rdt) df[f"REAL"] = np.cos( 2 * np.pi * rdt_angles) * df.loc[:, AMPLITUDE].to_numpy() df[f"IMAG"] = np.sin( 2 * np.pi * rdt_angles) * df.loc[:, AMPLITUDE].to_numpy() # in old files there was "EAMP" and "PHASE_STD" return df.loc[:, [ "S", "COUNT", AMPLITUDE, f"{ERR}{AMPLITUDE}", "PHASE", f"{ERR}PHASE", "REAL", "IMAG" ]]
def _calculate_with_compensation(meas_input, input_files, tunes, plane, model_df, compensation='none', no_errors=False): """ Calculates phase advances. Args: meas_input: the input object including settings and the accelerator class. input_files: includes measurement tfs. tunes: `TunesDict` object containing measured and model tunes and ac2bpm object plane: marking the horizontal or vertical plane, **X** or **Y**. no_errors: if ``True``, measured errors shall not be propagated (only their spread). Returns: A `dictionary` of `TfsDataFrames` indexed (BPMi x BPMj) yielding phase advance `phi_ij`. - "MEAS": measured phase advances, - "ERRMEAS": errors of measured phase advances, - "MODEL": model phase advances. +------++--------+--------+--------+--------+ | || BPM1 | BPM2 | BPM3 | BPM4 | +======++========+========+========+========+ | BPM1 || 0 | phi_12 | phi_13 | phi_14 | +------++--------+--------+--------+--------+ | BPM2 || phi_21 | 0 | phi_23 | phi_24 | +------++--------+--------+--------+--------+ | BPM3 || phi_31 | phi_32 | 0 | phi_34 | +------++--------+--------+--------+--------+ | BPM4 || phi_41 | phi_42 | phi_43 | 0 | +------++--------+--------+--------+--------+ The phase advance between BPM_i and BPM_j can be obtained via: phase_advances["MEAS"].loc[BPMi,BPMj] list of output data frames(for files) """ LOGGER.info("Calculating phase advances") LOGGER.info(f"Measured tune in plane {plane} = {tunes[plane]['Q']}") df = model_df.loc[:, ["S", f"MU{plane}"]] how = 'outer' if meas_input.union else 'inner' dpp_value = meas_input.dpp if "dpp" in meas_input.keys() else 0 df = pd.merge(df, input_files.joined_frame(plane, [f"MU{plane}", f"{ERR}MU{plane}"], dpp_value=dpp_value, how=how), how='inner', left_index=True, right_index=True) df[input_files.get_columns( df, f"MU{plane}")] = (input_files.get_data(df, f"MU{plane}") * meas_input.accelerator.beam_direction) phases_mdl = df.loc[:, f"MU{plane}"].to_numpy() phase_advances = { "MODEL": _get_square_data_frame( (phases_mdl[np.newaxis, :] - phases_mdl[:, np.newaxis]) % 1.0, df.index) } if compensation == "model": df = _compensate_by_model(input_files, meas_input, df, plane) phases_meas = input_files.get_data(df, f"MU{plane}") if meas_input.compensation == "equation": phases_meas = _compensate_by_equation(phases_meas, plane, tunes) phases_errors = input_files.get_data(df, f"{ERR}MU{plane}") if phases_meas.ndim < 2: phase_advances["MEAS"] = _get_square_data_frame( (phases_meas[np.newaxis, :] - phases_meas[:, np.newaxis]) % 1.0, df.index) phase_advances["ERRMEAS"] = _get_square_data_frame( np.zeros((len(phases_meas), len(phases_meas))), df.index) return phase_advances if meas_input.union: mask = np.isnan(phases_meas) phases_meas[mask], phases_errors[mask] = 0.0, np.inf if no_errors: phases_errors[~mask] = 1e-10 elif no_errors: phases_errors = None phases_3d = phases_meas[np.newaxis, :, :] - phases_meas[:, np.newaxis, :] if phases_errors is not None: errors_3d = phases_errors[ np.newaxis, :, :] + phases_errors[:, np.newaxis, :] else: errors_3d = None phase_advances["MEAS"] = _get_square_data_frame( stats.circular_mean(phases_3d, period=1, errors=errors_3d, axis=2) % 1.0, df.index) phase_advances["ERRMEAS"] = _get_square_data_frame( stats.circular_error(phases_3d, period=1, errors=errors_3d, axis=2), df.index) return phase_advances, [ _create_output_df(phase_advances, df, plane), _create_output_df(phase_advances, df, plane, tot=True) ]
def test_circular_zeros(zeros): assert stats.circular_mean(zeros) == 0 assert stats.circular_error(zeros) == 0
def test_one_important_number(some_numbers): errors = np.ones(10) errors[1:] = np.inf assert stats.circular_mean(some_numbers, errors=errors) == some_numbers[0] assert stats.circular_error(some_numbers, errors=errors, t_value_corr=False) ==\ stats.circular_error(errors[0], errors=1., t_value_corr=False)
def test_circular_empties(): empty = np.array([]) with pytest.warns(RuntimeWarning): stats.circular_mean(empty) with pytest.warns(RuntimeWarning): stats.circular_error(empty)