Skip to content
Snippets Groups Projects
Commit 157aa731 authored by Adam J. Jackson's avatar Adam J. Jackson
Browse files

Abins: proof-of-concept implementation for interpolated broadening

This is a rough implementation of a new scheme for frequency-dependent
broadening. The instrumental broadening function for TOSCA has an
energy-dependent width; while there are several ways of sequencing and
implementating the process, it generally requires a fresh Gaussian to
be evaluated at every frequency bin and those Gaussians to be combined
in a weighted sum.

We note that a Gaussian function may be approximated by a linear
combination of Gaussians with width parameters (sigma) that bracket
the target and are not too far away. An error of ~1% may be reached by
limiting the sigma span to a factor of sqrt(2), while a factor of two
gives error of ~5%. Given the relevant range of widths for
instrumental broadening, a suitable collection of broadening functions
may be obtained with just a few logarithmically-spaced function
evaluations.

In this proof-of-concept, the spectrum is convolved with five
Gaussian kernels, logarithmically spaced by factors of two. At each bin, the
broadened value is drawn from a corresponding broad spectrum, obtained
by interpolation from those at neighbouring sigma values. This
interpolation involves some "magic numbers" in the form of a cubic
function fitted to reproduce a Gaussian as closely as possible from
wider and narrower functions.

The main assumption made in this approach is that the broadening
function is short-ranged relative to the rate of change in width.
Compared to a sum of functions centered at each bin, this method
introduces a slight asymmetry to the peaks. The benefit is a
drastically reduced cost of evaluation; the implementation here is far
from optimal (as it convolutes larger spectral regions than necessary)
and reduces the runtime of Abins by almost half compared to the
fastest implementation of a full sum.
parent 4d2872bc
No related branches found
No related tags found
No related merge requests found
......@@ -17,10 +17,13 @@ class ToscaInstrument(Instrument, FrequencyPowderGenerator):
"""
Class for TOSCA and TOSCA-like instruments.
"""
parameters = AbinsParameters.instruments['TOSCA']
def __init__(self, name):
self._name = name
super(ToscaInstrument, self).__init__()
@classmethod
def calculate_q_powder(self, input_data=None):
"""Calculates squared Q vectors for TOSCA and TOSCA-like instruments.
......@@ -39,18 +42,17 @@ class ToscaInstrument(Instrument, FrequencyPowderGenerator):
constrained by conservation of mass/momentum and TOSCA geometry
"""
tosca_params = AbinsParameters.instruments['TOSCA']
k2_i = (input_data + tosca_params['final_neutron_energy']) * AbinsConstants.WAVENUMBER_TO_INVERSE_A
k2_f = tosca_params['final_neutron_energy'] * AbinsConstants.WAVENUMBER_TO_INVERSE_A
result = k2_i + k2_f - 2 * (k2_i * k2_f) ** 0.5 * tosca_params['cos_scattering_angle']
k2_i = (input_data + cls.parameters['final_neutron_energy']) * AbinsConstants.WAVENUMBER_TO_INVERSE_A
k2_f = cls.parameters['final_neutron_energy'] * AbinsConstants.WAVENUMBER_TO_INVERSE_A
result = k2_i + k2_f - 2 * (k2_i * k2_f) ** 0.5 * cls.parameters['cos_scattering_angle']
return result
def get_sigma(self, frequencies):
@classmethod
def get_sigma(cls, frequencies):
"""Frequency-dependent broadening width from empirical fit"""
a = AbinsParameters.instruments['TOSCA']['a']
b = AbinsParameters.instruments['TOSCA']['b']
c = AbinsParameters.instruments['TOSCA']['c']
a = cls.parameters['a']
b = cls.parameters['b']
c = cls.parameters['c']
sigma = a * frequencies ** 2 + b * frequencies + c
return sigma
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment