xcoll 0.6.3__py3-none-any.whl → 0.6.5__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.

@@ -0,0 +1,23 @@
1
+ // copyright ############################### #
2
+ // This file is part of the Xcoll package. #
3
+ // Copyright (c) CERN, 2025. #
4
+ // ######################################### #
5
+
6
+ #ifndef XCOLL_RF_SWEEP_H
7
+ #define XCOLL_RF_SWEEP_H
8
+
9
+ /*gpufun*/
10
+ void RFSweep_track_local_particle(RFSweepData el, LocalParticle* part0){
11
+ double const step = RFSweepData_get__rf_sweep_df_step(el); // L*df/(f0 + df)
12
+ int64_t const start_turn = RFSweepData_get_start_turn(el);
13
+ int64_t const stop_turn = RFSweepData_get_stop_turn(el);
14
+
15
+ //start_per_particle_block (part0->part)
16
+ int64_t at_turn = LocalParticle_get_at_turn(part);
17
+ if (at_turn >= start_turn && at_turn <= stop_turn){
18
+ LocalParticle_add_to_zeta(part, -(at_turn - start_turn + 1)*step);
19
+ }
20
+ //end_per_particle_block
21
+ }
22
+
23
+ #endif /* XCOLL_RF_SWEEP_H */
File without changes
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.6.3'
15
+ __version__ = '0.6.5'
16
16
  # ======================
xcoll/general.py.orig ADDED
@@ -0,0 +1,21 @@
1
+ # copyright ############################### #
2
+ # This file is part of the Xcoll package. #
3
+ # Copyright (c) CERN, 2025. #
4
+ # ######################################### #
5
+
6
+ from pathlib import Path
7
+
8
+ _pkg_root = Path(__file__).parent.absolute()
9
+
10
+ citation = "F.F. Van der Veken, et al.: Recent Developments with the New Tools for Collimation "
11
+ citation += "Simulations in Xsuite, Proceedings of HB2023, Geneva, Switzerland."
12
+
13
+ # ======================
14
+ # Do not change
15
+ # ======================
16
+ <<<<<<< HEAD
17
+ __version__ = '0.7.0rc0'
18
+ =======
19
+ __version__ = '0.6.4'
20
+ >>>>>>> main
21
+ # ======================
xcoll/geometry.md ADDED
@@ -0,0 +1,42 @@
1
+ PSEUDOCODE for material interactions tracking in collimator
2
+ ===========================================================
3
+
4
+ - create DriftTrajectory from particle
5
+ - loop:
6
+ - find first crossing with collimator shape (segments)
7
+ - if distance larger than end of BeamElement -> move particle to exendit and break loop
8
+ - move particle to collimator impact point
9
+ - create MCSTrajectory from new particle
10
+ - loop:
11
+ - find first crossing with collimator shape (segments)
12
+ - do not move, but calculate path length
13
+ - compare to distance to nuclear interaction
14
+ - shortest wins (nuclear or exit)
15
+ - move to next point
16
+ - when at exit, create DriftTrajectory from particle
17
+
18
+
19
+
20
+ PSEUDOCODE for material interactions tracking in crystal
21
+ ========================================================
22
+
23
+ - create DriftTrajectory from particle
24
+ - loop:
25
+ - find first crossing with crystal shape (segments)
26
+ - if distance larger than end of BeamElement -> move particle to end and break loop
27
+ - move particle to crystal impact point
28
+ - create MCSTrajectory (if amorphous) or CircularTrajectory (if channelling) from new particle
29
+ - loop:
30
+ - find first crossing with crystal shape (segments)
31
+ - do not move, but calculate path length
32
+ - compare to distance to nuclear interaction and dechannelling
33
+ - shortest wins (nuclear, dechannelling, or exit)
34
+ - move to next point
35
+ - when at exit, create DriftTrajectory from particle
36
+
37
+
38
+ PSEUDOCODE for crossing finder
39
+ ==============================
40
+
41
+ - if DriftTrajectory and any segment
42
+ => use analytical
@@ -3,5 +3,5 @@
3
3
  # Copyright (c) CERN, 2025. #
4
4
  # ######################################### #
5
5
 
6
- from .elements import DEFAULT_XCOLL_ELEMENTS
6
+ from .element_types import DEFAULT_XCOLL_ELEMENTS
7
7
  from .element_inits import XCOLL_ELEMENTS_INIT_DEFAULTS
xcoll/rf_sweep.py CHANGED
@@ -4,12 +4,13 @@
4
4
  # ######################################### #
5
5
 
6
6
  import numpy as np
7
+ from warnings import warn
7
8
  import scipy.constants as sc
8
9
 
9
10
  import xtrack as xt
10
11
 
11
12
 
12
- def prepare_rf_sweep(line, cavities=None, sweep=None, sweep_per_turn=None, num_turns=None):
13
+ def prepare_rf_sweep(line, *, cavities=None, sweep=None, sweep_per_turn=None, num_turns=None):
13
14
  rf_sweep = RFSweep(line=line, cavities=cavities)
14
15
  rf_sweep.prepare(sweep=sweep, sweep_per_turn=sweep_per_turn, num_turns=num_turns)
15
16
 
@@ -17,57 +18,63 @@ def prepare_rf_sweep(line, cavities=None, sweep=None, sweep_per_turn=None, num_t
17
18
  class RFSweep:
18
19
  def __init__(self, line, cavities=None):
19
20
  self.line = line
20
- if line._var_management is None:
21
- raise ValueError("Line must have a `var_management` to use RFSweep!" \
21
+ if line.env.ref_manager is None:
22
+ raise ValueError("Environment must have a `ref_manager` to use RFSweep!" \
22
23
  + "Do not use `optimize_for_tracking` as it will "
23
24
  + "disable expressions, which are needed for RFSweep.")
25
+ line.enable_time_dependent_vars = False # To be able to twiss in the prepare step
24
26
  self.env = line.env
25
27
  self.cavities = cavities
26
28
  self.env['rf_sweep_df'] = 0
29
+ self._prepared = False
27
30
 
28
31
  @property
29
32
  def current_sweep_value(self):
30
33
  return self.env['rf_sweep_df']
31
34
 
32
- def prepare(self, sweep=None, sweep_per_turn=None, num_turns=None):
33
- if sweep_per_turn is not None:
34
- if np.isclose(sweep_per_turn, 0):
35
- raise ValueError("Variable `sweep_per_turn` must be non-zero!")
36
- if sweep is not None:
37
- raise ValueError("Provide either `sweep` or `sweep_per_turn`, not both.")
38
- if num_turns is not None:
39
- raise ValueError("Variable `num_turns` cannot be set when using `sweep_per_turn`.")
40
- self.sweep_per_turn = sweep_per_turn
41
- elif sweep is not None:
42
- if np.isclose(sweep, 0):
43
- raise ValueError("Variable `sweep` must be non-zero!")
44
- if num_turns is None:
45
- num_turns = int(abs(sweep))
46
- if num_turns <= 0:
47
- raise ValueError("When using `sweep`, `num_turns` must be a positive integer.")
48
- self.sweep_per_turn = sweep / num_turns
49
- else:
50
- raise ValueError("Either `sweep` or `sweep_per_turn` must be provided.")
51
- self._get_cavity_data(self.sweep_per_turn)
52
- self._install_zeta_shift()
53
- self.tw = self.line.twiss()
54
- self.reset() # Initialize rf_sweep_df
55
- self.env['rf_sweep'].dzeta = f"{self.L} * rf_sweep_df / ({self.f_RF} + rf_sweep_df)"
56
- for cavs in self.cavities:
57
- for cav in cavs['names']:
58
- scale_factor = int(np.round(cavs['freq'] / self.f_RF))
59
- if scale_factor == 1:
60
- self.env.ref[cav].frequency += self.env.ref["rf_sweep_df"]
61
- else:
62
- self.env.ref[cav].frequency += scale_factor * self.env.ref["rf_sweep_df"]
63
- self.line.enable_time_dependent_vars = True
64
- print("Enabled time-dependent variables in the line.")
35
+ def prepare(self, *, sweep=None, num_turns=None, sweep_per_turn=None):
36
+ # TODO: if using sweep and num_turns, the sweep should stop after num_turns,
37
+ # but if using sweep_per_turn, it should continue indefinitely.
38
+ if not self._prepared:
39
+ if sweep_per_turn is not None:
40
+ if np.isclose(sweep_per_turn, 0):
41
+ raise ValueError("Variable `sweep_per_turn` must be non-zero!")
42
+ if sweep is not None:
43
+ raise ValueError("Provide either `sweep` or `sweep_per_turn`, not both.")
44
+ if num_turns is not None:
45
+ raise ValueError("Variable `num_turns` cannot be set when using `sweep_per_turn`.")
46
+ self.sweep_per_turn = sweep_per_turn
47
+ elif sweep is not None:
48
+ if np.isclose(sweep, 0):
49
+ raise ValueError("Variable `sweep` must be non-zero!")
50
+ if num_turns is None:
51
+ num_turns = int(abs(sweep))
52
+ if num_turns <= 0:
53
+ raise ValueError("When using `sweep`, `num_turns` must be a positive integer.")
54
+ self.sweep_per_turn = sweep / num_turns
55
+ else:
56
+ raise ValueError("Either `sweep` or `sweep_per_turn` must be provided.")
57
+ self._get_cavity_data()
58
+ self._install_zeta_shift()
59
+ self.tw = self.line.twiss()
60
+ self.reset() # Initialize rf_sweep_df
61
+ self.env['rf_sweep'].dzeta = f"{self.L} * rf_sweep_df / ({self.f_RF} + rf_sweep_df)"
62
+ for cavs in self.cavities:
63
+ for cav in cavs['names']:
64
+ scale_factor = int(np.round(cavs['freq'] / self.f_RF))
65
+ if scale_factor == 1:
66
+ self.env.ref[cav].frequency += self.env.ref["rf_sweep_df"]
67
+ else:
68
+ self.env.ref[cav].frequency += scale_factor * self.env.ref["rf_sweep_df"]
69
+ self.line.enable_time_dependent_vars = True
70
+ print("Enabled time-dependent variables in the line.")
71
+ self._prepared = True
65
72
 
66
73
 
67
74
  def reset(self):
68
75
  if self.sweep_per_turn is None:
69
76
  raise ValueError("RFSweep not prepared. Call `prepare` first.")
70
- t_turn = self.tw.T_rev0
77
+ t_turn = self.tw.T_rev0 # To start sweeping from turn 0
71
78
  current_time = self.env['t_turn_s']
72
79
  if current_time == 0:
73
80
  self.env['rf_sweep_df'] = f"(t_turn_s + {t_turn}) / {t_turn} * {self.sweep_per_turn}"
@@ -76,10 +83,12 @@ class RFSweep:
76
83
 
77
84
 
78
85
  def info(self, sweep=None, num_turns=None):
79
- if sweep is not None:
80
- raise DeprecationWarning("The `sweep` argument is deprecated.")
81
- if num_turns is not None:
82
- raise DeprecationWarning("The `num_turns` argument is deprecated.")
86
+ if sweep is not None or num_turns is not None:
87
+ if sweep is not None:
88
+ warn("The `sweep` argument is deprecated.", DeprecationWarning)
89
+ if num_turns is not None:
90
+ warn("The `num_turns` argument is deprecated.", DeprecationWarning)
91
+ self.prepare(sweep=sweep, num_turns=num_turns)
83
92
  if self.sweep_per_turn is None:
84
93
  raise ValueError("RFSweep not prepared. Call `prepare` first.")
85
94
  existing_sweep = self.current_sweep_value
@@ -98,8 +107,9 @@ class RFSweep:
98
107
  print(f"The current frequency is {self.f_RF + existing_sweep}Hz, adding "
99
108
  + f"{self.sweep_per_turn}Hz per turn.")
100
109
  print(f"This sweep will move the center of the bucket with \u0394\u03B4 = "
101
- + f"{delta_shift} per turn.")
102
- print(f"This implies one bucket shift every {bucket_turns} turns.")
110
+ + f"{delta_shift:.4} per turn.")
111
+ print(f"The bucket height is {bucket_height:.4}, so this implies the sweep "
112
+ + f"will shift one bucket every {round(bucket_turns, 2)} turns.")
103
113
  if self.tw.qs * bucket_turns < 3:
104
114
  print(f"Warning: This is a very fast sweep, moving ~1 bucket in "
105
115
  + f"~{round(self.tw.qs * bucket_turns, 2)} synchrotron oscillations "
@@ -110,11 +120,14 @@ class RFSweep:
110
120
 
111
121
  # For backward compatibility
112
122
  def track(self, sweep=0, particles=None, num_turns=0, verbose=True, *args, **kwargs):
113
- self.prepare(sweep, num_turns)
114
- self.line.track(particles=particles, *args, **kwargs)
123
+ warn("Using RFSweep.track() is deprecated. Please use RFSweep.prepare() "
124
+ + "and then xt.Line.track().", DeprecationWarning)
125
+ self.prepare(sweep=sweep, num_turns=num_turns)
126
+ self.line.track(particles=particles, num_turns=num_turns, *args, **kwargs)
115
127
 
116
128
 
117
- def _get_cavity_data(self, sweep):
129
+ def _get_cavity_data(self):
130
+ # Cavity data not yet extracted
118
131
  tt = self.line.get_table()
119
132
  tt_c = tt.rows[[nn for nn, ttt in zip(tt.name, tt.element_type)
120
133
  if 'Cavity' in ttt and 'CrabCavity' not in ttt]]
@@ -145,8 +158,8 @@ class RFSweep:
145
158
  raise ValueError(f"Cavity `{cav}` not found in the line!")
146
159
  idx = np.argsort(freq)
147
160
  boundaries = np.where(~np.isclose(freq[idx][1:], freq[idx][:-1],
148
- rtol=1e-8, atol=1e-12)
149
- )[0] + 1
161
+ rtol=1e-8, atol=1e-12)
162
+ )[0] + 1
150
163
  groups = []
151
164
  for gidx in np.split(idx, boundaries):
152
165
  groups.append({
@@ -168,10 +181,9 @@ class RFSweep:
168
181
  print("Found multiple cavities with different frequencies:")
169
182
  for g in self.cavities:
170
183
  print(f"{g['freq']}Hz at {g['voltage']}V: {g['names']}")
171
- print(r"The sweep ($\Delta f$ = " + f"{sweep}Hz per turn) will be "
172
- + f"performed with respect to the highest voltage cavity at "
173
- + f"{self.f_RF}Hz. The other cavities will be shifted "
174
- + f"accordingly.")
184
+ print(r"The sweep will be performed with respect to the highest "
185
+ + f"voltage cavity at {self.f_RF}Hz. The other cavities will "
186
+ + f"be shifted accordingly.")
175
187
 
176
188
 
177
189
  def _install_zeta_shift(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: xcoll
3
- Version: 0.6.3
3
+ Version: 0.6.5
4
4
  Summary: Xsuite collimation package
5
5
  License: Apache-2.0
6
6
  Author: Frederik F. Van der Veken
@@ -22,7 +22,7 @@ Requires-Dist: ruamel-yaml (>=0.17.31,<0.18.15)
22
22
  Requires-Dist: xdeps (>=0.10.6)
23
23
  Requires-Dist: xobjects (>=0.5.2)
24
24
  Requires-Dist: xpart (>=0.23.1)
25
- Requires-Dist: xtrack (>=0.89.3)
25
+ Requires-Dist: xtrack (>=0.90.1)
26
26
  Project-URL: Bug Tracker, https://github.com/xsuite/xsuite/issues
27
27
  Project-URL: Documentation, https://xsuite.readthedocs.io/
28
28
  Project-URL: Homepage, https://github.com/xsuite/xcoll
@@ -10,13 +10,17 @@ xcoll/beam_elements/elements_src/emittance_monitor.h,sha256=vlHzQFoUjKQHWBmzpaSz
10
10
  xcoll/beam_elements/elements_src/everest_block.h,sha256=ITSzfiqwm8ZNIkAj_odQkAjKhPcdT8b0AUlq_uxtsqI,6562
11
11
  xcoll/beam_elements/elements_src/everest_collimator.h,sha256=fkD5GazVv2zlmqyb6s9zVNMq6baXeFb_pf7gg9TKjNc,9787
12
12
  xcoll/beam_elements/elements_src/everest_crystal.h,sha256=LISp_9NEWMIi5GvZ3LwPfeSbmsbXvHWcTqxW6eCCsiE,11951
13
+ xcoll/beam_elements/elements_src/rf_sweep.h,sha256=eTPPSJvFrkoh9STI0hmmiozwMUL-TQVhz1mOZQhObWE,846
13
14
  xcoll/beam_elements/elements_src/transparent_collimator.h,sha256=pA_Fxx85N87iSbpHSjR2OSOx6JN9e38T1pOUKrC7zxs,4610
14
15
  xcoll/beam_elements/elements_src/transparent_crystal.h,sha256=DGX4uL0hpm4njOypoPuEWtMzYxnL9jQkf2ZrGaS0alI,4128
15
16
  xcoll/beam_elements/everest.py,sha256=iJva_S0OQnmG-qj7rIAiUCssu5WL_Qs5P_n6Qx-IWzo,9080
16
17
  xcoll/beam_elements/monitor.py,sha256=baMYT_PNya8KX35ReeMwk5Cm04ePUqiDF_s69L5GTX0,16968
18
+ xcoll/beam_elements/sweep.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
19
  xcoll/beam_elements/transparent.py,sha256=AZOWfH3dvsetL6DjQGejUgX7T18e_3omIIffG_1gwc0,2894
18
20
  xcoll/colldb.py,sha256=WaJC6gkDNVvxo65OhucTM6Fwo6pgRFHNnBnHSkiX7AQ,31054
19
- xcoll/general.py,sha256=4ksyfjB_QTQ5LHe22beup0CS-e0tu2HDyDX7yuwZxDM,534
21
+ xcoll/general.py,sha256=RyE6HAGBJF0DRK5n4X3-2o4fbRQwBZIV-LRjUo5-n8A,534
22
+ xcoll/general.py.orig,sha256=vIx4LhKIwbjcC8cyk6wtxrjuihDEF1THgzwb7_dpgJU,609
23
+ xcoll/geometry.md,sha256=AARDOk5lZWFBAllX75UYMRywSYSB04FIlYWE0ra1t5c,1623
20
24
  xcoll/headers/checks.h,sha256=qdXsOTBOK1MwW6bdFF93j4yE648mcDtEv5rGN1w9sfk,1582
21
25
  xcoll/headers/particle_states.py,sha256=N8ehLtg99358I4RGCJ3sjuKCk2LVdGqgVx2xGoHrRdM,1959
22
26
  xcoll/initial_distribution.py,sha256=CHhqeCVjVOyaBWhfy2sDgLwIgtXZoqcTW-su-M2YByE,10989
@@ -27,10 +31,10 @@ xcoll/interaction_record/interaction_types.py,sha256=XTeg2dcImMpqhTqzkJKh6JYam2v
27
31
  xcoll/line_tools.py,sha256=JBySkKKZ-RGumqAZF_8PSQ3OV0M87P78NeQgbXAdFc4,16699
28
32
  xcoll/lossmap.py,sha256=HLdhej9tUjk36T5BulVWurJtfiNa61L_1X7-8kT6JoQ,28407
29
33
  xcoll/plot.py,sha256=27fYdXstPg3o8XyeBlPuD2yz0GR3dKkNWy4kO2BD9WA,4071
30
- xcoll/prebuild_kernels/__init__.py,sha256=HITO-StW6e3GujTvLzEFz2Y8bMDGnavVttwixVPgA-M,286
31
- xcoll/prebuild_kernels/element_inits.py,sha256=9Qm34JXN7F08inWzXP6g6DU57ypRbyqHYwPK9Oc9BC4,219
32
- xcoll/prebuild_kernels/elements.py,sha256=7P5cxZgjfeNmUNuDer372KgtjmhH39Kk1wReyKMhqig,456
33
- xcoll/rf_sweep.py,sha256=Rrx4SmvKq4cmrfCU_Cetqmzp8c_uVa_QpXU4_rt4k_U,8611
34
+ xcoll/prebuilt_kernel_definitions/__init__.py,sha256=Dju9g0ME0F8FpFUZREyiEcd8rVyQqIro8_8LKqegTtk,291
35
+ xcoll/prebuilt_kernel_definitions/element_inits.py,sha256=9Qm34JXN7F08inWzXP6g6DU57ypRbyqHYwPK9Oc9BC4,219
36
+ xcoll/prebuilt_kernel_definitions/element_types.py,sha256=7P5cxZgjfeNmUNuDer372KgtjmhH39Kk1wReyKMhqig,456
37
+ xcoll/rf_sweep.py,sha256=_astbQSE7kr5AbnxOFR3WhduTvhkM6NR26EqyPMQ9EQ,9508
34
38
  xcoll/scattering_routines/engine.py,sha256=1VCBEZLMd5orFo3sZqK51NrqbqELBVrbsz6bB2SXsFQ,22962
35
39
  xcoll/scattering_routines/environment.py,sha256=xZ8A7XfvSfpe8vYbM5oD5qbcp8Tuag5qWAI6VqgGUlA,12033
36
40
  xcoll/scattering_routines/everest/__init__.py,sha256=7lkkeZ1liBjXVHCuRpgzZI6ohzHVMj5uJBO792147XY,286
@@ -57,9 +61,9 @@ xcoll/scattering_routines/geometry/rotation.h,sha256=lO3RaQBys9r0ROMjR8T8Rr7UsIE
57
61
  xcoll/scattering_routines/geometry/segments.h,sha256=7nKnnin2ByxkKyaYwGvFaqgLQg5uBba4CdLHL7L3iQs,7667
58
62
  xcoll/scattering_routines/geometry/sort.h,sha256=b1MkFO2ddzv1fWGeQzsLuz46qo2pKyRSXHjoAEVU7Ts,5763
59
63
  xcoll/xaux.py,sha256=mh4E_jhaUFm2LOKawJ0b6X4zuz8JiJhx6w7GcnRgIXQ,2291
60
- xcoll-0.6.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
61
- xcoll-0.6.3.dist-info/METADATA,sha256=kTXBtG7uiFxoFbGbikFmNyER0Ee2f7-ASiqsEKmYqC8,2953
62
- xcoll-0.6.3.dist-info/NOTICE,sha256=6DO_E7WCdRKc42vUoVVBPGttvQi4mRt9fAcxj9u8zy8,74
63
- xcoll-0.6.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
64
- xcoll-0.6.3.dist-info/entry_points.txt,sha256=fC9oojAU6WjKujnGBodo7ZcEeBGfSfeLPO5287echdY,26
65
- xcoll-0.6.3.dist-info/RECORD,,
64
+ xcoll-0.6.5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
65
+ xcoll-0.6.5.dist-info/METADATA,sha256=3HdRmdvs2oyskur291fR-oZf2lbRZAIRoX6fNyY0iuA,2953
66
+ xcoll-0.6.5.dist-info/NOTICE,sha256=6DO_E7WCdRKc42vUoVVBPGttvQi4mRt9fAcxj9u8zy8,74
67
+ xcoll-0.6.5.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
68
+ xcoll-0.6.5.dist-info/entry_points.txt,sha256=fC9oojAU6WjKujnGBodo7ZcEeBGfSfeLPO5287echdY,26
69
+ xcoll-0.6.5.dist-info/RECORD,,
File without changes
File without changes
File without changes