Open yangfg-bsrf opened 2 years ago
I guess you assume something about all these objects. And what you assume I certainly don't know. Please explain what you want to achieve by each of these methods.
This is the field for single electron case. I want to confirm the fields are same for the coherence analysis as suggested
The input for the analysis functions is a 3D stack of field images. It can be obtained directly from the undulator class, or from a plot object after several repeats of wave propagation of a filament beam through a beamline. Examples can be found in ...\tests\raycing\test_coherent_fraction_stack.py and in SoftiMAX at MAX IV.
But the method followingtest_coherent_fraction_stack.py
gives result that I can not explain.
I guess you assume something about all these objects. And what you assume I certainly don't know. Please explain what you want to achieve by each of these methods. I just followed the example
test_coherent_fraction_stack.py
still don't know what you want. Let's go over the three methods.
multi_electron_stack()
It gives a stack of single electron field maps, each one with its own shift in angle, position and e-beam energy. What is "phase" in this case that you plot?
still don't know what you want. Let's go over the three methods.
multi_electron_stack()
It gives a stick of single electron field maps, each one with its own shift in angle, position and e-beam energy. What is "phase" in this case that you plot?
Yes, I select one electron. it is calculated by Es, Ep = und.multi_electron_stack(energy, theta, psi) Es0 = Es[0,:,:] phase = np.angle(Es0)
Yes, one slice from the stack gives a one-electron image, and then phase makes sense.
We go to the 2nd example. shine()
gives samples of the radiation field. Unless you specify filamentBeam=True
in the kwargs of Undulator()
, these samples collectively belong to different electrons, which is ok for ray-tracing but not ok for wave propagation. The wave
object in the shine()
method, if it is given, specifies coordinates where you want to calculate these samples. The presence of wave
does not tell that you calculate a one-electron field. What was your intent here and what is in kwargs_SR
?
yes, the previous calculation filamentBeam=False
, for the True case, the result is shown as:
the phase for the one-electron field is more reasonable for the 2nd method. but their phase are still different, but the intensity distribution show no difference.
The intent of this work is to perform the coherence analysis on the Es / Ep using the multi_electron_stack,
and I want to check Es,Ep
by a different way.
I post the code below.
import os, sys; sys.path.append(os.path.join('..', '..')) # analysis:ignore
import numpy as np
import time, cmath
import matplotlib.pyplot as plt
# import matplotlib as mpl
# mpl.use('Agg')
import xrt.backends.raycing.sources as rs
import xrt.backends.raycing.coherence as rco
import xrt.backends.raycing as raycing
import xrt.backends.raycing.screens as rsc
import xrt.backends.raycing.run as rr
import xrt.plotter as xrtp
import xrt.runner as xrtr
from xrt.backends.raycing.physconsts import E0, C, M0, EV2ERG, K2B, SIE0, EMC,\
SIM0, FINE_STR, PI, PI2, SQ3, E2W, E2WC, CHeVcm
"""系统参数"""
accept_ang_x, accept_ang_z = 20e-6, 20e-6
binsx, binsz = 256, 256
repeats = 1 # "macro-electrons"
E0, n0 = 10000, 1 # 插入间工作能量点,及谐波级次
nrays= 2e5
p = 25000
n1 = 1 # 待分析谐波的能量点
# what = 'rays'
what = 'hybrid'
""" 光源 """
if True:
E1 = E0/n0*n1 # 待分析的能量点
if what == 'rays':
uniformRayDensity = False
filamentBeam = False
isMono = False
prefix = 'rays-'
else:
uniformRayDensity = True
filamentBeam = True
isMono = True
prefix = 'hybr-'
dE = E1*0.001/2
eMin0, eMax0 = E1-dE, E1+dE
kwargs_SR = dict(
center = [0, 0, 0],
eE = 6.0, eI = 0.2, eEspread = 0.00111*0,
eEpsilonX = 0.02728*0, eEpsilonZ = 0.002728*0,
# betaX = 10.12, betaZ = 9.64,
betaX = 2.83871, betaZ = 1.91667,
xPrimeMax = accept_ang_x, zPrimeMax = accept_ang_z,
xPrimeMaxAutoReduce = False, zPrimeMaxAutoReduce = False,
targetE = [E0, n0],
eMin = eMin0, eMax = eMax0,
uniformRayDensity = uniformRayDensity,
filamentBeam = filamentBeam,
period=16.8,n=176,
# R0=p,
# period=35,n=142,
K = r"auto")
und = rs.Undulator(**kwargs_SR)
thetaMax, psiMax = accept_ang_x, accept_ang_z # rad
theta = np.linspace(-thetaMax, thetaMax, binsx)
psi = np.linspace(-psiMax, psiMax, binsz)
energy = np.ones(repeats) * E1
Es, Ep = und.multi_electron_stack(energy, theta, psi)
harmonic = n1
if und.eEspread > 1e-12:
ses = '{0:.1e}'.format(und.eEspread)
ses = ses[:-2] + ses[-1] # removes "0" from power
else:
ses = '0'
st = 'st' if harmonic == 1 else 'nd' if harmonic == 2 else 'rd'\
if harmonic == 3 else 'th'
txt = '{0}{1} harmonic ({2:.0f} eV){5}{3} energy spread{5}' +\
'$\\epsilon_x$ = {4:.0f} pmrad + $\\epsilon_z$ = {6:.0f} pmrad'
cap = txt.format(harmonic, st, E1, ses, und.eEpsilonX*1e9, ', ', und.eEpsilonZ*1e9)
baseName = 'h{0:02d}-esp{1}-emx{2:04.0f}--emz{3:04.0f}'.format(
harmonic, und.eEspread, und.eEpsilonX*1e9, und.eEpsilonZ*1e9)
Es, Ep = und.multi_electron_stack(energy, theta, psi)
print("Es.shape", Es.shape)
Es0 = Es[0,:,:]
phase = np.angle(Es0)
plt.figure(8)
plt.subplot(1,2,1)
plt.imshow(phase)
plt.title('phase of the wavefront by the multi_electron_stack')
plt.subplot(1,2,2)
plt.title('Intensity by the multi_electron_stack')
plt.imshow(np.abs(Es0)**2)
plt.show()
#********The field generated by the shine method************
#***************************************
nrays = 5e5
beamLine = raycing.BeamLine()
beamLine.source = rs.Undulator(beamLine,nrays = nrays, **kwargs_SR)
beamLine.fsm1 = rsc.Screen(beamLine, 'FSM1', (0, p, 0))
limitx, limitz = 0.5, 0.5
bins0= 500
# ppb=1
edges = np.linspace(-limitx, limitx, bins0+1)
beamLine.fsmExpX = (edges[:-1] + edges[1:]) * 0.5
edges = np.linspace(-limitz, limitz, bins0+1)
beamLine.fsmExpZ = (edges[:-1] + edges[1:]) * 0.5
wave1 = beamLine.fsm1.prepare_wave(beamLine.source, beamLine.fsmExpX, beamLine.fsmExpZ)
beamSource = beamLine.source.shine(fixedEnergy=E1, wave= wave1)
outDict = {'beamSource': beamSource, 'beamFSM1': wave1}
Es1 = np.reshape(wave1.Es,[bins0,bins0])
phase1 = np.angle(Es1)
plt.figure(10)
plt.subplot(1,2,1)
plt.imshow(phase1)
plt.title('phase of the wavefront by the shine function')
plt.subplot(1,2,2)
plt.title('Intensity by the shine function')
plt.imshow(np.abs(Es1)**2)
plt.show()
The method multi_electron_stack()
and the underlying method build_I_map()
calculate the field in energy and two angles. They do not have any notion of distance to a screen or an optical element. If you want a field distribution on a particular surface then by specifying that surface the propagation path r becomes known (per wave sample) and we should add the propagation phase exp(ikr). We do this in the shine()
method when wave
is specified.
If you don't want the propagation phase then plot not the wave
object but rather the beam object returned by shine()
, its origin is at the source plane, and it doesn't have the propagation phase there.
Otherwise, add the propagation phase to multi_electron_stack()
as you know the propagation path. You can search the source code at the end of shine()
for how the phase can be added.
Note that if you calculate in near field (uncomment the kwarg R0=p
) then the distance is known and the propagation phase is a part of the field inside multi_electron_stack()
(and build_I_map()
).
Yea, I have tried it as you suggested. They became same in the new codes. Thanks!
Hi, I am now trying to use the XRT to generate the Es、Ep for further calculation. here, I compared the three method, (1) Es, Ep = und.multi_electron_stack(energy, theta, psi) (2) screen for the observation in beamline
(3) bulild a beamline in a standard way following the examples. the results are shown below. My problem is that the phase of the wavefront are different, I have checked the code
raying
and found they use thebuild_I_map
. Thanks!