Absorption correction example#

Assuming single scattering, the neutron intensity per unit solid angle at the position \(\mathbf{p}\) is modeled as

\[I(\lambda, \mathbf{x}) = \int_{sample} S(\lambda, \widehat{\mathbf{p}-\mathbf{x}}) T(\lambda, \mathbf{p}, \mathbf{x}) \ d\mathbf{x}\]

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:

\[I(\lambda, \mathbf{x}) \approx S(\lambda, \widehat{\mathbf{p} -\bar{\mathbf{x}}}) \int_{sample} T(\lambda, \mathbf{p}, \mathbf{x}) \ d\mathbf{x}\]

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

\[C(\lambda, \mathbf{p}) = \int_{sample} T(\lambda, \mathbf{p}, \mathbf{x}) \ d\mathbf{x}.\]

This is the “absorption correction” term.

The transmission fraction is a function of path length \(L\) of the neutron going through the sample

\[T(\lambda, \mathbf{p}, \mathbf{x}) = \exp{\big(-\mu(\lambda) L(\hat{\mathbf{b}}, \mathbf{p}, \mathbf{x})\big)}\]

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 defines L

  • 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]:
Show/Hide data repr Show/Hide attributes
scipp.DataArray (734.57 KB)
    • wavelength: 10
    • r: 1
    • theta: 60
    • phi: 120
    • detector_position
      (r, theta, phi)
      vector3
      m
      [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)
      float64
      rad
      0.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)
      float64
      rad
      0.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]:
../_images/user-guide_absorption-correction_3_0.svg
[4]:
show_correction_map(transmission_fraction('medium'))
[4]:
../_images/user-guide_absorption-correction_4_0.svg
[5]:
show_correction_map(transmission_fraction('expensive'))
[5]:
../_images/user-guide_absorption-correction_5_0.svg

What quadrature should I use?#

Use medium first, if it’d not good enough try expensive.