Beam Wavelength Spread in Specular Simulations

This example demonstrates beam wavelength spread effects in reflectivity computations. All simulation parameters (except for those related to beam spread itself) coincide with those defined in reflectometry simulation tutorial.

In real specular experiments the observed reflectivity is always affected by the beam spread in both wavelength and incident angle.

In this example the following parameters related to the spread of the beam were set to the simulation:

• Gaussian distributions both in wavelength and incident angle
• The mean value for beam wavelength $\lambda_0 = 1.54 , \unicode{x212B}$
• Standard deviation in the wavelength $\sigma_{\lambda} = 0.01 \cdot \lambda_0$
• Standard deviation in the incident angle $\sigma_{\alpha} = 0.01^{\circ}$

As one can see from the Python script, the definitions of beam parameter distributions match ones described in similar example for GISAS simulations. However, in the case of the incident angle one should always use a distribution with zero mean, since the actual mean value is substituted by SpecularSimulation in dependence on the defined inclination angle range. If the distribution of the incident angle has non-zero mean value, an exception is thrown:

terminate called after throwing an instance of 'std::runtime_error'
what():  Error in SpecularSimulation: parameter distribution of beam inclination angle should have zero mean.

  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  #!/usr/bin/env python3 """ An example of taking into account beam angular and wavelength divergence in reflectometry calculations with BornAgain. """ import bornagain as ba from bornagain import angstrom, deg # input parameters wavelength = 1.54*angstrom alpha_i_min = 0 # min incident angle, deg alpha_i_max = 2*deg # max incident angle, rad # convolution parameters d_wl = 0.01*wavelength # spread width for wavelength d_ang = 0.01*deg # spread width for incident angle n_sig = 3 # number of sigmas to convolve over n_points = 25 # number of points to convolve over # substrate (Si) si_sld_real = 2.0704e-06 # \AA^{-2} # layer parameters n_repetitions = 10 # Ni ni_sld_real = 9.4245e-06 # \AA^{-2} d_ni = 70*angstrom # ni layer thickness (nm) # Ti ti_sld_real = -1.9493e-06 # \AA^{-2} d_ti = 30*angstrom # ti layer thickness (nm) def get_sample(): # defining materials # this example implies beam divergence in the wavelength, # thus MaterialBySLD must be used to provide correct result m_vacuum = ba.MaterialBySLD("Vacuum", 0, 0) m_ni = ba.MaterialBySLD("Ni", ni_sld_real, 0) m_ti = ba.MaterialBySLD("Ti", ti_sld_real, 0) m_substrate = ba.MaterialBySLD("SiSubstrate", si_sld_real, 0) vacuum_layer = ba.Layer(m_vacuum) ni_layer = ba.Layer(m_ni, d_ni) ti_layer = ba.Layer(m_ti, d_ti) substrate_layer = ba.Layer(m_substrate) multi_layer = ba.MultiLayer() multi_layer.addLayer(vacuum_layer) for i in range(n_repetitions): multi_layer.addLayer(ti_layer) multi_layer.addLayer(ni_layer) multi_layer.addLayer(substrate_layer) return multi_layer def get_simulation(sample, scan_size=500): """ Returns a specular simulation with beam and detector defined. """ alpha_distr = ba.RangedDistributionGaussian(n_points, n_sig) wavelength_distr = ba.RangedDistributionGaussian(n_points, n_sig) scan = ba.AngularSpecScan(wavelength, scan_size, alpha_i_min, alpha_i_max) scan.setAbsoluteAngularResolution(alpha_distr, d_ang) scan.setAbsoluteWavelengthResolution(wavelength_distr, d_wl) simulation = ba.SpecularSimulation() simulation.setScan(scan) simulation.setSample(sample) return simulation if __name__ == '__main__': import ba_plot sample = get_sample() simulation = get_simulation(sample) ba_plot.run_and_plot(simulation) 
BeamFullDivergence.py