xcoll 0.3.4__tar.gz → 0.3.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of xcoll might be problematic. Click here for more details.
- {xcoll-0.3.4 → xcoll-0.3.5}/PKG-INFO +1 -1
- {xcoll-0.3.4 → xcoll-0.3.5}/pyproject.toml +1 -1
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/beam_elements/base.py +16 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/colldb.py +5 -6
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/general.py +1 -1
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/manager.py +5 -5
- xcoll-0.3.5/xcoll/rf_sweep.py +191 -0
- xcoll-0.3.4/xcoll/rf_sweep.py +0 -120
- {xcoll-0.3.4 → xcoll-0.3.5}/LICENSE +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/NOTICE +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/README.md +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/__init__.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/beam_elements/__init__.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/beam_elements/absorber.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/beam_elements/collimators_src/absorber.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/beam_elements/collimators_src/everest_block.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/beam_elements/collimators_src/everest_collimator.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/beam_elements/collimators_src/everest_crystal.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/beam_elements/everest.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/collimator_settings.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/headers/checks.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/headers/particle_states.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/impacts/__init__.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/impacts/impacts.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/impacts/impacts_src/impacts.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/impacts/interaction_types.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/__init__.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/constants.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/crystal.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/everest.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/everest.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/jaw.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/materials.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/multiple_coulomb_scattering.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/properties.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/scatter.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/everest/scatter_crystal.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/build_fluka_input.py +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/.git +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/.gitignore +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/CMakeLists.txt +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/ComponentMakefile +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/Makefile +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/README +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/Doxyfile +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO.asciidoc +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO.epub +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO.html +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO.pdf +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO__1.png +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO__2.png +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO__3.png +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO__4.png +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO__5.png +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO__6.png +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/FlukaIO__7.png +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/Makefile +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/doc/docbook.xsl +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/include/Connection.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/include/FlukaIO.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/include/FlukaIOServer.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/include/FortranFlukaIO.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/include/Message.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/include/ParticleInfo.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/lib/libFlukaIO64.a +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/lib/libFlukaIO64.so +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/samples/ClientTest.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/samples/ServerTest.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/samples/fclient.f +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/samples/fserver.f +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/Connection.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/Connection.d +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/Connection.o +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIO.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIO.d +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIO.o +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIOHandshake.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIOHandshake.d +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIOHandshake.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIOHandshake.o +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIOServer.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIOServer.d +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIOServer.o +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIOServer_private.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIO_private.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FortranFlukaIO.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FortranFlukaIO.d +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FortranFlukaIO.o +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/NetIO.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/NetIO.d +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/NetIO.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/NetIO.o +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/tags +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/AllTests.cpp +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/CommonTest.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/ConnectionTest.cpp +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/FlukaIOServerTest.cpp +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/FlukaIOTest.cpp +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/FortranFlukaIOTest.cpp +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeConnection.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeConnection.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIO.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIO.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIOHandshake.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIOHandshake.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIOServer.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIOServer.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFortranFlukaIO.h +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeNetIO.c +0 -0
- {xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeNetIO.h +0 -0
|
@@ -60,6 +60,14 @@ class BaseBlock(xt.BeamElement):
|
|
|
60
60
|
instance = super().__new__(cls)
|
|
61
61
|
return instance
|
|
62
62
|
|
|
63
|
+
def enable_scattering(self):
|
|
64
|
+
if hasattr(self, '_tracking'):
|
|
65
|
+
self._tracking = True
|
|
66
|
+
|
|
67
|
+
def disable_scattering(self):
|
|
68
|
+
if hasattr(self, '_tracking'):
|
|
69
|
+
self._tracking = False
|
|
70
|
+
|
|
63
71
|
def get_backtrack_element(self, _context=None, _buffer=None, _offset=None):
|
|
64
72
|
return InvalidXcoll(length=-self.length,
|
|
65
73
|
_context=_context, _buffer=_buffer, _offset=_offset)
|
|
@@ -196,6 +204,14 @@ class BaseCollimator(xt.BeamElement):
|
|
|
196
204
|
super().__init__(**kwargs)
|
|
197
205
|
|
|
198
206
|
|
|
207
|
+
def enable_scattering(self):
|
|
208
|
+
if hasattr(self, '_tracking'):
|
|
209
|
+
self._tracking = True
|
|
210
|
+
|
|
211
|
+
def disable_scattering(self):
|
|
212
|
+
if hasattr(self, '_tracking'):
|
|
213
|
+
self._tracking = False
|
|
214
|
+
|
|
199
215
|
@property
|
|
200
216
|
def jaw(self):
|
|
201
217
|
return _get_LR(self, 'jaw', neg=True)
|
|
@@ -214,9 +214,6 @@ class CollimatorDatabase:
|
|
|
214
214
|
cry[sline[1]][key] = float(sline[idx])
|
|
215
215
|
else:
|
|
216
216
|
cry[sline[1]][key] = int(sline[idx])
|
|
217
|
-
elif sline[0].lower() == "target":
|
|
218
|
-
variables['xdim'][sline[1]] = float(sline[2])
|
|
219
|
-
variables['ydim'][sline[1]] = float(sline[3])
|
|
220
217
|
elif sline[0].lower() == 'settings':
|
|
221
218
|
pass # Acknowledge and ignore this line
|
|
222
219
|
elif len(sline) == 6:
|
|
@@ -231,7 +228,7 @@ class CollimatorDatabase:
|
|
|
231
228
|
famdct = {key: {'gap': family_settings[key], 'stage': family_types[key]} for key in family_settings}
|
|
232
229
|
names = ['name', 'gap', 'material', 'active_length', 'angle', 'offset']
|
|
233
230
|
|
|
234
|
-
df = pd.read_csv(io.StringIO(coll_data_string), sep='\s+', index_col=False, names=names)
|
|
231
|
+
df = pd.read_csv(io.StringIO(coll_data_string), sep=r'\s+', index_col=False, names=names)
|
|
235
232
|
df['family'] = df['gap'].copy()
|
|
236
233
|
df['family'] = df['family'].apply(lambda s: None if re.match(r'^-?\d+(\.\d+)?$', str(s)) else s)
|
|
237
234
|
df.insert(5,'stage', df['gap'].apply(lambda s: family_types.get(s, 'UNKNOWN')))
|
|
@@ -307,8 +304,8 @@ class CollimatorDatabase:
|
|
|
307
304
|
fam_keys = dcts._family_dict[fam].keys()
|
|
308
305
|
coll_dict = {**{'<<': '*'+fam}, **coll_dict}
|
|
309
306
|
temp_items_to_print = []
|
|
310
|
-
if coll_dict['crystal']:
|
|
311
|
-
temp_items_to_print = ['
|
|
307
|
+
if coll_dict['crystal'] and str(coll_dict['crystal'])!='nan':
|
|
308
|
+
temp_items_to_print = ['bending_radius','xdim','ydim','miscut','crystal', 'thick']
|
|
312
309
|
if coll_dict['angle_L'] == coll_dict['angle_R']:
|
|
313
310
|
coll_dict.update({'angle': coll_dict['angle_L']})
|
|
314
311
|
else:
|
|
@@ -324,6 +321,8 @@ class CollimatorDatabase:
|
|
|
324
321
|
value = {}
|
|
325
322
|
overwritten_keys = coll_dict['overwritten_keys']
|
|
326
323
|
for key, val in coll_dict.items():
|
|
324
|
+
if key == 'active_length':
|
|
325
|
+
key = 'length'
|
|
327
326
|
if (key in coll_items_to_print+temp_items_to_print) and (key not in (set(fam_keys)-set(overwritten_keys))) and (val != 'both'):
|
|
328
327
|
value.update({key: val})
|
|
329
328
|
file.write(_format_dict_entry(coll, value, spacing=' '))
|
|
@@ -8,7 +8,7 @@ from pathlib import Path
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import pandas as pd
|
|
10
10
|
|
|
11
|
-
from .beam_elements import BaseCollimator, BlackAbsorber, EverestCollimator, EverestCrystal, _all_collimator_types
|
|
11
|
+
from .beam_elements import BaseCollimator, BlackAbsorber, EverestCollimator, EverestCrystal, _all_collimator_types, element_classes
|
|
12
12
|
from .colldb import CollimatorDatabase
|
|
13
13
|
from .impacts import CollimatorImpacts
|
|
14
14
|
from .scattering_routines.everest.materials import SixTrack_to_xcoll, CrystalMaterial
|
|
@@ -775,14 +775,14 @@ class CollimatorManager:
|
|
|
775
775
|
|
|
776
776
|
def enable_scattering(self):
|
|
777
777
|
# Prepare collimators for tracking
|
|
778
|
-
for
|
|
779
|
-
|
|
778
|
+
for el in self.line.get_elements_of_type(element_classes)[0]:
|
|
779
|
+
el.enable_scattering()
|
|
780
780
|
self._set_record_impacts()
|
|
781
781
|
|
|
782
782
|
def disable_scattering(self):
|
|
783
783
|
# Prepare collimators for tracking
|
|
784
|
-
for
|
|
785
|
-
|
|
784
|
+
for el in self.line.get_elements_of_type(element_classes)[0]:
|
|
785
|
+
el.disable_scattering()
|
|
786
786
|
|
|
787
787
|
@property
|
|
788
788
|
def scattering_enabled(self):
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# copyright ############################### #
|
|
2
|
+
# This file is part of the Xcoll Package. #
|
|
3
|
+
# Copyright (c) CERN, 2023. #
|
|
4
|
+
# ######################################### #
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import scipy.constants as sc
|
|
8
|
+
from time import perf_counter
|
|
9
|
+
|
|
10
|
+
import xtrack as xt
|
|
11
|
+
from xtrack.progress_indicator import progress
|
|
12
|
+
|
|
13
|
+
class RFSweep:
|
|
14
|
+
|
|
15
|
+
def __init__(self, line):
|
|
16
|
+
self.line = line
|
|
17
|
+
self._get_base_frequency()
|
|
18
|
+
self._install_zeta_shift()
|
|
19
|
+
|
|
20
|
+
def _get_base_frequency(self):
|
|
21
|
+
self.cavities = self.line.get_elements_of_type(xt.Cavity)[1]
|
|
22
|
+
freq = np.unique([round(self.line[cav].frequency, 9) for cav in self.cavities])
|
|
23
|
+
if len(freq) > 1:
|
|
24
|
+
raise NotImplementedError(f"Cannot sweep multiple cavities with different frequencies!")
|
|
25
|
+
elif abs(freq[0]) < 1e-9 :
|
|
26
|
+
raise ValueError(f"Cavity frequency not set!")
|
|
27
|
+
self.f_RF = freq[0]
|
|
28
|
+
phi = np.unique(np.array([self.line[cav].lag for cav in self.cavities])*np.pi/180.)
|
|
29
|
+
if len(phi) > 1:
|
|
30
|
+
raise NotImplementedError(f"Cannot sweep multiple cavities with different phases!")
|
|
31
|
+
self.phi = phi[0]
|
|
32
|
+
self.V = np.array([self.line[cav].voltage for cav in self.cavities]).sum()
|
|
33
|
+
self.L = self.line.get_length()
|
|
34
|
+
|
|
35
|
+
def _install_zeta_shift(self):
|
|
36
|
+
if 'rf_sweep' in self.line.element_names:
|
|
37
|
+
print(f"Found existing RF sweep in line.")
|
|
38
|
+
else:
|
|
39
|
+
s_cav = min([self.line.get_s_position(cav) for cav in self.cavities])
|
|
40
|
+
if self.line.tracker is not None:
|
|
41
|
+
self.line.unfreeze()
|
|
42
|
+
line_was_built = True
|
|
43
|
+
else:
|
|
44
|
+
line_was_built = False
|
|
45
|
+
self.line.insert_element(element=xt.ZetaShift(dzeta=0), name='rf_sweep', at_s=s_cav)
|
|
46
|
+
if line_was_built:
|
|
47
|
+
self.line.build_tracker()
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def current_sweep_value(self):
|
|
51
|
+
dzeta = self.line['rf_sweep'].dzeta
|
|
52
|
+
return round(self.f_RF * dzeta/(self.L-dzeta), 6)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def info(self, sweep=0, num_turns=0):
|
|
56
|
+
if abs(sweep) > 1e-9:
|
|
57
|
+
existing_sweep = self.current_sweep_value
|
|
58
|
+
|
|
59
|
+
beta0 = self.line.particle_ref.beta0[0]
|
|
60
|
+
E = self.line.particle_ref.energy0[0]
|
|
61
|
+
q = self.line.particle_ref.q0
|
|
62
|
+
h = self.f_RF * self.L / beta0 / sc.c
|
|
63
|
+
tw = self.line.twiss()
|
|
64
|
+
eta = tw.slip_factor
|
|
65
|
+
|
|
66
|
+
bucket_height = np.sqrt(abs(q*self.V*beta0**2 / (np.pi*h*eta*E) * (
|
|
67
|
+
2*np.cos(self.phi) + (2*self.phi-np.pi)*np.sin(self.phi)
|
|
68
|
+
)))
|
|
69
|
+
delta_shift = -sweep / self.f_RF / eta
|
|
70
|
+
bucket_shift = delta_shift / bucket_height / 2
|
|
71
|
+
if num_turns > 0:
|
|
72
|
+
rf_shift_per_turn = sweep / num_turns
|
|
73
|
+
print(f"The current frequency is {self.f_RF + existing_sweep}Hz, adding {rf_shift_per_turn}Hz "
|
|
74
|
+
+ f"per turn until {self.f_RF + existing_sweep + sweep} (for {num_turns} turns).")
|
|
75
|
+
print(f"This sweep will move the center of the bucket with \u0394\u03B4 = "
|
|
76
|
+
+ f"{delta_shift} ({bucket_shift} buckets).")
|
|
77
|
+
if num_turns > 0 and num_turns < 3*bucket_shift/tw.qs:
|
|
78
|
+
print(f"Warning: This is a very fast sweep, moving ~{round(bucket_shift, 2)} buckets in "
|
|
79
|
+
+ f"~{round(num_turns*tw.qs, 2)} synchrotron oscillations (on average). If the "
|
|
80
|
+
+ f"bucket moves faster than a particle can follow, that particle will move out of "
|
|
81
|
+
+ f"the bucket and remain uncaptured.")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def track(self, sweep=0, particles=None, num_turns=0, verbose=True, *args, **kwargs):
|
|
85
|
+
|
|
86
|
+
# Was there a previous sweep?
|
|
87
|
+
# If yes, we do not overwrite it but continue from there
|
|
88
|
+
existing_sweep = self.current_sweep_value
|
|
89
|
+
|
|
90
|
+
# Just set the new RF frequency, no tracking
|
|
91
|
+
if num_turns == 0:
|
|
92
|
+
sweep += existing_sweep
|
|
93
|
+
if verbose:
|
|
94
|
+
print(f"The current frequency is {self.f_RF + existing_sweep}Hz, moving to {self.f_RF + sweep}Hz."
|
|
95
|
+
+ "No tracking performed.")
|
|
96
|
+
self.line['rf_sweep'].dzeta = self.L * sweep / (self.f_RF + sweep)
|
|
97
|
+
|
|
98
|
+
# Sweep and track
|
|
99
|
+
else:
|
|
100
|
+
if self.line.tracker is None:
|
|
101
|
+
raise ValueError("Need to build tracker first!")
|
|
102
|
+
if particles is None:
|
|
103
|
+
raise ValueError("Need particles to track!")
|
|
104
|
+
time = kwargs.pop('time', False)
|
|
105
|
+
with_progress = kwargs.pop('with_progress', False)
|
|
106
|
+
rf_shift_per_turn = sweep / num_turns
|
|
107
|
+
|
|
108
|
+
# This is taken from xtrack.tracker.Tracker._track
|
|
109
|
+
if time:
|
|
110
|
+
t0 = perf_counter()
|
|
111
|
+
if with_progress:
|
|
112
|
+
if self.line.tracker.enable_pipeline_hold:
|
|
113
|
+
raise ValueError("Progress indicator is not supported with pipeline hold")
|
|
114
|
+
if num_turns < 2:
|
|
115
|
+
raise ValueError('Tracking with progress indicator is only '
|
|
116
|
+
'possible over more than one turn.')
|
|
117
|
+
if with_progress is True:
|
|
118
|
+
batch_size = scaling = 100
|
|
119
|
+
else:
|
|
120
|
+
batch_size = int(with_progress)
|
|
121
|
+
scaling = with_progress if batch_size > 1 else None
|
|
122
|
+
if kwargs.get('turn_by_turn_monitor') is True:
|
|
123
|
+
ele_start = kwargs.get('ele_start') or 0
|
|
124
|
+
ele_stop = kwargs.get('ele_stop')
|
|
125
|
+
if ele_stop is None:
|
|
126
|
+
ele_stop = len(self.line)
|
|
127
|
+
if ele_start >= ele_stop:
|
|
128
|
+
# we need an additional turn and space in the monitor for
|
|
129
|
+
# the incomplete turn
|
|
130
|
+
num_turns += 1
|
|
131
|
+
_, monitor, _, _ = self.line.tracker._get_monitor(particles, True, num_turns)
|
|
132
|
+
kwargs['turn_by_turn_monitor'] = monitor
|
|
133
|
+
|
|
134
|
+
for ii in progress(
|
|
135
|
+
range(0, num_turns, batch_size),
|
|
136
|
+
desc='Tracking',
|
|
137
|
+
unit_scale=scaling,
|
|
138
|
+
):
|
|
139
|
+
one_turn_kwargs = kwargs.copy()
|
|
140
|
+
is_first_batch = ii == 0
|
|
141
|
+
is_last_batch = ii + batch_size >= num_turns
|
|
142
|
+
|
|
143
|
+
if is_first_batch and is_last_batch:
|
|
144
|
+
# This is the only batch, we track as normal
|
|
145
|
+
pass
|
|
146
|
+
elif is_first_batch:
|
|
147
|
+
# Not the last batch, so track until the last element
|
|
148
|
+
one_turn_kwargs['ele_stop'] = None
|
|
149
|
+
one_turn_kwargs['num_turns'] = batch_size
|
|
150
|
+
elif is_last_batch:
|
|
151
|
+
# Not the first batch, so track from the first element
|
|
152
|
+
one_turn_kwargs['ele_start'] = None
|
|
153
|
+
remaining_turns = num_turns % batch_size
|
|
154
|
+
if remaining_turns == 0:
|
|
155
|
+
remaining_turns = batch_size
|
|
156
|
+
one_turn_kwargs['num_turns'] = remaining_turns
|
|
157
|
+
one_turn_kwargs['_reset_log'] = False
|
|
158
|
+
elif not is_first_batch and not is_last_batch:
|
|
159
|
+
# A 'middle batch', track from first to last element
|
|
160
|
+
one_turn_kwargs['num_turns'] = batch_size
|
|
161
|
+
one_turn_kwargs['ele_start'] = None
|
|
162
|
+
one_turn_kwargs['ele_stop'] = None
|
|
163
|
+
one_turn_kwargs['_reset_log'] = False
|
|
164
|
+
self._tracking_func(particles, rf_shift_per_turn, **one_turn_kwargs)
|
|
165
|
+
if not np.any(particles.state == 1):
|
|
166
|
+
break
|
|
167
|
+
|
|
168
|
+
else:
|
|
169
|
+
self._tracking_func(particles, rf_shift_per_turn, num_turns=num_turns, *args, **kwargs)
|
|
170
|
+
|
|
171
|
+
if not np.any(particles.state == 1):
|
|
172
|
+
print(f"All particles lost at turn {particles.at_turn.max()}, stopped sweep at "
|
|
173
|
+
+ f"{self.current_sweep_value}Hz.")
|
|
174
|
+
|
|
175
|
+
if time:
|
|
176
|
+
t1 = perf_counter()
|
|
177
|
+
self.line.tracker._context.synchronize()
|
|
178
|
+
self.line.tracker.time_last_track = t1 - t0
|
|
179
|
+
else:
|
|
180
|
+
self.line.tracker.time_last_track = None
|
|
181
|
+
|
|
182
|
+
def _tracking_func(self, particles, rf_shift_per_turn, num_turns=1, *args, **kwargs):
|
|
183
|
+
existing_sweep = self.current_sweep_value
|
|
184
|
+
for i in range(num_turns):
|
|
185
|
+
sweep = existing_sweep + i*rf_shift_per_turn
|
|
186
|
+
self.line['rf_sweep'].dzeta = self.L * sweep / (self.f_RF + sweep)
|
|
187
|
+
# for cav in cavities:
|
|
188
|
+
# self.line[cav].frequency = freq + sweep
|
|
189
|
+
self.line.track(particles, num_turns=1, *args, **kwargs)
|
|
190
|
+
if not np.any(particles.state == 1):
|
|
191
|
+
break
|
xcoll-0.3.4/xcoll/rf_sweep.py
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
# copyright ############################### #
|
|
2
|
-
# This file is part of the Xcoll Package. #
|
|
3
|
-
# Copyright (c) CERN, 2023. #
|
|
4
|
-
# ######################################### #
|
|
5
|
-
|
|
6
|
-
import numpy as np
|
|
7
|
-
import pandas as pd
|
|
8
|
-
import scipy.constants as sc
|
|
9
|
-
|
|
10
|
-
import xtrack as xt
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class RFSweep:
|
|
14
|
-
|
|
15
|
-
def __init__(self, line):
|
|
16
|
-
self.line = line
|
|
17
|
-
self._get_base_frequency()
|
|
18
|
-
self._install_zeta_shift()
|
|
19
|
-
|
|
20
|
-
def _get_base_frequency(self):
|
|
21
|
-
self.cavities = self.line.get_elements_of_type(xt.Cavity)[1]
|
|
22
|
-
freq = np.unique([round(self.line[cav].frequency, 9) for cav in self.cavities])
|
|
23
|
-
if len(freq) > 1:
|
|
24
|
-
raise NotImplementedError(f"Cannot sweep multiple cavities with different frequencies!")
|
|
25
|
-
elif abs(freq[0]) < 1e-9 :
|
|
26
|
-
raise ValueError(f"Cavity frequency not set!")
|
|
27
|
-
self.f_RF = freq[0]
|
|
28
|
-
phi = np.unique(np.array([self.line[cav].lag for cav in self.cavities])*np.pi/180.)
|
|
29
|
-
if len(phi) > 1:
|
|
30
|
-
raise NotImplementedError(f"Cannot sweep multiple cavities with different phases!")
|
|
31
|
-
self.phi = phi[0]
|
|
32
|
-
self.V = np.array([self.line[cav].voltage for cav in self.cavities]).sum()
|
|
33
|
-
self.L = self.line.get_length()
|
|
34
|
-
|
|
35
|
-
def _install_zeta_shift(self):
|
|
36
|
-
if 'rf_sweep' in self.line.element_names:
|
|
37
|
-
print(f"Found existing RF sweep in line.")
|
|
38
|
-
else:
|
|
39
|
-
s_cav = min([self.line.get_s_position(cav) for cav in self.cavities])
|
|
40
|
-
if self.line.tracker is not None:
|
|
41
|
-
self.line.unfreeze()
|
|
42
|
-
line_was_built = True
|
|
43
|
-
else:
|
|
44
|
-
line_was_built = False
|
|
45
|
-
self.line.insert_element(element=xt.ZetaShift(dzeta=0), name='rf_sweep', at_s=s_cav)
|
|
46
|
-
if line_was_built:
|
|
47
|
-
self.line.build_tracker()
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
def current_sweep_value(self):
|
|
51
|
-
dzeta = self.line['rf_sweep'].dzeta
|
|
52
|
-
return round(self.f_RF * dzeta/(self.L-dzeta), 6)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def info(self, sweep=0, num_turns=0):
|
|
56
|
-
if abs(sweep) > 1e-9:
|
|
57
|
-
existing_sweep = self.current_sweep_value
|
|
58
|
-
|
|
59
|
-
beta0 = self.line.particle_ref.beta0[0]
|
|
60
|
-
E = self.line.particle_ref.energy0[0]
|
|
61
|
-
q = self.line.particle_ref.q0
|
|
62
|
-
h = self.f_RF * self.L / beta0 / sc.c
|
|
63
|
-
tw = self.line.twiss()
|
|
64
|
-
eta = tw.slip_factor
|
|
65
|
-
|
|
66
|
-
bucket_height = np.sqrt(abs(q*self.V*beta0**2 / (np.pi*h*eta*E) * (
|
|
67
|
-
2*np.cos(self.phi) + (2*self.phi-np.pi)*np.sin(self.phi)
|
|
68
|
-
)))
|
|
69
|
-
delta_shift = -sweep / self.f_RF / eta
|
|
70
|
-
bucket_shift = delta_shift / bucket_height / 2
|
|
71
|
-
if num_turns > 0:
|
|
72
|
-
rf_shift_per_turn = sweep / num_turns
|
|
73
|
-
print(f"The current frequency is {self.f_RF + existing_sweep}Hz, adding {rf_shift_per_turn}Hz "
|
|
74
|
-
+ f"per turn until {self.f_RF + existing_sweep + sweep} (for {num_turns} turns).")
|
|
75
|
-
print(f"This sweep will move the center of the bucket with \u0394\u03B4 = "
|
|
76
|
-
+ f"{delta_shift} ({bucket_shift} buckets).")
|
|
77
|
-
if num_turns > 0 and num_turns < 3*bucket_shift/tw.qs:
|
|
78
|
-
print(f"Warning: This is a very fast sweep, moving ~{round(bucket_shift, 2)} buckets in "
|
|
79
|
-
+ f"~{round(num_turns*tw.qs, 2)} synchrotron oscillations (on average). If the "
|
|
80
|
-
+ f"bucket moves faster than a particle can follow, that particle will move out of "
|
|
81
|
-
+ f"the bucket and remain uncaptured.")
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def track(self, sweep=0, num_turns=0, particles=None, verbose=True, *args, **kwargs):
|
|
85
|
-
|
|
86
|
-
# Was there a previous sweep?
|
|
87
|
-
# If yes, we do not overwrite it but continue from there
|
|
88
|
-
existing_sweep = self.current_sweep_value
|
|
89
|
-
|
|
90
|
-
# Just set the new RF frequency, no tracking
|
|
91
|
-
if num_turns == 0:
|
|
92
|
-
sweep += existing_sweep
|
|
93
|
-
if verbose:
|
|
94
|
-
print(f"The current frequency is {self.f_RF + existing_sweep}Hz, moving to {self.f_RF + sweep}Hz."
|
|
95
|
-
+ "No tracking performed.")
|
|
96
|
-
self.line['rf_sweep'].dzeta = self.L * sweep / (self.f_RF + sweep)
|
|
97
|
-
|
|
98
|
-
# Sweep and track
|
|
99
|
-
else:
|
|
100
|
-
if self.line.tracker is None:
|
|
101
|
-
raise ValueError("Need to build tracker first!")
|
|
102
|
-
if particles is None:
|
|
103
|
-
raise ValueError("Need particles to track!")
|
|
104
|
-
rf_shift_per_turn = sweep / num_turns
|
|
105
|
-
if 'time' in kwargs and kwargs['time']:
|
|
106
|
-
self.line.tracker.time_last_track = 0
|
|
107
|
-
for i in range(num_turns):
|
|
108
|
-
sweep = existing_sweep + i*rf_shift_per_turn
|
|
109
|
-
self.line['rf_sweep'].dzeta = self.L * sweep / (self.f_RF + sweep)
|
|
110
|
-
# for cav in cavities:
|
|
111
|
-
# self.line[cav].frequency = freq + sweep
|
|
112
|
-
if 'time' in kwargs and kwargs['time']:
|
|
113
|
-
prev_time = self.line.time_last_track
|
|
114
|
-
self.line.track(particles, num_turns=1, *args, **kwargs)
|
|
115
|
-
if 'time' in kwargs and kwargs['time']:
|
|
116
|
-
self.line.tracker.time_last_track += prev_time
|
|
117
|
-
if not np.any(particles.state == 1):
|
|
118
|
-
print(f"All particles lost at turn {i}, stopped sweep at "
|
|
119
|
-
+ f"{existing_sweep + i*rf_shift_per_turn}Hz.")
|
|
120
|
-
break
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/include/FortranFlukaIO.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/src/FlukaIOServer_private.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/ConnectionTest.cpp
RENAMED
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/FlukaIOServerTest.cpp
RENAMED
|
File without changes
|
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/FortranFlukaIOTest.cpp
RENAMED
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeConnection.c
RENAMED
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeConnection.h
RENAMED
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIO.c
RENAMED
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIO.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIOServer.c
RENAMED
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFlukaIOServer.h
RENAMED
|
File without changes
|
{xcoll-0.3.4 → xcoll-0.3.5}/xcoll/scattering_routines/fluka/flukaio/tests/fakes/FakeFortranFlukaIO.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|