xoppylib.sources package

Submodules

xoppylib.sources.calc2d_kim module

Power density calculations and total power on slit after Kim (1989)

Main routines: calc2d_kim: Power density on a slit from an insertion device (Kim 1989 analytical). id_power_on_slit: total power [W] through a slit from an insertion device.

Implements Kim (1989) directly:

Angular power density (Eq. 4.61):

d2P/dOmega(phi, psi) = (d2P/dOmega)|_0 * fK(gamma*phi, gamma*psi)

On-axis density, practical units (after Eq. 4.63):

(d2P/dOmega)|_0 [W/mrad^2] = 10.84 * B0[T] * E^4[GeV] * I[A] * N * G(K)

(the factor 2N and the interference factor G(K) are already contained here:

10.84 = 2 * 5.42, and N and G(K) appear explicitly).

Normalized angular function (Eq. 4.62), valid for ANY K:
fK(g*phi, g*psi) = 16K/(7*pi*G(K)) * INT_{-pi}^{pi} dxi

sin^2(xi)/D^5 * [ (1+X^2-Y^2)^2 + 4 X^2 Y^2 ]

X = gamma*psi, Y = K*cos(xi) - gamma*phi, D = 1 + X^2 + Y^2

fK is normalized so fK(0,0) = 1.

Interference factor (Eq. 4.60):

G(K) = K*(K^6 + (24/7)K^4 + 4K^2 + 16/7) / (1+K^2)^(7/2) -> 1 for K>>1

Power through the slit is the on-axis density times the integral of fK over the angular window subtended by the slit (the integral is carried out in mrad so it matches the W/mrad^2 units of the on-axis density):

P = (d2P/dOmega)|_0 * INT INT fK(gamma*phi, gamma*psi) d(phi) d(psi)

The slit at distance D subtends:

phi in [-w_h/(2D), +w_h/(2D)] horizontal [rad] psi in [-w_v/(2D), +w_v/(2D)] vertical [rad]

No bending-magnet approximation and no separate 2N*G(K) multiplication are needed: the full fK already carries the correct horizontal and vertical angle dependence, and 2N*G(K) lives in the on-axis density.

References

K.-J. Kim, AIP Conf. Proc. 184, 565 (1989). Eqs. 4.60-4.63, 4.66

https://doi.org/10.1063/1.38046

xoppylib.sources.calc2d_kim.G_K(K)[source]

Interference factor G(K), Kim (1989) eq. (4.60).

G(K) = K * [K^6 + (24/7)K^4 + 4K^2 + 16/7] / (1 + K^2)^(7/2)

G(K) -> 1 for K >> 1 (pure wiggler limit); G(K) < 1 at moderate K.

xoppylib.sources.calc2d_kim.calc2d_kim(bl, zero_emittance=False, fileName=None, fileAppend=False, hSlitPoints=21, vSlitPoints=51, n_xi=256)[source]

Power density on a slit from an insertion device (Kim 1989 analytical).

input: a dictionary ‘bl’ with the beamline (same keys as calc2d_urgent) output: (hhh, vvv, int_mesh2)

hhh [mm] horizontal coordinates, length 2*hSlitPoints-1 vvv [mm] vertical coordinates, length 2*vSlitPoints-1 int_mesh2 [W/mm^2] power density map (and, if fileName is given, a SPEC file is written/appended)

xoppylib.sources.calc2d_kim.fK(gamma_phi, gamma_psi, K, GK=None, n_xi=512)[source]

Normalized angular power function fK(gamma*phi, gamma*psi), Kim eq. (4.62).

Parameters:
  • gamma_phi (array_like gamma * phi (phi = horizontal angle [rad])) –

  • gamma_psi (array_like gamma * psi (psi = vertical angle [rad])) – must broadcast against gamma_phi

  • K (float deflection parameter) –

  • GK (float precomputed G(K) (optional)) –

  • n_xi (int phase-integration points over xi in [-pi, pi]) –

Returns:

fK

Return type:

ndarray dimensionless, with fK(0,0) = 1

xoppylib.sources.calc2d_kim.id_power_on_slit(K=1.6563, period_m=0.018, n_periods=111, energy_GeV=6.0, current=0.2, slit_h_mm=1.8, slit_v_mm=1.0, distance=23.0, n_phi=101, n_psi=101)[source]

Total power [W] through a rectangular slit from an insertion device, using Kim (1989) eqs. (4.60), (4.62), (4.63).

Parameters:
  • K (float deflection parameter) –

  • period_m (float undulator period [m]) –

  • n_periods (int number of periods N) –

  • energy_GeV (float electron beam energy [GeV]) –

  • current (float beam current [A]) –

  • slit_h_mm (float slit horizontal full width [mm]) –

  • slit_v_mm (float slit vertical full height [mm]) –

  • distance (float source-to-slit distance [m]) –

  • n_phi (int horizontal angle grid points) –

  • n_psi (int vertical angle grid points) –

Returns:

power

Return type:

float [W]

xoppylib.sources.calc2d_kim.on_axis_density(K, period_m, n_periods, energy_GeV, current, B0_T=None)[source]

Forward power density (d2P/dOmega)|_0 in W/mrad^2, Kim eq. (4.63):

(d2P/dOmega)|_0 = 10.84 * B0 * E^4 * I * N * G(K) [W/mrad^2]

xoppylib.sources.parse_urgent module

Parsing utilities for URGENT binary output files.

xoppylib.sources.parse_urgent.parse_urgent_2d_from_harmonics(filepath, flag_full_grid=True)[source]

Parse an URGENT .out file into numpy arrays.

Returns:

  • harmonics (list[int] e.g. [1, 2, …, 20] or [10])

  • POWER_DENSITY (ndarray (H, nX, nY) W/mm² or W/mrad²)

  • ENERGY (ndarray (H, nX, nY) eV (NaN for summed block))

  • FLUX (ndarray (H, nX, nY) ph/s/0.1%BW)

  • X_grid (ndarray (nX, nY) mm)

  • Y_grid (ndarray (nX, nY) mm)

xoppylib.sources.srundplug module

xoppylib.sources.urgentpy_power_density_from_harmonics module

Calculation of the power density for the individual harmonics.

Exact implementation like in the URGENT code: Walker & Diviacco, Rev. Sci. Instrum. 63, 392 (1992)

PLANE UNDULATOR (Kx=0), Section VI Power Density.

Amplitude (from paper, Kx=0):
A = xi * ( 2*alpha_x*S0 - Ky*(S1 + S_minus1),

2*alpha_y*S0, 0 )

S_q = sum_{p} J_p(Y) * J_{2p+q+n}(X) q = 0, +1, -1 xi = n / (1 + Ky^2/2 + alpha^2) X = 2 * xi * alpha_x * Ky (alpha_x = gamma * theta_x) Y = xi * Ky^2 / 4

Power density (Walker 1992, Section VI):
Integrate d²I/dw dΩ over frequency:

integral L(Δω/ω₁) dω = N · ω₁ [N in NUMERATOR] ω₁ = 4πcγ² / (λ₀ · denom)

=>

dI/dΩ = (e · γ⁴ · Ib · N) / (ε₀ · λ₀) · |An|² / denom [W/rad²]

p_max RULE (adaptive):

The Bessel sums converge once |J_p(Y)| and |J_{2p+n}(X)| are negligible. X is maximised at alpha = sqrt(1 + Ky²/2), giving X_max = n·Ky/sqrt(1+Ky²/2). Safe rule (error < 1e-12):

p_max(n, K) = ceil( n · (K/sqrt(1+K²/2) + 1) / 2 ) + 3

For K=1.358: p_max = 4, 5, 6, 7, 8 … for n = 1, 2, 3, 4, 5 … Using a fixed p_max=20 wastes ~40% CPU for typical K and low harmonics.

xoppylib.sources.urgentpy_power_density_from_harmonics.harmonic_energy(n, K, period_m, gamma)[source]

Resonant photon energy [eV] for harmonic n on-axis.

xoppylib.sources.urgentpy_power_density_from_harmonics.power_density_all_harmonics(Ky, N_periods, period_m, gamma, current_A, theta_x_rad, theta_y_rad, n_harmonics=200, p_max=None, sigma_x=0.0, sigma_y=0.0, sigma_xp=0.0, sigma_yp=0.0, distance_m=1.0, zero_emittance=True)[source]

Sum power density [W/rad²] over harmonics 1 … n_harmonics.

Optional Gaussian emittance convolution (angular broadening only):

use_emittance : flag, to do convolution sigma_x, sigma_y : rms beam sizes [m] sigma_xp, sigma_yp : rms beam divergences [rad] distance_m : source-to-screen distance [m]

xoppylib.sources.urgentpy_power_density_from_harmonics.power_density_harmonic(n, Ky, N_periods, period_m, gamma, current_A, theta_x_rad, theta_y_rad, p_max=None)[source]

Power density [W/rad²] for harmonic n of a plane undulator.

Walker & Diviacco, Rev. Sci. Instrum. 63, 392 (1992), Section VI.

Parameters:

p_max (int or None) – Bessel sum truncation. None (default) uses the adaptive rule and is recommended. A fixed p_max=20 is always valid but up to 4× slower.

xoppylib.sources.urgentpy_spectrum module

urgent_spectrum.py — URGENT Fortran faithful Python translation Walker & Diviacco, Rev. Sci. Instrum. 63, 392 (1992).

Two modes, matching the two Fortran paths:

zero_emittance=True → SUB4/ICALC=3 : RAD0 = F3 · |An|² · SINC at slit grid zero_emittance=False → SUB2/ICALC=1 : infinite-N envelope + sinc² convolution

Grid convention (both modes):

np.outer(x_mm, np.ones(NYP)) → shape (NXP, NYP), axis-0 = X = Fortran IB-loop np.outer(np.ones(NXP), y_mm) → shape (NXP, NYP), axis-1 = Y = Fortran IC-loop W2d = np.outer(Wx, Wy) with the same (NXP, NYP) layout.

Convolution (emittance mode):

Fortran: F(I) = sum_{J=1}^{NW} G(I + NE1 - J) * H(J) * DW (1-indexed) Python: F[i] = sum_{j=0}^{NW-1} G[i + NE1_py - j] * H[j] * DW (0-indexed) where NE1_py = NOMEGA//2 (= Fortran NE1 - 1).

xoppylib.sources.urgentpy_spectrum.calc1d_urgentpy(bl, photonEnergyMin=1000.0, photonEnergyMax=100000.0, photonEnergyPoints=500, n_harmonics=None, hSlitPoints=50, vSlitPoints=50, zero_emittance=False, fileName='', fileAppend=False, verbose=True)[source]

Undulator spectral flux [ph/s/0.1%bw] through a rectangular slit. Faithful Python translation of URGENT Fortran (Walker & Diviacco 1992).

Parameters:
  • bl (dict) – ElectronEnergy [GeV] ElectronCurrent [A] ElectronBeamSizeH/V [m] rms ElectronBeamDivergenceH/V [rad] rms PeriodID [m] NPeriods int Kv deflection parameter Ky distance [m] gapH, gapV [m] full aperture

  • photonEnergyMin/Max (float [eV]) –

  • photonEnergyPoints (int) –

  • n_harmonics (int or None (None → auto)) –

  • hSlitPoints (int) – Number of slit integration intervals (Fortran NXP/NYP input). NXP_points = hSlitPoints+1, DXP = gapH/2 / hSlitPoints. Default 50 matches the Fortran example (NXP=50).

  • vSlitPoints (int) – Number of slit integration intervals (Fortran NXP/NYP input). NXP_points = hSlitPoints+1, DXP = gapH/2 / hSlitPoints. Default 50 matches the Fortran example (NXP=50).

  • zero_emittance (bool) –

  • verbose (bool) –

Returns:

  • eArray (ndarray [eV])

  • fluxArray (ndarray [ph/s/0.1%bw])

xoppylib.sources.urgentpy_spectrum.harmonic_energy(n, K, period_m, gamma)[source]

xoppylib.sources.xoppy_bm_wiggler module

XOPPY bending magnet and wiggler radiation spectrum and power calculations.

xoppylib.sources.xoppy_bm_wiggler.create_magnetic_field_for_bending_magnet(do_plot=False, filename='', B0=-1.0, divergence=0.001, radius=10.0, npoints=500)[source]
xoppylib.sources.xoppy_bm_wiggler.crossings_nonzero_all(data)[source]
xoppylib.sources.xoppy_bm_wiggler.get_fwhm(histogram, bins, ret0=None)[source]
xoppylib.sources.xoppy_bm_wiggler.interpolate_multivalued_function(divX, intensity, divX_i, s)[source]
xoppylib.sources.xoppy_bm_wiggler.trapezoidal_rule_2d_1darrays(data2D, h=None, v=None)[source]
xoppylib.sources.xoppy_bm_wiggler.xoppy_calc_bm(MACHINE_NAME='ESRF bending magnet', RB_CHOICE=0, MACHINE_R_M=25.0, BFIELD_T=0.8, BEAM_ENERGY_GEV=6.04, CURRENT_A=0.1, HOR_DIV_MRAD=1.0, VER_DIV=0, PHOT_ENERGY_MIN=100.0, PHOT_ENERGY_MAX=100000.0, NPOINTS=500, LOG_CHOICE=1, PSI_MRAD_PLOT=1.0, PSI_MIN=-1.0, PSI_MAX=1.0, PSI_NPOINTS=500, TYPE_CALC=0, FILE_DUMP=0)[source]
xoppylib.sources.xoppy_bm_wiggler.xoppy_calc_wigg(FIELD=0, NPERIODS=12, ULAMBDA=0.125, K=14.0, ENERGY=6.04, PHOT_ENERGY_MIN=100.0, PHOT_ENERGY_MAX=100100.0, NPOINTS=100, NTRAJPOINTS=101, CURRENT=200.0, FILE='?', outFileTraj='xwiggler_traj.spec', outFile='xwiggler.spec')[source]
xoppylib.sources.xoppy_bm_wiggler.xoppy_calc_wiggler_on_aperture(FIELD=0, NPERIODS=12, ULAMBDA=0.125, K=14.0, ENERGY=6.04, PHOT_ENERGY_MIN=100.0, PHOT_ENERGY_MAX=100100.0, NPOINTS=100, NTRAJPOINTS=101, CURRENT=200.0, FILE='?', SLIT_FLAG=0, SLIT_D=30.0, SLIT_NY=100, SLIT_WIDTH_H_MM=1.0, SLIT_HEIGHT_V_MM=1.0, SLIT_CENTER_H_MM=0.0, SLIT_CENTER_V_MM=0.0, SHIFT_X_FLAG=0, SHIFT_X_VALUE=0.0, SHIFT_BETAX_FLAG=0, SHIFT_BETAX_VALUE=0.0, TRAJ_RESAMPLING_FACTOR=10000.0, SLIT_POINTS_FACTOR=1, outFileTraj='xwiggler_traj.spec', outFile='xwiggler.spec')[source]
xoppylib.sources.xoppy_bm_wiggler.xoppy_calc_wiggler_radiation(ELECTRONENERGY=3.0, ELECTRONCURRENT=0.1, PERIODID=0.12, NPERIODS=37.0, KV=22.416, DISTANCE=30.0, HSLITPOINTS=500, VSLITPOINTS=500, PHOTONENERGYMIN=100.0, PHOTONENERGYMAX=100100.0, PHOTONENERGYPOINTS=101, NTRAJPOINTS=1001, FIELD=0, FILE='/Users/srio/Oasys/Bsin.txt', POLARIZATION=0, SHIFT_X_FLAG=0, SHIFT_X_VALUE=0.0, SHIFT_BETAX_FLAG=0, SHIFT_BETAX_VALUE=0.0, CONVOLUTION=1, PASSEPARTOUT=3.0, h5_file='wiggler_radiation.h5', h5_entry_name='XOPPY_RADIATION', h5_initialize=True, h5_parameters=None, do_plot=False)[source]

xoppylib.sources.xoppy_calc_black_body module

XOPPY black body radiation spectrum calculator.

xoppylib.sources.xoppy_calc_black_body.xoppy_calc_black_body(TITLE='Thermal source: Planck distribution', TEMPERATURE=1200000.0, E_MIN=10.0, E_MAX=1000.0, NPOINTS=500)[source]

xoppylib.sources.xoppy_calc_tcpy module

xoppylib.sources.xoppy_calc_tcpy.xoppy_calc_tcpy(ENERGY=7.0, CURRENT=100.0, ENERGY_SPREAD=0.00096, SIGX=0.274, SIGY=0.011, SIGX1=0.0113, SIGY1=0.0036, PERIOD=3.23, NP=70, EMIN=2950.0, EMAX=13500.0, N=40, HARMONIC_FROM=1, HARMONIC_TO=15, HARMONIC_STEP=2, HELICAL=0, METHOD=1, NEKS=100, output_file='tcpy.out', verbose=True)[source]

Pure python version of xoppylib.xoppy_run_binaries.xoppy_calc_xtc (TC: undulator on-axis brilliance tuning curves, infinite-N method with convolution). Returns (data, harmonics_data) with the same structure: data is the stack of all rows [E_no_emittance, E_peak, Brilliance, Ky, Ptot, Pd], and harmonics_data is a list of [harmonic_number, rows-of-that-harmonic].

xoppylib.sources.xoppy_calc_wspy module

xoppylib.sources.xoppy_calc_wspy.xoppy_calc_wspy(ENERGY=7.0, CUR=100.0, PERIOD=8.5, N=28.0, KX=0.0, KY=8.74, EMIN=1000.0, EMAX=100000.0, NEE=2000, D=30.0, XPC=0.0, YPC=0.0, XPS=2.0, YPS=2.0, NXP=10, NYP=10, output_file='wspy.spec', verbose=True, return_file=True)[source]

Pure python version of xoppylib.xoppy_run_binaries.xoppy_calc_ws (WS in MODE=4: flux spectrum through a pinhole).

Returns the name of the written spec file with 4 columns: Energy(eV), Flux(photons/s/0.1%bw), Spectral power(W/eV), Cumulated power(W)

xoppylib.sources.xoppy_undulators module

Module contents