xcoll 0.5.10__py3-none-any.whl → 0.5.12__py3-none-any.whl
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/beam_elements/base.py +22 -4
- xcoll/general.py +1 -1
- xcoll/headers/particle_states.h +2 -2
- xcoll/initial_distribution.py +18 -16
- xcoll/line_tools.py +6 -7
- xcoll/scattering_routines/engine.py +403 -0
- xcoll/scattering_routines/everest/properties.h +1 -1
- xcoll/xaux.py +117 -0
- {xcoll-0.5.10.dist-info → xcoll-0.5.12.dist-info}/METADATA +5 -5
- {xcoll-0.5.10.dist-info → xcoll-0.5.12.dist-info}/RECORD +13 -11
- {xcoll-0.5.10.dist-info → xcoll-0.5.12.dist-info}/LICENSE +0 -0
- {xcoll-0.5.10.dist-info → xcoll-0.5.12.dist-info}/NOTICE +0 -0
- {xcoll-0.5.10.dist-info → xcoll-0.5.12.dist-info}/WHEEL +0 -0
xcoll/beam_elements/base.py
CHANGED
|
@@ -12,8 +12,8 @@ from ..interaction_record import InteractionRecord
|
|
|
12
12
|
from ..general import _pkg_root
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
OPEN_JAW = 3
|
|
16
|
-
OPEN_GAP = 999
|
|
15
|
+
OPEN_JAW = 3
|
|
16
|
+
OPEN_GAP = 999
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class InvalidXcoll(xt.BeamElement):
|
|
@@ -659,6 +659,11 @@ class BaseCollimator(BaseBlock):
|
|
|
659
659
|
self._nemitt_x = val
|
|
660
660
|
self._apply_optics()
|
|
661
661
|
|
|
662
|
+
@property
|
|
663
|
+
def gemitt_x(self):
|
|
664
|
+
if self.nemitt_x is not None and self.optics_ready():
|
|
665
|
+
return self.nemitt_x / self.optics['beta_gamma_rel']
|
|
666
|
+
|
|
662
667
|
@property
|
|
663
668
|
def nemitt_y(self):
|
|
664
669
|
if self._nemitt_y == 0:
|
|
@@ -674,6 +679,11 @@ class BaseCollimator(BaseBlock):
|
|
|
674
679
|
self._nemitt_y = val
|
|
675
680
|
self._apply_optics()
|
|
676
681
|
|
|
682
|
+
@property
|
|
683
|
+
def gemitt_y(self):
|
|
684
|
+
if self.nemitt_y is not None and self.optics_ready():
|
|
685
|
+
return self.nemitt_y / self.optics['beta_gamma_rel']
|
|
686
|
+
|
|
677
687
|
@property
|
|
678
688
|
def emittance(self):
|
|
679
689
|
if self.nemitt_x is not None and self.nemitt_y is not None:
|
|
@@ -734,8 +744,8 @@ class BaseCollimator(BaseBlock):
|
|
|
734
744
|
alfy = self.optics[self.align]['alfy'][0]
|
|
735
745
|
betx = self.optics[self.align]['betx'][0]
|
|
736
746
|
bety = self.optics[self.align]['bety'][0]
|
|
737
|
-
divx = -np.sqrt(self.
|
|
738
|
-
divy = -np.sqrt(self.
|
|
747
|
+
divx = -np.sqrt(self.gemitt_x/betx)*alfx
|
|
748
|
+
divy = -np.sqrt(self.gemitt_y/bety)*alfy
|
|
739
749
|
if hasattr(self, '_cos_zL'):
|
|
740
750
|
if self.side != 'right':
|
|
741
751
|
return divx if abs(self.angle_L) < 1e-6 else divy
|
|
@@ -1256,6 +1266,10 @@ class BaseCrystal(BaseBlock):
|
|
|
1256
1266
|
def nemitt_x(self, val):
|
|
1257
1267
|
BaseCollimator.nemitt_x.fset(self, val)
|
|
1258
1268
|
|
|
1269
|
+
@property
|
|
1270
|
+
def gemitt_x(self):
|
|
1271
|
+
return BaseCollimator.gemitt_x.fget(self)
|
|
1272
|
+
|
|
1259
1273
|
@property
|
|
1260
1274
|
def nemitt_y(self):
|
|
1261
1275
|
return BaseCollimator.nemitt_y.fget(self)
|
|
@@ -1264,6 +1278,10 @@ class BaseCrystal(BaseBlock):
|
|
|
1264
1278
|
def nemitt_y(self, val):
|
|
1265
1279
|
BaseCollimator.nemitt_y.fset(self, val)
|
|
1266
1280
|
|
|
1281
|
+
@property
|
|
1282
|
+
def gemitt_y(self):
|
|
1283
|
+
return BaseCollimator.gemitt_y.fget(self)
|
|
1284
|
+
|
|
1267
1285
|
@property
|
|
1268
1286
|
def emittance(self):
|
|
1269
1287
|
return BaseCollimator.emittance.fget(self)
|
xcoll/general.py
CHANGED
xcoll/headers/particle_states.h
CHANGED
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
#define XC_LOST_ON_EVEREST_COLL -331
|
|
11
11
|
#define XC_LOST_ON_EVEREST_CRYSTAL -332
|
|
12
12
|
#define XC_LOST_ON_FLUKA_BLOCK -333
|
|
13
|
-
#define
|
|
13
|
+
#define XC_LOST_ON_FLUKA_COLL -334
|
|
14
14
|
#define XC_LOST_ON_FLUKA_CRYSTAL -335
|
|
15
15
|
#define XC_LOST_ON_GEANT4_BLOCK -336
|
|
16
|
-
#define
|
|
16
|
+
#define XC_LOST_ON_GEANT4_COLL -337
|
|
17
17
|
#define XC_LOST_ON_GEANT4_CRYSTAL -338
|
|
18
18
|
#define XC_LOST_ON_ABSORBER -340
|
|
19
19
|
|
xcoll/initial_distribution.py
CHANGED
|
@@ -57,8 +57,14 @@ def generate_pencil_on_collimator(line, name, num_particles, *, side='+-', penci
|
|
|
57
57
|
if twiss is None:
|
|
58
58
|
twiss = line.twiss()
|
|
59
59
|
|
|
60
|
-
# Is it converging or diverging?
|
|
61
|
-
|
|
60
|
+
# Is it converging or diverging?
|
|
61
|
+
# TODO: dispersion might change this
|
|
62
|
+
# TODO: this should be checked jaw by jaw (we are currently checking the left jaw - watch out for sign of tilt of right jaw)
|
|
63
|
+
# TODO: skew collimators
|
|
64
|
+
tilt = coll.tilt[0] if isinstance(coll.tilt, list) else coll.tilt
|
|
65
|
+
betatron_angle = coll.gap * coll.divergence
|
|
66
|
+
tolerance_tilt = 1e-12 # 0.1 urad tolerance on jaw tilt => we prioritise converging
|
|
67
|
+
is_converging = tilt + tolerance_tilt >= betatron_angle
|
|
62
68
|
print(f"Collimator {name} is {'con' if is_converging else 'di'}verging.")
|
|
63
69
|
|
|
64
70
|
beam_sizes = twiss.get_beam_covariance(nemitt_x=coll.nemitt_x, nemitt_y=coll.nemitt_y)
|
|
@@ -181,25 +187,21 @@ def _generate_4D_pencil_one_jaw(line, name, num_particles, plane, side, impact_p
|
|
|
181
187
|
coll = line[name]
|
|
182
188
|
|
|
183
189
|
if side == '+':
|
|
184
|
-
if
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
else:
|
|
188
|
-
pencil_pos = coll.jaw_LU + impact_parameter
|
|
190
|
+
if isinstance(coll, EverestCrystal):
|
|
191
|
+
# A pencil on the crystal should always be upstream
|
|
192
|
+
pencil_pos = coll.jaw_U + impact_parameter
|
|
189
193
|
else:
|
|
190
|
-
if
|
|
191
|
-
pencil_pos = coll.
|
|
194
|
+
if is_converging:
|
|
195
|
+
pencil_pos = coll.jaw_LU + impact_parameter
|
|
192
196
|
else:
|
|
193
197
|
pencil_pos = coll.jaw_LD + impact_parameter
|
|
194
198
|
elif side == '-':
|
|
195
|
-
if
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
else:
|
|
199
|
-
pencil_pos = coll.jaw_RU - impact_parameter
|
|
199
|
+
if isinstance(coll, EverestCrystal):
|
|
200
|
+
# A pencil on the crystal should always be upstream
|
|
201
|
+
pencil_pos = coll.jaw_U - impact_parameter
|
|
200
202
|
else:
|
|
201
|
-
if
|
|
202
|
-
pencil_pos = coll.
|
|
203
|
+
if is_converging:
|
|
204
|
+
pencil_pos = coll.jaw_RU - impact_parameter
|
|
203
205
|
else:
|
|
204
206
|
pencil_pos = coll.jaw_RD - impact_parameter
|
|
205
207
|
|
xcoll/line_tools.py
CHANGED
|
@@ -33,7 +33,7 @@ class XcollScatteringAPI:
|
|
|
33
33
|
if nemitt_y is None:
|
|
34
34
|
nemitt_y = el.nemitt_y
|
|
35
35
|
if not np.isclose(el.nemitt_x, nemitt_x) \
|
|
36
|
-
or not np.isclose(el.
|
|
36
|
+
or not np.isclose(el.nemitt_y, nemitt_y):
|
|
37
37
|
raise ValueError("Not all collimators have the same "
|
|
38
38
|
+ "emittance. This is not supported.")
|
|
39
39
|
if hasattr(el, 'enable_scattering'):
|
|
@@ -78,7 +78,6 @@ class XcollCollimatorAPI:
|
|
|
78
78
|
|
|
79
79
|
# Verify elements
|
|
80
80
|
for el in elements:
|
|
81
|
-
print(el.__class__)
|
|
82
81
|
assert isinstance(el, block_classes)
|
|
83
82
|
el._tracking = False
|
|
84
83
|
|
|
@@ -243,7 +242,7 @@ class XcollCollimatorAPI:
|
|
|
243
242
|
tw_upstream, tw_downstream = self.get_optics_at(names, twiss=twiss)
|
|
244
243
|
beta_gamma_rel = self.line.particle_ref._xobject.gamma0[0]*self.line.particle_ref._xobject.beta0[0]
|
|
245
244
|
for coll in names:
|
|
246
|
-
self.line[coll].assign_optics(name=coll, nemitt_x=nemitt_x, nemitt_y=
|
|
245
|
+
self.line[coll].assign_optics(name=coll, nemitt_x=nemitt_x, nemitt_y=nemitt_y, twiss_upstream=tw_upstream,
|
|
247
246
|
twiss_downstream=tw_downstream, beta_gamma_rel=beta_gamma_rel)
|
|
248
247
|
|
|
249
248
|
def open(self, names=None):
|
|
@@ -282,22 +281,22 @@ class XcollCollimatorAPI:
|
|
|
282
281
|
|
|
283
282
|
def assign_optics_to_collimators(line, nemitt_x=None, nemitt_y=None, twiss=None):
|
|
284
283
|
warn("The function xcoll.assign_optics_to_collimators() is deprecated and will be "
|
|
285
|
-
+ "removed in the future. Please use line.
|
|
284
|
+
+ "removed in the future. Please use line.collimators.assign_optics() instead.", FutureWarning)
|
|
286
285
|
line.collimators.assign_optics(nemitt_x=nemitt_x, nemitt_y=nemitt_y, twiss=twiss)
|
|
287
286
|
|
|
288
287
|
def get_optics_at(names, *, twiss=None, line=None):
|
|
289
288
|
warn("The function xcoll.get_optics_at() is deprecated and will be "
|
|
290
|
-
+ "removed in the future. Please use line.
|
|
289
|
+
+ "removed in the future. Please use line.collimators.get_optics_at() instead.", FutureWarning)
|
|
291
290
|
return line.collimators.get_optics_at(names=names, twiss=twiss)
|
|
292
291
|
|
|
293
292
|
def open_collimators(line, names=None):
|
|
294
293
|
warn("The function xcoll.open_collimators() is deprecated and will be "
|
|
295
|
-
+ "removed in the future. Please use line.
|
|
294
|
+
+ "removed in the future. Please use line.collimators.open_collimators() instead.", FutureWarning)
|
|
296
295
|
line.collimators.open(names=names)
|
|
297
296
|
|
|
298
297
|
def send_to_parking(line, names=None):
|
|
299
298
|
warn("The function xcoll.send_to_parking() is deprecated and will be "
|
|
300
|
-
+ "removed in the future. Please use line.
|
|
299
|
+
+ "removed in the future. Please use line.collimators.send_to_parking() instead.", FutureWarning)
|
|
301
300
|
line.collimators.to_parking(names=names)
|
|
302
301
|
|
|
303
302
|
def enable_scattering(line):
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
# copyright ############################### #
|
|
2
|
+
# This file is part of the Xcoll Package. #
|
|
3
|
+
# Copyright (c) CERN, 2024. #
|
|
4
|
+
# ######################################### #
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import numpy as np
|
|
8
|
+
import shutil
|
|
9
|
+
|
|
10
|
+
import xobjects as xo
|
|
11
|
+
import xpart as xp
|
|
12
|
+
import xtrack as xt
|
|
13
|
+
try:
|
|
14
|
+
# TODO: once xaux is in Xsuite keep only this
|
|
15
|
+
from xaux import ClassProperty, ClassPropertyMeta, FsPath, singleton
|
|
16
|
+
except ImportError:
|
|
17
|
+
from ..xaux import ClassProperty, ClassPropertyMeta, FsPath, singleton
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class BaseEngineMeta(xo.hybrid_class.MetaHybridClass, ClassPropertyMeta):
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
@singleton
|
|
24
|
+
class BaseEngine(xo.HybridClass, metaclass=BaseEngineMeta):
|
|
25
|
+
_xofields = {
|
|
26
|
+
'_particle_ref': xp.Particles,
|
|
27
|
+
'_seed': xo.UInt64,
|
|
28
|
+
'_capacity': xo.Int64,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
_int32 = False
|
|
32
|
+
_element_classes = None
|
|
33
|
+
_only_protons = False
|
|
34
|
+
_uses_input_file = False
|
|
35
|
+
_uses_run_folder = False
|
|
36
|
+
|
|
37
|
+
def __init__(self, **kwargs):
|
|
38
|
+
if not self._initialised:
|
|
39
|
+
if np.any([key[0] != '_' for key in self._xofields.keys()]):
|
|
40
|
+
raise ValueError(f"All fields in `{self.__class__.__name__}._xofields` have "
|
|
41
|
+
+ f"to start with an underscore! This is to ensure to work "
|
|
42
|
+
+ f"correctly with `ClassProperty`.")
|
|
43
|
+
if '_xobject' not in kwargs:
|
|
44
|
+
# Initialise defaults
|
|
45
|
+
self._cwd = None
|
|
46
|
+
self._line = None
|
|
47
|
+
self._verbose = False
|
|
48
|
+
self._input_file = None
|
|
49
|
+
self._element_dict = {}
|
|
50
|
+
self._warning_given = False
|
|
51
|
+
self._tracking_initialised = False
|
|
52
|
+
kwargs.setdefault('_particle_ref', xp.Particles())
|
|
53
|
+
kwargs.setdefault('_seed', 0)
|
|
54
|
+
kwargs.setdefault('_capacity', 0)
|
|
55
|
+
filtered_kwargs = {}
|
|
56
|
+
remaining_kwargs = {}
|
|
57
|
+
for key, value in kwargs.items():
|
|
58
|
+
if key in self._xofields.keys() or key == '_xobject':
|
|
59
|
+
filtered_kwargs[key] = value
|
|
60
|
+
else:
|
|
61
|
+
remaining_kwargs[key] = value
|
|
62
|
+
super().__init__(**filtered_kwargs)
|
|
63
|
+
kwargs = remaining_kwargs
|
|
64
|
+
self._initialised = True
|
|
65
|
+
# Apply kwargs
|
|
66
|
+
for kk, vv in kwargs.items():
|
|
67
|
+
if not hasattr(self.__class__, kk):
|
|
68
|
+
raise ValueError(f"Invalid attribute {kk} for {self.__class__.__name__}!")
|
|
69
|
+
setattr(self, kk, vv)
|
|
70
|
+
|
|
71
|
+
def __del__(self, *args, **kwargs):
|
|
72
|
+
self.stop(warn=False)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _warn(self, error=None):
|
|
76
|
+
if not self._warning_given:
|
|
77
|
+
print(f"Warning: Failed to import {self.__class__.__name__} environment "
|
|
78
|
+
+ f" (did you compile?).\n{self.__class__.__name__.replace('Engine', '')} "
|
|
79
|
+
+ f"elements will be installed but are not trackable.\n", flush=True)
|
|
80
|
+
if error:
|
|
81
|
+
print(error, flush=True)
|
|
82
|
+
self._warning_given = True
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# ==================
|
|
86
|
+
# === Properties ===
|
|
87
|
+
# ==================
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@ClassProperty
|
|
91
|
+
def name(cls):
|
|
92
|
+
return cls.__name__.replace('Engine', '').lower()
|
|
93
|
+
|
|
94
|
+
@ClassProperty
|
|
95
|
+
def verbose(cls):
|
|
96
|
+
return cls.get_self()._verbose
|
|
97
|
+
|
|
98
|
+
@verbose.setter
|
|
99
|
+
def verbose(cls, val):
|
|
100
|
+
cls.get_self()._verbose = val
|
|
101
|
+
|
|
102
|
+
@ClassProperty
|
|
103
|
+
def line(cls):
|
|
104
|
+
return cls.get_self()._line
|
|
105
|
+
|
|
106
|
+
@line.setter
|
|
107
|
+
def line(cls, val):
|
|
108
|
+
if not val is None and not isinstance(val, xt.Line):
|
|
109
|
+
raise ValueError("`line` has to be an xt.Line object!")
|
|
110
|
+
cls.get_self()._line = val
|
|
111
|
+
|
|
112
|
+
@line.deleter
|
|
113
|
+
def line(cls):
|
|
114
|
+
cls.get_self()._line = None
|
|
115
|
+
|
|
116
|
+
@ClassProperty
|
|
117
|
+
def particle_ref(cls):
|
|
118
|
+
self = cls.get_self()
|
|
119
|
+
initial = xp.Particles().to_dict()
|
|
120
|
+
current = self._particle_ref.to_dict()
|
|
121
|
+
if xt.line._dicts_equal(initial, current):
|
|
122
|
+
return None
|
|
123
|
+
else:
|
|
124
|
+
return self._particle_ref
|
|
125
|
+
|
|
126
|
+
@particle_ref.setter
|
|
127
|
+
def particle_ref(cls, val):
|
|
128
|
+
self = cls.get_self()
|
|
129
|
+
if val is None:
|
|
130
|
+
self._particle_ref = xp.Particles()
|
|
131
|
+
else:
|
|
132
|
+
if not isinstance(val, xp.Particles):
|
|
133
|
+
raise ValueError("`particle_ref` has to be an xp.Particles object!")
|
|
134
|
+
if val._capacity > 1:
|
|
135
|
+
raise ValueError("`particle_ref` has to be a single particle!")
|
|
136
|
+
if val.pdg_id[0] == 0:
|
|
137
|
+
if cls._only_protons:
|
|
138
|
+
val.pdg_id[0] = xp.get_pdg_id_from_name('proton')
|
|
139
|
+
else:
|
|
140
|
+
raise ValueError("`particle_ref` needs to have a valid pdg_id")
|
|
141
|
+
elif cls._only_protons and val.pdg_id[0] != xp.get_pdg_id_from_name('proton'):
|
|
142
|
+
raise ValueError("{cls.__name__} only supports protons!")
|
|
143
|
+
self._particle_ref = val
|
|
144
|
+
|
|
145
|
+
@particle_ref.deleter
|
|
146
|
+
def particle_ref(cls):
|
|
147
|
+
cls.get_self()._particle_ref = xp.Particles()
|
|
148
|
+
|
|
149
|
+
@ClassProperty
|
|
150
|
+
def capacity(cls):
|
|
151
|
+
self = cls.get_self()
|
|
152
|
+
if self._capacity == 0:
|
|
153
|
+
return None
|
|
154
|
+
else:
|
|
155
|
+
return int(self._capacity)
|
|
156
|
+
|
|
157
|
+
@capacity.setter
|
|
158
|
+
def capacity(cls, val):
|
|
159
|
+
if val is None:
|
|
160
|
+
val = 0
|
|
161
|
+
cls.get_self()._capacity = int(val)
|
|
162
|
+
|
|
163
|
+
@capacity.deleter
|
|
164
|
+
def capacity(cls):
|
|
165
|
+
raise ValueError("Not allowed.")
|
|
166
|
+
|
|
167
|
+
@ClassProperty
|
|
168
|
+
def seed(cls):
|
|
169
|
+
self = cls.get_self()
|
|
170
|
+
if self._seed == 0:
|
|
171
|
+
return None
|
|
172
|
+
else:
|
|
173
|
+
return self._seed
|
|
174
|
+
|
|
175
|
+
@seed.setter
|
|
176
|
+
def seed(cls, val):
|
|
177
|
+
if val is None:
|
|
178
|
+
val = 0
|
|
179
|
+
val = int(val)
|
|
180
|
+
if cls._int32:
|
|
181
|
+
new_val = np.uint32(val)
|
|
182
|
+
else:
|
|
183
|
+
new_val = np.uint64(val)
|
|
184
|
+
if new_val != val:
|
|
185
|
+
print(f"Warning: type change for seed {val}. Using {new_val}.")
|
|
186
|
+
cls.get_self()._seed = new_val
|
|
187
|
+
|
|
188
|
+
@seed.deleter
|
|
189
|
+
def seed(cls):
|
|
190
|
+
cls.get_self()._seed = 0
|
|
191
|
+
|
|
192
|
+
@ClassProperty
|
|
193
|
+
def input_file(cls):
|
|
194
|
+
return cls.get_self()._input_file
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
# ======================
|
|
198
|
+
# === Public Methods ===
|
|
199
|
+
# ======================
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@classmethod
|
|
203
|
+
def start(cls, *, line=None, elements=None, names=None, cwd=None, seed=None,
|
|
204
|
+
particle_ref=None, input_file=None, **kwargs):
|
|
205
|
+
self = cls.get_self(**kwargs)
|
|
206
|
+
if self.is_running() is None:
|
|
207
|
+
raise NotImplementedError(f"Need to implement `is_running` for {cls.__name__}!")
|
|
208
|
+
elif self.is_running() is True:
|
|
209
|
+
if self.verbose:
|
|
210
|
+
print("Engine already running.", flush=True)
|
|
211
|
+
return
|
|
212
|
+
|
|
213
|
+
self._starting_engine = True # We need this to allow changing the element settings which otherwise are locked
|
|
214
|
+
self._use_seed(seed)
|
|
215
|
+
self._use_line(line)
|
|
216
|
+
self._use_particle_ref(particle_ref)
|
|
217
|
+
self._sync_line_particle_ref()
|
|
218
|
+
self._get_elements(line=line, elements=elements, names=names)
|
|
219
|
+
self._set_cwd(cwd=cwd)
|
|
220
|
+
self._use_input_file(input_file=input_file, **kwargs)
|
|
221
|
+
self.clean_output_files()
|
|
222
|
+
self._starting_engine = False
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@classmethod
|
|
226
|
+
def stop(cls, clean=False, **kwargs):
|
|
227
|
+
self = cls.get_self(**kwargs)
|
|
228
|
+
if hasattr(self, '_old_seed'):
|
|
229
|
+
self.seed = self._old_seed
|
|
230
|
+
del self._old_seed
|
|
231
|
+
if hasattr(self, '_old_line'):
|
|
232
|
+
self.line = self._old_line
|
|
233
|
+
del self._old_line
|
|
234
|
+
if hasattr(self, '_old_particle_ref'):
|
|
235
|
+
self.particle_ref = self._old_particle_ref
|
|
236
|
+
del self._old_particle_ref
|
|
237
|
+
self._sync_line_particle_ref()
|
|
238
|
+
if hasattr(self, '_old_cwd') and self._old_cwd is not None:
|
|
239
|
+
os.chdir(self._old_cwd)
|
|
240
|
+
del self._old_cwd
|
|
241
|
+
if clean:
|
|
242
|
+
self.clean_output_files(clean_all=True)
|
|
243
|
+
self._cwd = None
|
|
244
|
+
self._input_file = None
|
|
245
|
+
self._element_dict = {}
|
|
246
|
+
self._warning_given = False
|
|
247
|
+
self._tracking_initialised = False
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
@classmethod
|
|
251
|
+
def assert_particle_ref(cls, **kwargs):
|
|
252
|
+
if cls.get_self(**kwargs).particle_ref is None:
|
|
253
|
+
raise ValueError(f"{cls.__name__} reference particle not set!")
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
# =======================
|
|
257
|
+
# === Private Methods ===
|
|
258
|
+
# =======================
|
|
259
|
+
|
|
260
|
+
# For all the following fields, they can either be set in advance on the engine,
|
|
261
|
+
# or they can be set when the engine is started. In the latter case, the values
|
|
262
|
+
# are temporary and the original will be restored when the engine is stopped.
|
|
263
|
+
|
|
264
|
+
def _use_line(self, line=None):
|
|
265
|
+
self._old_line = self.line
|
|
266
|
+
self.line = line
|
|
267
|
+
|
|
268
|
+
def _use_seed(self, seed=None):
|
|
269
|
+
self._old_seed = self.seed
|
|
270
|
+
if seed is not None:
|
|
271
|
+
self.seed = seed
|
|
272
|
+
else:
|
|
273
|
+
if self.seed is None:
|
|
274
|
+
if self._int32:
|
|
275
|
+
self.seed = np.random.randint(0, int(2**32))
|
|
276
|
+
else:
|
|
277
|
+
self.seed = np.random.randint(0, int(2**64))
|
|
278
|
+
if self.verbose:
|
|
279
|
+
print(f"Using seed {self.seed}.")
|
|
280
|
+
|
|
281
|
+
def _use_particle_ref(self, particle_ref=None):
|
|
282
|
+
# Prefer: provided particle_ref > existing particle_ref > particle_ref from line
|
|
283
|
+
self._old_particle_ref = self.particle_ref
|
|
284
|
+
if particle_ref is not None:
|
|
285
|
+
self.particle_ref = particle_ref
|
|
286
|
+
elif self.particle_ref is None:
|
|
287
|
+
if self.line is None or not hasattr(self.line, 'particle_ref') \
|
|
288
|
+
or self.line.particle_ref is None:
|
|
289
|
+
raise ValueError("Need to provide either a line with a reference "
|
|
290
|
+
+ "particle, or `particle_ref`.")
|
|
291
|
+
self.particle_ref = self.line.particle_ref
|
|
292
|
+
if self.verbose:
|
|
293
|
+
print(f"Using {xp.get_name_from_pdg_id(self.particle_ref.pdg_id[0])}.")
|
|
294
|
+
|
|
295
|
+
def _sync_line_particle_ref(self):
|
|
296
|
+
if self.line is None:
|
|
297
|
+
return
|
|
298
|
+
if self.line.particle_ref is not None \
|
|
299
|
+
and not xt.line._dicts_equal(self.line.particle_ref.to_dict(),
|
|
300
|
+
self.particle_ref.to_dict()):
|
|
301
|
+
overwrite_particle_ref_in_line = True
|
|
302
|
+
if overwrite_particle_ref_in_line:
|
|
303
|
+
print("Warning: Found different reference particle in line! Temporarily overwritten.")
|
|
304
|
+
self.line.particle_ref = self.particle_ref
|
|
305
|
+
|
|
306
|
+
def _get_elements(self, line=None, elements=None, names=None):
|
|
307
|
+
if self._element_classes is None:
|
|
308
|
+
raise NotImplementedError(f"{self.__class__.__name__} needs to define `_element_classes`!")
|
|
309
|
+
if line is None:
|
|
310
|
+
if elements is None:
|
|
311
|
+
raise ValueError("Need to provide either `line` or `elements`.")
|
|
312
|
+
if not hasattr(elements, '__iter__') or isinstance(elements, str):
|
|
313
|
+
elements = [elements]
|
|
314
|
+
if names is None:
|
|
315
|
+
names = [f"{self.__class__.name}_el_{i}" for i, _ in enumerate(elements)]
|
|
316
|
+
else:
|
|
317
|
+
if not hasattr(names, '__iter__') or isinstance(names, str):
|
|
318
|
+
names = [names]
|
|
319
|
+
if len(names) != len(elements):
|
|
320
|
+
raise ValueError("Length of `elements` and `names` doesn't match.")
|
|
321
|
+
else:
|
|
322
|
+
if elements is not None:
|
|
323
|
+
raise ValueError("Cannot provide both `line` and `elements`.")
|
|
324
|
+
if names is None:
|
|
325
|
+
elements, names = line.get_elements_of_type(self._element_classes)
|
|
326
|
+
else:
|
|
327
|
+
if not hasattr(names, '__iter__') or isinstance(names, str):
|
|
328
|
+
names = [names]
|
|
329
|
+
elements = [line[name] for name in names]
|
|
330
|
+
elements = [el for el in elements if el.active and el.jaw is not None]
|
|
331
|
+
names = [name for el, name in zip(elements,names) if el.active and el.jaw is not None]
|
|
332
|
+
for el in elements:
|
|
333
|
+
if not isinstance(el, self._element_classes):
|
|
334
|
+
raise ValueError(f"Element {el} is not a "
|
|
335
|
+
+ ", or a ".join([c.__name__ for c in self._element_classes])
|
|
336
|
+
+ ".")
|
|
337
|
+
if len(elements) == 0:
|
|
338
|
+
raise ValueError(f"No active {self.name} elements found!")
|
|
339
|
+
self._element_dict = dict(zip(names, elements))
|
|
340
|
+
|
|
341
|
+
def _set_cwd(self, cwd):
|
|
342
|
+
if self._uses_run_folder:
|
|
343
|
+
if cwd is not None:
|
|
344
|
+
cwd = FsPath(cwd).expanduser().resolve()
|
|
345
|
+
else:
|
|
346
|
+
# TODO: use xaux.ranID here
|
|
347
|
+
import base64
|
|
348
|
+
ran = base64.urlsafe_b64encode(os.urandom(8)).decode('utf-8')
|
|
349
|
+
ran_str = ''.join(c if c.isalnum() else 'X' for c in ran)
|
|
350
|
+
cwd = FsPath.cwd() / f'{self.name}_run_{ran_str}'
|
|
351
|
+
self._cwd = cwd
|
|
352
|
+
cwd.mkdir(parents=True, exist_ok=True)
|
|
353
|
+
self._old_cwd = FsPath.cwd()
|
|
354
|
+
os.chdir(cwd)
|
|
355
|
+
|
|
356
|
+
def _use_input_file(self, input_file=None, **kwargs):
|
|
357
|
+
if self._uses_input_file:
|
|
358
|
+
if input_file is None:
|
|
359
|
+
if not hasattr(self, 'generate_input_file'):
|
|
360
|
+
raise NotImplementedError("Need to implement `generate_input_file`"
|
|
361
|
+
"for {cls.__name__}!")
|
|
362
|
+
input_file = self.generate_input_file(**kwargs)
|
|
363
|
+
if not hasattr(input_file, '__iter__') or isinstance(input_file, str):
|
|
364
|
+
# Some engines might need multiple input files (like Fluka)
|
|
365
|
+
input_file = [input_file]
|
|
366
|
+
input_file = [FsPath(f).expanduser().resolve() for f in input_file]
|
|
367
|
+
new_files = []
|
|
368
|
+
for file in input_file:
|
|
369
|
+
if not file.exists():
|
|
370
|
+
raise ValueError(f"Input file {file.as_posix()} not found!")
|
|
371
|
+
if file.parent != FsPath.cwd():
|
|
372
|
+
shutil.copy(file, FsPath.cwd())
|
|
373
|
+
new_files.append(FsPath.cwd() / file.name)
|
|
374
|
+
else:
|
|
375
|
+
new_files.append(file)
|
|
376
|
+
self._input_file = new_files[0] if len(new_files)==1 else new_files
|
|
377
|
+
self._match_input_file()
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
# ===============================
|
|
381
|
+
# === Methods to be inherited ===
|
|
382
|
+
# ===============================
|
|
383
|
+
|
|
384
|
+
@classmethod
|
|
385
|
+
def is_running(cls, **kwargs):
|
|
386
|
+
self = cls.get_self(**kwargs)
|
|
387
|
+
if hasattr(self, '_starting_engine') and self._starting_engine:
|
|
388
|
+
# We need this to allow changing the element settings which otherwise are locked
|
|
389
|
+
return False
|
|
390
|
+
# If we get here, we cannot say if the engine is running or not and we need an
|
|
391
|
+
# implementation in the child class
|
|
392
|
+
return None
|
|
393
|
+
|
|
394
|
+
@classmethod
|
|
395
|
+
def clean_output_files(cls, **kwargs):
|
|
396
|
+
pass
|
|
397
|
+
|
|
398
|
+
def _match_input_file(self, **kwargs):
|
|
399
|
+
raise NotImplementedError("Need to implement `_match_input_file` for {cls.__name__}!")
|
|
400
|
+
|
|
401
|
+
@classmethod
|
|
402
|
+
def generate_input_file(cls, **kwargs):
|
|
403
|
+
raise NotImplementedError("Need to implement `generate_input_file` for {cls.__name__}!")
|
|
@@ -171,7 +171,7 @@ double calculate_dechanneling_length(EverestData restrict everest, double pc) {
|
|
|
171
171
|
double energy = sqrt(pow(momentum, 2.) + pow(XC_PROTON_MASS, 2.)); // [MeV]
|
|
172
172
|
double gammar = energy/XC_PROTON_MASS;
|
|
173
173
|
|
|
174
|
-
double const_dech = 256.0/(9.*pow(M_PI, 2.)) / (log(2.*XC_ELECTRON_MASS*gammar/exenergy) - 1.);
|
|
174
|
+
double const_dech = 256.0/(9.*pow(M_PI, 2.)) / (log(2.*XC_ELECTRON_MASS*gammar/exenergy/1000) - 1.);
|
|
175
175
|
const_dech *= (XC_SCREENING*XC_PLANE_DISTANCE)/(XC_CRADE*XC_ELECTRON_MASS)*1.0e3; // [m/GeV]
|
|
176
176
|
return const_dech;
|
|
177
177
|
}
|
xcoll/xaux.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# copyright ############################### #
|
|
2
|
+
# This file is part of the Xcoll Package. #
|
|
3
|
+
# Copyright (c) CERN, 2024. #
|
|
4
|
+
# ######################################### #
|
|
5
|
+
|
|
6
|
+
import functools
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
FsPath = Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def singleton(cls):
|
|
13
|
+
# Store the original __new__ method if it exists
|
|
14
|
+
original_new = cls.__new__ if hasattr(cls, '__new__') else None
|
|
15
|
+
|
|
16
|
+
# Define a new __new__ method for the singleton
|
|
17
|
+
def singleton_new(cls, *args, **kwargs):
|
|
18
|
+
if not hasattr(cls, 'instance'):
|
|
19
|
+
cls.instance = (original_new(cls, *args, **kwargs)
|
|
20
|
+
if original_new
|
|
21
|
+
else super(cls, cls).__new__(cls))
|
|
22
|
+
cls.instance._initialised = False
|
|
23
|
+
return cls.instance
|
|
24
|
+
cls.__new__ = singleton_new
|
|
25
|
+
|
|
26
|
+
# Define the get_self method
|
|
27
|
+
@classmethod
|
|
28
|
+
def get_self(cls, **kwargs):
|
|
29
|
+
# Filter kwargs to include only ClassProperty attributes
|
|
30
|
+
filtered_kwargs = {key: value for key, value in kwargs.items()
|
|
31
|
+
if key in ClassProperty.get_properties(cls) or
|
|
32
|
+
key in getattr(cls, '_xofields', {})}
|
|
33
|
+
return cls(**filtered_kwargs)
|
|
34
|
+
cls.get_self = get_self
|
|
35
|
+
|
|
36
|
+
return cls
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ClassPropertyMeta(type):
|
|
41
|
+
def __setattr__(cls, key, value):
|
|
42
|
+
# Check if the attribute is a ClassProperty
|
|
43
|
+
for parent in cls.__mro__:
|
|
44
|
+
if key in parent.__dict__ and isinstance(parent.__dict__[key], ClassProperty):
|
|
45
|
+
return parent.__dict__[key].__set__(cls, value)
|
|
46
|
+
return super(ClassPropertyMeta, cls).__setattr__(key, value)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ClassProperty:
|
|
50
|
+
_registry = {} # Registry to store ClassProperty names for each class
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def get_properties(cls, owner, parents=True):
|
|
54
|
+
if not parents:
|
|
55
|
+
return cls._registry.get(owner, [])
|
|
56
|
+
else:
|
|
57
|
+
return [prop for parent in owner.__mro__
|
|
58
|
+
for prop in cls._registry.get(parent, [])]
|
|
59
|
+
|
|
60
|
+
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
|
|
61
|
+
functools.update_wrapper(self, fget)
|
|
62
|
+
self.fget = fget
|
|
63
|
+
self.fset = fset
|
|
64
|
+
self.fdel = fdel
|
|
65
|
+
if doc is None and fget is not None:
|
|
66
|
+
doc = fget.__doc__
|
|
67
|
+
self.__doc__ = doc
|
|
68
|
+
|
|
69
|
+
def __set_name__(self, owner, name):
|
|
70
|
+
self.name = name
|
|
71
|
+
# Verify that the class is a subclass of ClassPropertyMeta
|
|
72
|
+
if ClassPropertyMeta not in type(owner).__mro__:
|
|
73
|
+
raise AttributeError(f"Class `{owner.__name__}` must be a subtype of ClassPropertyMeta!")
|
|
74
|
+
# Add the property name to the registry for the class
|
|
75
|
+
if owner not in ClassProperty._registry:
|
|
76
|
+
ClassProperty._registry[owner] = []
|
|
77
|
+
ClassProperty._registry[owner].append(name)
|
|
78
|
+
# Create default getter, setter, and deleter
|
|
79
|
+
if self.fget is None:
|
|
80
|
+
def _getter(*args, **kwargs):
|
|
81
|
+
raise AttributeError(f"Unreadable attribute `{name}` for class {owner.__name__}!")
|
|
82
|
+
self.fget = _getter
|
|
83
|
+
if self.fset is None:
|
|
84
|
+
def _setter(self, *args, **kwargs):
|
|
85
|
+
raise AttributeError(f"Can't set attribute `{name}` for class {owner.__name__}!")
|
|
86
|
+
self.fset = _setter
|
|
87
|
+
if self.fdel is None:
|
|
88
|
+
def _deleter(*args, **kwargs):
|
|
89
|
+
raise AttributeError(f"Can't delete attribute `{name}` for class {owner.__name__}!")
|
|
90
|
+
self.fdel = _deleter
|
|
91
|
+
|
|
92
|
+
def __get__(self, instance, owner):
|
|
93
|
+
if owner is None:
|
|
94
|
+
owner = type(instance)
|
|
95
|
+
try:
|
|
96
|
+
return self.fget(owner)
|
|
97
|
+
except ValueError:
|
|
98
|
+
# Return a fallback if initialization fails
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
def __set__(self, cls, value):
|
|
102
|
+
self.fset(cls, value)
|
|
103
|
+
|
|
104
|
+
def __delete__(self, instance):
|
|
105
|
+
self.fdel(instance.__class__)
|
|
106
|
+
|
|
107
|
+
def getter(self, fget):
|
|
108
|
+
self.fget = fget
|
|
109
|
+
return self
|
|
110
|
+
|
|
111
|
+
def setter(self, fset):
|
|
112
|
+
self.fset = fset
|
|
113
|
+
return self
|
|
114
|
+
|
|
115
|
+
def deleter(self, fdel):
|
|
116
|
+
self.fdel = fdel
|
|
117
|
+
return self
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: xcoll
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.12
|
|
4
4
|
Summary: Xsuite collimation package
|
|
5
5
|
Home-page: https://github.com/xsuite/xcoll
|
|
6
6
|
License: Apache 2.0
|
|
@@ -18,10 +18,10 @@ Provides-Extra: tests
|
|
|
18
18
|
Requires-Dist: numpy (>=1.0)
|
|
19
19
|
Requires-Dist: pandas (>=1.4)
|
|
20
20
|
Requires-Dist: ruamel-yaml (>=0.17.31,<0.18.0) ; extra == "tests"
|
|
21
|
-
Requires-Dist: xdeps (>=0.
|
|
22
|
-
Requires-Dist: xobjects (>=0.4.
|
|
23
|
-
Requires-Dist: xpart (>=0.19.
|
|
24
|
-
Requires-Dist: xtrack (>=0.
|
|
21
|
+
Requires-Dist: xdeps (>=0.8.4)
|
|
22
|
+
Requires-Dist: xobjects (>=0.4.6)
|
|
23
|
+
Requires-Dist: xpart (>=0.19.3)
|
|
24
|
+
Requires-Dist: xtrack (>=0.72.2)
|
|
25
25
|
Project-URL: Repository, https://github.com/xsuite/xcoll
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
|
|
@@ -4,7 +4,7 @@ xcoll/__init__.py,sha256=b_61vh5irhf5fPmqTFJlyhNSt4rmftXg9uXPIEpgVB4,1612
|
|
|
4
4
|
xcoll/_manager.py,sha256=9NQKaNxZR2I1ChMVBeKQc0A8h6W8gVgRRg72a5NgbXU,808
|
|
5
5
|
xcoll/beam_elements/__init__.py,sha256=06bU8rzvlUPhcvwpaUippddm5IChpcCHBvpmvXJQU74,1122
|
|
6
6
|
xcoll/beam_elements/absorber.py,sha256=efK6gyUgD4x_FnBLpMR7-5_HCdp_753nkYikcdn6ulw,2502
|
|
7
|
-
xcoll/beam_elements/base.py,sha256=
|
|
7
|
+
xcoll/beam_elements/base.py,sha256=J69dwAILHGwGthaQK3D9f2Etibv6fe11oczcKftTEac,53943
|
|
8
8
|
xcoll/beam_elements/blowup.py,sha256=gBXdlISvoDiMjXVpA77ls5QdAU3H9krwvFt2bSW_NII,8029
|
|
9
9
|
xcoll/beam_elements/elements_src/black_absorber.h,sha256=jCyQoaZ7VsIu8coQ99J1dDtAGqZpFIxxFLBlfhO6Drw,5027
|
|
10
10
|
xcoll/beam_elements/elements_src/black_crystal.h,sha256=x7oUwsrkUwUrFvhFsq8vtPkJJTSi1hYAhSt6fjzkJQo,4622
|
|
@@ -16,18 +16,19 @@ xcoll/beam_elements/elements_src/everest_crystal.h,sha256=WwwNF6it7TuOimhpSXJa7U
|
|
|
16
16
|
xcoll/beam_elements/everest.py,sha256=PA_VWpnPrIuO1xN__eKyT_ejbGZK7p93QHDVi3re7cM,8541
|
|
17
17
|
xcoll/beam_elements/monitor.py,sha256=zzMdN3JMFSAs-30_ntRvd5qZGdsXfGtColhiFDuMcIk,16928
|
|
18
18
|
xcoll/colldb.py,sha256=hGScl4lU93KDemHrgHOKfu2OqVAufP1BtgKKHJ_THDc,30501
|
|
19
|
-
xcoll/general.py,sha256=
|
|
19
|
+
xcoll/general.py,sha256=VqLfCrl6mLRBUaBR8TC0bGG8MH271fZEGKITEw3UfYo,535
|
|
20
20
|
xcoll/headers/checks.h,sha256=qdXsOTBOK1MwW6bdFF93j4yE648mcDtEv5rGN1w9sfk,1582
|
|
21
|
-
xcoll/headers/particle_states.h,sha256=
|
|
22
|
-
xcoll/initial_distribution.py,sha256=
|
|
21
|
+
xcoll/headers/particle_states.h,sha256=9hzp5abC_pIV6QrHy0iNm0qblcvsymI-pJQMv6v1Rhc,840
|
|
22
|
+
xcoll/initial_distribution.py,sha256=yjjEk2PJjE1YB9xDMeVDa-qFVlPTvVWEf8yynHvgAow,9015
|
|
23
23
|
xcoll/install.py,sha256=SxEFQnhWXlsXyPBIo847q6wPgId_f5ZtFRR1awGbkjc,2108
|
|
24
24
|
xcoll/interaction_record/__init__.py,sha256=UFoLiKa-z2oX7YoszP-7Vgdt1nM6kT382v1CaIu8_u0,50
|
|
25
25
|
xcoll/interaction_record/interaction_record.py,sha256=ixsQtVZn71vVEuTAA27a2NWcZZZ8iAcWFOa58bcWEQU,13271
|
|
26
26
|
xcoll/interaction_record/interaction_record_src/interaction_record.h,sha256=0rNagnfSGc2i1jauOMIcDbj9QFic9dV_MOyqVx1kw5Q,6067
|
|
27
27
|
xcoll/interaction_record/interaction_types.py,sha256=Vh6oFYKdRNOx9hc_E0iT8auNZVKC0qYVp_p7oyClZ8o,2894
|
|
28
|
-
xcoll/line_tools.py,sha256=
|
|
28
|
+
xcoll/line_tools.py,sha256=ZVUNRP_UI9RP7PBYBUVegww4J_BmdSo2dn3BS4ZAohI,14298
|
|
29
29
|
xcoll/lossmap.py,sha256=W2EzOe4aKmJFd8kEpebeQaAn1818QF3ih_nhA_br-2I,8062
|
|
30
30
|
xcoll/rf_sweep.py,sha256=P2X1S9pGi4OpNYnzYfQVyblFt2p8aw9EWHsKDkAuYt0,8936
|
|
31
|
+
xcoll/scattering_routines/engine.py,sha256=ZE2a_RbjGvoRZEr6XNGa6avsB_faiIqPBqb7SVWZyng,15018
|
|
31
32
|
xcoll/scattering_routines/everest/__init__.py,sha256=7lkkeZ1liBjXVHCuRpgzZI6ohzHVMj5uJBO792147XY,286
|
|
32
33
|
xcoll/scattering_routines/everest/amorphous.h,sha256=0eSV8F7yb2xrhrEGPZGWu_Lgr3gjtU8RddaJElsZ-Tk,10362
|
|
33
34
|
xcoll/scattering_routines/everest/channeling.h,sha256=k7ohwPec3gk3WCvwm-0C8cB39F__CO2yLyvKCWCg714,11050
|
|
@@ -39,7 +40,7 @@ xcoll/scattering_routines/everest/jaw.h,sha256=BWpfrHNPLaMF8JjsNAhWwy6TDI0jsiOT3
|
|
|
39
40
|
xcoll/scattering_routines/everest/materials.py,sha256=nO0ZayGRgqgF7Eku-mtxDl0BPOls5YS8a0qPPG32qw0,10260
|
|
40
41
|
xcoll/scattering_routines/everest/multiple_coulomb_scattering.h,sha256=NgrUEX-zCaiS1mwJvMLhfmg8GPNcPSGzh6UQKYqphJ8,5432
|
|
41
42
|
xcoll/scattering_routines/everest/nuclear_interaction.h,sha256=jr49uo2cCk5SiebMZtb_If2WFHSxNLpYYKDJiQbhW1g,3110
|
|
42
|
-
xcoll/scattering_routines/everest/properties.h,sha256=
|
|
43
|
+
xcoll/scattering_routines/everest/properties.h,sha256=9kf-a8EYGTVVZPkIzI-YXLW3ZvKEAJvACB8eSpcD2dM,6779
|
|
43
44
|
xcoll/scattering_routines/fluka/flukaio/.git,sha256=5ZxurpwP1waJk2Zu2AstENGOp4rXU8-C-oU4CypmIVI,73
|
|
44
45
|
xcoll/scattering_routines/fluka/flukaio/.gitignore,sha256=bhrpWiAnKChkcwIaIPX_zKxyG2nCtNzNgQAHnIJa8Fw,12
|
|
45
46
|
xcoll/scattering_routines/fluka/flukaio/CMakeLists.txt,sha256=iWWqTC26UqcuQWQj_JCKtX6iiOb7arnhQ9kOo1fDVkE,591
|
|
@@ -406,8 +407,9 @@ xcoll/scattering_routines/geometry/objects.h,sha256=A5ktGvVlSkC4hUsI_PQFsE80CuDw
|
|
|
406
407
|
xcoll/scattering_routines/geometry/rotation.h,sha256=lO3RaQBys9r0ROMjR8T8Rr7UsIEm-H9_C_70Nwz4MXY,701
|
|
407
408
|
xcoll/scattering_routines/geometry/segments.h,sha256=7nKnnin2ByxkKyaYwGvFaqgLQg5uBba4CdLHL7L3iQs,7667
|
|
408
409
|
xcoll/scattering_routines/geometry/sort.h,sha256=b1MkFO2ddzv1fWGeQzsLuz46qo2pKyRSXHjoAEVU7Ts,5763
|
|
409
|
-
xcoll
|
|
410
|
-
xcoll-0.5.
|
|
411
|
-
xcoll-0.5.
|
|
412
|
-
xcoll-0.5.
|
|
413
|
-
xcoll-0.5.
|
|
410
|
+
xcoll/xaux.py,sha256=KME-8QXkZwQLqgtuC2q7KM27WCCBDLWHR9zq7uVaMlc,4085
|
|
411
|
+
xcoll-0.5.12.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
412
|
+
xcoll-0.5.12.dist-info/METADATA,sha256=Ag2SZen5Cuuvjz6ZoIZjvxluHWDkaDEgsxVC4XLU9Io,2676
|
|
413
|
+
xcoll-0.5.12.dist-info/NOTICE,sha256=6DO_E7WCdRKc42vUoVVBPGttvQi4mRt9fAcxj9u8zy8,74
|
|
414
|
+
xcoll-0.5.12.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
415
|
+
xcoll-0.5.12.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|