/Framework/PythonInterface/plugins/functions/PrimStretchedExpFT.py

https://github.com/mantidproject/mantid · Python · 94 lines · 41 code · 11 blank · 42 comment · 1 complexity · 971a269812eb06e7e3fd9e4439709e11 MD5 · raw file

  1. # Mantid Repository : https://github.com/mantidproject/mantid
  2. #
  3. # Copyright © 2007 ISIS Rutherford Appleton Laboratory UKRI,
  4. # NScD Oak Ridge National Laboratory, European Spallation Source,
  5. # Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
  6. # SPDX - License - Identifier: GPL - 3.0 +
  7. # pylint: disable=invalid-name, anomalous-backslash-in-string, attribute-defined-outside-init
  8. """
  9. @author Jose Borreguero, NScD
  10. @date June 01, 2017
  11. """
  12. import numpy as np
  13. from mantid.api import IFunction1D, FunctionFactory
  14. from StretchedExpFTHelper import surrogate, function1Dcommon
  15. class PrimStretchedExpFT(IFunction1D):
  16. # pylint: disable=super-on-old-class
  17. def __init__(self):
  18. super(self.__class__, self).__init__()
  19. self._parmList = list()
  20. def category(self):
  21. return 'QuasiElastic'
  22. @surrogate
  23. def init(self):
  24. """Declare parameters that participate in the fitting"""
  25. pass
  26. @surrogate
  27. def validateParams(self):
  28. """Check parameters are positive"""
  29. pass
  30. def function1D(self, xvals, **optparms):
  31. r""" Fourier transform of the symmetrized stretched exponential integrated
  32. within each energy bin.
  33. The Symmetrized Stretched Exponential:
  34. height * exp( - |t/tau|**beta )
  35. The Fourier Transform:
  36. F(E) \int_{-infty}^{infty} (dt/h) e^{-i2\pi Et/h} f(t)
  37. F(E) is normalized:
  38. \int_{-infty}^{infty} dE F(E) = 1
  39. Let P(E) be the primitive of F(E) from minus infinity to E, then for element i of
  40. xvals we compute:
  41. 1. bin_boundaries[i] = (xvals[i]+xvals[i+1])/2
  42. 3. P(bin_boundaries[i+1])- P(bin_boundaries[i])
  43. :param xvals: list of values where to evaluate the function
  44. :param optparms: alternate list of function parameters
  45. :return: P(bin_boundaries[i+1])- P(bin_boundaries[i]), the difference of the primitive
  46. """
  47. rf = 16
  48. parms, de, energies, fourier = function1Dcommon(
  49. self, xvals, rf=rf, **optparms)
  50. if parms is None:
  51. return fourier # return zeros if parameters not valid
  52. denergies = (energies[-1] - energies[0]) / (len(energies)-1)
  53. # Find bin boundaries
  54. boundaries = (xvals[1:]+xvals[:-1])/2 # internal bin boundaries
  55. # external lower boundary
  56. boundaries = np.insert(boundaries, 0, 2*xvals[0]-boundaries[0])
  57. # external upper boundary
  58. boundaries = np.append(boundaries, 2*xvals[-1]-boundaries[-1])
  59. primitive = np.cumsum(fourier) * (denergies / (rf*de)) # running Riemann sum
  60. transform = np.interp(boundaries[1:] - parms['Centre'], energies, primitive) - \
  61. np.interp(boundaries[:-1] - parms['Centre'], energies, primitive)
  62. return transform * parms['Height']
  63. @surrogate
  64. def fillJacobian(self, xvals, jacobian, partials):
  65. """Fill the jacobian object with the dictionary of partial derivatives
  66. :param xvals: domain where the derivatives are to be calculated
  67. :param jacobian: jacobian object
  68. :param partials: dictionary with partial derivates with respect to the
  69. fitting parameters
  70. """
  71. pass
  72. @surrogate
  73. def functionDeriv1D(self, xvals, jacobian):
  74. """Numerical derivative except for Height parameter"""
  75. # partial derivatives with respect to the fitting parameters
  76. pass
  77. # Required to have Mantid recognise the new function
  78. FunctionFactory.subscribe(PrimStretchedExpFT)