# Energy and angular dispersive analysis

`refnx`

able to deal with reflectivity from systems containing energy dispersive materials, i.e. those whose optical properties change as a function of wavelength. For neutrons this mainly corresponds to elements with strong absorption effects. The treatment below is also able to deal with energy dispersive X-ray measurements

```
import numpy as np
import matplotlib.pyplot as plt
from refnx.reflect import ReflectModelTL, ReflectModel, SLD, MaterialSLD
from refnx.util import q, xray_wavelength
```

Start off by creating a `MaterialSLD`

. This is a variant of `Scatterer`

, whose optical properties are controlled by a formula, mass density (g/cc), and whether the material is being used for neutron or X-ray calculation.

Here we’ll calculate the SLD of the material at two different wavelengths.

```
gdgao_disp = MaterialSLD("GdGa5O12", 7, probe='neutron') # can be 'x-ray'
gdgao_disp.wavelength = 2.8 # Angstrom
print(f"SLD: {complex(gdgao_disp)} at {gdgao_disp.wavelength} Angstrom")
gdgao_disp.wavelength = 18.
print(f"SLD: {complex(gdgao_disp)} at {gdgao_disp.wavelength} Angstrom")
```

```
SLD: (6.544686245235056+0.7318962182191739j) at 2.8 Angstrom
SLD: (6.471928664642279+0.648390380281317j) at 18.0 Angstrom
```

For comparison let’s create a non-dispersive version. By non-dispersive we mean that the optical properties don’t change as a function of wavelength

```
gdgao_nondisp = SLD(6.5 + 0.68j)
```

The `MaterialSLD.density`

attribute can be allowed to vary during a fit.

```
print(gdgao_disp.parameters)
```

```
________________________________________________________________________________
Parameters: ''
<Parameter: 'density' , value=7 (fixed) , bounds=[-inf, inf]>
```

In comparison, with the non-dispersive analogue one can allow the real and imaginary part of the SLD to vary.

```
print(gdgao_nondisp.parameters)
```

```
________________________________________________________________________________
Parameters: ''
<Parameter: ' - sld' , value=6.5 (fixed) , bounds=[-inf, inf]>
<Parameter: ' - isld' , value=0.68 (fixed) , bounds=[-inf, inf]>
```

Now we create two `Structure`

s that are ostensibly the same, but one has a dispersive material in it, the other a non-dispersive analogue.

```
air = SLD(0.0)
si = SLD(2.07)
s_disp = air | gdgao_disp(300, 5) | si(0, 3)
s_nondisp = air | gdgao_nondisp(300, 5) | si(0, 3)
```

Now we generate `theta`

/`wavelength`

arrays, with a corresponding Q value.
Subsequently we create a `ReflectModelTL`

and a `ReflectModel`

. `ReflectModelTL`

is a variant of `ReflectModel`

. Instead of calculating reflectivity as a function of Q (a. la. `ReflectModel`

), it calculates as a function of incident angle and wavelength

```
npnts = 201
theta = np.ones(npnts) * 0.65
wavelength = np.geomspace(2.8, 18, npnts)
qq = q(theta, wavelength)
model_disp = ReflectModelTL(s_disp)
model_nondisp = ReflectModel(s_nondisp)
```

Now let’s compare the reflectivity from the dispersive and non-dispersive analogues. The reflectivities are almost identical, the energy dispersive absorption effect has little effect in this case.

```
plt.plot(qq, model_nondisp(qq), label='nondisp')
# note how we provide theta and wavelength to the ReflectModelTL object.
plt.plot(qq, model_disp(np.c_[theta, wavelength]), label='disp')
plt.yscale('log')
plt.xscale('log')
plt.legend();
```

To reassure ourselves let’s loko at the slab representation of the the dispersive `Structure`

at two different wavelengths. We can see that the real and imaginary components of the SLD (second column) do change, just not by much.

```
print(s_disp.slabs(wavelength=2.8))
print()
print(s_disp.slabs(wavelength=18.0))
```

```
[[ 0. 0. 0. 0. 0. ]
[300. 6.54468625 0.73189622 5. 0. ]
[ 0. 2.07 0. 3. 0. ]]
[[ 0. 0. 0. 0. 0. ]
[300. 6.47192866 0.64839038 5. 0. ]
[ 0. 2.07 0. 3. 0. ]]
```

For comparison here is the non-dispersive system.

```
print(s_nondisp.slabs(wavelength=2.8))
print()
print(s_nondisp.slabs(wavelength=18.0))
```

```
[[ 0. 0. 0. 0. 0. ]
[300. 6.5 0.68 5. 0. ]
[ 0. 2.07 0. 3. 0. ]]
[[ 0. 0. 0. 0. 0. ]
[300. 6.5 0.68 5. 0. ]
[ 0. 2.07 0. 3. 0. ]]
```