diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py similarity index 95% rename from Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py rename to Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py index ab8aff547baf..5c2cf1fe5ec4 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py @@ -7,7 +7,7 @@ import os -class Fury(PythonAlgorithm): +class TransformToIqt(PythonAlgorithm): _sample = None _resolution = None @@ -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), @@ -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) @@ -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 == '': @@ -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 @@ -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) @@ -212,7 +212,7 @@ def _add_logs(self): def _fury(self): """ - Run Fury. + Run TransformToIqt. """ from IndirectCommon import CheckHistZero, CheckHistSame, CheckAnalysers @@ -261,4 +261,4 @@ def _fury(self): # Register algorithm with Mantid -AlgorithmFactory.subscribe(Fury) +AlgorithmFactory.subscribe(TransformToIqt) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp index 87c3b3416da0..f2bd5459329c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp @@ -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()); @@ -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()); diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py index 573b3654654d..17d104c215a7 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py @@ -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. @@ -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, @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/Code/Mantid/docs/source/algorithms/Fury-v1.rst b/Code/Mantid/docs/source/algorithms/Fury-v1.rst deleted file mode 100644 index a82a566e5ec7..000000000000 --- a/Code/Mantid/docs/source/algorithms/Fury-v1.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. algorithm:: - -.. summary:: - -.. alias:: - -.. properties:: - -Description ------------ - -The model that is being fitted is that of a delta-function (elastic component) of amplitude :math:`A(0)` and Lorentzians of amplitude :math:`A(j)` and HWHM :math:`W(j)` where :math:`j=1,2,3`. The whole function is then convolved with the resolution function. The -function and Lorentzians are intrinsically -normalised to unity so that the amplitudes represent their integrated areas. - -For a Lorentzian, the Fourier transform does the conversion: :math:`1/(x^{2}+\delta^{2}) \Leftrightarrow exp[-2\pi(\delta k)]`. -If :math:`x` is identified with energy :math:`E` and :math:`2\pi k` with :math:`t/\hbar` where t is time then: :math:`1/[E^{2}+(\hbar / \tau )^{2}] \Leftrightarrow exp[-t /\tau]` and :math:`\sigma` is identified with :math:`\hbar / \tau`. -The program estimates the quasielastic components of each of the groups of spectra and requires the resolution file and optionally the normalisation file created by ResNorm. - -For a Stretched Exponential, the choice of several Lorentzians is replaced with a single function with the shape : :math:`\psi\beta(x) \Leftrightarrow exp[-2\pi(\sigma k)\beta]`. This, in the energy to time FT transformation, is :math:`\psi\beta(E) \Leftrightarrow exp[-(t/\tau)\beta]`. So \sigma is identified with :math:`(2\pi)\beta\hbar/\tau`. -The model that is fitted is that of an elastic component and the stretched exponential and the program gives the best estimate for the :math:`\beta` parameter and the width for each group of spectra. - -This routine was originally part of the MODES package. - -.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/TransformToIqt-v1.rst b/Code/Mantid/docs/source/algorithms/TransformToIqt-v1.rst new file mode 100644 index 000000000000..e3b9ecf1d4be --- /dev/null +++ b/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}=+\Delta X_{k}` where :math:`` 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=`. The FT of :math:`X_{k}` is defined by +:math:`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:: diff --git a/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst b/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst index 30201258338f..604af290896c 100644 --- a/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst +++ b/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst @@ -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 ` algorithm. Options ~~~~~~~ @@ -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}=+\Delta X_{k}` where :math:`` 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=`. The FT of :math:`X_{k}` is defined by -:math:`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 -------- diff --git a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py index c258965efba5..a1d11b69033a 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py +++ b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py @@ -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