syned 1.0.48__py3-none-any.whl → 1.0.49__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.
- syned/beamline/__init__.py +1 -1
- syned/beamline/beamline.py +155 -155
- syned/beamline/beamline_element.py +76 -76
- syned/beamline/element_coordinates.py +199 -199
- syned/beamline/optical_element.py +47 -47
- syned/beamline/optical_element_with_surface_shape.py +126 -126
- syned/beamline/optical_elements/__init__.py +1 -1
- syned/beamline/optical_elements/absorbers/absorber.py +21 -21
- syned/beamline/optical_elements/absorbers/beam_stopper.py +63 -63
- syned/beamline/optical_elements/absorbers/filter.py +61 -61
- syned/beamline/optical_elements/absorbers/holed_filter.py +67 -67
- syned/beamline/optical_elements/absorbers/slit.py +80 -80
- syned/beamline/optical_elements/crystals/__init__.py +1 -1
- syned/beamline/optical_elements/crystals/crystal.py +70 -70
- syned/beamline/optical_elements/gratings/__init__.py +1 -1
- syned/beamline/optical_elements/gratings/grating.py +279 -279
- syned/beamline/optical_elements/ideal_elements/__init__.py +1 -1
- syned/beamline/optical_elements/ideal_elements/ideal_element.py +15 -15
- syned/beamline/optical_elements/ideal_elements/ideal_fzp.py +183 -183
- syned/beamline/optical_elements/ideal_elements/ideal_lens.py +54 -54
- syned/beamline/optical_elements/ideal_elements/screen.py +15 -15
- syned/beamline/optical_elements/mirrors/__init__.py +1 -1
- syned/beamline/optical_elements/mirrors/mirror.py +39 -39
- syned/beamline/optical_elements/multilayers/__init__.py +46 -46
- syned/beamline/optical_elements/multilayers/multilayer.py +45 -45
- syned/beamline/optical_elements/refractors/__init__.py +1 -1
- syned/beamline/optical_elements/refractors/crl.py +79 -79
- syned/beamline/optical_elements/refractors/interface.py +60 -60
- syned/beamline/optical_elements/refractors/lens.py +105 -105
- syned/beamline/shape.py +2884 -2803
- syned/storage_ring/__init__.py +1 -1
- syned/storage_ring/electron_beam.py +804 -804
- syned/storage_ring/empty_light_source.py +40 -40
- syned/storage_ring/light_source.py +90 -90
- syned/storage_ring/magnetic_structure.py +8 -8
- syned/storage_ring/magnetic_structures/__init__.py +1 -1
- syned/storage_ring/magnetic_structures/bending_magnet.py +329 -329
- syned/storage_ring/magnetic_structures/insertion_device.py +169 -169
- syned/storage_ring/magnetic_structures/undulator.py +413 -413
- syned/storage_ring/magnetic_structures/wiggler.py +27 -27
- syned/syned_object.py +273 -275
- syned/util/__init__.py +21 -21
- syned/util/json_tools.py +196 -198
- syned/widget/widget_decorator.py +66 -66
- {syned-1.0.48.dist-info → syned-1.0.49.dist-info}/METADATA +88 -87
- syned-1.0.49.dist-info/RECORD +52 -0
- {syned-1.0.48.dist-info → syned-1.0.49.dist-info}/WHEEL +1 -1
- {syned-1.0.48.dist-info → syned-1.0.49.dist-info}/licenses/LICENSE +20 -20
- syned/__test/__init__.py +0 -46
- syned/__test/test.py +0 -28
- syned-1.0.48.dist-info/RECORD +0 -54
- {syned-1.0.48.dist-info → syned-1.0.49.dist-info}/top_level.txt +0 -0
|
@@ -1,329 +1,329 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Base class for a Bending Magnet
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
from syned.storage_ring.magnetic_structure import MagneticStructure
|
|
7
|
-
import numpy
|
|
8
|
-
import scipy.constants as codata
|
|
9
|
-
|
|
10
|
-
class BendingMagnet(MagneticStructure):
|
|
11
|
-
"""
|
|
12
|
-
Constructor.
|
|
13
|
-
|
|
14
|
-
Parameters
|
|
15
|
-
----------
|
|
16
|
-
radius : float, optional
|
|
17
|
-
Physical Radius/curvature of the magnet in m.
|
|
18
|
-
magnetic_field : float, optional
|
|
19
|
-
Magnetic field strength in T.
|
|
20
|
-
length : float, optional
|
|
21
|
-
physical length of the bending magnet (along the arc) in m.
|
|
22
|
-
|
|
23
|
-
"""
|
|
24
|
-
def __init__(self, radius=1.0, magnetic_field=1.0, length=1.0):
|
|
25
|
-
MagneticStructure.__init__(self)
|
|
26
|
-
self._radius = radius
|
|
27
|
-
self._magnetic_field = magnetic_field
|
|
28
|
-
self._length = length
|
|
29
|
-
|
|
30
|
-
# support text contaning name of variable, help text and unit. Will be stored in self._support_dictionary
|
|
31
|
-
self._set_support_text([
|
|
32
|
-
("radius" , "Radius of bending magnet" , "m" ),
|
|
33
|
-
("magnetic_field" , "Magnetic field", "T" ),
|
|
34
|
-
("length" , "Bending magnet length", "m" ),
|
|
35
|
-
] )
|
|
36
|
-
|
|
37
|
-
#
|
|
38
|
-
#methods for practical calculations
|
|
39
|
-
#
|
|
40
|
-
@classmethod
|
|
41
|
-
def initialize_from_magnetic_field_divergence_and_electron_energy(cls,
|
|
42
|
-
magnetic_field=1.0,
|
|
43
|
-
divergence=1e-3,
|
|
44
|
-
electron_energy_in_GeV=1.0,
|
|
45
|
-
**params):
|
|
46
|
-
"""
|
|
47
|
-
Returns an bending magnet from the magnetic field and electron energy.
|
|
48
|
-
|
|
49
|
-
Parameters
|
|
50
|
-
----------
|
|
51
|
-
magnetic_field : float, optional
|
|
52
|
-
Magnetic field strength in T.
|
|
53
|
-
divergence : float, optional
|
|
54
|
-
The beam divergence also corresponding to the BM angle in rad.
|
|
55
|
-
electron_energy_in_GeV : float, optional
|
|
56
|
-
The electron beam energy in GeV.
|
|
57
|
-
|
|
58
|
-
params :
|
|
59
|
-
Other parameters accepted by BendingMagnet.
|
|
60
|
-
|
|
61
|
-
Returns
|
|
62
|
-
-------
|
|
63
|
-
instance of BendingMagnet
|
|
64
|
-
|
|
65
|
-
"""
|
|
66
|
-
magnetic_radius = cls.calculate_magnetic_radius(magnetic_field, electron_energy_in_GeV)
|
|
67
|
-
|
|
68
|
-
return cls(magnetic_radius, magnetic_field, numpy.abs(divergence * magnetic_radius), **params)
|
|
69
|
-
|
|
70
|
-
@classmethod
|
|
71
|
-
def initialize_from_magnetic_radius_divergence_and_electron_energy(cls,
|
|
72
|
-
magnetic_radius=10.0,
|
|
73
|
-
divergence=1e-3,
|
|
74
|
-
electron_energy_in_GeV=1.0,
|
|
75
|
-
**params):
|
|
76
|
-
"""
|
|
77
|
-
Returns an bending magnet from the magnetic radius and electron energy.
|
|
78
|
-
|
|
79
|
-
Parameters
|
|
80
|
-
----------
|
|
81
|
-
magnetic_radius : float, optional
|
|
82
|
-
Magnetic radius in m.
|
|
83
|
-
divergence : float, optional
|
|
84
|
-
The beam divergence also corresponding to the BM angle in rad.
|
|
85
|
-
electron_energy_in_GeV : float, optional
|
|
86
|
-
The electron beam energy in GeV.
|
|
87
|
-
|
|
88
|
-
params :
|
|
89
|
-
Other parameters accepted by BendingMagnet.
|
|
90
|
-
|
|
91
|
-
Returns
|
|
92
|
-
-------
|
|
93
|
-
instance of BendingMagnet
|
|
94
|
-
|
|
95
|
-
"""
|
|
96
|
-
magnetic_field = cls.calculate_magnetic_field(magnetic_radius, electron_energy_in_GeV)
|
|
97
|
-
|
|
98
|
-
return cls(magnetic_radius,magnetic_field,numpy.abs(divergence * magnetic_radius), **params)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def length(self):
|
|
102
|
-
"""
|
|
103
|
-
returns the BM length in m.
|
|
104
|
-
|
|
105
|
-
Returns
|
|
106
|
-
-------
|
|
107
|
-
float
|
|
108
|
-
|
|
109
|
-
"""
|
|
110
|
-
return self._length
|
|
111
|
-
|
|
112
|
-
def magnetic_field(self):
|
|
113
|
-
"""
|
|
114
|
-
Returns the bagnetic field in T.
|
|
115
|
-
|
|
116
|
-
Returns
|
|
117
|
-
-------
|
|
118
|
-
float
|
|
119
|
-
|
|
120
|
-
"""
|
|
121
|
-
return self._magnetic_field
|
|
122
|
-
|
|
123
|
-
def radius(self):
|
|
124
|
-
"""
|
|
125
|
-
Returns the BM radius in m.
|
|
126
|
-
|
|
127
|
-
Returns
|
|
128
|
-
-------
|
|
129
|
-
float
|
|
130
|
-
|
|
131
|
-
"""
|
|
132
|
-
return self._radius
|
|
133
|
-
|
|
134
|
-
def horizontal_divergence(self):
|
|
135
|
-
"""
|
|
136
|
-
returns the horizontal divergence in rad.
|
|
137
|
-
|
|
138
|
-
Returns
|
|
139
|
-
-------
|
|
140
|
-
float
|
|
141
|
-
|
|
142
|
-
"""
|
|
143
|
-
return numpy.abs(self.length()/self.radius())
|
|
144
|
-
|
|
145
|
-
def get_magnetic_field(self, electron_energy_in_GeV):
|
|
146
|
-
"""
|
|
147
|
-
returns magnetic field in T (from the magnetic radius and electron energy).
|
|
148
|
-
|
|
149
|
-
Parameters
|
|
150
|
-
----------
|
|
151
|
-
electron_energy_in_GeV : float, optional
|
|
152
|
-
The electron beam energy in GeV.
|
|
153
|
-
|
|
154
|
-
Returns
|
|
155
|
-
-------
|
|
156
|
-
float
|
|
157
|
-
|
|
158
|
-
"""
|
|
159
|
-
return BendingMagnet.calculate_magnetic_field(self._radius, electron_energy_in_GeV)
|
|
160
|
-
|
|
161
|
-
def get_magnetic_radius(self, electron_energy_in_GeV):
|
|
162
|
-
"""
|
|
163
|
-
Calculates magnetic radius (from the magnetic field and electron energy).
|
|
164
|
-
|
|
165
|
-
Parameters
|
|
166
|
-
----------
|
|
167
|
-
electron_energy_in_GeV : float, optional
|
|
168
|
-
The electron beam energy in GeV.
|
|
169
|
-
|
|
170
|
-
Returns
|
|
171
|
-
-------
|
|
172
|
-
float
|
|
173
|
-
|
|
174
|
-
"""
|
|
175
|
-
return BendingMagnet.calculate_magnetic_radius(self._magnetic_field, electron_energy_in_GeV)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def get_critical_energy(self, electron_energy_in_GeV, method=1):
|
|
179
|
-
"""
|
|
180
|
-
Returns the photon critical energy in eV.
|
|
181
|
-
|
|
182
|
-
Parameters
|
|
183
|
-
----------
|
|
184
|
-
electron_energy_in_GeV : float, optional
|
|
185
|
-
The electron beam energy in GeV.
|
|
186
|
-
method : int, optional
|
|
187
|
-
0= uses magnetic radius, 1=uses magnetic field
|
|
188
|
-
|
|
189
|
-
Returns
|
|
190
|
-
-------
|
|
191
|
-
float
|
|
192
|
-
|
|
193
|
-
"""
|
|
194
|
-
if method == 0:
|
|
195
|
-
return BendingMagnet.calculate_critical_energy(self._radius, electron_energy_in_GeV)
|
|
196
|
-
else:
|
|
197
|
-
return BendingMagnet.calculate_critical_energy_from_magnetic_field(self._magnetic_field, electron_energy_in_GeV)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
# for equations, see for example https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
202
|
-
@classmethod
|
|
203
|
-
def calculate_magnetic_field(cls, magnetic_radius, electron_energy_in_GeV):
|
|
204
|
-
"""
|
|
205
|
-
Calculates magnetic field from magnetic radius and electron energy.
|
|
206
|
-
|
|
207
|
-
Parameters
|
|
208
|
-
----------
|
|
209
|
-
magnetic_radius : float
|
|
210
|
-
Magnetic radius in m.
|
|
211
|
-
electron_energy_in_GeV : float
|
|
212
|
-
The electron beam energy in GeV.
|
|
213
|
-
|
|
214
|
-
Returns
|
|
215
|
-
-------
|
|
216
|
-
float
|
|
217
|
-
The magnetic field in T.
|
|
218
|
-
|
|
219
|
-
References
|
|
220
|
-
----------
|
|
221
|
-
See, for example, https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
222
|
-
|
|
223
|
-
"""
|
|
224
|
-
# return 3.334728*electron_energy_in_GeV/magnetic_radius
|
|
225
|
-
return 1e9 / codata.c * electron_energy_in_GeV / magnetic_radius
|
|
226
|
-
|
|
227
|
-
@classmethod
|
|
228
|
-
def calculate_magnetic_radius(cls, magnetic_field, electron_energy_in_GeV):
|
|
229
|
-
"""
|
|
230
|
-
Calculates magnetic radius from magnetic field and electron energy.
|
|
231
|
-
|
|
232
|
-
Parameters
|
|
233
|
-
----------
|
|
234
|
-
magnetic_field : float
|
|
235
|
-
Magnetic field in T.
|
|
236
|
-
electron_energy_in_GeV : float
|
|
237
|
-
The electron beam energy in GeV.
|
|
238
|
-
|
|
239
|
-
Returns
|
|
240
|
-
-------
|
|
241
|
-
float
|
|
242
|
-
The magnetic radius in m.
|
|
243
|
-
|
|
244
|
-
References
|
|
245
|
-
----------
|
|
246
|
-
See, for example, https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
247
|
-
|
|
248
|
-
"""
|
|
249
|
-
# return 3.334728*electron_energy_in_GeV/magnetic_field
|
|
250
|
-
return 1e9 / codata.c * electron_energy_in_GeV / magnetic_field
|
|
251
|
-
|
|
252
|
-
@classmethod
|
|
253
|
-
def calculate_critical_energy(cls, magnetic_radius, electron_energy_in_GeV):
|
|
254
|
-
"""
|
|
255
|
-
Calculates the photon critical energy from magnetic radius and electron energy.
|
|
256
|
-
|
|
257
|
-
Parameters
|
|
258
|
-
----------
|
|
259
|
-
magnetic_radius : float
|
|
260
|
-
Magnetic radius in m.
|
|
261
|
-
electron_energy_in_GeV : float
|
|
262
|
-
The electron beam energy in GeV.
|
|
263
|
-
|
|
264
|
-
Returns
|
|
265
|
-
-------
|
|
266
|
-
float
|
|
267
|
-
The photon critical energy in eV.
|
|
268
|
-
|
|
269
|
-
References
|
|
270
|
-
----------
|
|
271
|
-
See, for example, https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
272
|
-
|
|
273
|
-
"""
|
|
274
|
-
# omega = 3 g3 c / (2r)
|
|
275
|
-
gamma = 1e9 * electron_energy_in_GeV / (codata.m_e * codata.c**2 / codata.e)
|
|
276
|
-
critical_energy_J = 3 * codata.c * codata.hbar * gamma**3 / (2 * numpy.abs(magnetic_radius))
|
|
277
|
-
critical_energy_eV = critical_energy_J / codata.e
|
|
278
|
-
return critical_energy_eV
|
|
279
|
-
|
|
280
|
-
@classmethod
|
|
281
|
-
def calculate_critical_energy_from_magnetic_field(cls, magnetic_field, electron_energy_in_GeV):
|
|
282
|
-
"""
|
|
283
|
-
Calculates the photon critical energy from magnetic field and electron energy.
|
|
284
|
-
|
|
285
|
-
Parameters
|
|
286
|
-
----------
|
|
287
|
-
magnetic_field : float
|
|
288
|
-
Magnetic field in T.
|
|
289
|
-
electron_energy_in_GeV : float
|
|
290
|
-
The electron beam energy in GeV.
|
|
291
|
-
|
|
292
|
-
Returns
|
|
293
|
-
-------
|
|
294
|
-
float
|
|
295
|
-
The critical energy in eV.
|
|
296
|
-
|
|
297
|
-
References
|
|
298
|
-
----------
|
|
299
|
-
See, for example, https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
300
|
-
|
|
301
|
-
"""
|
|
302
|
-
# omega = 3 g3 c / (2r)
|
|
303
|
-
magnetic_radius = cls.calculate_magnetic_radius(magnetic_field, electron_energy_in_GeV)
|
|
304
|
-
return cls.calculate_critical_energy(magnetic_radius, electron_energy_in_GeV)
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
if __name__ == "__main__":
|
|
308
|
-
print("input for ESRF: ")
|
|
309
|
-
B = BendingMagnet.calculate_magnetic_field(25.0,6.04)
|
|
310
|
-
print(">> B = ",B)
|
|
311
|
-
print(">> R = ",BendingMagnet.calculate_magnetic_radius(B,6.04))
|
|
312
|
-
print(">> Ec = ",BendingMagnet.calculate_critical_energy(25.0,6.04))
|
|
313
|
-
print(">> Ec = ",BendingMagnet.calculate_critical_energy_from_magnetic_field(B, 6.04))
|
|
314
|
-
BB = BendingMagnet.calculate_magnetic_radius (BendingMagnet.calculate_magnetic_radius (B,6.04),6.04)
|
|
315
|
-
RR = BendingMagnet.calculate_magnetic_radius(BendingMagnet.calculate_magnetic_field(25.0,6.04), 6.04)
|
|
316
|
-
assert(BB == B)
|
|
317
|
-
assert(RR == 25.0)
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
print("input for ALS: ")
|
|
321
|
-
B = BendingMagnet.calculate_magnetic_field(5.0,1.9)
|
|
322
|
-
print(">> B = ",B)
|
|
323
|
-
print(">> R = ",BendingMagnet.calculate_magnetic_radius (B,1.9))
|
|
324
|
-
print(">> Ec = ",BendingMagnet.calculate_critical_energy(5.0,1.9))
|
|
325
|
-
print(">> Ec = ",BendingMagnet.calculate_critical_energy_from_magnetic_field(B, 1.9))
|
|
326
|
-
BB = BendingMagnet.calculate_magnetic_radius (BendingMagnet.calculate_magnetic_radius (B,1.9),1.9)
|
|
327
|
-
RR = BendingMagnet.calculate_magnetic_radius(BendingMagnet.calculate_magnetic_field(5.0, 1.9), 1.9)
|
|
328
|
-
assert(BB == B)
|
|
329
|
-
assert(RR == 5.0)
|
|
1
|
+
"""
|
|
2
|
+
Base class for a Bending Magnet
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
from syned.storage_ring.magnetic_structure import MagneticStructure
|
|
7
|
+
import numpy
|
|
8
|
+
import scipy.constants as codata
|
|
9
|
+
|
|
10
|
+
class BendingMagnet(MagneticStructure):
|
|
11
|
+
"""
|
|
12
|
+
Constructor.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
radius : float, optional
|
|
17
|
+
Physical Radius/curvature of the magnet in m.
|
|
18
|
+
magnetic_field : float, optional
|
|
19
|
+
Magnetic field strength in T.
|
|
20
|
+
length : float, optional
|
|
21
|
+
physical length of the bending magnet (along the arc) in m.
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
def __init__(self, radius=1.0, magnetic_field=1.0, length=1.0):
|
|
25
|
+
MagneticStructure.__init__(self)
|
|
26
|
+
self._radius = radius
|
|
27
|
+
self._magnetic_field = magnetic_field
|
|
28
|
+
self._length = length
|
|
29
|
+
|
|
30
|
+
# support text contaning name of variable, help text and unit. Will be stored in self._support_dictionary
|
|
31
|
+
self._set_support_text([
|
|
32
|
+
("radius" , "Radius of bending magnet" , "m" ),
|
|
33
|
+
("magnetic_field" , "Magnetic field", "T" ),
|
|
34
|
+
("length" , "Bending magnet length", "m" ),
|
|
35
|
+
] )
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
#methods for practical calculations
|
|
39
|
+
#
|
|
40
|
+
@classmethod
|
|
41
|
+
def initialize_from_magnetic_field_divergence_and_electron_energy(cls,
|
|
42
|
+
magnetic_field=1.0,
|
|
43
|
+
divergence=1e-3,
|
|
44
|
+
electron_energy_in_GeV=1.0,
|
|
45
|
+
**params):
|
|
46
|
+
"""
|
|
47
|
+
Returns an bending magnet from the magnetic field and electron energy.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
magnetic_field : float, optional
|
|
52
|
+
Magnetic field strength in T.
|
|
53
|
+
divergence : float, optional
|
|
54
|
+
The beam divergence also corresponding to the BM angle in rad.
|
|
55
|
+
electron_energy_in_GeV : float, optional
|
|
56
|
+
The electron beam energy in GeV.
|
|
57
|
+
|
|
58
|
+
params :
|
|
59
|
+
Other parameters accepted by BendingMagnet.
|
|
60
|
+
|
|
61
|
+
Returns
|
|
62
|
+
-------
|
|
63
|
+
instance of BendingMagnet
|
|
64
|
+
|
|
65
|
+
"""
|
|
66
|
+
magnetic_radius = cls.calculate_magnetic_radius(magnetic_field, electron_energy_in_GeV)
|
|
67
|
+
|
|
68
|
+
return cls(magnetic_radius, magnetic_field, numpy.abs(divergence * magnetic_radius), **params)
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def initialize_from_magnetic_radius_divergence_and_electron_energy(cls,
|
|
72
|
+
magnetic_radius=10.0,
|
|
73
|
+
divergence=1e-3,
|
|
74
|
+
electron_energy_in_GeV=1.0,
|
|
75
|
+
**params):
|
|
76
|
+
"""
|
|
77
|
+
Returns an bending magnet from the magnetic radius and electron energy.
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
magnetic_radius : float, optional
|
|
82
|
+
Magnetic radius in m.
|
|
83
|
+
divergence : float, optional
|
|
84
|
+
The beam divergence also corresponding to the BM angle in rad.
|
|
85
|
+
electron_energy_in_GeV : float, optional
|
|
86
|
+
The electron beam energy in GeV.
|
|
87
|
+
|
|
88
|
+
params :
|
|
89
|
+
Other parameters accepted by BendingMagnet.
|
|
90
|
+
|
|
91
|
+
Returns
|
|
92
|
+
-------
|
|
93
|
+
instance of BendingMagnet
|
|
94
|
+
|
|
95
|
+
"""
|
|
96
|
+
magnetic_field = cls.calculate_magnetic_field(magnetic_radius, electron_energy_in_GeV)
|
|
97
|
+
|
|
98
|
+
return cls(magnetic_radius,magnetic_field,numpy.abs(divergence * magnetic_radius), **params)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def length(self):
|
|
102
|
+
"""
|
|
103
|
+
returns the BM length in m.
|
|
104
|
+
|
|
105
|
+
Returns
|
|
106
|
+
-------
|
|
107
|
+
float
|
|
108
|
+
|
|
109
|
+
"""
|
|
110
|
+
return self._length
|
|
111
|
+
|
|
112
|
+
def magnetic_field(self):
|
|
113
|
+
"""
|
|
114
|
+
Returns the bagnetic field in T.
|
|
115
|
+
|
|
116
|
+
Returns
|
|
117
|
+
-------
|
|
118
|
+
float
|
|
119
|
+
|
|
120
|
+
"""
|
|
121
|
+
return self._magnetic_field
|
|
122
|
+
|
|
123
|
+
def radius(self):
|
|
124
|
+
"""
|
|
125
|
+
Returns the BM radius in m.
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
float
|
|
130
|
+
|
|
131
|
+
"""
|
|
132
|
+
return self._radius
|
|
133
|
+
|
|
134
|
+
def horizontal_divergence(self):
|
|
135
|
+
"""
|
|
136
|
+
returns the horizontal divergence in rad.
|
|
137
|
+
|
|
138
|
+
Returns
|
|
139
|
+
-------
|
|
140
|
+
float
|
|
141
|
+
|
|
142
|
+
"""
|
|
143
|
+
return numpy.abs(self.length()/self.radius())
|
|
144
|
+
|
|
145
|
+
def get_magnetic_field(self, electron_energy_in_GeV):
|
|
146
|
+
"""
|
|
147
|
+
returns magnetic field in T (from the magnetic radius and electron energy).
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
electron_energy_in_GeV : float, optional
|
|
152
|
+
The electron beam energy in GeV.
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
float
|
|
157
|
+
|
|
158
|
+
"""
|
|
159
|
+
return BendingMagnet.calculate_magnetic_field(self._radius, electron_energy_in_GeV)
|
|
160
|
+
|
|
161
|
+
def get_magnetic_radius(self, electron_energy_in_GeV):
|
|
162
|
+
"""
|
|
163
|
+
Calculates magnetic radius (from the magnetic field and electron energy).
|
|
164
|
+
|
|
165
|
+
Parameters
|
|
166
|
+
----------
|
|
167
|
+
electron_energy_in_GeV : float, optional
|
|
168
|
+
The electron beam energy in GeV.
|
|
169
|
+
|
|
170
|
+
Returns
|
|
171
|
+
-------
|
|
172
|
+
float
|
|
173
|
+
|
|
174
|
+
"""
|
|
175
|
+
return BendingMagnet.calculate_magnetic_radius(self._magnetic_field, electron_energy_in_GeV)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def get_critical_energy(self, electron_energy_in_GeV, method=1):
|
|
179
|
+
"""
|
|
180
|
+
Returns the photon critical energy in eV.
|
|
181
|
+
|
|
182
|
+
Parameters
|
|
183
|
+
----------
|
|
184
|
+
electron_energy_in_GeV : float, optional
|
|
185
|
+
The electron beam energy in GeV.
|
|
186
|
+
method : int, optional
|
|
187
|
+
0= uses magnetic radius, 1=uses magnetic field
|
|
188
|
+
|
|
189
|
+
Returns
|
|
190
|
+
-------
|
|
191
|
+
float
|
|
192
|
+
|
|
193
|
+
"""
|
|
194
|
+
if method == 0:
|
|
195
|
+
return BendingMagnet.calculate_critical_energy(self._radius, electron_energy_in_GeV)
|
|
196
|
+
else:
|
|
197
|
+
return BendingMagnet.calculate_critical_energy_from_magnetic_field(self._magnetic_field, electron_energy_in_GeV)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
# for equations, see for example https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
202
|
+
@classmethod
|
|
203
|
+
def calculate_magnetic_field(cls, magnetic_radius, electron_energy_in_GeV):
|
|
204
|
+
"""
|
|
205
|
+
Calculates magnetic field from magnetic radius and electron energy.
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
magnetic_radius : float
|
|
210
|
+
Magnetic radius in m.
|
|
211
|
+
electron_energy_in_GeV : float
|
|
212
|
+
The electron beam energy in GeV.
|
|
213
|
+
|
|
214
|
+
Returns
|
|
215
|
+
-------
|
|
216
|
+
float
|
|
217
|
+
The magnetic field in T.
|
|
218
|
+
|
|
219
|
+
References
|
|
220
|
+
----------
|
|
221
|
+
See, for example, https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
222
|
+
|
|
223
|
+
"""
|
|
224
|
+
# return 3.334728*electron_energy_in_GeV/magnetic_radius
|
|
225
|
+
return 1e9 / codata.c * electron_energy_in_GeV / magnetic_radius
|
|
226
|
+
|
|
227
|
+
@classmethod
|
|
228
|
+
def calculate_magnetic_radius(cls, magnetic_field, electron_energy_in_GeV):
|
|
229
|
+
"""
|
|
230
|
+
Calculates magnetic radius from magnetic field and electron energy.
|
|
231
|
+
|
|
232
|
+
Parameters
|
|
233
|
+
----------
|
|
234
|
+
magnetic_field : float
|
|
235
|
+
Magnetic field in T.
|
|
236
|
+
electron_energy_in_GeV : float
|
|
237
|
+
The electron beam energy in GeV.
|
|
238
|
+
|
|
239
|
+
Returns
|
|
240
|
+
-------
|
|
241
|
+
float
|
|
242
|
+
The magnetic radius in m.
|
|
243
|
+
|
|
244
|
+
References
|
|
245
|
+
----------
|
|
246
|
+
See, for example, https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
247
|
+
|
|
248
|
+
"""
|
|
249
|
+
# return 3.334728*electron_energy_in_GeV/magnetic_field
|
|
250
|
+
return 1e9 / codata.c * electron_energy_in_GeV / magnetic_field
|
|
251
|
+
|
|
252
|
+
@classmethod
|
|
253
|
+
def calculate_critical_energy(cls, magnetic_radius, electron_energy_in_GeV):
|
|
254
|
+
"""
|
|
255
|
+
Calculates the photon critical energy from magnetic radius and electron energy.
|
|
256
|
+
|
|
257
|
+
Parameters
|
|
258
|
+
----------
|
|
259
|
+
magnetic_radius : float
|
|
260
|
+
Magnetic radius in m.
|
|
261
|
+
electron_energy_in_GeV : float
|
|
262
|
+
The electron beam energy in GeV.
|
|
263
|
+
|
|
264
|
+
Returns
|
|
265
|
+
-------
|
|
266
|
+
float
|
|
267
|
+
The photon critical energy in eV.
|
|
268
|
+
|
|
269
|
+
References
|
|
270
|
+
----------
|
|
271
|
+
See, for example, https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
272
|
+
|
|
273
|
+
"""
|
|
274
|
+
# omega = 3 g3 c / (2r)
|
|
275
|
+
gamma = 1e9 * electron_energy_in_GeV / (codata.m_e * codata.c**2 / codata.e)
|
|
276
|
+
critical_energy_J = 3 * codata.c * codata.hbar * gamma**3 / (2 * numpy.abs(magnetic_radius))
|
|
277
|
+
critical_energy_eV = critical_energy_J / codata.e
|
|
278
|
+
return critical_energy_eV
|
|
279
|
+
|
|
280
|
+
@classmethod
|
|
281
|
+
def calculate_critical_energy_from_magnetic_field(cls, magnetic_field, electron_energy_in_GeV):
|
|
282
|
+
"""
|
|
283
|
+
Calculates the photon critical energy from magnetic field and electron energy.
|
|
284
|
+
|
|
285
|
+
Parameters
|
|
286
|
+
----------
|
|
287
|
+
magnetic_field : float
|
|
288
|
+
Magnetic field in T.
|
|
289
|
+
electron_energy_in_GeV : float
|
|
290
|
+
The electron beam energy in GeV.
|
|
291
|
+
|
|
292
|
+
Returns
|
|
293
|
+
-------
|
|
294
|
+
float
|
|
295
|
+
The critical energy in eV.
|
|
296
|
+
|
|
297
|
+
References
|
|
298
|
+
----------
|
|
299
|
+
See, for example, https://people.eecs.berkeley.edu/~attwood/srms/2007/Lec09.pdf
|
|
300
|
+
|
|
301
|
+
"""
|
|
302
|
+
# omega = 3 g3 c / (2r)
|
|
303
|
+
magnetic_radius = cls.calculate_magnetic_radius(magnetic_field, electron_energy_in_GeV)
|
|
304
|
+
return cls.calculate_critical_energy(magnetic_radius, electron_energy_in_GeV)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
if __name__ == "__main__":
|
|
308
|
+
print("input for ESRF: ")
|
|
309
|
+
B = BendingMagnet.calculate_magnetic_field(25.0,6.04)
|
|
310
|
+
print(">> B = ",B)
|
|
311
|
+
print(">> R = ",BendingMagnet.calculate_magnetic_radius(B,6.04))
|
|
312
|
+
print(">> Ec = ",BendingMagnet.calculate_critical_energy(25.0,6.04))
|
|
313
|
+
print(">> Ec = ",BendingMagnet.calculate_critical_energy_from_magnetic_field(B, 6.04))
|
|
314
|
+
BB = BendingMagnet.calculate_magnetic_radius (BendingMagnet.calculate_magnetic_radius (B,6.04),6.04)
|
|
315
|
+
RR = BendingMagnet.calculate_magnetic_radius(BendingMagnet.calculate_magnetic_field(25.0,6.04), 6.04)
|
|
316
|
+
assert(BB == B)
|
|
317
|
+
assert(RR == 25.0)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
print("input for ALS: ")
|
|
321
|
+
B = BendingMagnet.calculate_magnetic_field(5.0,1.9)
|
|
322
|
+
print(">> B = ",B)
|
|
323
|
+
print(">> R = ",BendingMagnet.calculate_magnetic_radius (B,1.9))
|
|
324
|
+
print(">> Ec = ",BendingMagnet.calculate_critical_energy(5.0,1.9))
|
|
325
|
+
print(">> Ec = ",BendingMagnet.calculate_critical_energy_from_magnetic_field(B, 1.9))
|
|
326
|
+
BB = BendingMagnet.calculate_magnetic_radius (BendingMagnet.calculate_magnetic_radius (B,1.9),1.9)
|
|
327
|
+
RR = BendingMagnet.calculate_magnetic_radius(BendingMagnet.calculate_magnetic_field(5.0, 1.9), 1.9)
|
|
328
|
+
assert(BB == B)
|
|
329
|
+
assert(RR == 5.0)
|