xcoll 0.5.3__py3-none-any.whl → 0.5.4__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/__init__.py +2 -2
- xcoll/_manager.py +22 -0
- xcoll/beam_elements/__init__.py +1 -1
- xcoll/beam_elements/absorber.py +1 -1
- xcoll/beam_elements/base.py +1 -1
- xcoll/beam_elements/blowup.py +1 -1
- xcoll/beam_elements/elements_src/black_absorber.h +1 -1
- xcoll/beam_elements/elements_src/black_crystal.h +1 -1
- xcoll/beam_elements/elements_src/blowup.h +1 -1
- xcoll/beam_elements/elements_src/emittance_monitor.h +1 -1
- xcoll/beam_elements/elements_src/everest_block.h +8 -18
- xcoll/beam_elements/elements_src/everest_collimator.h +7 -18
- xcoll/beam_elements/elements_src/everest_crystal.h +18 -24
- xcoll/beam_elements/everest.py +7 -2
- xcoll/beam_elements/monitor.py +1 -1
- xcoll/colldb.py +1 -1
- xcoll/general.py +2 -2
- xcoll/headers/checks.h +1 -1
- xcoll/headers/particle_states.h +1 -1
- xcoll/initial_distribution.py +32 -20
- xcoll/install.py +1 -1
- xcoll/interaction_record/interaction_record.py +1 -1
- xcoll/interaction_record/interaction_record_src/interaction_record.h +1 -1
- xcoll/interaction_record/interaction_types.py +1 -1
- xcoll/line_tools.py +6 -1
- xcoll/lossmap.py +4 -4
- xcoll/rf_sweep.py +1 -1
- xcoll/scattering_routines/everest/__init__.py +1 -1
- xcoll/scattering_routines/everest/amorphous.h +11 -9
- xcoll/scattering_routines/everest/channeling.h +4 -4
- xcoll/scattering_routines/everest/constants.h +1 -1
- xcoll/scattering_routines/everest/crystal_parameters.h +36 -16
- xcoll/scattering_routines/everest/everest.h +10 -2
- xcoll/scattering_routines/everest/everest.py +1 -1
- xcoll/scattering_routines/everest/jaw.h +1 -2
- xcoll/scattering_routines/everest/materials.py +1 -1
- xcoll/scattering_routines/everest/multiple_coulomb_scattering.h +9 -8
- xcoll/scattering_routines/everest/nuclear_interaction.h +1 -1
- xcoll/scattering_routines/everest/properties.h +1 -1
- xcoll/scattering_routines/geometry/__init__.py +1 -1
- xcoll/scattering_routines/geometry/collimator_geometry.h +1 -1
- xcoll/scattering_routines/geometry/crystal_geometry.h +1 -1
- xcoll/scattering_routines/geometry/geometry.py +1 -1
- xcoll/scattering_routines/geometry/get_s.h +1 -1
- xcoll/scattering_routines/geometry/methods.h +1 -1
- xcoll/scattering_routines/geometry/objects.h +1 -1
- xcoll/scattering_routines/geometry/rotation.h +1 -1
- xcoll/scattering_routines/geometry/segments.h +1 -1
- xcoll/scattering_routines/geometry/sort.h +1 -1
- xcoll/scattering_routines/geometry/temp.c +953 -0
- {xcoll-0.5.3.dist-info → xcoll-0.5.4.dist-info}/METADATA +1 -1
- {xcoll-0.5.3.dist-info → xcoll-0.5.4.dist-info}/RECORD +55 -54
- xcoll/manager.py +0 -10
- {xcoll-0.5.3.dist-info → xcoll-0.5.4.dist-info}/LICENSE +0 -0
- {xcoll-0.5.3.dist-info → xcoll-0.5.4.dist-info}/NOTICE +0 -0
- {xcoll-0.5.3.dist-info → xcoll-0.5.4.dist-info}/WHEEL +0 -0
xcoll/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# copyright ############################### #
|
|
2
|
-
# This file is part of the Xcoll
|
|
2
|
+
# This file is part of the Xcoll package. #
|
|
3
3
|
# Copyright (c) CERN, 2024. #
|
|
4
4
|
# ######################################### #
|
|
5
5
|
|
|
@@ -17,7 +17,7 @@ from .initial_distribution import *
|
|
|
17
17
|
from .lossmap import LossMap
|
|
18
18
|
|
|
19
19
|
# Deprecated
|
|
20
|
-
from .
|
|
20
|
+
from ._manager import CollimatorManager
|
|
21
21
|
|
|
22
22
|
# print("If you use Xcoll in your simulations, please cite us :-)")
|
|
23
23
|
# print(citation)
|
xcoll/_manager.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# copyright ############################### #
|
|
2
|
+
# This file is part of the Xcoll package. #
|
|
3
|
+
# Copyright (c) CERN, 2024. #
|
|
4
|
+
# ######################################### #
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CollimatorManager:
|
|
8
|
+
|
|
9
|
+
def __init__(self, **kwargs):
|
|
10
|
+
raise ValueError("`CollimatorManager` is deprecated. Use `CollimatorDatabase` instead.")
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def from_yaml(cls, file, **kwargs):
|
|
14
|
+
raise ValueError("`CollimatorManager` is deprecated. Use `CollimatorDatabase` instead.")
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def from_json(cls, file, **kwargs):
|
|
18
|
+
raise ValueError("`CollimatorManager` is deprecated. Use `CollimatorDatabase` instead.")
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def from_dict(cls, file, **kwargs):
|
|
22
|
+
raise ValueError("`CollimatorManager` is deprecated. Use `CollimatorDatabase` instead.")
|
xcoll/beam_elements/__init__.py
CHANGED
xcoll/beam_elements/absorber.py
CHANGED
xcoll/beam_elements/base.py
CHANGED
xcoll/beam_elements/blowup.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// copyright ############################### #
|
|
2
|
-
// This file is part of the Xcoll
|
|
2
|
+
// This file is part of the Xcoll package. #
|
|
3
3
|
// Copyright (c) CERN, 2024. #
|
|
4
4
|
// ######################################### #
|
|
5
5
|
|
|
@@ -59,7 +59,6 @@ EverestCollData EverestBlock_init(EverestBlockData el, LocalParticle* part0, int
|
|
|
59
59
|
coll->record_scatterings = EverestBlockData_get_record_scatterings(el);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
|
|
63
62
|
return coll;
|
|
64
63
|
}
|
|
65
64
|
|
|
@@ -69,15 +68,10 @@ EverestData EverestBlock_init_data(LocalParticle* part, EverestCollData coll){
|
|
|
69
68
|
EverestData everest = (EverestData) malloc(sizeof(EverestData_));
|
|
70
69
|
everest->coll = coll;
|
|
71
70
|
everest->rescale_scattering = 1;
|
|
72
|
-
#ifndef XCOLL_REFINE_ENERGY
|
|
73
71
|
// Preinitialise scattering parameters
|
|
74
|
-
double
|
|
75
|
-
double mass_ratio = charge_ratio / LocalParticle_get_chi(part);
|
|
76
|
-
double energy = ( LocalParticle_get_ptau(part) + 1 / LocalParticle_get_beta0(part)
|
|
77
|
-
) * mass_ratio * LocalParticle_get_p0c(part) / 1e9; // energy in GeV
|
|
72
|
+
double energy = LocalParticle_get_energy(part) / 1e9; // energy in GeV
|
|
78
73
|
calculate_scattering(everest, energy);
|
|
79
74
|
calculate_ionisation_properties(everest, energy);
|
|
80
|
-
#endif
|
|
81
75
|
return everest;
|
|
82
76
|
}
|
|
83
77
|
|
|
@@ -107,9 +101,6 @@ void EverestBlock_track_local_particle(EverestBlockData el, LocalParticle* part0
|
|
|
107
101
|
LocalParticle_set_s(part, 0);
|
|
108
102
|
|
|
109
103
|
// Store initial coordinates for updating later
|
|
110
|
-
double const e0 = LocalParticle_get_energy0(part);
|
|
111
|
-
double const p0 = LocalParticle_get_p0c(part);
|
|
112
|
-
double const ptau_in = LocalParticle_get_ptau(part);
|
|
113
104
|
double const rvv_in = LocalParticle_get_rvv(part);
|
|
114
105
|
#ifdef XCOLL_USE_EXACT
|
|
115
106
|
double const xp_in = LocalParticle_get_exact_xp(part);
|
|
@@ -119,20 +110,19 @@ void EverestBlock_track_local_particle(EverestBlockData el, LocalParticle* part0
|
|
|
119
110
|
double const yp_in = LocalParticle_get_yp(part);
|
|
120
111
|
#endif
|
|
121
112
|
double const zeta_in = LocalParticle_get_zeta(part);
|
|
122
|
-
double const
|
|
123
|
-
double
|
|
113
|
+
double const energy_in = LocalParticle_get_energy(part);
|
|
114
|
+
double energy_out;
|
|
124
115
|
|
|
125
116
|
EverestData everest = EverestBlock_init_data(part, coll);
|
|
126
|
-
|
|
117
|
+
energy_out = jaw(everest, part, energy_in, length, 0);
|
|
127
118
|
free(everest);
|
|
128
119
|
LocalParticle_add_to_s(part, s_block);
|
|
129
120
|
|
|
130
121
|
LocalParticle_set_zeta(part, zeta_in);
|
|
131
122
|
// Survived particles need correcting:
|
|
132
123
|
if (LocalParticle_get_state(part)>0){
|
|
133
|
-
// Update energy
|
|
134
|
-
|
|
135
|
-
LocalParticle_update_ptau(part, ptau_out);
|
|
124
|
+
// Update energy; the last flag keeps angles constant (even valid for exact angles!)
|
|
125
|
+
LocalParticle_add_to_energy(part, energy_out - energy_in, 0);
|
|
136
126
|
// Update zeta
|
|
137
127
|
#ifdef XCOLL_USE_EXACT
|
|
138
128
|
double xp = LocalParticle_get_exact_xp(part);
|
|
@@ -155,4 +145,4 @@ void EverestBlock_track_local_particle(EverestBlockData el, LocalParticle* part0
|
|
|
155
145
|
|
|
156
146
|
|
|
157
147
|
|
|
158
|
-
#endif /* XCOLL_EVEREST_BLOCK_H */
|
|
148
|
+
#endif /* XCOLL_EVEREST_BLOCK_H */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// copyright ############################### #
|
|
2
|
-
// This file is part of the Xcoll
|
|
2
|
+
// This file is part of the Xcoll package. #
|
|
3
3
|
// Copyright (c) CERN, 2024. #
|
|
4
4
|
// ######################################### #
|
|
5
5
|
|
|
@@ -125,7 +125,6 @@ EverestCollData EverestCollimator_init(EverestCollimatorData el, LocalParticle*
|
|
|
125
125
|
coll->record_scatterings = EverestCollimatorData_get_record_scatterings(el);
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
|
|
129
128
|
return coll;
|
|
130
129
|
}
|
|
131
130
|
|
|
@@ -135,16 +134,10 @@ EverestData EverestCollimator_init_data(LocalParticle* part, EverestCollData col
|
|
|
135
134
|
EverestData everest = (EverestData) malloc(sizeof(EverestData_));
|
|
136
135
|
everest->coll = coll;
|
|
137
136
|
everest->rescale_scattering = 1;
|
|
138
|
-
#ifndef XCOLL_REFINE_ENERGY
|
|
139
137
|
// Preinitialise scattering parameters
|
|
140
|
-
double
|
|
141
|
-
double mass_ratio = charge_ratio / LocalParticle_get_chi(part);
|
|
142
|
-
double energy = ( LocalParticle_get_ptau(part) + 1 / LocalParticle_get_beta0(part)
|
|
143
|
-
) * mass_ratio * LocalParticle_get_p0c(part) / 1e9; // energy in GeV
|
|
144
|
-
energy = LocalParticle_get_energy0(part) / 1e9;
|
|
138
|
+
double energy = LocalParticle_get_energy(part) / 1e9; // energy in GeV
|
|
145
139
|
calculate_scattering(everest, energy);
|
|
146
140
|
calculate_ionisation_properties(everest, energy);
|
|
147
|
-
#endif
|
|
148
141
|
return everest;
|
|
149
142
|
}
|
|
150
143
|
|
|
@@ -175,9 +168,6 @@ void EverestCollimator_track_local_particle(EverestCollimatorData el, LocalParti
|
|
|
175
168
|
LocalParticle_set_s(part, 0);
|
|
176
169
|
|
|
177
170
|
// Store initial coordinates for updating later
|
|
178
|
-
double const e0 = LocalParticle_get_energy0(part);
|
|
179
|
-
double const p0 = LocalParticle_get_p0c(part);
|
|
180
|
-
double const ptau_in = LocalParticle_get_ptau(part);
|
|
181
171
|
double const rvv_in = LocalParticle_get_rvv(part);
|
|
182
172
|
#ifdef XCOLL_USE_EXACT
|
|
183
173
|
double const xp_in = LocalParticle_get_exact_xp(part);
|
|
@@ -187,8 +177,8 @@ void EverestCollimator_track_local_particle(EverestCollimatorData el, LocalParti
|
|
|
187
177
|
double const yp_in = LocalParticle_get_yp(part);
|
|
188
178
|
#endif
|
|
189
179
|
double const zeta_in = LocalParticle_get_zeta(part);
|
|
190
|
-
double const
|
|
191
|
-
double
|
|
180
|
+
double const energy_in = LocalParticle_get_energy(part);
|
|
181
|
+
double energy_out;
|
|
192
182
|
|
|
193
183
|
// Check if hit on jaws
|
|
194
184
|
int8_t is_hit = hit_jaws_check_and_transform(part, cg);
|
|
@@ -198,7 +188,7 @@ void EverestCollimator_track_local_particle(EverestCollimatorData el, LocalParti
|
|
|
198
188
|
double remaining_length = length - LocalParticle_get_s(part);
|
|
199
189
|
// Scatter
|
|
200
190
|
EverestData everest = EverestCollimator_init_data(part, coll);
|
|
201
|
-
|
|
191
|
+
energy_out = jaw(everest, part, energy_in, remaining_length, 1);
|
|
202
192
|
free(everest);
|
|
203
193
|
}
|
|
204
194
|
|
|
@@ -209,9 +199,8 @@ void EverestCollimator_track_local_particle(EverestCollimatorData el, LocalParti
|
|
|
209
199
|
LocalParticle_set_zeta(part, zeta_in);
|
|
210
200
|
// Hit and survived particles need correcting:
|
|
211
201
|
if (is_hit!=0 && LocalParticle_get_state(part)>0){
|
|
212
|
-
// Update energy
|
|
213
|
-
|
|
214
|
-
LocalParticle_update_ptau(part, ptau_out);
|
|
202
|
+
// Update energy; the last flag keeps angles constant (even valid for exact angles!)
|
|
203
|
+
LocalParticle_add_to_energy(part, energy_out - energy_in, 0);
|
|
215
204
|
// Update zeta
|
|
216
205
|
#ifdef XCOLL_USE_EXACT
|
|
217
206
|
double xp = LocalParticle_get_exact_xp(part);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// copyright ############################### #
|
|
2
|
-
// This file is part of the Xcoll
|
|
2
|
+
// This file is part of the Xcoll package. #
|
|
3
3
|
// Copyright (c) CERN, 2024. #
|
|
4
4
|
// ######################################### #
|
|
5
5
|
|
|
@@ -162,17 +162,12 @@ EverestData EverestCrystal_init_data(LocalParticle* part, EverestCollData restri
|
|
|
162
162
|
EverestData everest = (EverestData) malloc(sizeof(EverestData_));
|
|
163
163
|
everest->coll = coll;
|
|
164
164
|
everest->rescale_scattering = 1;
|
|
165
|
-
#ifndef XCOLL_REFINE_ENERGY
|
|
166
165
|
// Preinitialise scattering parameters
|
|
167
|
-
double
|
|
168
|
-
double mass_ratio = charge_ratio / LocalParticle_get_chi(part);
|
|
169
|
-
double energy = ( LocalParticle_get_ptau(part) + 1 / LocalParticle_get_beta0(part)
|
|
170
|
-
) * mass_ratio * LocalParticle_get_p0c(part) / 1e9; // energy in GeV
|
|
166
|
+
double energy = LocalParticle_get_energy(part) / 1e9; // energy in GeV
|
|
171
167
|
calculate_scattering(everest, energy);
|
|
172
168
|
calculate_ionisation_properties(everest, energy);
|
|
173
169
|
calculate_critical_angle(everest, part, cg, energy);
|
|
174
170
|
calculate_VI_parameters(everest, part, energy);
|
|
175
|
-
#endif
|
|
176
171
|
return everest;
|
|
177
172
|
}
|
|
178
173
|
|
|
@@ -188,7 +183,13 @@ void EverestCrystal_track_local_particle(EverestCrystalData el, LocalParticle* p
|
|
|
188
183
|
EverestCollData coll = EverestCrystal_init(el, part0, active);
|
|
189
184
|
CrystalGeometry cg = EverestCrystal_init_geometry(el, part0, active);
|
|
190
185
|
|
|
191
|
-
|
|
186
|
+
// For info
|
|
187
|
+
double const e0 = LocalParticle_get_energy0(part0);
|
|
188
|
+
double t_c0 = _critical_angle0(coll, e0);
|
|
189
|
+
double Rcrit = _critical_radius(coll, e0);
|
|
190
|
+
double t_c = _critical_angle(coll, t_c0, Rcrit / fabs(cg->bending_radius));
|
|
191
|
+
EverestCrystalData_set__critical_radius(el, Rcrit);
|
|
192
|
+
EverestCrystalData_set__critical_angle(el, t_c);
|
|
192
193
|
|
|
193
194
|
//start_per_particle_block (part0->part)
|
|
194
195
|
if (!active){
|
|
@@ -200,13 +201,11 @@ void EverestCrystal_track_local_particle(EverestCrystalData el, LocalParticle* p
|
|
|
200
201
|
int8_t is_valid = xcoll_check_particle_init(coll->rng, part);
|
|
201
202
|
|
|
202
203
|
if (is_valid) {
|
|
204
|
+
// Store s-location of start of crystal
|
|
203
205
|
double const s_coll = LocalParticle_get_s(part);
|
|
204
206
|
LocalParticle_set_s(part, 0);
|
|
205
207
|
|
|
206
208
|
// Store initial coordinates for updating later
|
|
207
|
-
double const e0 = LocalParticle_get_energy0(part);
|
|
208
|
-
double const p0 = LocalParticle_get_p0c(part);
|
|
209
|
-
double const ptau_in = LocalParticle_get_ptau(part);
|
|
210
209
|
double const rvv_in = LocalParticle_get_rvv(part);
|
|
211
210
|
#ifdef XCOLL_USE_EXACT
|
|
212
211
|
double const xp_in = LocalParticle_get_exact_xp(part);
|
|
@@ -216,8 +215,8 @@ void EverestCrystal_track_local_particle(EverestCrystalData el, LocalParticle* p
|
|
|
216
215
|
double const yp_in = LocalParticle_get_yp(part);
|
|
217
216
|
#endif
|
|
218
217
|
double const zeta_in = LocalParticle_get_zeta(part);
|
|
219
|
-
double const
|
|
220
|
-
double
|
|
218
|
+
double const energy_in = LocalParticle_get_energy(part);
|
|
219
|
+
double energy_out;
|
|
221
220
|
|
|
222
221
|
// Check if hit on jaws
|
|
223
222
|
int8_t is_hit = hit_crystal_check_and_transform(part, cg);
|
|
@@ -226,7 +225,7 @@ void EverestCrystal_track_local_particle(EverestCrystalData el, LocalParticle* p
|
|
|
226
225
|
// Hit one of the jaws, so scatter
|
|
227
226
|
double remaining_length = length - LocalParticle_get_s(part);
|
|
228
227
|
// Scatter
|
|
229
|
-
EverestData everest = EverestCrystal_init_data(
|
|
228
|
+
EverestData everest = EverestCrystal_init_data(part, coll, cg);
|
|
230
229
|
calculate_initial_angle(everest, part, cg);
|
|
231
230
|
#ifdef XCOLL_USE_EXACT
|
|
232
231
|
double const xp = LocalParticle_get_exact_xp(part);
|
|
@@ -234,13 +233,10 @@ void EverestCrystal_track_local_particle(EverestCrystalData el, LocalParticle* p
|
|
|
234
233
|
double const xp = LocalParticle_get_xp(part);
|
|
235
234
|
#endif
|
|
236
235
|
if (fabs(xp - everest->t_I) < everest->t_c) {
|
|
237
|
-
|
|
236
|
+
energy_out = Channel(everest, part, cg, energy_in/1.e9, remaining_length)*1.e9;
|
|
238
237
|
} else {
|
|
239
|
-
|
|
238
|
+
energy_out = Amorphous(everest, part, cg, energy_in/1.e9, remaining_length, 1)*1.e9;
|
|
240
239
|
}
|
|
241
|
-
// Temporary workaround to store the critical angle for use later
|
|
242
|
-
calculate_critical_angle(everest, part, cg, e0/1.e9);
|
|
243
|
-
t_c = everest->t_c;
|
|
244
240
|
free(everest);
|
|
245
241
|
}
|
|
246
242
|
|
|
@@ -251,9 +247,8 @@ void EverestCrystal_track_local_particle(EverestCrystalData el, LocalParticle* p
|
|
|
251
247
|
LocalParticle_set_zeta(part, zeta_in);
|
|
252
248
|
// Hit and survived particles need correcting:
|
|
253
249
|
if (is_hit!=0 && LocalParticle_get_state(part)>0){
|
|
254
|
-
// Update energy
|
|
255
|
-
|
|
256
|
-
LocalParticle_update_ptau(part, ptau_out);
|
|
250
|
+
// Update energy; the last flag keeps angles constant (even valid for exact angles!)
|
|
251
|
+
LocalParticle_add_to_energy(part, energy_out - energy_in, 0);
|
|
257
252
|
// Update zeta
|
|
258
253
|
#ifdef XCOLL_USE_EXACT
|
|
259
254
|
double xp = LocalParticle_get_exact_xp(part);
|
|
@@ -271,10 +266,9 @@ void EverestCrystal_track_local_particle(EverestCrystalData el, LocalParticle* p
|
|
|
271
266
|
}
|
|
272
267
|
}
|
|
273
268
|
//end_per_particle_block
|
|
274
|
-
EverestCrystalData_set__critical_angle(el, t_c);
|
|
275
269
|
EverestCrystal_free(cg, active);
|
|
276
270
|
free(coll);
|
|
277
271
|
}
|
|
278
272
|
|
|
279
273
|
|
|
280
|
-
#endif /* XCOLL_EVEREST_CRYSTAL_H */
|
|
274
|
+
#endif /* XCOLL_EVEREST_CRYSTAL_H */
|
xcoll/beam_elements/everest.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# copyright ############################### #
|
|
2
|
-
# This file is part of the Xcoll
|
|
2
|
+
# This file is part of the Xcoll package. #
|
|
3
3
|
# Copyright (c) CERN, 2024. #
|
|
4
4
|
# ######################################### #
|
|
5
5
|
|
|
@@ -154,6 +154,7 @@ class EverestCrystal(BaseCrystal):
|
|
|
154
154
|
'miscut': xo.Float64,
|
|
155
155
|
'_orient': xo.Int8,
|
|
156
156
|
'_critical_angle': xo.Float64,
|
|
157
|
+
'_critical_radius': xo.Float64,
|
|
157
158
|
'_material': CrystalMaterial,
|
|
158
159
|
'rutherford_rng': xt.RandomRutherford,
|
|
159
160
|
'_tracking': xo.Int8
|
|
@@ -215,7 +216,11 @@ class EverestCrystal(BaseCrystal):
|
|
|
215
216
|
|
|
216
217
|
@property
|
|
217
218
|
def critical_angle(self):
|
|
218
|
-
return self._critical_angle if abs(self._critical_angle) > 1.e-
|
|
219
|
+
return self._critical_angle if abs(self._critical_angle) > 1.e-12 else None
|
|
220
|
+
|
|
221
|
+
@property
|
|
222
|
+
def critical_radius(self):
|
|
223
|
+
return self._critical_radius if abs(self._critical_radius) > 1.e-10 else None
|
|
219
224
|
|
|
220
225
|
@property
|
|
221
226
|
def lattice(self):
|
xcoll/beam_elements/monitor.py
CHANGED
xcoll/colldb.py
CHANGED
xcoll/general.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# copyright ############################### #
|
|
2
|
-
# This file is part of the Xcoll
|
|
2
|
+
# This file is part of the Xcoll package. #
|
|
3
3
|
# Copyright (c) CERN, 2024. #
|
|
4
4
|
# ######################################### #
|
|
5
5
|
|
|
@@ -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.
|
|
15
|
+
__version__ = '0.5.4'
|
|
16
16
|
# ======================
|
xcoll/headers/checks.h
CHANGED
xcoll/headers/particle_states.h
CHANGED
xcoll/initial_distribution.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# copyright ############################### #
|
|
2
|
-
# This file is part of the Xcoll
|
|
2
|
+
# This file is part of the Xcoll package. #
|
|
3
3
|
# Copyright (c) CERN, 2024. #
|
|
4
4
|
# ######################################### #
|
|
5
5
|
|
|
@@ -13,14 +13,14 @@ from .beam_elements import _all_collimator_classes, EverestCrystal
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def generate_pencil_on_collimator(line, name, num_particles, *, side='+-', pencil_spread=1e-6,
|
|
16
|
-
impact_parameter=0, sigma_z=7.61e-2,
|
|
17
|
-
longitudinal_betatron_cut=None):
|
|
16
|
+
impact_parameter=0, sigma_z=7.61e-2, twiss=None, longitudinal=None,
|
|
17
|
+
longitudinal_betatron_cut=None, tw=None):
|
|
18
18
|
"""
|
|
19
19
|
Generate a pencil beam on a collimator.
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
22
|
if not line._has_valid_tracker():
|
|
23
|
-
raise
|
|
23
|
+
raise ValueError("Please build tracker before generating pencil distribution!")
|
|
24
24
|
|
|
25
25
|
coll = line[name]
|
|
26
26
|
|
|
@@ -28,7 +28,7 @@ def generate_pencil_on_collimator(line, name, num_particles, *, side='+-', penci
|
|
|
28
28
|
raise ValueError("Need to provide a valid collimator!")
|
|
29
29
|
|
|
30
30
|
if coll.optics is None:
|
|
31
|
-
raise
|
|
31
|
+
raise ValueError("Need to assign optics to collimators before generating pencil distribution!")
|
|
32
32
|
|
|
33
33
|
num_particles = int(num_particles)
|
|
34
34
|
|
|
@@ -48,26 +48,32 @@ def generate_pencil_on_collimator(line, name, num_particles, *, side='+-', penci
|
|
|
48
48
|
else:
|
|
49
49
|
raise NotImplementedError("Pencil beam on a skew collimator not yet supported!")
|
|
50
50
|
|
|
51
|
-
if tw is None:
|
|
52
|
-
|
|
51
|
+
if tw is not None:
|
|
52
|
+
print("The argument tw is deprecated. Please use twiss instead.")
|
|
53
|
+
if twiss is None:
|
|
54
|
+
twiss = tw
|
|
55
|
+
|
|
56
|
+
if twiss is None:
|
|
57
|
+
twiss = line.twiss()
|
|
53
58
|
|
|
54
59
|
# Is it converging or diverging? # TODO: This might change with a tilt!!!!!!
|
|
55
|
-
|
|
56
|
-
s_back = s_front + coll.length
|
|
57
|
-
is_converging = tw[f'alf{plane}', name] > 0
|
|
60
|
+
is_converging = twiss[f'alf{plane}', name] > 0
|
|
58
61
|
print(f"Collimator {name} is {'con' if is_converging else 'di'}verging.")
|
|
59
62
|
|
|
60
|
-
beam_sizes =
|
|
63
|
+
beam_sizes = twiss.get_beam_covariance(nemitt_x=coll.nemitt_x, nemitt_y=coll.nemitt_y)
|
|
61
64
|
if is_converging:
|
|
62
65
|
# pencil at front of jaw
|
|
63
|
-
match_at_s = s_front
|
|
64
66
|
sigma = beam_sizes.rows[name:f'{name}>>1'][f'sigma_{plane}'][0]
|
|
65
67
|
sigma_transv = beam_sizes.rows[name:f'{name}>>1'][f'sigma_{transv_plane}'][0]
|
|
68
|
+
tw_at_s = twiss.rows[name]
|
|
69
|
+
at_element = name
|
|
66
70
|
else:
|
|
67
71
|
# pencil at back of jaw
|
|
68
|
-
match_at_s = s_back
|
|
69
72
|
sigma = beam_sizes.rows[name:f'{name}>>1'][f'sigma_{plane}'][1]
|
|
70
73
|
sigma_transv = beam_sizes.rows[name:f'{name}>>1'][f'sigma_{transv_plane}'][1]
|
|
74
|
+
tw_at_s = twiss.rows[f'{name}>>1']
|
|
75
|
+
at_element = line.element_names[line.element_names.index(name)+1]
|
|
76
|
+
|
|
71
77
|
dr_sigmas = pencil_spread/sigma
|
|
72
78
|
|
|
73
79
|
# Generate 4D coordinates
|
|
@@ -75,11 +81,11 @@ def generate_pencil_on_collimator(line, name, num_particles, *, side='+-', penci
|
|
|
75
81
|
if side == '+-':
|
|
76
82
|
num_plus = int(num_particles/2)
|
|
77
83
|
num_min = int(num_particles - num_plus)
|
|
78
|
-
coords_plus = _generate_4D_pencil_one_jaw(line, name, num_plus, plane, '+', impact_parameter, dr_sigmas,
|
|
79
|
-
coords_min = _generate_4D_pencil_one_jaw(line, name, num_min, plane, '-', impact_parameter, dr_sigmas,
|
|
84
|
+
coords_plus = _generate_4D_pencil_one_jaw(line, name, num_plus, plane, '+', impact_parameter, dr_sigmas, at_element, is_converging, tw_at_s)
|
|
85
|
+
coords_min = _generate_4D_pencil_one_jaw(line, name, num_min, plane, '-', impact_parameter, dr_sigmas, at_element, is_converging, tw_at_s)
|
|
80
86
|
coords = [ [*c_plus, *c_min] for c_plus, c_min in zip(coords_plus, coords_min)]
|
|
81
87
|
else:
|
|
82
|
-
coords = _generate_4D_pencil_one_jaw(line, name, num_particles, plane, side, impact_parameter, dr_sigmas,
|
|
88
|
+
coords = _generate_4D_pencil_one_jaw(line, name, num_particles, plane, side, impact_parameter, dr_sigmas, at_element, is_converging, tw_at_s)
|
|
83
89
|
pencil = coords[0]
|
|
84
90
|
p_pencil = coords[1]
|
|
85
91
|
transverse_norm = coords[2]
|
|
@@ -123,19 +129,25 @@ def generate_pencil_on_collimator(line, name, num_particles, *, side='+-', penci
|
|
|
123
129
|
part = xp.build_particles(
|
|
124
130
|
x=pencil, px=p_pencil, y_norm=transverse_norm, py_norm=p_transverse_norm,
|
|
125
131
|
zeta=zeta, delta=delta, nemitt_x=coll.nemitt_x, nemitt_y=coll.nemitt_y,
|
|
126
|
-
line=line, at_element=
|
|
132
|
+
line=line, at_element=at_element, #match_at_s=match_at_s,
|
|
127
133
|
_context=coll._buffer.context
|
|
128
134
|
)
|
|
129
135
|
else:
|
|
130
136
|
part = xp.build_particles(
|
|
131
137
|
x_norm=transverse_norm, px_norm=p_transverse_norm, y=pencil, py=p_pencil,
|
|
132
138
|
zeta=zeta, delta=delta, nemitt_x=coll.nemitt_x, nemitt_y=coll.nemitt_y,
|
|
133
|
-
line=line, at_element=
|
|
139
|
+
line=line, at_element=at_element, #match_at_s=match_at_s,
|
|
134
140
|
_context=coll._buffer.context
|
|
135
141
|
)
|
|
136
142
|
|
|
137
143
|
part._init_random_number_generator()
|
|
138
144
|
|
|
145
|
+
if not is_converging:
|
|
146
|
+
dri = xt.Drift(length=-coll.length)
|
|
147
|
+
dri.track(part)
|
|
148
|
+
part.start_tracking_at_element -= 1
|
|
149
|
+
part.at_element -= 1
|
|
150
|
+
|
|
139
151
|
return part
|
|
140
152
|
|
|
141
153
|
|
|
@@ -166,7 +178,7 @@ def generate_delta_from_dispersion(line, at_element, *, plane, position_mm, nemi
|
|
|
166
178
|
|
|
167
179
|
|
|
168
180
|
def _generate_4D_pencil_one_jaw(line, name, num_particles, plane, side, impact_parameter,
|
|
169
|
-
dr_sigmas,
|
|
181
|
+
dr_sigmas, at_element, is_converging, tw_at_s=None):
|
|
170
182
|
coll = line[name]
|
|
171
183
|
|
|
172
184
|
if side == '+':
|
|
@@ -196,7 +208,7 @@ def _generate_4D_pencil_one_jaw(line, name, num_particles, plane, side, impact_p
|
|
|
196
208
|
pencil, p_pencil = xp.generate_2D_pencil_with_absolute_cut(
|
|
197
209
|
num_particles, plane=plane, absolute_cut=pencil_pos, line=line,
|
|
198
210
|
dr_sigmas=dr_sigmas, nemitt_x=coll.nemitt_x, nemitt_y=coll.nemitt_y,
|
|
199
|
-
at_element=
|
|
211
|
+
at_element=at_element, side=side, twiss=tw_at_s
|
|
200
212
|
)
|
|
201
213
|
|
|
202
214
|
# Other plane: generate gaussian distribution in normalized coordinates
|
xcoll/install.py
CHANGED
xcoll/line_tools.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# copyright ############################### #
|
|
2
|
-
# This file is part of the Xcoll
|
|
2
|
+
# This file is part of the Xcoll package. #
|
|
3
3
|
# Copyright (c) CERN, 2024. #
|
|
4
4
|
# ######################################### #
|
|
5
5
|
|
|
@@ -9,6 +9,11 @@ import xtrack as xt
|
|
|
9
9
|
from .beam_elements import element_classes, _all_collimator_classes
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
class XcollLineAPI:
|
|
13
|
+
def __init__(self, line):
|
|
14
|
+
self._line = line
|
|
15
|
+
|
|
16
|
+
|
|
12
17
|
def assign_optics_to_collimators(line, nemitt_x=None, nemitt_y=None, twiss=None):
|
|
13
18
|
if not line._has_valid_tracker():
|
|
14
19
|
raise Exception("Please build tracker before setting the openings!")
|