Skip to content

Commit

Permalink
Rename algorithm, correct docs
Browse files Browse the repository at this point in the history
Refs #11437
  • Loading branch information
DanNixon committed Mar 27, 2015
1 parent ec2817f commit ff62e1b
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 114 deletions.
Expand Up @@ -7,7 +7,7 @@
import os


class Fury(PythonAlgorithm):
class TransformToIqt(PythonAlgorithm):

_sample = None
_resolution = None
Expand Down Expand Up @@ -43,7 +43,7 @@ def PyInit(self):

self.declareProperty(MatrixWorkspaceProperty('ParameterWorkspace', '',\
direction=Direction.Output, optional=PropertyMode.Optional),
doc='Table workspace for saving Fury properties')
doc='Table workspace for saving TransformToIqt properties')

self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '',\
direction=Direction.Output, optional=PropertyMode.Optional),
Expand Down Expand Up @@ -76,7 +76,7 @@ def PyExec(self):
if self._plot:
self._plot_output()
else:
logger.information('Dry run, will not run Fury')
logger.information('Dry run, will not run TransformToIqt')

self.setProperty('ParameterWorkspace', self._parameter_table)
self.setProperty('OutputWorkspace', self._output_workspace)
Expand All @@ -97,7 +97,7 @@ def _setup(self):

self._parameter_table = self.getPropertyValue('ParameterWorkspace')
if self._parameter_table == '':
self._parameter_table = getWSprefix(self._sample) + 'FuryParameters'
self._parameter_table = getWSprefix(self._sample) + 'TransformToIqtParameters'

self._output_workspace = self.getPropertyValue('OutputWorkspace')
if self._output_workspace == '':
Expand Down Expand Up @@ -128,11 +128,11 @@ def validateInputs(self):

def _calculate_parameters(self):
"""
Calculates the Fury parameters and saves in a table workspace.
Calculates the TransformToIqt parameters and saves in a table workspace.
"""
CropWorkspace(InputWorkspace=self._sample, OutputWorkspace='__Fury_sample_cropped',
CropWorkspace(InputWorkspace=self._sample, OutputWorkspace='__TransformToIqt_sample_cropped',
Xmin=self._e_min, Xmax=self._e_max)
x_data = mtd['__Fury_sample_cropped'].readX(0)
x_data = mtd['__TransformToIqt_sample_cropped'].readX(0)
number_input_points = len(x_data) - 1
num_bins = number_input_points / self._number_points_per_bin
self._e_width = (abs(self._e_min) + abs(self._e_max)) / num_bins
Expand Down Expand Up @@ -179,7 +179,7 @@ def _calculate_parameters(self):
self._e_min, self._e_max, self._e_width,
resolution, resolution_bins])

DeleteWorkspace('__Fury_sample_cropped')
DeleteWorkspace('__TransformToIqt_sample_cropped')

self.setProperty('ParameterWorkspace', param_table)

Expand Down Expand Up @@ -212,7 +212,7 @@ def _add_logs(self):

def _fury(self):
"""
Run Fury.
Run TransformToIqt.
"""
from IndirectCommon import CheckHistZero, CheckHistSame, CheckAnalysers

Expand Down Expand Up @@ -261,4 +261,4 @@ def _fury(self):


# Register algorithm with Mantid
AlgorithmFactory.subscribe(Fury)
AlgorithmFactory.subscribe(TransformToIqt)
4 changes: 2 additions & 2 deletions Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp
Expand Up @@ -94,7 +94,7 @@ namespace IDA
bool plot = m_uiForm.ckPlot->isChecked();
bool save = m_uiForm.ckSave->isChecked();

IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("Fury", -1);
IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("TransformToIqt", -1);
furyAlg->initialize();

furyAlg->setProperty("Sample", wsName.toStdString());
Expand Down Expand Up @@ -192,7 +192,7 @@ namespace IDA
if(numBins == 0)
return;

IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("Fury");
IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("TransformToIqt");
furyAlg->initialize();

furyAlg->setProperty("Sample", wsName.toStdString());
Expand Down
Expand Up @@ -682,7 +682,7 @@ def get_reference_files(self):

#==============================================================================
class ISISIndirectInelasticMoments(ISISIndirectInelasticBase):
'''A base class for the ISIS indirect inelastic Fury/FuryFit tests
'''A base class for the ISIS indirect inelastic TransformToIqt/TransformToIqtFit tests
The output of Elwin is usually used with MSDFit and so we plug one into
the other in this test.
Expand Down Expand Up @@ -865,7 +865,7 @@ def _run(self):
LoadNexus(sample, OutputWorkspace=sample)
LoadNexus(self.resolution, OutputWorkspace=self.resolution)

fury_props, fury_ws = Fury(Sample=self.samples[0],
fury_props, fury_ws = TransformToIqt(Sample=self.samples[0],
Resolution=self.resolution,
EnergyMin=self.e_min,
EnergyMax=self.e_max,
Expand Down Expand Up @@ -922,7 +922,7 @@ class OSIRISFuryAndFuryFit(ISISIndirectInelasticFuryAndFuryFit):
def __init__(self):
ISISIndirectInelasticFuryAndFuryFit.__init__(self)

# Fury
# TransformToIqt
self.samples = ['osi97935_graphite002_red.nxs']
self.resolution = 'osi97935_graphite002_res.nxs'
self.e_min = -0.4
Expand All @@ -947,7 +947,7 @@ class IRISFuryAndFuryFit(ISISIndirectInelasticFuryAndFuryFit):
def __init__(self):
ISISIndirectInelasticFuryAndFuryFit.__init__(self)

# Fury
# TransformToIqt
self.samples = ['irs53664_graphite002_red.nxs']
self.resolution = 'irs53664_graphite002_res.nxs'
self.e_min = -0.4
Expand Down Expand Up @@ -1045,7 +1045,7 @@ def skipTests(self):
def __init__(self):
ISISIndirectInelasticFuryAndFuryFitMulti.__init__(self)

# Fury
# TransformToIqt
self.samples = ['osi97935_graphite002_red.nxs']
self.resolution = 'osi97935_graphite002_res.nxs'
self.e_min = -0.4
Expand All @@ -1070,7 +1070,7 @@ class IRISFuryAndFuryFitMulti(ISISIndirectInelasticFuryAndFuryFitMulti):
def __init__(self):
ISISIndirectInelasticFuryAndFuryFitMulti.__init__(self)

# Fury
# TransformToIqt
self.samples = ['irs53664_graphite002_red.nxs']
self.resolution = 'irs53664_graphite002_res.nxs'
self.e_min = -0.4
Expand Down
24 changes: 0 additions & 24 deletions Code/Mantid/docs/source/algorithms/Fury-v1.rst

This file was deleted.

79 changes: 79 additions & 0 deletions Code/Mantid/docs/source/algorithms/TransformToIqt-v1.rst
@@ -0,0 +1,79 @@
.. algorithm::

.. summary::

.. alias::

.. properties::

Description
-----------

The measured spectrum :math:`I(Q, \omega)` is proportional to the four
dimensional convolution of the scattering law :math:`S(Q, \omega)` with the
resolution function :math:`R(Q, \omega)` of the spectrometer via :math:`I(Q,
\omega) = S(Q, \omega) ⊗ R(Q, \omega)`, so :math:`S(Q, \omega)` can be obtained,
in principle, by a deconvolution in :math:`Q` and :math:`\omega`. The method
employed here is based on the Fourier Transform (FT) technique [6,7]. On Fourier
transforming the equation becomes :math:`I(Q, t) = S(Q, t) x R(Q, t)` where the
convolution in :math:`\omega`-space is replaced by a simple multiplication in
:math:`t`-space. The intermediate scattering law :math:`I(Q, t)` is then
obtained by simple division and the scattering law :math:`S(Q, \omega)` itself
can be obtained by back transformation. The latter however is full of pitfalls
for the unwary. The advantage of this technique over that of a fitting procedure
such as SWIFT is that a functional form for :math:`I(Q, t)` does not have to be
assumed. On IRIS the resolution function is close to a Lorentzian and the
scattering law is often in the form of one or more Lorentzians. The FT of a
Lorentzian is a decaying exponential, :math:`exp(-\alpha t)` , so that plots of
:math:`ln(I(Q, t))` against t would be straight lines thus making interpretation
easier.

In general, the origin in energy for the sample run and the resolution run need
not necessarily be the same or indeed be exactly zero in the conversion of the
RAW data from time-of-flight to energy transfer. This will depend, for example,
on the sample and vanadium shapes and positions and whether the analyser
temperature has changed between the runs. The procedure takes this into account
automatically, without using an arbitrary fitting procedure, in the following
way. From the general properties of the FT, the transform of an offset
Lorentzian has the form :math:`(cos(\omega_{0}t) + isin(\omega_{0}t))exp(-\Gamma
t)` , thus taking the modulus produces the exponential :math:`exp(-\Gamma t)`
which is the required function. If this is carried out for both sample and
resolution, the difference in the energy origin is automatically removed. The
results of this procedure should however be treated with some caution when
applied to more complicated spectra in which it is possible for :math:`I(Q, t)`
to become negative, for example, when inelastic side peaks are comparable in
height to the elastic peak.

The interpretation of the data must also take into account the propagation of
statistical errors (counting statistics) in the measured data as discussed by
Wild et al [1]. If the count in channel :math:`k` is :math:`X_{k}` , then
:math:`X_{k}=<X_{k}>+\Delta X_{k}` where :math:`<X_{k}>` is the mean value and
:math:`\Delta X_{k}` the error. The standard deviation for channel :math:`k` is
:math:`\sigma k` :math:`2=<\Delta X_{k}>2` which is assumed to be given by
:math:`\sigma k=<X_{k}>`. The FT of :math:`X_{k}` is defined by
:math:`X_{j}=<X_{j}>+\Delta X_{j}` and the real and imaginary parts denoted by
:math:`X_{j} I` and :math:`X_{j} I` respectively. The standard deviations on
:math:`X_{j}` are then given by :math:`\sigma 2(X_{j} R)=1/2 X0 R + 1/2 X2j R`
and :math:`\sigma 2(X_{j} I)=1/2 X0 I - 1/2 X2j I`.

Note that :math:`\sigma 2(X_{0} R) = X_{0} R` and from the properties of FT
:math:`X_{0} R = X_{k}`. Thus the standard deviation of the first coefficient
of the FT is the square root of the integrated intensity of the spectrum. In
practice, apart from the first few coefficients, the error is nearly constant
and close to :math:`X_{0} R`. A further point to note is that the errors make
the imaginary part of :math:`I(Q, t)` non-zero and that, although these will be
distributed about zero, on taking the modulus of :math:`I(Q, t)`, they become
positive at all times and are distributed about a non-zero positive value. When
:math:`I(Q, t)` is plotted on a log-scale the size of the error bars increases
with time (coefficient) and for the resolution will reach a point where the
error on a coefficient is comparable to its value. This region must therefore be
treated with caution. For a true deconvolution by back transforming, the data
would be truncated to remove this poor region before back transforming. If the
truncation is severe the back transform may contain added ripples, so an
automatic back transform is not provided.

References:

1. U P Wild, R Holzwarth & H P Good, Rev Sci Instr 48 1621 (1977)

.. categories::
72 changes: 1 addition & 71 deletions Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst
Expand Up @@ -144,7 +144,7 @@ Fury
:widget: tabFury

Given sample and resolution inputs, carries out a fit as per the theory detailed
below.
in the :ref:`TransformToIqt <algm-TransformToIqt>` algorithm.

Options
~~~~~~~
Expand Down Expand Up @@ -194,76 +194,6 @@ ResolutionBins
Number of bins in the resolution after rebinning, typically this should be at
least 5 and a warning will be shown if it is less.

Theory
~~~~~~

The measured spectrum :math:`I(Q, \omega)` is proportional to the four
dimensional convolution of the scattering law :math:`S(Q, \omega)` with the
resolution function :math:`R(Q, \omega)` of the spectrometer via :math:`I(Q,
\omega) = S(Q, \omega) ⊗ R(Q, \omega)`, so :math:`S(Q, \omega)` can be obtained,
in principle, by a deconvolution in :math:`Q` and :math:`\omega`. The method
employed here is based on the Fourier Transform (FT) technique [6,7]. On Fourier
transforming the equation becomes :math:`I(Q, t) = S(Q, t) x R(Q, t)` where the
convolution in :math:`\omega`-space is replaced by a simple multiplication in
:math:`t`-space. The intermediate scattering law :math:`I(Q, t)` is then
obtained by simple division and the scattering law :math:`S(Q, \omega)` itself
can be obtained by back transformation. The latter however is full of pitfalls
for the unwary. The advantage of this technique over that of a fitting procedure
such as SWIFT is that a functional form for :math:`I(Q, t)` does not have to be
assumed. On IRIS the resolution function is close to a Lorentzian and the
scattering law is often in the form of one or more Lorentzians. The FT of a
Lorentzian is a decaying exponential, :math:`exp(-\alpha t)` , so that plots of
:math:`ln(I(Q, t))` against t would be straight lines thus making interpretation
easier.

In general, the origin in energy for the sample run and the resolution run need
not necessarily be the same or indeed be exactly zero in the conversion of the
RAW data from time-of-flight to energy transfer. This will depend, for example,
on the sample and vanadium shapes and positions and whether the analyser
temperature has changed between the runs. The procedure takes this into account
automatically, without using an arbitrary fitting procedure, in the following
way. From the general properties of the FT, the transform of an offset
Lorentzian has the form :math:`(cos(\omega_{0}t) + isin(\omega_{0}t))exp(-\Gamma
t)` , thus taking the modulus produces the exponential :math:`exp(-\Gamma t)`
which is the required function. If this is carried out for both sample and
resolution, the difference in the energy origin is automatically removed. The
results of this procedure should however be treated with some caution when
applied to more complicated spectra in which it is possible for :math:`I(Q, t)`
to become negative, for example, when inelastic side peaks are comparable in
height to the elastic peak.

The interpretation of the data must also take into account the propagation of
statistical errors (counting statistics) in the measured data as discussed by
Wild et al [1]. If the count in channel :math:`k` is :math:`X_{k}` , then
:math:`X_{k}=<X_{k}>+\Delta X_{k}` where :math:`<X_{k}>` is the mean value and
:math:`\Delta X_{k}` the error. The standard deviation for channel :math:`k` is
:math:`\sigma k` :math:`2=<\Delta X_{k}>2` which is assumed to be given by
:math:`\sigma k=<X_{k}>`. The FT of :math:`X_{k}` is defined by
:math:`X_{j}=<X_{j}>+\Delta X_{j}` and the real and imaginary parts denoted by
:math:`X_{j} I` and :math:`X_{j} I` respectively. The standard deviations on
:math:`X_{j}` are then given by :math:`\sigma 2(X_{j} R)=1/2 X0 R + 1/2 X2j R`
and :math:`\sigma 2(X_{j} I)=1/2 X0 I - 1/2 X2j I`.

Note that :math:`\sigma 2(X_{0} R) = X_{0} R` and from the properties of FT
:math:`X_{0} R = X_{k}`. Thus the standard deviation of the first coefficient
of the FT is the square root of the integrated intensity of the spectrum. In
practice, apart from the first few coefficients, the error is nearly constant
and close to :math:`X_{0} R`. A further point to note is that the errors make
the imaginary part of :math:`I(Q, t)` non-zero and that, although these will be
distributed about zero, on taking the modulus of :math:`I(Q, t)`, they become
positive at all times and are distributed about a non-zero positive value. When
:math:`I(Q, t)` is plotted on a log-scale the size of the error bars increases
with time (coefficient) and for the resolution will reach a point where the
error on a coefficient is comparable to its value. This region must therefore be
treated with caution. For a true deconvolution by back transforming, the data
would be truncated to remove this poor region before back transforming. If the
truncation is severe the back transform may contain added ripples, so an
automatic back transform is not provided.

References:

1. U P Wild, R Holzwarth & H P Good, Rev Sci Instr 48 1621 (1977)

Fury Fit
--------

Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py
Expand Up @@ -288,7 +288,7 @@ def furyfitMult(inputWS, function, ftype, startx, endx, spec_min=0, spec_max=Non
if Plot != 'None':
furyfitPlotSeq(result_workspace, Plot)

EndTime('FuryFit Multi')
EndTime('TransformToIqtFit Multi')
return result_workspace


Expand Down

0 comments on commit ff62e1b

Please sign in to comment.