Source code for ess.estia.resolution

# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)
import scipp as sc
from scipp import constants

from ..reflectometry.tools import fwhm_to_std


[docs] def wavelength_resolution( source_pulse_length: sc.Variable, wavelength: sc.Variable, Ltotal: sc.Variable, ): """ Find the wavelength resolution contribution of the ESTIA instrument. Parameters ---------- source_pulse_length: The length of the ESS source pulse. wavelength: The wavelength of the neutron. Ltotal: The distance from source to detector. Returns ------- : The wavelength resolution, ratio of the standard deviation of wavelength and the wavelength. """ # The exact factor depends on the shape of the source pulse. # The factor here assumes a rectangular source pulse: # import sympy as sp # x, D = sp.symbols('x, D', positive=True) # sp.sqrt(sp.integrate(1/D * (x-D/2)**2, (x, 0, D))) standard_deviation_of_time_at_source = (1 / 12**0.5) * source_pulse_length tof = wavelength * Ltotal * constants.m_n / constants.h return (standard_deviation_of_time_at_source / tof).to(unit='dimensionless')
[docs] def sample_size_resolution( L2: sc.Variable, sample_size: sc.Variable, ): """ The resolution from the projected sample size, where it may be bigger than the detector pixel resolution as described in Section 4.3.3 of the Amor publication (doi: 10.1016/j.nima.2016.03.007). Parameters ---------- L2: Distance from sample to detector. sample_size: Size of sample. Returns ------- : Standard deviation of contribution from the sample size. """ return fwhm_to_std(sample_size.to(unit=L2.unit, dtype='float64') / L2)
[docs] def angular_resolution( theta: sc.Variable, L2: sc.Variable, detector_spatial_resolution: sc.Variable, ): """ Determine the angular resolution of the ESTIA instrument. Parameters ---------- theta: Angle of reflection. L2: Distance between sample and detector. detector_spatial_resolution: FWHM of detector pixel resolution. Returns ------- : Angular resolution standard deviation over the reflection angle. """ return ( fwhm_to_std( sc.atan(detector_spatial_resolution.to(unit=L2.unit, dtype='float64') / L2) ).to(unit=theta.unit, dtype='float64', copy=False) / theta )
[docs] def q_resolution( Q: sc.Variable, angular_resolution: sc.Variable, wavelength_resolution: sc.Variable, sample_size_resolution: sc.Variable, ): """ Compute resolution in Q. Parameters ---------- Q: Momentum transfer. angular_resolution: Angular resolution contribution. wavelength_resolution: Wavelength resolution contribution. sample_size_resolution: Sample size resolution contribution. Returns ------- : Q resolution function. """ return sc.sqrt( (angular_resolution**2 + wavelength_resolution**2 + sample_size_resolution**2) * Q**2 )