File: sources.py

package info (click to toggle)
python-xrt 1.6.0%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 17,572 kB
  • sloc: python: 59,424; xml: 4,786; lisp: 4,082; sh: 22; javascript: 18; makefile: 17
file content (726 lines) | stat: -rw-r--r-- 34,861 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
# -*- coding: utf-8 -*-
r"""
Sources
-------
.. _sampling-strategies:

Sampling strategies
^^^^^^^^^^^^^^^^^^^

There are three main strategies for creating samples of optical sources,
depending on study purpose, implemented in xrt.

1. Monte Carlo sampling by intensity, or *ray* generation. This is the default
mode of all synchrotron sources in xrt and is the best sampling strategy for
ray tracing or hybrid wave propagation (when the wave part starts at a
downstream optical element). Technically it is done by the
`acceptance-rejection method
<https://en.wikipedia.org/wiki/Rejection_sampling>`_. In this method, the
optical field is calculated in a 3D space – energy and two transverse angles –
for a set of uniformly random values of these three variables within the
predefined ranges. The transverse angles also get normally distributed angular
shifts within the emittance distribution, independently for each ray. The
acceptance random variable is uniformly sampled in the range from zero to the
intensity maximum for each field sample, and the sample is accepted if the
acceptance variable is below the sample intensity, otherwise it is rejected.
The sampling continues until the requested number of samples is reached. The
resulted space density of the samples (rays) is proportional to the field
intensity. Simultaneously, this sampling gives the value of total flux as the
product of the acceptance ratio times the 3D sample volume times the intensity
maximum.

2. Uniform Monte Carlo sampling, or *wave* generation. This mode is necessary
for wave propagation when it starts right from the source. The 3D calculation
space – energy and two transverse angles – is sampled uniformly. This way of
sampling is still possible to use for ray tracing, and it is even faster at the
source as no samples are rejected, but it is less efficient at the downstream
part of the beamline as a significant part of the samples (or even a majority
of them) is of low intensity. The main usage pattern of this sampling is,
however, for single electron (or *macro electrons*) field propagation (enabled
by the source option *filamentBeam=True*), when all wave samples are attributed
to the same electron with a single displacement within emittance distribution
and a single shift of gamma (relative electron energy) within energy spread
distribution. The flux is a sum of all intensities times the 3D sample volume
over the number of samples.

3. Grid sampling. This is frequently a quick method for studying synchrotron
sources in reciprocal space and energy that must be used with care as it is
full of pitfalls. Grid samples can be obtained by `intensities_on_mesh()`
method of the synchrotron source. Three aspects must be considered when making
a grid. (i) For a sharp field distribution, e.g. for an undulator at zero
emittance and zero electron beam energy spread, the sharp field rings may
interfere with the grid (form moiré patterns) and result in false fringes in
spectral flux density. In such cases, the grid has to be very finely spaced.
(ii) When the electron beam emittance is non-zero, the calculated field values
have to be convolved with the electron beam divergence; this convolution is
done inside `intensities_on_mesh()`. Due to the edge effects of the
convolution, the grid borders of the thickness of the doubled electron beam
divergence must be discarded from the field arrays returned by
`intensities_on_mesh()` and therefore these grid margins have to be added
beforehand. (iii) The number of energy spread samples must be set sufficient
for the used energy spread value, see the end of the next paragraph.

Electron beam energy spread is treated differently in the above three sampling
strategies. In ray sampling, every ray gets its gamma sample (relative electron
energy) of the normal energy spread distribution. In wave sampling, energy
spread is sampled once for all wave samples when in filamentBeam regime and
individually per wave sample otherwise. In grid sampling, a new grid dimension
is introduced internally that contains samples of gamma within energy spread
distribution with subsequent averaging over that dimension. Notice that a wide
energy spread distribution (that can be a case for linacs) may require more
energy spread samples (the parameter *eSpreadNSamples* of
`intensities_on_mesh()`) than the default number 36 that is usually good for
energy spread sigma of 0.1%. Because of this new dimension, the grid may become
too large to fit into RAM, which might force the user to invoke the method
`intensities_on_mesh()` in a loop that scans over individual photon energies.

Electron beam real space size is also treated differently in the above three
sampling strategies. In ray sampling, every ray gets its transverse origin
shift in the source plane within emittance distribution. In wave sampling, the
wave source position is sampled once for all wave samples when in filamentBeam
regime and individually per wave sample otherwise. In grid sampling, real space
electron beam size is totally ignored.

See the example :ref:`Undulator radiation through rectangular aperture
<through-aperture>`, where several calculation methods are compared.

Geometric sources
^^^^^^^^^^^^^^^^^

Module :mod:`~xrt.backends.raycing.sources` defines the container class
:class:`Beam` that holds beam properties as numpy arrays and defines the beam
sources. The sources are geometric sources in continuous and mesh forms and
:ref:`synchrotron sources <own-synchrotron-sources>`.

The intensity and polarization of each ray are determined via coherency matrix.
This way is appropriate for incoherent addition of rays, in which the
components of the coherency matrix of different rays are simply added.

.. autoclass:: Beam
   :members: export_beam, concatenate
.. autoclass:: GeometricSource()
   :members: __init__
.. autoclass:: MeshSource()
   :members: __init__
.. autoclass:: CollimatedMeshSource
.. autoclass:: GaussianBeam
   :members: __init__
.. autoclass:: LaguerreGaussianBeam
   :members: __init__
.. autoclass:: HermiteGaussianBeam
   :members: __init__

.. autofunction:: make_energy
.. autofunction:: make_polarization
.. autofunction:: rotate_coherency_matrix
.. autofunction:: copy_beam
.. autofunction:: shrink_source

.. _own-synchrotron-sources:

Synchrotron sources
^^^^^^^^^^^^^^^^^^^

.. note::

    In this section we consider z-axis to be directed along the beamline in
    order to be compatible with the cited works. Elsewhere in xrt z-axis looks
    upwards.

The synchrotron sources have two implementations: based on own fully pythonic
or OpenCL aided calculations and based on external codes [Urgent]_ and [WS]_.
The latter codes have some drawbacks, as demonstrated in the section
:ref:`comparison-synchrotron-sources`, but nonetheless can be used for
comparison purposes. If you are going to use them, the codes are freely
available as parts of [XOP]_ package.

.. [Urgent] R. P. Walker, B. Diviacco, URGENT, A computer program for
   calculating undulator radiation spectral, angular, polarization and power
   density properties, ST-M-91-12B, July 1991, Presented at 4th Int. Conf. on
   Synchrotron Radiation Instrumentation, Chester, England, Jul 15-19, 1991

.. [WS] R. J. Dejus, Computer simulations of the wiggler spectrum, Nucl.
   Instrum. Methods Phys. Res., Sect. A, **347** (1994) 56-60

.. [XOP] M. Sanchez del Rio, R. J. Dejus, XOP: A Multiplatform Graphical User
   Interface for Synchrotron Radiation Spectral and Optics Calculations,
   SPIE Proc. **3152** (1997) 148; web page:
   http://www.esrf.eu/Instrumentation/software/data-analysis/xop2.3.

The internal synchrotron sources are based on the following works:
[Kim]_ and [Walker]_.
We use the general formulation for the flux distribution in 3-dimensional
phase space (solid angle and energy) [Kim]_:

    .. math::
        \mathcal{F}(\theta,\psi,E) &= \alpha\frac{\Delta \omega}{\omega}
        \frac{I_e}{e^{-}}(A_{\sigma}^2 + A_{\pi}^2)\\

For the bending magnets the amplitudes can be calculated analytically using the
modified Bessel functions :math:`K_v(y)`:

   .. math::
       \begin{bmatrix}
       A_{\sigma}\\
       A_{\pi}
       \end{bmatrix} &= \frac{\sqrt{3}}{2\pi}\gamma\frac{\omega}{\omega_c}
       (1+\gamma^2\psi^2)\begin{bmatrix}-i K_{2/3}(\eta)\\
       \frac{\gamma\psi}{\sqrt{1+\gamma^2\psi^2}}
       K_{1/3}(\eta)\end{bmatrix}

where
   .. math::
       \gamma &= \frac{E_e}{m_{e}c^2} = 1957E_e[{\rm GeV}]\\
       \eta &= \frac{1}{2}\frac{\omega}{\omega_c}(1+\gamma^2\psi^2)^{3/2}\\
       \omega_c &= \frac{3\gamma^{3}c}{2\rho}\\
       \rho &= \frac{m_{e}c\gamma}{e^{-}B}

with :math:`I_e` - the current in the synchrotron ring, :math:`B` - magnetic
field strength, :math:`e^{-}, m_e`- the electron charge and mass,
:math:`c` - the speed of light.

Wiggler radiation relies on the same equation considering each pole as a
bending magnet with variable magnetic field/curvature radius:
:math:`\rho(\theta) = \sin(\arccos(\theta\gamma/K))`, where :math:`K` is
deflection parameter. Total flux is multiplied then by :math:`2N`, where
:math:`N` is the number of wiggler periods.

For the undulator sources the amplitude integrals must be calculated
numerically, starting from the magnetic field.

    .. math::
        \begin{bmatrix}
        A_{\sigma}\\
        A_{\pi}
        \end{bmatrix} &= \frac{1}{2\pi}\int\limits_{-\infty}^{+\infty}dt'
        \begin{bmatrix}\frac{[\textbf{n}\times[(\textbf{n}-
        \boldsymbol{\beta})\times\dot{\boldsymbol{\beta}}]]}
        {(1 - \textbf{n}\cdot\boldsymbol{\beta})^2}\end{bmatrix}_{x, y}
        e^{i\omega (t' + R(t')/c)}

    .. math::
        B_x &= B_{x0}\sin(2\pi z /\lambda_u + \phi),\\
        B_y &= B_{y0}\sin(2\pi z /\lambda_u)

the corresponding velosity components are

    .. math::
        \beta_x &= \frac{K_y}{\gamma}\cos(\omega_u t),\\
        \beta_y &= -\frac{K_x}{\gamma}\cos(\omega_u t + \phi)\\
        \beta_z &= \sqrt{1-\frac{1}{\gamma^2}-\beta_{x}^{2}-\beta_{y}^{2}},

where :math:`\omega_u = 2\pi c /\lambda_u` - undulator frequency,
:math:`\phi` - phase shift between the magnetic field components. In this
simple case one can consider only one period in the integral phase term
replacing the exponential series by a factor
:math:`\frac{\sin(N\pi\omega/\omega_1)}{\sin(\pi\omega/\omega_1)}`, where
:math:`\omega_1 = \frac{2\gamma^2}{1+K_x^2/2+K_y^2/2+\gamma^2(\theta^2+\psi^2)}
\omega_u`.

In the case of tapered undulator, the vertical magnetic field is multiplied by
an additional factor :math:`1 - \alpha z`, that in turn results in modification
of horizontal velocity and coordinate.

In the far-field approximation we consider the undulator as a point source and
replace the distance :math:`R` by a projection
:math:`-\mathbf{n}\cdot\mathbf{r}`, where :math:`\mathbf{n} =
[\theta,\psi,1-\frac{1}{2}(\theta^2+\psi^2)]` - direction to the observation
point, :math:`\mathbf{r} = [\frac{K_y}{\gamma}\sin(\omega_u t'),
-\frac{K_x}{\gamma}\sin(\omega_u t' + \phi)`,
:math:`\beta_m\omega t'-\frac{1}{8\gamma^2}
(K_y^2\sin(2\omega_u t')+K_x^2\sin(2\omega_u t'+2\phi))]` - electron
trajectory, :math:`\beta_m = 1-\frac{1}{2\gamma^2}-\frac{K_x^2}{4\gamma^2}-
\frac{K_y^2}{4\gamma^2}`.

Configurations with non-equivalent undulator periods i.e. tapered undulator
require integration over full undulator length, similar approach is
used for the near field calculations, where the undulator extension is taken
into account and the phase component in the integral is taken in its initial
form :math:`i\omega (t' + R(t')/c)`.

For the custom field configuratiuons, where the magnetic field components
are tabulated as functions of longitudinal coordinate
:math:`\textbf{B}=[B_{x}(z), B_{y}(z), B_{z}(z))]`, preliminary numerical
calculation of the velocity and coordinate is nesessary. For that we solve the
system of differential equations in the trajectory coordinate :math:`s`:

    .. math::
        \frac{d^2}{ds^2}
        \begin{bmatrix}x\\ y\\ z\end{bmatrix} &=
        \frac{e^{-}}{\gamma m_{e} c}
        \begin{bmatrix}\beta_{y}B_{z}-B_{y}\\
        -\beta_{x}B_{z}+B_{x}\\
        -\beta_{y}B_{x}+\beta_{x}B_{y}\end{bmatrix}

using the classical Runge-Kutta fourth-order method.

.. _undulator-grid:

For the Undulator and custom field models we directly calculate the integral
using the `Clenshaw-Curtis quadrature
<https://en.wikipedia.org/wiki/Clenshaw%E2%80%93Curtis_quadrature>`_, it proves
to converge as quickly as the previously used Gauss-Legendre method, but the
nodes and weights are calculated significantly faster. The size
of the integration grid is evaluated at the points of slowest convergence
(highest energy, maximum angular deviation i.e. a corner of the plot) before
the start of intensity map calculation and then applied to all points.
This approach creates certain computational overhead for the on-axis/low energy
parts of the distribution but enables efficient parallelization and gives
significant overall gain in performance. Initial evaluation typically takes
just a few seconds, but might get much longer for custom magnetic fields and
near edge calculations. If such heavy task is repeated many times for the given
angular and energy limits it might make sense to note the evaluated size of
the grid during the first run or call the :meth:`test_convergence` method once,
and then use the fixed grid by defining the *gNodes* at the init.
Note also that the grid size will be automatically re-evaluated if any of the
limits/electron energy/undulator deflection parameter or period length are
redefined dynamically in the script.

Typical convergence threshold is defined by machine precision multiplied by the
size of the integration grid. Default integration parameters proved to work
very well in most cases, but may fail if the angular and/or energy limits are
unreasonably wide. If in doubt, check the convergence
with :meth:`test_convergence`. See also
:ref:`a convergence study <test_undulator>` that justifies our automatic grid
evaluation.

.. _undulator-source-size:

For the purpose of ray tracing (and this is not necessary for wave propagation)
the undulator source size is calculated following [TanakaKitamura]_. Their
formulation includes dependence on electron beam energy spread. The effective
linear and angular source sizes are given by

    .. math::
        \Sigma &= \left(\sigma_e^2 + \sigma_r^2\right)^{1/2}
        =\left(\varepsilon\beta + \frac{\lambda L}{2\pi^2}
        [Q(\sigma_\epsilon/4)]^{4/3}\right)^{1/2}\\
        \Sigma' &= \left({\sigma'_e}^2 + {\sigma'_r}^2\right)^{1/2}
        =\left(\varepsilon/\beta + \frac{\lambda}{2L}
        [Q(\sigma_\epsilon)]^2\right)^{1/2},

where :math:`\varepsilon` and :math:`\beta` are the electron beam emittance and
betatron function, the scaling function :math:`Q` is defined as

    .. math::
        Q(x) = \left(\frac{2x^2}{\exp(-2x^2)+(2\pi)^{1/2}x\ {\rm erf}
        (2^{1/2}x)-1}\right)^{1/2}

(notice :math:`Q(0)=1`) and :math:`\sigma_\epsilon` is the normalized energy
spread

    .. math::
        \sigma_\epsilon = 2\pi nN\sigma_E

i.e. the energy spread :math:`\sigma_E` divided by the undulator bandwidth
:math:`1/nN` of the n-th harmonic, with an extra factor :math:`2\pi`. See an
application example :ref:`here <example-undulator-sizes>`.

.. note::

   If you want to compare the source size with that by [SPECTRA]_, note that
   their radiation source size :math:`\sigma_r` is by a factor of 2 smaller in
   order to be compatible with the traditional formula by [Kim]_. In this
   aspect SPECTRA contradicts to their own paper [TanakaKitamura]_, see the
   paragraph after Eq(23).

.. [Kim] K.-J. Kim, Characteristics of Synchrotron Radiation, AIP Conference
   Proceedings, **184** (AIP, 1989) 565.

.. [Walker] R. Walker, Insertion devices: undulators and wigglers, CAS - CERN
   Accelerator School: Synchrotron Radiation and Free Electron Lasers,
   Grenoble, France, 22-27 Apr 1996: proceedings (CERN. Geneva, 1998) 129-190.

.. [TanakaKitamura] T. Tanaka and H. Kitamura, Universal function for the
   brilliance of undulator radiation considering the energy spread effect,
   J. Synchrotron Rad. **16** (2009) 380–6.

.. autoclass:: UndulatorUrgent()
   :members: __init__
.. autoclass:: WigglerWS()
   :members: __init__
.. autoclass:: BendingMagnetWS()
   :members: __init__

.. autoclass:: SourceBase()
   :members: __init__, real_photon_source_sizes,
             multi_electron_stack, intensities_on_mesh
.. autoclass:: IntegratedSource()
   :members: __init__, test_convergence, shine

.. autoclass:: Undulator()
   :members: __init__, get_SIGMA, get_SIGMAP, power_vs_K, tuning_curves
.. autoclass:: SourceFromField()
   :members: __init__
.. autoclass:: Wiggler()
   :members: __init__
.. autoclass:: BendingMagnet()
   :members: __init__

.. _comparison-synchrotron-sources:

Comparison of synchrotron source codes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. _mesh-methods:

Using xrt synchrotron sources on a mesh
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The main modus operandi of xrt synchrotron sources is to provide Monte Carlo
rays or wave samples. For comparing our sources with other codes – all of them
are fully deterministic, being defined on certain meshes – we also supply mesh
methods such as `intensities_on_mesh`, `power_vs_K` and `tuning_curves`. Note
that we do not provide any internal mesh optimization, as these mesh functions
are not our core objectives. Instead, the user themself should care about the
proper mesh limits and step sizes. In particular, the angular meshes must be
wider than the electron beam divergences in order to convolve the field
distribution with the electron distribution of non-zero emittance. The above
mentioned mesh methods will print a warning (new in version 1.3.4) if the
requested meshes are too narrow.

If you want to calculate flux through a narrow aperture, you first calculate
`intensities_on_mesh` on wide enough angular meshes and then slice the
intensity down to the needed aperture size. An example of such calculations is
given in `tests/raycing/test_undulator_on_mesh.py` which produces the following
plot (for a BESSY undulator, zero energy spread, as Urgent cannot take account
of it):

.. imagezoom:: _images/flux_case3_xrt_UrgentICALC1.png

Undulator spectrum across a harmonic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The above six classes result in ray distributions with the density of rays
proportional to intensity. This requires an algorithm of Monte Carlo ray
sampling that needs a 3D (two directions + energy) intensity distribution. The
classes using the external mesh-based codes interpolate the source intensity
pre-calculated over the user specified mesh. The latter three classes (internal
implementation of synchrotron sources) do not require interpolation, which
eliminates two problems: artefacts of interpolation and the need for the mesh
optimization. However, this requires the calculations of intensity *for each*
ray.

For bending magnet and wiggler sources these calculations are not heavy and
are actually faster than 3D interpolation. See the absence of interpolation
artefacts in :ref:`Synchrotron sources <synchrotron-sources>` in the gallery.

For an undulator the calculations are much more demanding and for a wide
angular acceptance the Monte Carlo ray sampling can be extremely inefficient.
To improve the efficiency, a reasonably small acceptance should be considered.

There are several codes that can calculate undulator spectra: [Urgent]_,
[US]_, [SPECTRA]_. There is a common problem about them that the
energy spectrum may get *strong distortions* if calculated with a sparse
spatial and energy mesh. SPECTRA code seems to provide the best reference for
undulator spectra, which was used to optimize the meshes of the other codes.
The final comparison of the resulted undulator spectra around a single
harmonic is shown below.

.. [US] R. J. Dejus,
   *US: Program to calculate undulator spectra.* Part of XOP.

.. [SPECTRA] T. Tanaka and H. Kitamura, *SPECTRA - a synchrotron radiation
   calculation code*, J. Synchrotron Radiation **8** (2001) 1221-8.

.. note::

    If you are going to use UndulatorUrgent, you should optimize the spatial
    and energy meshes! The resulted ray distribution is strongly dependent on
    them, especially on the energy mesh. Try different numbers of points and
    various energy ranges.

.. imagezoom:: _images/compareUndulators.png

.. _undulator_highE:

Undulator spectrum at very high energies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The codes [Urgent]_ and [SPECTRA]_ result in saturation at high
energies (see the image below) thus leading to a divergent total power
integral. The false radiation has a circular off-axis shape. To the contrary,
xrt and [SRW]_ flux at high energies vanishes and follows the wiggler
approximation. More discussion will follow in a future journal article about
xrt.

.. imagezoom:: _images/flux_BioNanoMAX.png

Single-electron and multi-electron undulator radiation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Here we compare single-electron and multi-electron (i.e. with a finite electron
beam size and energy spread) undulator radiation, as calculated by xrt and
[SRW]_. The calculations are done on a 3D mesh of energy (the long axis on the
images below) and two transverse angles. Notice also the duration of execution
given below each image. The 3D mesh was the following: theta = 321 point, -0.3
to +0.3 mrad, psi = 161 point, -0.15 to +0.15 mrad, energy: 301 point 1.5 to
4.5 keV.

.. [SRW] O. Chubar, P. Elleaume, *Accurate And Efficient Computation Of
   Synchrotron Radiation In The Near Field Region*, proc. of the EPAC98
   Conference, 22-26 June 1998, p.1177-1179.

+-------------+------------------------+------------------------+
|             |         SRW            |           xrt          |
+=============+========================+========================+
|  single     |    |srw_single|        |    |xrt_single|        |
|  electron   +------------------------+------------------------+
|             | execution time 974 s   | execution time 17.4 s  |
+-------------+------------------------+------------------------+
|  non-zero   |    |srw_non0em|        |    |xrt_non0em|        |
|  emittance  +------------------------+------------------------+
|             | execution time 65501 s | execution time 18.6 s  |
|             | (*sic*)                |                        |
+-------------+------------------------+------------------------+
|  non-zero   |   |srw_non0emsp|       |   |xrt_non0emsp|       |
|  emittance, +------------------------+------------------------+
|  non-zero   | execution time 66180 s | execution time 216 s   |
|  energy     | (*sic*)                |                        |
|  spread     |                        |                        |
+-------------+------------------------+------------------------+

.. |srw_single| imagezoom:: _images/mayavi_0em_2srw.png
.. |srw_non0em| imagezoom:: _images/mayavi_non0em_2srw.png
.. |srw_non0emsp| imagezoom:: _images/mayavi_non0em_non0spread_2srw.png
.. |xrt_single| imagezoom:: _images/mayavi_0em_3xrt.png
   :loc: upper-right-corner
.. |xrt_non0em| imagezoom:: _images/mayavi_non0em_3xrt.png
   :loc: upper-right-corner
.. |xrt_non0emsp| imagezoom:: _images/mayavi_non0em_non0spread_3xrt.png
   :loc: upper-right-corner

.. _tapering_comparison:

Undulator spectrum with tapering
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The spectrum can be broadened by tapering the magnetic gap. The figure below
shows a comparison of xrt with [SPECTRA]_, [YAUP]_ and
experimental measurements [exp_taper]_. The gap values and the taper were
slightly varied in all three codes to reach the best match with the
experimental curve. We had to do so because in the other codes taper is not
clearly defined (where is the gap invariant -- at the center or at one of the
ends?) and also because the nominal experimental gap and taper are not fully
trustful.

.. [YAUP] B. I. Boyanov, G. Bunker, J. M. Lee, and T. I. Morrison, *Numerical
   Modeling of Tapered Undulators*, Nucl. Instr. Meth. **A339** (1994) 596-603.

.. [exp_taper] Measured on 27 Nov 2013 on P06 beamline at Petra 3,
   R. Chernikov and O. Müller, unpublished.

The source code is in ``examples\withRaycing\01_SynchrotronSources``

.. imagezoom:: _images/compareTaper.png

Notice that not only the band width is affected by tapering. Also the
transverse distribution attains inhomogeneity which varies with energy, see the
animation below. Notice also that such a picture is sensitive to emittance; the
one below was calculated for the emittance of Petra III ring.

.. imagezoom:: _images/taperingEnergyScan

Undulator spectrum in transverse plane
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The codes calculating undulator spectra -- [Urgent]_, [US]_, [SPECTRA]_ --
calculate either the spectrum of flux through a given aperture *or* the
transversal distribution at a fixed energy. It is not possible to
simultaneously have two dependencies: on energy *and* on transversal
coordinates.

Whereas xrt gives equal results to other codes in such univariate
distributions as flux through an aperture:

.. imagezoom:: _images/compareFlux.png

... and transversal distribution at a fixed energy:

+----------------+--------------------+--------------------+
|                |       SPECTRA      |        xrt         |
+================+====================+====================+
| *E* = 4850 eV  |                    |                    |
| (3rd harmonic) |   |spectra_lowE|   |     |xrt_lowE|     |
+----------------+--------------------+--------------------+
| *E* = 11350 eV |                    |                    |
| (7th harmonic) |   |spectra_highE|  |    |xrt_highE|     |
+----------------+--------------------+--------------------+

.. |spectra_lowE| imagezoom:: _images/undulator-E=04850eV-spectra.*
.. |spectra_highE| imagezoom:: _images/undulator-E=11350eV-spectra.*
.. |xrt_lowE| imagezoom:: _images/undulator-E=04850eV-xrt.*
   :loc: upper-right-corner
.. |xrt_highE| imagezoom:: _images/undulator-E=11350eV-xrt.*
   :loc: upper-right-corner

..., xrt can combine the two distributions in one image and thus be more
informative:

+----------------+-------------------+--------------------+
|                |      zoom in      |      zoom out      |
+================+===================+====================+
| *E* ≈ 4850 eV  |                   |                    |
| (3rd harmonic) |      |xrtLo|      |      |xrtLo5|      |
+----------------+-------------------+--------------------+
| *E* ≈ 11350 eV |                   |                    |
| (7th harmonic) |      |xrtHi|      |      |xrtHi5|      |
+----------------+-------------------+--------------------+

.. |xrtLo| imagezoom:: _images/oneHarmonic-E=04850eV-xrt.*
.. |xrtHi| imagezoom:: _images/oneHarmonic-E=11350eV-xrt.*
.. |xrtLo5| imagezoom:: _images/oneHarmonic-E=04850eV-xrt_x5.*
   :loc: upper-right-corner
.. |xrtHi5| imagezoom:: _images/oneHarmonic-E=11350eV-xrt_x5.*
   :loc: upper-right-corner

In particular, it is seen that divergence strongly depends on energy, even for
such a narrow energy band within one harmonic. It is also seen that the maximum
flux corresponds to slightly off-axis radiation (greenish color) but not to the
on-axis radiation (bluish color).

.. _near_field_comparison:

Undulator radiation in near field
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Notice that on the following pictures the p-polarized flux is only ~6% of the
total flux.

+------------------------+--------------------+--------------------+
|  at 5 m                |      SPECTRA       |         xrt        |
+========================+====================+====================+
|   far field at 5 m,    |                    |                    |
|   full flux            |  |spectra_f05m0|   |    |xrt_f05m0|     |
+------------------------+--------------------+--------------------+
|   far field at 5 m,    |                    |                    |
|   p-polarized          |  |spectra_f05mP|   |    |xrt_f05mP|     |
+------------------------+--------------------+--------------------+
|   near field at 5 m,   |                    |                    |
|   full flux            |  |spectra_n05m0|   |    |xrt_n05m0|     |
+------------------------+--------------------+--------------------+
|   near field at 5 m,   |                    |                    |
|   p-polarized          |  |spectra_n05mP|   |    |xrt_n05mP|     |
+------------------------+--------------------+--------------------+

.. |spectra_f05m0| imagezoom:: _images/spectra-05m-far.png
.. |spectra_f05mP| imagezoom:: _images/spectra-05m-far_p.png
.. |spectra_n05m0| imagezoom:: _images/spectra-05m-near.png
.. |spectra_n05mP| imagezoom:: _images/spectra-05m-near_p.png

.. |xrt_f05m0| imagezoom:: _images/xrt-far05m1TotalFlux-rays.png
   :loc: upper-right-corner
.. |xrt_f05mP| imagezoom:: _images/xrt-far05m3vertFlux-rays.png
   :loc: upper-right-corner
.. |xrt_n05m0| imagezoom:: _images/xrt-near05m1TotalFlux-rays.png
   :loc: upper-right-corner
.. |xrt_n05mP| imagezoom:: _images/xrt-near05m3vertFlux-rays.png
   :loc: upper-right-corner

+------------------------+--------------------+--------------------+
|  at 25 m               |      SPECTRA       |         xrt        |
+========================+====================+====================+
|   far field at 25 m,   |                    |                    |
|   full flux            |  |spectra_f25m0|   |    |xrt_f25m0|     |
+------------------------+--------------------+--------------------+
|   far field at 25 m,   |                    |                    |
|   p-polarized          |  |spectra_f25mP|   |    |xrt_f25mP|     |
+------------------------+--------------------+--------------------+
|   near field at 25 m   |                    |                    |
|   full flux            |  |spectra_n25m0|   |    |xrt_n25m0|     |
+------------------------+--------------------+--------------------+
|   near field at 25 m,  |                    |                    |
|   p-polarized          |  |spectra_n25mP|   |    |xrt_n25mP|     |
+------------------------+--------------------+--------------------+

.. |spectra_f25m0| imagezoom:: _images/spectra-25m-far.png
.. |spectra_f25mP| imagezoom:: _images/spectra-25m-far_p.png
.. |spectra_n25m0| imagezoom:: _images/spectra-25m-near.png
.. |spectra_n25mP| imagezoom:: _images/spectra-25m-near_p.png

.. |xrt_f25m0| imagezoom:: _images/xrt-far25m1TotalFlux-rays.png
   :loc: upper-right-corner
.. |xrt_f25mP| imagezoom:: _images/xrt-far25m3vertFlux-rays.png
   :loc: upper-right-corner
.. |xrt_n25m0| imagezoom:: _images/xrt-near25m1TotalFlux-rays.png
   :loc: upper-right-corner
.. |xrt_n25mP| imagezoom:: _images/xrt-near25m3vertFlux-rays.png
   :loc: upper-right-corner

Field phase in near field
~~~~~~~~~~~~~~~~~~~~~~~~~

The phase of the radiation field on a flat screen as calculated by the three
codes is compared below. Notice that the visualization (brightness=intensity,
color=phase) is not by SRW and SPECTRA but was done by us.

+--------------------+--------------------+--------------------+
|     SRW [SRW]_     |      SPECTRA       |         xrt        |
+====================+====================+====================+
|      |srw_ps|      |    |spectra_ps|    |      |xrt_ps|      |
+--------------------+--------------------+--------------------+
|      |srw_pp|      |    |spectra_pp|    |      |xrt_pp|      |
+--------------------+--------------------+--------------------+

.. |srw_ps| imagezoom:: _images/phase_SRWres-0em-05m_s.png
.. |srw_pp| imagezoom:: _images/phase_SRWres-0em-05m_p.png
.. |spectra_ps| imagezoom:: _images/phase_spectra-near5-0em-field_s.png
.. |spectra_pp| imagezoom:: _images/phase_spectra-near5-0em-field_p.png
.. |xrt_ps| imagezoom:: _images/phase_xrt-near05m1horFlux-wave-filament.png
   :loc: upper-right-corner
.. |xrt_pp| imagezoom:: _images/phase_xrt-near05m3verFlux-wave-filament.png
   :loc: upper-right-corner

.. _example-undulator-sizes:

Undulator source size dependent on energy spread and detuning
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The linear and angular source sizes, as calculated with equations from
[TanakaKitamura]_ (summarized :ref:`here <undulator-source-size>`) for a
U19 undulator in MAX IV 3 GeV ring (:math:`E_1` = 1429 eV) with
:math:`\varepsilon_x` = 263 pmrad, :math:`\varepsilon_y` = 8 pmrad,
:math:`\beta_x` = 9 m and :math:`\beta_y` = 2 m, are shown below. Energy
spread mainly affects the angular sizes and not the linear ones.

The calculated sizes were further compared with those of the sampled field
(circles) at variable energies around the nominal harmonic positions, i.e. at
so called undulator detuning. To get the photon source size distribution, the
angular distributions of Es and Ep field amplitudes were Fourier transformed,
as described in [Coïsson]_. The sampled field sizes strongly vary due to
undulator detuning, as is better seen on the magnified insets. The size
variation by detuning is the underlying reason for the size dependence on
energy spread: with a non-zero energy spread the undulator becomes effectively
detuned for some electrons depending on their velocity.

The size of the circles is proportional to the total flux normalized to the
maximum at each respective harmonic. It sharply decreases at the higher energy
end of a harmonic and has a long tail at the lower energy end, in accordance
with the above examples.

The effect of energy detuning from the nominal undulator harmonic energy on the
photon source size is compared to the results by Coïsson [Coïsson]_ (crosses in
the figures below). He calculated the sizes for a single electron field, and
thus without emittance and energy spread. For comparison, we also sampled the
undulator field at zero energy spread and emittance.

.. imagezoom:: _images/undulatorLinearSize.png
.. imagezoom:: _images/undulatorAngularSize.png

.. [Coïsson] R. Coïsson, Effective phase space widths of undulator radiation,
   Opt. Eng. **27** (1988) 250–2.

"""
__author__ = "Konstantin Klementiev", "Roman Chernikov"
__all__ = ('GeometricSource', 'MeshSource', 'BendingMagnet', 'Wiggler',
           'Undulator')

from .sources_beams import Beam, BeamProxy,\
    copy_beam, rotate_coherency_matrix, defaultEnergy
from .sources_geoms import GeometricSource, MeshSource, NESWSource,\
    CollimatedMeshSource, shrink_source, make_energy, make_polarization,\
    GaussianBeam, LaguerreGaussianBeam, HermiteGaussianBeam
from .sources_legacy import UndulatorUrgent, WigglerWS, BendingMagnetWS,\
    UndulatorSRW, SourceFromFieldSRW
from .sources_synchr import BendingMagnet, Wiggler, Undulator, SourceFromField
from .sources_sybase import SourceBase, IntegratedSource