-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Arc corr and glob check fix #437
base: master
Are you sure you want to change the base?
Changes from all commits
68f6d8b
284544e
49354ae
2cf3400
0eead2b
d908b34
0b34c5f
2488022
e861a08
9406ea8
f977613
a7cf7e9
8c762a1
5e0257a
0904fae
b56bd02
aecbb3c
23e41b3
3020b80
5cfe24c
099c42d
7d4c1ad
51c2400
67570e0
5ac386f
ee71a70
4d18da9
c97a9ff
bba82c7
33b67ce
a34f920
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -246,7 +246,7 @@ | |
from omc3.correction.response_twiss import PLANES | ||
from omc3.definitions.optics import ( | ||
OpticsMeasurement, ColumnsAndLabels, | ||
FILE_COLUMN_MAPPING, RDT_COLUMN_MAPPING, TUNE_COLUMN | ||
FILE_COLUMN_MAPPING, RDT_COLUMN_MAPPING, TUNE_COLUMN, TOTAL_PHASE_NAME, MU_COLUMN | ||
) | ||
from omc3.global_correction import _get_default_values, CORRECTION_DEFAULTS, OPTICS_PARAMS_CHOICES | ||
from omc3.model import manager | ||
|
@@ -481,8 +481,10 @@ def _create_model_and_write_diff_to_measurements( | |
diff_columns = ( | ||
list(OPTICS_PARAMS_CHOICES[:-4]) + | ||
[col for col in corr_model_elements.columns if col.startswith("F1")] + | ||
list(PLANES) | ||
list(PLANES) + | ||
['MUX', 'MUY'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could also probably be from constants |
||
) | ||
|
||
diff_models = diff_twiss_parameters(corr_model_elements, accel_inst.model, parameters=diff_columns) | ||
LOG.debug("Differences to nominal model calculated.") | ||
|
||
|
@@ -520,12 +522,17 @@ def _create_model_and_write_diff_to_measurements( | |
LOG.debug(f"Checking correction for {attribute}") | ||
plane = filename[-1].upper() | ||
cols = colmap.set_plane(plane) | ||
if filename[:-1] == TOTAL_PHASE_NAME: | ||
model_cols = MU_COLUMN.set_plane(plane) | ||
else: | ||
model_cols = cols | ||
|
||
_create_check_columns( | ||
measurement=measurement, | ||
output_measurement=output_measurement, | ||
diff_models=diff_models, | ||
colmap_meas=cols, | ||
colmap_model=cols, | ||
colmap_model=model_cols, | ||
attribute=attribute, | ||
rms_mask=rms_mask, | ||
) | ||
|
@@ -577,7 +584,7 @@ def _create_check_columns(measurement: OpticsMeasurement, output_measurement: Op | |
diff = diff_models.loc[df.index, colmap_model.delta_column] | ||
|
||
df[colmap_meas.diff_correction_column] = diff | ||
if colmap_meas.column == PHASE: | ||
if colmap_meas.column[:-1] == PHASE: | ||
df[colmap_meas.expected_column] = pd.to_numeric(ang_diff(df[colmap_meas.delta_column], diff)) # assumes period 1 | ||
df.headers[colmap_meas.delta_rms_header] = circular_rms(df[colmap_meas.delta_column], period=1) | ||
df.headers[colmap_meas.expected_rms_header] = circular_rms(df[colmap_meas.expected_column], period=1) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import numpy as np | ||
import pandas as pd | ||
|
||
|
||
def identify_closest_arc_bpm_to_ip(ip, side, beam, bpms): | ||
indices = range(1,15) | ||
for ii in indices: | ||
bpm = f'BPM.{ii}{side}{ip}.B{beam}' | ||
if bpm in bpms: | ||
return bpm | ||
|
||
|
||
def get_left_right_pair(arc, beam, bpms): | ||
left_of_arc = identify_closest_arc_bpm_to_ip(int(arc[0]), 'R', beam, bpms) | ||
right_of_arc = identify_closest_arc_bpm_to_ip(int(arc[1]), 'L', beam, bpms) | ||
return [left_of_arc, right_of_arc] | ||
|
||
|
||
def get_arc_by_arc_bpm_pairs(meas_dict, opt, plane): | ||
bpms = meas_dict[f'PHASE{plane}'].index | ||
beam = bpms[0][-1] | ||
bpm_pairs = {} | ||
bpm_pairs_with_ips = {} | ||
|
||
arcs_to_cycle = ['81', '12', '23', '34', '45', '56', '67', '78'] | ||
|
||
for lhc_arc in arcs_to_cycle: | ||
bpm_pairs[lhc_arc] = get_left_right_pair(lhc_arc, beam, bpms) | ||
|
||
if opt.include_ips_in_arc_by_arc == 'left': | ||
bpm_pairs_with_ips['81'] = [bpm_pairs['78'][1], bpm_pairs['81'][1]] | ||
bpm_pairs_with_ips['12'] = [bpm_pairs['81'][1], bpm_pairs['12'][1]] | ||
bpm_pairs_with_ips['23'] = [bpm_pairs['12'][1], bpm_pairs['23'][1]] | ||
bpm_pairs_with_ips['34'] = [bpm_pairs['23'][1], bpm_pairs['34'][1]] | ||
bpm_pairs_with_ips['45'] = [bpm_pairs['34'][1], bpm_pairs['45'][1]] | ||
bpm_pairs_with_ips['56'] = [bpm_pairs['45'][1], bpm_pairs['56'][1]] | ||
bpm_pairs_with_ips['67'] = [bpm_pairs['56'][1], bpm_pairs['67'][1]] | ||
bpm_pairs_with_ips['78'] = [bpm_pairs['67'][1], bpm_pairs['78'][1]] | ||
bpm_pairs = bpm_pairs_with_ips | ||
elif opt.include_ips_in_arc_by_arc == 'right': | ||
bpm_pairs_with_ips['81'] = [bpm_pairs['78'][0], bpm_pairs['81'][0]] | ||
bpm_pairs_with_ips['12'] = [bpm_pairs['81'][0], bpm_pairs['12'][0]] | ||
bpm_pairs_with_ips['23'] = [bpm_pairs['12'][0], bpm_pairs['23'][0]] | ||
bpm_pairs_with_ips['34'] = [bpm_pairs['23'][0], bpm_pairs['34'][0]] | ||
bpm_pairs_with_ips['45'] = [bpm_pairs['34'][0], bpm_pairs['45'][0]] | ||
bpm_pairs_with_ips['56'] = [bpm_pairs['45'][0], bpm_pairs['56'][0]] | ||
bpm_pairs_with_ips['67'] = [bpm_pairs['56'][0], bpm_pairs['67'][0]] | ||
bpm_pairs_with_ips['78'] = [bpm_pairs['67'][0], bpm_pairs['78'][0]] | ||
bpm_pairs = bpm_pairs_with_ips | ||
|
||
return bpm_pairs | ||
|
||
|
||
def circular_sum_phase(phase_df, tune, bpm_pair, key): | ||
idx_0 = phase_df[key].index.get_loc(bpm_pair[0]) | ||
idx_1 = phase_df[key].index.get_loc(bpm_pair[1]) | ||
if idx_0 > idx_1: | ||
inverted_result = sum(phase_df[key][bpm_pair[1]:bpm_pair[0]]) | ||
result = tune - inverted_result | ||
else: | ||
result = sum(phase_df[key][bpm_pair[0]:bpm_pair[1]]) | ||
return result | ||
|
||
|
||
def circular_sum_phase_error(phase_df, bpm_pair): | ||
idx_0 = phase_df['ERROR'].index.get_loc(bpm_pair[0]) | ||
idx_1 = phase_df['ERROR'].index.get_loc(bpm_pair[1]) | ||
if idx_0 > idx_1: | ||
selection = pd.concat([phase_df['ERROR'].loc[:bpm_pair[1]], phase_df['ERROR'].loc[bpm_pair[0]:]]) | ||
result = np.sqrt(np.sum(selection**2)) | ||
else: | ||
result = np.sqrt(np.sum(phase_df['ERROR'][bpm_pair[0]:bpm_pair[1]]**2)) | ||
return result | ||
|
||
def get_arc_phases(bpm_pairs, meas_dict, tune, plane): | ||
arc_meas = [] | ||
for arc, bpm_pair in bpm_pairs.items(): | ||
results = {} | ||
results['NAME'] = bpm_pair[0] | ||
results['NAME2'] = bpm_pair[1] | ||
results['WEIGHT'] = meas_dict[f'PHASE{plane}'].loc[bpm_pair[0], 'WEIGHT'] | ||
results['VALUE'] = circular_sum_phase(meas_dict[f'PHASE{plane}'], tune, bpm_pair, 'VALUE') | ||
results['MODEL'] = circular_sum_phase(meas_dict[f'PHASE{plane}'], tune, bpm_pair, 'MODEL') | ||
results['ERROR'] = circular_sum_phase_error(meas_dict[f'PHASE{plane}'], bpm_pair) | ||
results['DIFF'] = results['VALUE'] - results['MODEL'] | ||
arc_meas.append(results) | ||
|
||
meas_dict[f'PHASE{plane}'] = pd.DataFrame(arc_meas).set_index('NAME') | ||
|
||
return meas_dict | ||
|
||
|
||
def reduce_to_arc_extremities(meas_dict, nominal_model, opt): | ||
bpm_pairs_x = get_arc_by_arc_bpm_pairs(meas_dict, opt, "X") | ||
bpm_pairs_y = get_arc_by_arc_bpm_pairs(meas_dict, opt, "Y") | ||
meas_dict = get_arc_phases(bpm_pairs_x, meas_dict, nominal_model.headers['Q1'], 'X') | ||
meas_dict = get_arc_phases(bpm_pairs_y, meas_dict, nominal_model.headers['Q2'], 'Y') | ||
return meas_dict |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
from sklearn.linear_model import OrthogonalMatchingPursuit | ||
|
||
import omc3.madx_wrapper as madx_wrapper | ||
from omc3.correction import filters, model_appenders, response_twiss, response_madx | ||
from omc3.correction import filters, model_appenders, response_twiss, response_madx, arc_by_arc as abba | ||
from omc3.correction.constants import DIFF, ERROR, VALUE, WEIGHT, ORBIT_DPP | ||
from omc3.correction.model_appenders import add_coupling_to_model | ||
from omc3.correction.response_io import read_fullresponse | ||
|
@@ -69,6 +69,9 @@ def correct(accel_inst: Accelerator, opt: DotDict) -> None: | |
meas_dict = filters.filter_measurement(optics_params, meas_dict, nominal_model, opt) | ||
meas_dict = model_appenders.add_differences_to_model_to_measurements(nominal_model, meas_dict) | ||
|
||
if opt.arc_by_arc_phase and accel_inst.NAME == 'lhc': | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have to hardcode here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would go with |
||
meas_dict = abba.reduce_to_arc_extremities(meas_dict, nominal_model, opt) | ||
|
||
resp_dict = filters.filter_response_index(resp_dict, meas_dict, optics_params) | ||
resp_matrix = _join_responses(resp_dict, optics_params, vars_list) | ||
delta = tfs.TfsDataFrame(0., index=vars_list, columns=[DELTA]) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,10 +67,16 @@ def _get_model_generic(model: pd.DataFrame, meas: pd.DataFrame, key: str) -> pd. | |
|
||
|
||
def _get_model_phases(model: pd.DataFrame, meas: pd.DataFrame, key: str) -> pd.DataFrame: | ||
model_column = f"{PHASE_ADV}{key[-1]}" | ||
plane = key[-1] | ||
tunes = {'X':model.headers['Q1'], | ||
'Y':model.headers['Q2'], | ||
} | ||
model_column = f"{PHASE_ADV}{plane}" | ||
with logging_tools.log_pandas_settings_with_copy(LOG.debug): | ||
meas[MODEL] = (model.loc[meas["NAME2"].to_numpy(), model_column].to_numpy() - | ||
model.loc[meas.index.to_numpy(), model_column].to_numpy()) | ||
model_phases_advances = (model.loc[meas["NAME2"].to_numpy(), model_column].to_numpy() - | ||
model.loc[meas.index.to_numpy(), model_column].to_numpy()) | ||
model_phases_advances[model_phases_advances < 0] += tunes[plane] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is probably a settingswithcopywarning, this PR could be the opportunity to use |
||
meas[MODEL] = model_phases_advances | ||
meas[DIFF] = df_diff(meas, VALUE, MODEL) | ||
return meas | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -175,7 +175,7 @@ | |
NORM_DISPERSION, PHASE, TUNE) | ||
from omc3.model import manager | ||
from omc3.utils import logging_tools | ||
from omc3.utils.iotools import PathOrStr, save_config | ||
from omc3.utils.iotools import PathOrStr, OptionalStr, save_config | ||
|
||
if TYPE_CHECKING: | ||
from generic_parser import DotDict | ||
|
@@ -190,14 +190,14 @@ | |
f"{F1001}R", f"{F1001}I", f"{F1010}R", f"{F1010}I") | ||
|
||
CORRECTION_DEFAULTS = { | ||
"optics_file": None, | ||
"output_filename": "changeparameters_iter", | ||
"svd_cut": 0.01, | ||
"optics_params": OPTICS_PARAMS_CHOICES[:6], | ||
"variable_categories": ["MQM", "MQT", "MQTL", "MQY"], | ||
"beta_filename": "beta_phase_", | ||
"method": "pinv", | ||
"iterations": 4, | ||
"include_ips_in_arc_by_arc": None, | ||
} | ||
|
||
|
||
|
@@ -276,6 +276,14 @@ def correction_params(): | |
params.add_parameter(name="update_response", | ||
action="store_true", | ||
help="Update the (analytical) response per iteration.", ) | ||
params.add_parameter(name="arc_by_arc_phase", | ||
action="store_true", | ||
help="Set to perform arc-by-arc total phase correction.", ) | ||
params.add_parameter(name="include_ips_in_arc_by_arc", | ||
type=str, | ||
choices=("left", "right"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are the choices correct here since the default is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think "None" is always a choice when not required. I implemented this somewhen. |
||
default=CORRECTION_DEFAULTS["include_ips_in_arc_by_arc"], | ||
help="If not specified only takes pure arcs. Otherwise it includes IPs left or right of arcs.", ) | ||
return params | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
|
||
from generic_parser import EntryPoint | ||
|
||
from omc3.model.accelerators.accelerator import AccElementTypes, Accelerator | ||
|
||
|
||
class Generic(Accelerator): | ||
NAME = "generic" | ||
RE_DICT = {AccElementTypes.BPMS: r"B", | ||
AccElementTypes.MAGNETS: r".*", | ||
AccElementTypes.ARC_BPMS: r"B", | ||
} | ||
|
||
def __init__(self, *args, **kwargs): | ||
parser = EntryPoint(self.get_parameters(), strict=True) | ||
opt = parser.parse(*args, **kwargs) | ||
super().__init__(opt) | ||
fsoubelet marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we waiting for more to release? The Kmod branch?