Skip to content

Commit 07c50ce

Browse files
authored
B4 option in LHCSetup (#97)
1 parent 11875bf commit 07c50ce

File tree

2 files changed

+43
-12
lines changed

2 files changed

+43
-12
lines changed

pyhdtoolkit/cpymadtools/setup.py

+42-11
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
from pyhdtoolkit.cpymadtools import lhc
1616

1717

18-
def prepare_lhc_run2(opticsfile: str, beam: int = 1, energy: float = 6500, slicefactor: int = None, **kwargs) -> Madx:
18+
def prepare_lhc_run2(
19+
opticsfile: str, beam: int = 1, use_b4: bool = False, energy: float = 6500, slicefactor: int = None, **kwargs
20+
) -> Madx:
1921
"""
2022
.. versionadded:: 1.0.0
2123
@@ -37,6 +39,8 @@ def prepare_lhc_run2(opticsfile: str, beam: int = 1, energy: float = 6500, slice
3739
opticsfile (str): name of the optics file to be used. Can be the string path to the file or only the opticsfile
3840
name itself, which would be looked for at the **acc-models-lhc/operation/optics/** path.
3941
beam (int): which beam to set up for. Defaults to beam 1.
42+
use_b4 (bool): if `True`, the lhcb4 sequence file will be used. This is the beam 2 sequence but for tracking
43+
purposes. Defaults to `False`.
4044
energy (float): beam energy to set up for, in GeV. Defaults to 6500.
4145
slicefactor (int): if provided, the sequence will be sliced and made thin. Defaults to `None`,
4246
which leads to an unsliced sequence.
@@ -54,17 +58,24 @@ def prepare_lhc_run2(opticsfile: str, beam: int = 1, energy: float = 6500, slice
5458
... "/afs/cern.ch/eng/lhc/optics/runII/2018/PROTON/opticsfile.22", beam=2, stdout=True
5559
... )
5660
"""
61+
if use_b4 and beam != 2:
62+
logger.error("Cannot use beam 4 sequence file for beam 1")
63+
raise ValueError("Cannot use beam 4 sequence file for beam 1")
5764

58-
def _run2_sequence_from_opticsfile(opticsfile: Path) -> Path:
59-
return opticsfile.parent.parent / "lhc_as-built.seq"
65+
def _run2_sequence_from_opticsfile(opticsfile: Path, use_b4: bool = False) -> Path:
66+
filename = "lhc_as-built.seq" if not use_b4 else "lhcb4_as-built.seq"
67+
seqfile_path = opticsfile.parent.parent / filename
68+
if not seqfile_path.is_file():
69+
logger.error("Could not find sequence file '{filename}' at expected location '{seqfile_path}'")
70+
return seqfile_path
6071

6172
logger.debug("Creating Run 3 setup MAD-X instance")
6273
echo, warn = kwargs.pop("echo", False), kwargs.pop("warn", False)
6374

6475
madx = Madx(**kwargs)
6576
madx.option(echo=echo, warn=warn)
6677
logger.debug("Calling sequence")
67-
madx.call(_fullpath(_run2_sequence_from_opticsfile(Path(opticsfile))))
78+
madx.call(_fullpath(_run2_sequence_from_opticsfile(Path(opticsfile)), use_b4=use_b4))
6879
lhc.make_lhc_beams(madx, energy=energy)
6980

7081
if slicefactor:
@@ -82,7 +93,9 @@ def _run2_sequence_from_opticsfile(opticsfile: Path) -> Path:
8293
return madx
8394

8495

85-
def prepare_lhc_run3(opticsfile: str, beam: int = 1, energy: float = 6800, slicefactor: int = None, **kwargs) -> Madx:
96+
def prepare_lhc_run3(
97+
opticsfile: str, beam: int = 1, use_b4: bool = False, energy: float = 6800, slicefactor: int = None, **kwargs
98+
) -> Madx:
8699
"""
87100
.. versionadded:: 1.0.0
88101
@@ -102,6 +115,8 @@ def prepare_lhc_run3(opticsfile: str, beam: int = 1, energy: float = 6800, slice
102115
opticsfile (str): name of the optics file to be used. Can be the string path to the file or only the opticsfile
103116
name itself, which would be looked for at the **acc-models-lhc/operation/optics/** path.
104117
beam (int): which beam to set up for. Defaults to beam 1.
118+
use_b4 (bool): if `True`, the lhcb4 sequence file will be used. This is the beam 2 sequence but for tracking
119+
purposes. Defaults to `False`.
105120
energy (float): beam energy to set up for, in GeV. Defaults to 6800.
106121
slicefactor (int): if provided, the sequence will be sliced and made thin. Defaults to `None`,
107122
which leads to an unsliced sequence.
@@ -118,13 +133,19 @@ def prepare_lhc_run3(opticsfile: str, beam: int = 1, energy: float = 6800, slice
118133
... "R2022a_A30cmC30cmA10mL200cm.madx", slicefactor=4, stdout=True
119134
... )
120135
"""
136+
if use_b4 and beam != 2:
137+
logger.error("Cannot use beam 4 sequence file for beam 1")
138+
raise ValueError("Cannot use beam 4 sequence file for beam 1")
139+
121140
logger.debug("Creating Run 3 setup MAD-X instance")
122141
echo, warn = kwargs.pop("echo", False), kwargs.pop("warn", False)
123142

124143
madx = Madx(**kwargs)
125144
madx.option(echo=echo, warn=warn)
126-
logger.debug("Calling sequence")
127-
madx.call("acc-models-lhc/lhc.seq")
145+
146+
sequence = "lhc.seq" if not use_b4 else "lhcb4.seq"
147+
logger.debug(f"Calling sequence file '{sequence}'")
148+
madx.call(f"acc-models-lhc/{sequence}")
128149
lhc.make_lhc_beams(madx, energy=energy)
129150

130151
if slicefactor:
@@ -160,14 +181,19 @@ class LHCSetup:
160181
Matching is **not** performed by this setup and should be taken care of by the user, but the working
161182
point should be set by the definitions in the *opticsfile*.
162183
184+
.. note::
185+
If you intend to do tracking for beam 2, remember that the ``lhcb4`` sequence needs to be called.
186+
This is handled by giving the ``use_b4`` argument as `True` to the constructor.
187+
163188
Args:
164189
run (int): which run to set up for, should be 2 or 3. Defaults to run 3.
165190
opticsfile (str): name of the opticsfile to be used. For a Run 2 setup, should be the string path to the file.
166191
For a Run 3 setup, can be the string path to the file or only the opticsfile name itself, which would be
167192
looked for at the **acc-models-lhc/operation/optics/** path. Defaults to `None`, which will raise an error.
168193
beam (int): which beam to set up for. Defaults to beam 1.
169-
energy (float): beam energy to set up for, in GeV. Defaults to `None`, and is handled by either `~prepare_lhc_run2`
170-
or `~prepare_lhc_run3`. This means the default actually depends on the value of the **run** argument.
194+
use_b4 (bool): if `True`, the lhcb4 sequence file will be used. This is the beam 2 sequence but for tracking
195+
purposes. Defaults to `False`.
196+
energy (float): beam energy to set up for, in GeV. Defaults to 6800, to match the default of run 3.
171197
slicefactor (int): if provided, the sequence will be sliced and "made thin". Defaults to `None`,
172198
which leads to an unsliced sequence.
173199
**kwargs: if `echo` or `warn` are found in the keyword arguments they will be transmitted as options to ``MAD-X``.
@@ -202,20 +228,25 @@ def __init__(
202228
run: int = 3,
203229
opticsfile: str = None,
204230
beam: int = 1,
231+
use_b4: bool = False,
205232
energy: float = 6800,
206233
slicefactor: int = None,
207234
**kwargs,
208235
):
209236
assert opticsfile is not None, "An opticsfile must be provided"
237+
if use_b4 and beam != 2:
238+
logger.error("Cannot use beam 4 sequence file for beam 1")
239+
raise ValueError("Cannot use beam 4 sequence file for beam 1")
240+
210241
if int(run) not in (2, 3):
211242
raise NotImplementedError("This setup is only possible for Run 2 and Run 3 configurations.")
212243
elif run == 2:
213244
self.madx = prepare_lhc_run2(
214-
opticsfile=opticsfile, beam=beam, energy=energy, slicefactor=slicefactor, **kwargs
245+
opticsfile=opticsfile, beam=beam, use_b4=use_b4, energy=energy, slicefactor=slicefactor, **kwargs
215246
)
216247
else:
217248
self.madx = prepare_lhc_run3(
218-
opticsfile=opticsfile, beam=beam, energy=energy, slicefactor=slicefactor, **kwargs
249+
opticsfile=opticsfile, beam=beam, use_b4=use_b4, energy=energy, slicefactor=slicefactor, **kwargs
219250
)
220251

221252
def __enter__(self):

pyhdtoolkit/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION = "1.0.0rc0"
1+
VERSION = "1.0.0rc1"
22

33

44
def version_info() -> str:

0 commit comments

Comments
 (0)