Skip to content
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

Acc-Models Creation #432

Merged
merged 89 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
b2e5a34
try to print out some useful help messages
awegsche Jul 20, 2021
2a14b04
Merge branch 'master' into enhancement/292/modelcreation
awegsche Jul 20, 2021
61c603d
add fetchers
awegsche Aug 2, 2021
5b9a70a
Merge branch 'master' into enhancement/292/modelcreation
awegsche Aug 2, 2021
78e7d5b
Merge branch 'master' into enhancement/292/modelcreation
awegsche Sep 13, 2021
87fffe9
Merge branch 'master' into enhancement/292/modelcreation
awegsche Oct 12, 2021
7436659
Merge branch 'master' into enhancement/292/modelcreation
awegsche Dec 14, 2021
d834c11
comments, formatting, add CreatedModel
awegsche Sep 2, 2022
ab22144
Merge branch 'master' into enhancement/292/modelcreation
awegsche Sep 2, 2022
81b0953
comments, fix in `CreatedModel`
awegsche Sep 5, 2022
a4c133e
start restructuring `lhc_model_creator` to reflect acc-models
awegsche Sep 5, 2022
b422e0c
add `require_param` and refactor model creation
awegsche Sep 6, 2022
1a3408e
also print available accelerators in help message
awegsche Sep 6, 2022
66f94e0
Refactoring model creation
awegsche Sep 7, 2022
4f69d02
some comments
awegsche Sep 7, 2022
e720bf8
no silence
awegsche Sep 21, 2022
00e2c05
Merge branch 'master' into enhancement/292/modelcreation
awegsche Sep 21, 2022
fbab08e
error type
awegsche Sep 21, 2022
f8213c2
Merge branch 'master' into enhancement/292/modelcreation
awegsche Oct 4, 2022
07c9642
add PSB model creation
awegsche Oct 7, 2022
33af415
refactoring PS and PSB modelcreation to use acc-models
awegsche Jan 11, 2023
bd7f74a
bugfixes,
awegsche Jan 13, 2023
cc863ad
Remove debug prints and wrong comments
awegsche Jan 17, 2023
00cad93
formatting
awegsche Jan 17, 2023
c7d382e
improve comments and structure of PS base mask
awegsche Jan 17, 2023
d6b835c
Remove some more debug prints
awegsche Jan 17, 2023
cedbc32
PsBase and PsBaseModelcreator
awegsche Jan 27, 2023
1993827
Merge branch 'master' into enhancement/292/modelcreation
awegsche Jan 27, 2023
aeef18a
query model creation args
awegsche Mar 1, 2023
3c4b6c5
suppress output from base sequence loading in lhc
awegsche Mar 15, 2023
1488cca
add tests for new modelcreator
awegsche Mar 16, 2023
8c61d9e
Path or String?
awegsche Mar 16, 2023
6674d11
Set beam energy
awegsche Mar 16, 2023
7e740f2
find integer tune
awegsche Mar 16, 2023
a5094dd
new modelcreator tests
awegsche Mar 16, 2023
03cc468
remove debug prints
awegsche Mar 16, 2023
f57b5f9
add input folders for modelcreation tests
awegsche Mar 16, 2023
74389ec
revert beam energy setting (didn't work with fullesponse)
awegsche Mar 20, 2023
abe3d5b
read acc-models from model_dir
awegsche Mar 27, 2023
d967139
job filename by type (avoids overwriting)
awegsche Mar 29, 2023
6beb318
madx job filename fix
JoschD Apr 7, 2023
9cc86d2
Merge branch 'master' into enhancement/292/modelcreation
awegsche Apr 17, 2023
52cf37c
Merge branch 'master' into model_creation_merged_with_master
JoschD Jun 19, 2023
a27e7d5
Merge branch 'master' into model_creation_merged_with_master
JoschD Aug 29, 2023
49133d1
HL acc-models lattice and fix for deprecated optics
awegsche Sep 20, 2023
c945876
Merge branch 'master' into enhancement/292/modelcreation
awegsche Sep 20, 2023
c578da5
Merge branch 'master' into model_creation_merged_with_master
JoschD Sep 21, 2023
4ce013a
Merge branch 'master' into enhancement/292/modelcreation
awegsche Oct 16, 2023
8c76af8
Merge branch 'master' into enhancement/292/modelcreation
awegsche Nov 2, 2023
a9f7e6e
Make model creator tests working
awegsche Nov 3, 2023
92f025a
make best knowledge test extended
awegsche Nov 7, 2023
c58d496
maybe get
awegsche Nov 7, 2023
2a2a6dc
formatting
awegsche Nov 29, 2023
4466fb3
remove ps test
awegsche Nov 29, 2023
a714e6c
Merge branch 'enhancement/292/modelcreation' into model_creation_merg…
awegsche Nov 29, 2023
a7e7cfa
Move knobs.madx creation to model_creator
awegsche Nov 29, 2023
c9bfed4
Add clones to workflows `extended` and `coverage`
awegsche Nov 29, 2023
1a8e796
no best knowledge tests yet
awegsche Nov 29, 2023
7f1beea
Merge branch 'master' into model_creation_merged_with_master
awegsche Nov 29, 2023
c755e1e
remove lattice files
awegsche Nov 29, 2023
1d19e18
Merge branch 'model_creation_merged_with_master' of github.com:pylhc/…
awegsche Nov 29, 2023
41726e2
add ps test
awegsche Nov 30, 2023
11f782a
add test for parsertools
awegsche Dec 1, 2023
1a4d4b5
test missing best knowledge for PS/PSB
awegsche Dec 1, 2023
668a595
remove debug prints
awegsche Dec 4, 2023
ae7aa72
not (a or b) = not a and not b
awegsche Dec 4, 2023
6dd9fc3
removed unused code
awegsche Dec 4, 2023
cb1c86f
Added doc to accel model creators
awegsche Dec 4, 2023
be24451
move git clones to fixture
awegsche Dec 7, 2023
7f9b4e3
add gitpython as dependency
awegsche Dec 7, 2023
be6baf4
remove prints
awegsche Dec 7, 2023
28c584c
Add best_knowledge_model test
awegsche Dec 7, 2023
478df4a
Check best knowledge creation
awegsche Dec 7, 2023
dd9e78b
moved B2 root to constants
awegsche Dec 7, 2023
1ad7592
Add doc to check_folder_choices
awegsche Dec 7, 2023
6a93665
add cli tests
awegsche Dec 11, 2023
f023e00
add a few more tests
awegsche Dec 11, 2023
7127d76
SKEKB tests
awegsche Dec 12, 2023
1db6ee6
cleanup
awegsche Dec 12, 2023
04e5be0
Merge branch 'master' into model_creation_merged_with_master
awegsche Dec 12, 2023
5e05d96
Merge branch 'model_creation_merged_with_master' of github.com:pylhc/…
awegsche Dec 12, 2023
05dbb00
version bump and changelog
awegsche Dec 12, 2023
7f89fd5
add explanation for the modifier tag
awegsche Dec 12, 2023
514034e
implemented suggestions
awegsche Dec 15, 2023
800d355
pyright missed one replace
awegsche Dec 15, 2023
9a8873b
restructure acc-models check in from_model_dir
awegsche Dec 15, 2023
5f692e8
comment about PS tunematching <= 2018
awegsche Dec 18, 2023
0ba0a6d
implemented suggestion on docstring
awegsche Dec 18, 2023
4099470
add (flaky) exception checks
awegsche Dec 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# OMC3 Changelog

#### 2023-12-07 - v0.13.0 - _awegsche_

- Added:
- complete overhaul of model creation, uses now `acc-models` for LHC, PS and PSB and prints
fsoubelet marked this conversation as resolved.
Show resolved Hide resolved
useful information about available model parameters. Can load from either a user defined path
(`--path <PATH>`) or from the afs copy of acc-models (`--afs`)

#### 2023-11-29 - v0.12.1 - _jdilly_

- Fixed:
Expand Down
2 changes: 1 addition & 1 deletion omc3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
__title__ = "omc3"
__description__ = "An accelerator physics tools package for the OMC team at CERN."
__url__ = "https://github.com/pylhc/omc3"
__version__ = "0.12.1"
__version__ = "0.13.0"
__author__ = "pylhc"
__author_email__ = "[email protected]"
__license__ = "MIT"
Expand Down
41 changes: 30 additions & 11 deletions omc3/model/accelerators/accelerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
It contains entrypoint the parent `Accelerator` class as well as other support classes.
"""
import re
import os
from pathlib import Path
from typing import List, Union, Sequence

Expand All @@ -16,7 +17,7 @@

from omc3.model.constants import (
ERROR_DEFFS_TXT,
JOB_MODEL_MADX,
JOB_MODEL_MADX_NOMINAL,
MODIFIER_TAG,
MODIFIERS_MADX,
TWISS_AC_DAT,
Expand Down Expand Up @@ -59,6 +60,8 @@ class Accelerator:
AccElementTypes.ARC_BPMS: r".*",
}
BPM_INITIAL = "B"
NAME=None
REPOSITORY=None

@staticmethod
def get_parameters():
Expand Down Expand Up @@ -95,11 +98,11 @@ def get_parameters():
params.add_parameter(
name="energy",
type=float,
help="Energy in Tev.",
help="Energy in GeV.",
)
params.add_parameter(
name="modifiers",
type=Path,
type=PathOrStr,
nargs="*",
help="Path to the optics file to use (modifiers file).",
)
Expand All @@ -118,6 +121,7 @@ def __init__(self, opt) -> None:
self.model_best_knowledge = None
self.elements = None
self.error_defs_file = None
self.acc_model_path = None
self.modifiers = None
self._beam_direction = 1
self._beam = None
Expand All @@ -137,11 +141,7 @@ def __init__(self, opt) -> None:
else:
self.init_from_options(opt)

def init_from_options(self, opt) -> None:
if opt.nat_tunes is None:
raise AcceleratorDefinitionError("Argument 'nat_tunes' is required.")
if (opt.drv_tunes is None) and (opt.driven_excitation is not None):
raise AcceleratorDefinitionError("Argument 'drv_tunes' is required.")
def init_from_options(self, opt):
self.nat_tunes = opt.nat_tunes

if opt.driven_excitation is not None:
Expand Down Expand Up @@ -193,6 +193,17 @@ def init_from_model_dir(self, model_dir: Path) -> None:
if best_knowledge_path.is_file():
self.model_best_knowledge = tfs.read(best_knowledge_path, index="NAME")

# Base Model ########################################
if self.REPOSITORY is not None:
acc_models = model_dir / self.REPOSITORY

if acc_models.is_dir():
if acc_models.is_symlink():
self.acc_model_path = Path(os.readlink(acc_models)).absolute()
else:
self.acc_model_path = acc_models
# else this wasn't an acc-models based model

# Modifiers #########################################
self.modifiers = _get_modifiers_from_modeldir(model_dir)

Expand Down Expand Up @@ -256,7 +267,12 @@ def verify_object(self):
"""
Verifies that this instance of an `Accelerator` is properly instantiated.
"""
raise NotImplementedError("A function should have been overwritten, check stack trace.")
# since we removed `required` args, we check here if everything has been passed
if self.model_dir is None:
if self.nat_tunes is None:
raise AttributeError("Natural tunes not set (missing `--nat_tunes` flag?)")
if self.excitation != AccExcitationMode.FREE and self.drv_tunes is None:
raise AttributeError("Driven excitation selected but no driven tunes given (missing `--drv_tunes` flag?)")
fsoubelet marked this conversation as resolved.
Show resolved Hide resolved

def get_exciter_bpm(self, plane: str, commonbpms: List[str]):
"""
Expand Down Expand Up @@ -355,13 +371,16 @@ class AcceleratorDefinitionError(Exception):

def _get_modifiers_from_modeldir(model_dir: Path) -> List[Path]:
"""Parse modifiers from job.create_model.madx or use modifiers.madx file."""
job_file = model_dir / JOB_MODEL_MADX
job_file = model_dir / JOB_MODEL_MADX_NOMINAL
if job_file.exists():
job_madx = job_file.read_text()

# find modifier tag in lines and return called file in these lines
# the modifier tag is used by the model creator to mark which line defines modifiers
# see e.g. `get_base_madx_script()` in `lhc.py`
# example for a match to the regex: `call, file = 'modifiers.madx'; MODIFIER_TAG`
modifiers = re.findall(
fr"\s+call,\s*file\s*=\s*[\"\']?([^;\'\"]+)[\"\']?\s*;\s*{MODIFIER_TAG}",
fr"\s*call,\s*file\s*=\s*[\"\']?([^;\'\"]+)[\"\']?\s*;\s*{MODIFIER_TAG}",
tpersson marked this conversation as resolved.
Show resolved Hide resolved
fsoubelet marked this conversation as resolved.
Show resolved Hide resolved
job_madx,
flags=re.IGNORECASE,
)
Expand Down
129 changes: 89 additions & 40 deletions omc3/model/accelerators/lhc.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class Lhc(Accelerator):
"""

NAME = "lhc"
REPOSITORY = "acc-models-lhc"
RE_DICT: Dict[str, str] = {
AccElementTypes.BPMS: r"BPM",
AccElementTypes.MAGNETS: r"M",
Expand All @@ -132,15 +133,23 @@ def get_parameters():
params.add_parameter(
name="year",
type=str,
required=True,
choices=("2012", "2015", "2016", "2017", "2018", "2022", "hllhc1.3"),
help="Year of the optics (or hllhc1.x version).",
)
params.add_parameter(
name="ats",
action="store_true",
help="Force use of ATS macros and knobs for years which are not ATS by default.",
)
)
params.add_parameter(
name="b2_errors",
type=str,
help="The B2 error table to load for the best knowledge model.",
)
params.add_parameter(
name="list_b2_errors",
action="store_true",
help="Lists all available b2 error tables",
)
return params

def __init__(self, *args, **kwargs):
Expand All @@ -150,36 +159,38 @@ def __init__(self, *args, **kwargs):
self.correctors_dir = "2012"
self.year = opt.year
self.ats = opt.ats
self.b2_errors = opt.b2_errors
self.list_b2_errors = opt.list_b2_errors
if self.year == "hllhc1.3":
self.correctors_dir = "hllhc1.3"
self.beam = opt.beam
beam_to_beam_direction = {1: 1, 2: -1}
self.beam_direction = beam_to_beam_direction[self.beam]
self.verify_object()

def verify_object(self) -> None: # TODO: Maybe more checks?
"""
Verifies if everything is defined which should be defined.
Will Raise an ``AcceleratorDefinitionError`` if one of the checks is invalid.
"""
LOGGER.debug("Accelerator class verification")

Accelerator.verify_object(self)
_ = self.beam

if self.model_dir is None and self.xing is None:
raise AcceleratorDefinitionError("Crossing on or off not set.")

if self.excitation is None:
raise AcceleratorDefinitionError("Excitation mode not set.")
if (self.excitation != AccExcitationMode.FREE) and (self.drv_tunes is None):
raise AcceleratorDefinitionError("An excitation mode was given but driven tunes are not set.")

# TODO: write more output prints
LOGGER.debug("... verification passed. \nSome information about the accelerator:")
LOGGER.debug(
"... verification passed. \nSome information about the accelerator:"
)
LOGGER.debug(f"Class name {self.__class__.__name__}")
LOGGER.debug(f"Beam {self.beam}")
LOGGER.debug(f"Beam direction {self.beam_direction}")
if self.modifiers:
LOGGER.debug(f"Modifiers {', '.join([str(m) for m in self.modifiers])}")
LOGGER.debug(
f"Modifiers {', '.join([str(m) for m in self.modifiers])}"
)

@property
def beam(self) -> int:
Expand Down Expand Up @@ -216,7 +227,11 @@ def get_variables(self, frm: float = None, to: float = None, classes: Iterable[s
LOGGER.debug("The following classes are not found as corrector/variable classes and "
f"are assumed to be the variable names directly instead:\n{str(unknown_classes)}")

vars = list(set(_flatten_list(all_vars_by_class[corr_cls] for corr_cls in known_classes)))
vars = list( set(
_flatten_list(
all_vars_by_class[corr_cls]
for corr_cls in known_classes))
)
vars = vars + unknown_classes

# Sort variables by S (nice for comparing different files)
Expand Down Expand Up @@ -297,6 +312,11 @@ def log_status(self) -> None:
LOGGER.info(f"> Driven Tune Y [{self.drv_tunes[1]:10.3f}]")

def load_main_seq_madx(self) -> str:
if self.acc_model_path is not None:
main_call = f'call, file = \'{self.acc_model_path / "lhc.seq"}\';'
if self.year.startswith('hl'):
main_call += f'\ncall, file = \'{self.acc_model_path / "hllhc_sequence.madx"}\';'
fsoubelet marked this conversation as resolved.
Show resolved Hide resolved
return main_call
try:
return _get_call_main_for_year(self.year)
except AttributeError:
Expand All @@ -323,19 +343,28 @@ def get_exciter_bpm(self, plane: str, commonbpms: List[str]):
if self.excitation == AccExcitationMode.ACD:
try:
return (
_is_one_of_in([f"BPMY{a_b}.6L4.B{beam}", f"BPM.7L4.B{beam}"], commonbpms),
_is_one_of_in(
[f"BPMY{a_b}.6L4.B{beam}", f"BPM.7L4.B{beam}"], commonbpms
),
f"MKQA.6L4.B{beam}",
)
except KeyError as e:
raise KeyError("AC-Dipole BPM not found in the common BPMs. Maybe cleaned?") from e
raise KeyError(
"AC-Dipole BPM not found in the common BPMs. Maybe cleaned?"
) from e
if self.excitation == AccExcitationMode.ADT:
try:
return (
_is_one_of_in([f"BPMWA.B5{l_r}4.B{beam}", f"BPMWA.A5{l_r}4.B{beam}"], commonbpms),
_is_one_of_in(
[f"BPMWA.B5{l_r}4.B{beam}", f"BPMWA.A5{l_r}4.B{beam}"],
commonbpms,
),
f"ADTK{adt}5{l_r}4.B{beam}",
)
except KeyError as e:
raise KeyError("ADT BPM not found in the common BPMs. Maybe cleaned?") from e
raise KeyError(
"ADT BPM not found in the common BPMs. Maybe cleaned?"
) from e
return None

def important_phase_advances(self) -> List[List[str]]:
Expand Down Expand Up @@ -379,34 +408,46 @@ def get_base_madx_script(self, best_knowledge: bool = False) -> str:
high_beta = False
madx_script = (
f"{self._get_madx_script_info_comments()}"
f"! ----- Calling Sequence and Optics -----\n"
f"call, file = '{self.model_dir / MACROS_DIR / GENERAL_MACROS}';\n"
f"call, file = '{self.model_dir / MACROS_DIR / LHC_MACROS}';\n"
)
)
madx_script += f"omc3_beam_energy = {self.energy};\n"
madx_script += "exec, define_nominal_beams();\n\n"
if self._uses_run3_macros():
LOGGER.debug("According to the optics year, Run 3 versions of the macros will be used")
LOGGER.debug(
"According to the optics year, Run 3 versions of the macros will be used"
)
madx_script += (
f"call, file = '{self.model_dir / MACROS_DIR / LHC_MACROS_RUN3}';\n"
)

madx_script += (
f"{self.load_main_seq_madx()}\n"
f"exec, define_nominal_beams();\n"
)
madx_script += "! ----- Calling Sequence and Optics -----\n"
madx_script += "option, -echo; ! suppress output from base sequence loading to keep the log small\n"
madx_script += self.load_main_seq_madx()
madx_script += "\n\n"

fsoubelet marked this conversation as resolved.
Show resolved Hide resolved
if self.modifiers is not None:
madx_script += "".join(
f"call, file = '{self.model_dir / modifier}'; {MODIFIER_TAG}\n"
for modifier in self.modifiers
)

if self.year in ['2012', '2015', '2016', '2017', '2018', '2021', 'hllhc1.3']:
# backwards compatibility with pre acc-models optics
madx_script += (
f"\n! ----- Defining Configuration Specifics -----\n"
f"xing_angles = {'1' if self.xing else '0'};\n"
f"if(xing_angles==1){{\n"
f" exec, set_crossing_scheme_ON();\n"
f"}}else{{\n"
f" exec, set_default_crossing_scheme();\n"
f"}}\n"
)
else:
madx_script += 'call, file="knobs.madx";\n\n'

madx_script += (
f"\n! ----- Defining Configuration Specifics -----\n"
f"exec, cycle_sequences();\n"
f"xing_angles = {'1' if self.xing else '0'};\n"
f"if(xing_angles==1){{\n"
f" exec, set_crossing_scheme_ON();\n"
f"}}else{{\n"
f" exec, set_default_crossing_scheme();\n"
f"}}\n"
"exec, cycle_sequences();\n"
f"use, sequence = LHCB{self.beam};\n"
f"option, echo;\n"
)
Expand All @@ -422,14 +463,19 @@ def get_base_madx_script(self, best_knowledge: bool = False) -> str:
madx_script += "exec, high_beta_matcher();\n"

madx_script += f"\n! ----- Matching Knobs and Output Files -----\n"
if self._uses_ats_knobs():
LOGGER.debug("According to the optics year or the --ats flag being provided, ATS macros and knobs will be used")
madx_script += f"exec, match_tunes_ats({self.nat_tunes[0]}, {self.nat_tunes[1]}, {self.beam});\n"
madx_script += f"exec, coupling_knob_ats({self.beam});\n"
else:
madx_script += f"exec, match_tunes({self.nat_tunes[0]}, {self.nat_tunes[1]}, {self.beam});\n"
madx_script += f"exec, coupling_knob({self.beam});\n"


# in the best knowledge case, all knobs are loaded from actual knowledge
if not best_knowledge:
if self._uses_ats_knobs():
LOGGER.debug(
"According to the optics year or the --ats flag being provided, ATS macros and knobs will be used"
)
madx_script += f"exec, match_tunes_ats({self.nat_tunes[0]}, {self.nat_tunes[1]}, {self.beam});\n"
madx_script += f"exec, coupling_knob_ats({self.beam});\n"
else:
madx_script += f"exec, match_tunes({self.nat_tunes[0]}, {self.nat_tunes[1]}, {self.beam});\n"
madx_script += f"exec, coupling_knob({self.beam});\n"

if ats_md:
madx_script += "exec, full_response_ats();\n"

Expand Down Expand Up @@ -461,13 +507,16 @@ def _uses_run3_macros(self) -> bool:
except ValueError: # if a "hllhc1.x" year is given
return False


# General functions ##########################################################


def _get_call_main_for_year(year: str) -> str:
call_main = f"call, file = '{_get_file_for_year(year, 'main.seq')}';\n"
if year == "2012":
call_main += f"call, file = '{LHC_DIR / '2012' / 'install_additional_elements.madx'}';\n"
call_main += (
f"call, file = '{LHC_DIR / '2012' / 'install_additional_elements.madx'}';\n"
)
if year == "hllhc1.3":
call_main += f"call, file = '{LHC_DIR / 'hllhc1.3' / 'main_update.seq'}';\n"
return call_main
Expand Down
Loading
Loading