Absorption correction example#
Assuming single scattering, the neutron intensity per unit solid angle at the position \(\mathbf{p}\) is modeled as
where \(S(\lambda, \hat{\mathbf{s}})\) is the probability that a neutron with wavelength \(\lambda\) scatters in the direction \(\hat{\mathbf{s}}\) and \(T(\lambda, \mathbf{p}, \mathbf{x})\) is the transmission rate for neutrons scattering at \(\mathbf{x}\) towards \(\mathbf{p}\). Here the \(\widehat{\quad \cdot\quad}\) means that the vector is normalized to length 1.
If the detector is far away from the sample relative to the size of the sample then \(\widehat{\mathbf{p}-\mathbf{x}}\) is close to constant in the integral, or if \(S\) represents inhomogeneous scattering, the \(S\) term does not depend on \(\mathbf{x}\) and can be moved outside of the integtral:
where \(\bar{\mathbf{x}}\) denotes the center of the sample.
To compute the scattering probabiltiy \(S\) from the intensity \(I\) we need to estimate the term
This is the “absorption correction” term.
The transmission fraction is a function of path length \(L\) of the neutron going through the sample
where \(\mu\) is material dependent and \(\hat{\mathbf{b}}\) is the direction of the incoming neutron.
The path length through the sample depends on the shape of the sample, the scattering point \(\mathbf{x}\) and the detection position \(\mathbf{p}\).
To compute \(C(\lambda, \mathbf{p})\) you can use
scippneutron.absorption.base.compute_transmission_map(
shape,
material,
beam_direction,
wavelength,
detector_position
)
where shape
and material
are sample properties:
shape
definesL
material
defines \(\mu\)beam_direction
is \(\hat{\mathbf{b}}\)wavelength
is \(\lambda\)detector_position
is \(\mathbf{p}\)
[1]:
import scipp as sc
import numpy as np
from scippneutron.absorption import compute_transmission_map, Cylinder, Material
from scippneutron.atoms import ScatteringParams
# Create a material with scattering parameters to represent a Vanadium sample
sample_material = Material(scattering_params=ScatteringParams.for_isotope('V'), effective_sample_number_density=sc.scalar(1, unit='1/angstrom**3'))
# Create a sample shape
sample_shape = Cylinder(
symmetry_line=sc.vector([0, 1, 0]),
# center_of_base is placed slightly below the origin, so that the center of the cylinder is at the origin
center_of_base=sc.vector([0, -.5, 0], unit='cm'),
radius=sc.scalar(1., unit='cm'),
height=sc.scalar(0.3, unit='cm')
)
# Create detector positions, in this case the detector positions are placed in a sphere around the sample
theta = sc.linspace('theta', 0, np.pi, 60, endpoint=True, unit='rad')
phi = sc.linspace('phi', 0, 2 * np.pi, 120, endpoint=False, unit='rad')
r = sc.array(dims='r', values=[5.], unit='m')
dims = (*r.dims, *theta.dims, *phi.dims)
# Detector positions in grid on a sphere around the origin
detector_positions = sc.vectors(
dims=dims,
values=sc.concat(
[
r * sc.sin(theta) * sc.cos(phi),
sc.broadcast(r * sc.cos(theta), sizes={**r.sizes, **theta.sizes, **phi.sizes}),
r * sc.sin(theta) * sc.sin(phi),
],
dim='row',
)
.transpose([*dims, 'row'])
.values,
unit=r.unit,
)
def transmission_fraction(quadrature_kind):
'Evaluate the transmission fraction using the selected quadrature kind'
da = compute_transmission_map(
sample_shape,
sample_material,
beam_direction=sc.vector([0, 0, 1]),
wavelength=sc.linspace('wavelength', 0.5, 2.5, 10, unit='angstrom'),
detector_position=detector_positions,
quadrature_kind=quadrature_kind,
)
da.coords['phi'] = phi
da.coords['theta'] = theta
return da
def show_correction_map(da):
'Plotting utility'
return (
da['wavelength', 0]['r', 0].plot() /
da['wavelength', 0]['r', 0]['theta', da.sizes['theta']//2].plot() /
da['wavelength', 0]['r', 0]['theta', da.sizes['theta']//2]['phi', da.sizes['phi']//4 - da.sizes['phi']//6:da.sizes['phi']//4 + da.sizes['phi']//6].plot() /
da['wavelength', 0]['r', 0]['theta', da.sizes['theta']//2]['phi', da.sizes['phi']//2 - da.sizes['phi']//6:da.sizes['phi']//2 + da.sizes['phi']//6].plot() /
da['wavelength', 0]['r', 0]['phi', da.sizes['phi']//2].plot()
)
[2]:
transmission_fraction('medium')
[2]:
- wavelength: 10
- r: 1
- theta: 60
- phi: 120
- detector_position(r, theta, phi)vector3m[0. 5. 0.], [0. 5. 0.], ..., [ 6.08969028e-16 -5.00000000e+00 -6.40052240e-17], [ 6.11484232e-16 -5.00000000e+00 -3.20465306e-17]
Values:
array([[[[ 0.00000000e+00, 5.00000000e+00, 0.00000000e+00], [ 0.00000000e+00, 5.00000000e+00, 0.00000000e+00], [ 0.00000000e+00, 5.00000000e+00, 0.00000000e+00], ..., [ 0.00000000e+00, 5.00000000e+00, -0.00000000e+00], [ 0.00000000e+00, 5.00000000e+00, -0.00000000e+00], [ 0.00000000e+00, 5.00000000e+00, -0.00000000e+00]], [[ 2.66110874e-01, 4.99291348e+00, 0.00000000e+00], [ 2.65746179e-01, 4.99291348e+00, 1.39271671e-02], [ 2.64653091e-01, 4.99291348e+00, 2.78161607e-02], ..., [ 2.62834608e-01, 4.99291348e+00, -4.16289122e-02], [ 2.64653091e-01, 4.99291348e+00, -2.78161607e-02], [ 2.65746179e-01, 4.99291348e+00, -1.39271671e-02]], [[ 5.31467428e-01, 4.97167400e+00, 0.00000000e+00], [ 5.30739071e-01, 4.97167400e+00, 2.78148561e-02], [ 5.28555994e-01, 4.97167400e+00, 5.55534736e-02], ..., [ 5.24924182e-01, 4.97167400e+00, -8.31398228e-02], [ 5.28555994e-01, 4.97167400e+00, -5.55534736e-02], [ 5.30739071e-01, 4.97167400e+00, -2.78148561e-02]], ..., [[ 5.31467428e-01, -4.97167400e+00, 0.00000000e+00], [ 5.30739071e-01, -4.97167400e+00, 2.78148561e-02], [ 5.28555994e-01, -4.97167400e+00, 5.55534736e-02], ..., [ 5.24924182e-01, -4.97167400e+00, -8.31398228e-02], [ 5.28555994e-01, -4.97167400e+00, -5.55534736e-02], [ 5.30739071e-01, -4.97167400e+00, -2.78148561e-02]], [[ 2.66110874e-01, -4.99291348e+00, 0.00000000e+00], [ 2.65746179e-01, -4.99291348e+00, 1.39271671e-02], [ 2.64653091e-01, -4.99291348e+00, 2.78161607e-02], ..., [ 2.62834608e-01, -4.99291348e+00, -4.16289122e-02], [ 2.64653091e-01, -4.99291348e+00, -2.78161607e-02], [ 2.65746179e-01, -4.99291348e+00, -1.39271671e-02]], [[ 6.12323400e-16, -5.00000000e+00, 0.00000000e+00], [ 6.11484232e-16, -5.00000000e+00, 3.20465306e-17], [ 6.08969028e-16, -5.00000000e+00, 6.40052240e-17], ..., [ 6.04784682e-16, -5.00000000e+00, -9.57884834e-17], [ 6.08969028e-16, -5.00000000e+00, -6.40052240e-17], [ 6.11484232e-16, -5.00000000e+00, -3.20465306e-17]]]]) - phi(phi)float64rad0.0, 0.052, ..., 6.178, 6.231
Values:
array([0. , 0.05235988, 0.10471976, 0.15707963, 0.20943951, 0.26179939, 0.31415927, 0.36651914, 0.41887902, 0.4712389 , 0.52359878, 0.57595865, 0.62831853, 0.68067841, 0.73303829, 0.78539816, 0.83775804, 0.89011792, 0.9424778 , 0.99483767, 1.04719755, 1.09955743, 1.15191731, 1.20427718, 1.25663706, 1.30899694, 1.36135682, 1.41371669, 1.46607657, 1.51843645, 1.57079633, 1.6231562 , 1.67551608, 1.72787596, 1.78023584, 1.83259571, 1.88495559, 1.93731547, 1.98967535, 2.04203522, 2.0943951 , 2.14675498, 2.19911486, 2.25147474, 2.30383461, 2.35619449, 2.40855437, 2.46091425, 2.51327412, 2.565634 , 2.61799388, 2.67035376, 2.72271363, 2.77507351, 2.82743339, 2.87979327, 2.93215314, 2.98451302, 3.0368729 , 3.08923278, 3.14159265, 3.19395253, 3.24631241, 3.29867229, 3.35103216, 3.40339204, 3.45575192, 3.5081118 , 3.56047167, 3.61283155, 3.66519143, 3.71755131, 3.76991118, 3.82227106, 3.87463094, 3.92699082, 3.97935069, 4.03171057, 4.08407045, 4.13643033, 4.1887902 , 4.24115008, 4.29350996, 4.34586984, 4.39822972, 4.45058959, 4.50294947, 4.55530935, 4.60766923, 4.6600291 , 4.71238898, 4.76474886, 4.81710874, 4.86946861, 4.92182849, 4.97418837, 5.02654825, 5.07890812, 5.131268 , 5.18362788, 5.23598776, 5.28834763, 5.34070751, 5.39306739, 5.44542727, 5.49778714, 5.55014702, 5.6025069 , 5.65486678, 5.70722665, 5.75958653, 5.81194641, 5.86430629, 5.91666616, 5.96902604, 6.02138592, 6.0737458 , 6.12610567, 6.17846555, 6.23082543]) - theta(theta)float64rad0.0, 0.053, ..., 3.088, 3.142
Values:
array([0. , 0.05324733, 0.10649467, 0.159742 , 0.21298933, 0.26623667, 0.319484 , 0.37273133, 0.42597866, 0.479226 , 0.53247333, 0.58572066, 0.638968 , 0.69221533, 0.74546266, 0.79871 , 0.85195733, 0.90520466, 0.958452 , 1.01169933, 1.06494666, 1.118194 , 1.17144133, 1.22468866, 1.27793599, 1.33118333, 1.38443066, 1.43767799, 1.49092533, 1.54417266, 1.59741999, 1.65066733, 1.70391466, 1.75716199, 1.81040933, 1.86365666, 1.91690399, 1.97015133, 2.02339866, 2.07664599, 2.12989332, 2.18314066, 2.23638799, 2.28963532, 2.34288266, 2.39612999, 2.44937732, 2.50262466, 2.55587199, 2.60911932, 2.66236666, 2.71561399, 2.76886132, 2.82210865, 2.87535599, 2.92860332, 2.98185065, 3.03509799, 3.08834532, 3.14159265]) - wavelength(wavelength)float64Å0.5, 0.722, ..., 2.278, 2.5
Values:
array([0.5 , 0.72222222, 0.94444444, 1.16666667, 1.38888889, 1.61111111, 1.83333333, 2.05555556, 2.27777778, 2.5 ])
- (wavelength, r, theta, phi)float64𝟙0.043, 0.043, ..., 0.014, 0.014
Values:
array([[[[0.04271322, 0.04271322, 0.04271322, ..., 0.04271322, 0.04271322, 0.04271322], [0.04267256, 0.04267246, 0.04267236, ..., 0.04267287, 0.04267277, 0.04267266], [0.04267524, 0.04267296, 0.04266973, ..., 0.0426769 , 0.04267691, 0.04267655], ..., [0.04267527, 0.04267299, 0.04266975, ..., 0.04267702, 0.04267695, 0.04267658], [0.04267245, 0.04267235, 0.04267224, ..., 0.04267275, 0.04267265, 0.04267255], [0.04271322, 0.04271322, 0.04271322, ..., 0.04271322, 0.04271322, 0.04271322]]], [[[0.03657755, 0.03657755, 0.03657755, ..., 0.03657755, 0.03657755, 0.03657755], [0.03654083, 0.03654073, 0.03654064, ..., 0.03654111, 0.03654101, 0.03654092], [0.03654229, 0.03654019, 0.03653722, ..., 0.03654384, 0.03654385, 0.03654351], ..., [0.03654232, 0.03654023, 0.03653725, ..., 0.03654395, 0.03654389, 0.03654354], [0.03654072, 0.03654063, 0.03654054, ..., 0.03654101, 0.03654091, 0.03654082], [0.03657755, 0.03657755, 0.03657755, ..., 0.03657755, 0.03657755, 0.03657755]]], [[[0.03163303, 0.03163303, 0.03163303, ..., 0.03163303, 0.03163303, 0.03163303], [0.03159979, 0.0315997 , 0.03159962, ..., 0.03160005, 0.03159996, 0.03159988], [0.03159933, 0.03159742, 0.0315947 , ..., 0.03160076, 0.03160077, 0.03160045], ..., [0.03159936, 0.03159745, 0.03159473, ..., 0.03160087, 0.03160081, 0.03160048], [0.0315997 , 0.03159961, 0.03159952, ..., 0.03159996, 0.03159987, 0.03159978], [0.03163303, 0.03163303, 0.03163303, ..., 0.03163303, 0.03163303, 0.03163303]]], ..., [[[0.01710855, 0.01710855, 0.01710855, ..., 0.01710855, 0.01710855, 0.01710855], [0.01708774, 0.01708768, 0.01708763, ..., 0.01708791, 0.01708786, 0.0170878 ], [0.01707638, 0.01707526, 0.01707368, ..., 0.01707725, 0.01707726, 0.01707705], ..., [0.01707638, 0.01707526, 0.01707367, ..., 0.01707729, 0.01707726, 0.01707705], [0.01708768, 0.01708763, 0.01708757, ..., 0.01708785, 0.0170878 , 0.01708774], [0.01710855, 0.01710855, 0.01710855, ..., 0.01710855, 0.01710855, 0.01710855]]], [[[0.01539386, 0.01539386, 0.01539386, ..., 0.01539386, 0.01539386, 0.01539386], [0.0153748 , 0.01537475, 0.0153747 , ..., 0.01537496, 0.01537491, 0.01537485], [0.01536183, 0.01536083, 0.01535943, ..., 0.01536261, 0.01536262, 0.01536243], ..., [0.01536183, 0.01536082, 0.01535942, ..., 0.01536264, 0.01536261, 0.01536242], [0.01537475, 0.0153747 , 0.01537464, ..., 0.01537491, 0.01537485, 0.0153748 ], [0.01539386, 0.01539386, 0.01539386, ..., 0.01539386, 0.01539386, 0.01539386]]], [[[0.01391455, 0.01391455, 0.01391455, ..., 0.01391455, 0.01391455, 0.01391455], [0.01389705, 0.013897 , 0.01389696, ..., 0.0138972 , 0.01389715, 0.0138971 ], [0.01388275, 0.01388186, 0.01388062, ..., 0.01388344, 0.01388345, 0.01388328], ..., [0.01388273, 0.01388184, 0.0138806 , ..., 0.01388346, 0.01388344, 0.01388327], [0.013897 , 0.01389695, 0.01389691, ..., 0.01389715, 0.0138971 , 0.01389705], [0.01391455, 0.01391455, 0.01391455, ..., 0.01391455, 0.01391455, 0.01391455]]]])
[3]:
show_correction_map(transmission_fraction('cheap'))
[3]:
[4]:
show_correction_map(transmission_fraction('medium'))
[4]:
[5]:
show_correction_map(transmission_fraction('expensive'))
[5]:
What quadrature should I use?#
Use medium
first, if it’d not good enough try expensive
.