xcoll 0.5.11__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/general.py CHANGED
@@ -12,5 +12,5 @@ citation = "F.F. Van der Veken, et al.: Recent Developments with the New Tools f
12
12
  # ======================
13
13
  # Do not change
14
14
  # ======================
15
- __version__ = '0.5.11'
15
+ __version__ = '0.5.12'
16
16
  # ======================
@@ -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 XC_LOST_ON_FLUKA -334
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 XC_LOST_ON_GEANT4 -337
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
 
@@ -187,25 +187,21 @@ def _generate_4D_pencil_one_jaw(line, name, num_particles, plane, side, impact_p
187
187
  coll = line[name]
188
188
 
189
189
  if side == '+':
190
- if is_converging:
191
- if isinstance(coll, EverestCrystal):
192
- pencil_pos = coll.jaw_U + impact_parameter
193
- else:
194
- 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
195
193
  else:
196
- if isinstance(coll, EverestCrystal):
197
- pencil_pos = coll.jaw_D - impact_parameter
194
+ if is_converging:
195
+ pencil_pos = coll.jaw_LU + impact_parameter
198
196
  else:
199
197
  pencil_pos = coll.jaw_LD + impact_parameter
200
198
  elif side == '-':
201
- if is_converging:
202
- if isinstance(coll, EverestCrystal):
203
- pencil_pos = coll.jaw_U - impact_parameter
204
- else:
205
- 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
206
202
  else:
207
- if isinstance(coll, EverestCrystal):
208
- pencil_pos = coll.jaw_D + impact_parameter
203
+ if is_converging:
204
+ pencil_pos = coll.jaw_RU - impact_parameter
209
205
  else:
210
206
  pencil_pos = coll.jaw_RD - impact_parameter
211
207
 
xcoll/line_tools.py CHANGED
@@ -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
 
@@ -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.11
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.8.1)
22
- Requires-Dist: xobjects (>=0.4.5)
21
+ Requires-Dist: xdeps (>=0.8.4)
22
+ Requires-Dist: xobjects (>=0.4.6)
23
23
  Requires-Dist: xpart (>=0.19.3)
24
- Requires-Dist: xtrack (>=0.70.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
 
@@ -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=H2J2KyTTt9XNt9y4_fugX7x8iem6oBuXkNvN2kUrh1c,535
19
+ xcoll/general.py,sha256=VqLfCrl6mLRBUaBR8TC0bGG8MH271fZEGKITEw3UfYo,535
20
20
  xcoll/headers/checks.h,sha256=qdXsOTBOK1MwW6bdFF93j4yE648mcDtEv5rGN1w9sfk,1582
21
- xcoll/headers/particle_states.h,sha256=DZa_ZSaJrjnA8aHFriZKfRCkArQ8nK1t445MRwevDtA,840
22
- xcoll/initial_distribution.py,sha256=lHKKO0jA2_KkAamZAjM7lI4Z4tijnG2xHWw8Jw3y3ys,9147
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=UFgQwU6sO5PDS_AJDg0sbQ1Tt_-HakOpgdlud4vK6uk,14330
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=mVPntq9lgZPnJdtOJDi_tSawecBPLB09b7BKbisPe7w,6774
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-0.5.11.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
410
- xcoll-0.5.11.dist-info/METADATA,sha256=ghK22ioLEwuzKOuR_ODqox2CjujH-TS1epZL668PePg,2676
411
- xcoll-0.5.11.dist-info/NOTICE,sha256=6DO_E7WCdRKc42vUoVVBPGttvQi4mRt9fAcxj9u8zy8,74
412
- xcoll-0.5.11.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
413
- xcoll-0.5.11.dist-info/RECORD,,
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