<jupyter_start><jupyter_text>SIMEX notebook for CRL focussing.In this example, we add a focussing element to our beamline, a *Compound Refractive Lense* stack, or CRL. A CRL is a group of lenses stacked along the beam direction. Since the refractive index of most materials in the x-ray regime is close to $n=1$, multiple lenses have to be stacked to achieve a relatively short focal length $f$.A schematic drawing of a single lense and a CRL is given in the figure below (credits: http://www.x-ray-optics.de/index.php/en/types-of-optics/refractive-lenses, accessed on Oct. 13 2021):  ![image.png](attachment:a89c42f6-ceca-485a-9a74-2e28d1f56520.png)The CRL lense can be made from various materials, here we us Beryllium. We will need the refractive index of Beryllium at our chosen photon energy. These material x-ray properties can be looked up at the website https://henke.lbl.gov/optical_constants/getdb2.html or programmatically using the python `xraydb` library.<jupyter_code>%load_ext autoreload
%autoreload 2
%matplotlib inline
# Import all SimEx modules
from SimEx.Calculators.WavePropagator import WavePropagator
from SimEx.Calculators.GaussianPhotonSource import GaussianPhotonSource
from SimEx.Parameters.WavePropagatorParameters import WavePropagatorParameters
from SimEx.Parameters.GaussWavefrontParameters import GaussWavefrontParameters
from SimEx.Analysis.XFELPhotonAnalysis import XFELPhotonAnalysis

from SimEx.Utilities.Units import electronvolt, meter, joule, radian
import numpy
import copy
import xraydb

from IPython.display import Markdown as md<jupyter_output><empty_output><jupyter_text>Setup the initial wavefrontWe first create a wavefront at $z=100$ m downstream from the source. The intensity distribution in $x$, $y$, and $t$ is assumed to be Gaussian. To this end, we use the `GaussianPhotonSource` Calculator and it's corresponding parameter class, the `GaussWavefrontParameters`. We first describe the wavefront parameters which will then be used to create the wavefront itself:<jupyter_code>wavefront_parameters = GaussWavefrontParameters(photon_energy=8.0e3*electronvolt,
                                                photon_energy_relative_bandwidth=1e-3,
                                                beam_diameter_fwhm=1.0e-4*meter,
                                                pulse_energy=2.0e-6*joule,
                                                number_of_transverse_grid_points=400,
                                                number_of_time_slices=30,
                                                z = 100*meter
                                                )<jupyter_output><empty_output><jupyter_text>Now, we use the just created `wavefront_parameters` to initialize the Photon Source.<jupyter_code>photon_source = GaussianPhotonSource(wavefront_parameters, input_path="/dev/null", output_path="initial_wavefront.h5")<jupyter_output><empty_output><jupyter_text>Let's calculate the initial wavefront and visualize it:<jupyter_code>photon_source.backengine()<jupyter_output><empty_output><jupyter_text>Save wavefront data for later re-use<jupyter_code>photon_source.saveH5()<jupyter_output><empty_output><jupyter_text>Creata analysis object and generate some plots<jupyter_code>analysis = XFELPhotonAnalysis('initial_wavefront.h5')<jupyter_output>Start initialization.

 Loading wavefront from initial_wavefront.h5.
 ... done.

 Getting intensities.
 ... done.
 Data dimensions =  (400, 400, 30)

 Masking NANs.
 ... done.<jupyter_text>Intensity map<jupyter_code>analysis.plotIntensityMap()<jupyter_output>Plotting intensity map.
R-space<jupyter_text>On-axis power density as function of time<jupyter_code>analysis.plotOnAxisPowerDensity()<jupyter_output>Plotting on-axis power density.<jupyter_text>Plot intensity distribution in q-space<jupyter_code>analysis.plotIntensityMap(qspace=True)<jupyter_output>Plotting intensity map.

 Switching to reciprocal space.
 ... done.
Q-space<jupyter_text>Plot the power as a function of time integrated over the transverse dimensions<jupyter_code>analysis.plotTotalPower()<jupyter_output>Plotting total power.
Pulse energy 2e-06 J<jupyter_text>Plot the power spectrum<jupyter_code>analysis.plotTotalPower(spectrum=True)
import wpg
from wpg import wpg_uti_wf as wpg_utils
from wpg import wpg_uti_oe as optics_utils
wavefront = copy.deepcopy(photon_source.data)<jupyter_output><empty_output><jupyter_text>Check the sampling quality<jupyter_code>print(wpg_utils.check_sampling(wavefront))<jupyter_output>WAVEFRONT SAMPLING REPORT
+----------+---------+---------+---------+---------+---------+---------+---------+
|x/y       |FWHM     |px       |ROI      |R        |Fzone    |px*7     |px*10    |
+----------+---------+---------+---------+---------+---------+---------+---------+
|Horizontal|1.147e-04|6.386e-06|2.548e-03|1.772e+02|1.196e-04|4.470e-05|6.386e-05|
|Vertical  |1.147e-04|6.386e-06|2.548e-03|1.772e+02|1.196e-04|4.470e-05|6.386e-05|
+----------+---------+---------+---------+---------+---------+---------+---------+

Horizontal Fresnel zone extension NOT within [7,10]*pixel_width -> Check pixel width."
Vertical Fresnel zone extension NOT within [7,10]*pixel_height -> Check pixel width."
Horizontal ROI > 3* FWHM(x) -> OK
Horizontal ROI > 3* FWHM(y) -> OK
Focus sampling: FWHM > 10*px

END OF REPORT<jupyter_text>Setup the beamlineOur experiment consists of* The photon source at the origin* 100 m of free space (already taken into account in the wavefront construction).* The CRL* Another distance of free space* The detector (screen)The goal of this exercise is to minimize the size of the beam by varying the final screen position along the beam direction.<jupyter_code>from wpg import Beamline, optical_elements, srwlib
from wpg.useful_code.wfrutils import propagate_wavefront
beamline = Beamline()<jupyter_output><empty_output><jupyter_text>Setting up the CRLWe employ the `CRL` class in `wpg.optical_elements`.<jupyter_code>optical_elements.CRL?<jupyter_output><empty_output><jupyter_text>We set up a circular (`shape='c'`) obstacle (`ap_or_ob = 'ob'`) of radius $100$ nm in both and place it at the beam center$x_\text{center} = y_\text{center} = 0$ (`x=0`, `y=0`).  Get the components of the refractive index for Be (solid Be density is 1.85 g/ccm)<jupyter_code>delta, beta, att = xraydb.xray_delta_beta("Be", density=1.85, energy=photon_source.parameters.photon_energy.m_as(electronvolt))
delta, beta, att
crl = optical_elements.CRL(
    _foc_plane=3,
    _delta=delta,
    _atten_len=att*1e-2,
    _shape=1,
    _apert_h=5.0e-3,
    _apert_v=5.0e-3,
    _r_min=5.8e-3,
    _n=20,
    _wall_thick=8.0e-5,
    _xc=0.0,
    _yc=0.0,
    _void_cen_rad=None,
    _e_start=0,
    _e_fin=0,
    _nx=1001,
    _ny=1001,
)
optics_utils.show_transmission(crl)
crl_pp = optical_elements.Use_PP(semi_analytical_treatment=1,
                                    zoom=1,
                                    sampling=1
                                   )
beamline.append(crl, crl_pp)
srwlib.srwl.SetRepresElecField(wavefront._srwl_wf, 'f')
propagate_wavefront(wavefront,beamline)
srwlib.srwl.SetRepresElecField(wavefront._srwl_wf, 't')
wpg_utils.plot_intensity_map(wavefront)
wpg_utils.plot_intensity_qmap(wavefront)
print(wpg_utils.check_sampling(wavefront))<jupyter_output>WAVEFRONT SAMPLING REPORT
+----------+---------+---------+---------+---------+---------+---------+---------+
|x/y       |FWHM     |px       |ROI      |R        |Fzone    |px*7     |px*10    |
+----------+---------+---------+---------+---------+---------+---------+---------+
|Horizontal|1.147e-04|6.386e-06|2.548e-03|1.772e+02|1.196e-04|4.470e-05|6.386e-05|
|Vertical  |1.147e-04|6.386e-06|2.548e-03|1.772e+02|1.196e-04|4.470e-05|6.386e-05|
+----------+---------+---------+---------+---------+---------+---------+---------+

Horizontal Fresnel zone extension NOT within [7,10]*pixel_width -> Check pixel width."
Vertical Fresnel zone extension NOT within [7,10]*pixel_height -> Check pixel width."
Horizontal ROI > 3* FWHM(x) -> OK
Horizontal ROI > 3* FWHM(y) -> OK
Focus sampling: FWHM > 10*px

END OF REPORT<jupyter_text>Estimate focus positionUse the classical lense formula$$\frac{1}{z_O} + \frac{1}{z_I} = \frac{1}{f}$$where $z_O$ and $z_I$ are the distances from the object to the lense and distance from lense to image, respectively. **Solution**:With $z_O = 100\,\text{m}$ and $f = 27.2 m$, rearranging the lens formula yields<jupyter_code>z_O = 100
f = 27.2
z_I = 1./(1/f - 1/z_O)
z_I
md(f"The image position is at {numpy.round(z_I, 1)} m behind the lense")<jupyter_output><empty_output><jupyter_text>Propagate for another 37.4 m<jupyter_code>crl_to_screen = optical_elements.Drift(_L=37.4, _treat=1)
crl_to_screen_pp = optical_elements.Use_PP(semi_analytical_treatment=1)
beamline.append(crl_to_screen, crl_to_screen_pp)
# Reset the wavefront.
wavefront = copy.deepcopy(photon_source.data)
srwlib.srwl.SetRepresElecField(wavefront._srwl_wf, 'f')
propagate_wavefront(wavefront, beamline)
srwlib.srwl.SetRepresElecField(wavefront._srwl_wf, 't')
wpg_utils.plot_intensity_map(wavefront)<jupyter_output>R-space
(400,) (400,)
FWHM in x = 3.822e-05 m.
FWHM in y = 3.822e-05 m.<jupyter_text>**Tasks**1. Optimize the focus: Measure the focus FWHM at 10 positions around the chosen screen distance of 37.4 m. 1. Plot the focus FWHM against distance from CRL.1. Revisit the analytical expression for the beam waist of a Gaussian beam as a function of distance from focus. 1. Fit the beam waist expression to your data and compare the fitted focus FWHM to the analytical solution and the numerical data.<jupyter_code>!git add crl_focus.ipynb
!git commit -a -m "Update CRL focus notebook:\nFinalize propagation to screen,\n Estimate focus from lens formua,\n Add tasks"<jupyter_output>[simple_diffraction 340e2ba] Update CRL focus notebook:\nFinalize propagation to screen,\n Estimate focus from lens formua,\n Add tasks
 2 files changed, 1094 insertions(+), 1 deletion(-)
 create mode 100644 examples_diffraction/crl_focus.ipynb