15#include <gsl/gsl_poly.h>
24const char *MASS_NAME =
"Mass";
40 const auto &spectrumInfo = ws->spectrumInfo();
41 if (!spectrumInfo.hasDetectors(
index))
42 throw std::invalid_argument(
"VesuvioResolution - Workspace has no detector "
43 "attached to histogram at index " +
47 const auto &
pmap = ws->constInstrumentParameters();
48 const auto &det = spectrumInfo.detector(
index);
60 m_resolutionSigma(0.0), m_lorentzFWHM(0.0) {}
85 double startX,
double endX) {
102 double theta = detpar.
theta;
111 const double k1 = std::sqrt(detpar.
efixed / mevToK);
112 const double l2l1 = detpar.
l2 / detpar.
l1;
120 if ((
m_mass - 1.0) > DBL_EPSILON) {
121 double x0(0.0), x1(0.0);
122 gsl_poly_solve_quadratic(
m_mass - 1.0, 2.0 * std::cos(theta), -(
m_mass + 1.0), &x0, &x1);
123 k0k1 = std::max(x0, x1);
126 k0k1 = 1.0 / std::cos(theta);
128 double qy0(0.0), wgauss(0.0);
131 qy0 = std::sqrt(k1 * k1 *
m_mass * (k0k1 * k0k1 - 1));
132 double k0k1p3 = std::pow(k0k1, 3);
133 double r1 = -(1.0 + l2l1 * k0k1p3);
134 double r2 = 1.0 - l2l1 * k0k1p3 + l2l1 * std::pow(k0k1, 2) * std::cos(theta) - k0k1 * std::cos(theta);
136 double factor = (0.2413 / qy0) * ((
m_mass / mn) * r1 - r2);
138 wgauss = std::abs(factor * hwhmGaussE * 2);
140 qy0 = k1 * std::tan(theta);
141 double factor = (0.2413 * 2.0 / k1) * std::abs((std::cos(theta) + l2l1) / std::sin(theta));
143 wgauss = hwhmGaussE * factor;
146 double k0y0 = k1 * k0k1;
147 double wtheta = 2.0 *
STDDEV_TO_HWHM * std::abs(k0y0 * k1 * std::sin(theta) / qy0) * respar.
dthe;
148 double common = (
m_mass / mn) - 1 + k1 * std::cos(theta) / k0y0;
149 double wl1 = 2.0 *
STDDEV_TO_HWHM * std::abs((std::pow(k0y0, 2) / (qy0 * detpar.
l1)) * common) * respar.
dl1;
150 double wl2 = 2.0 *
STDDEV_TO_HWHM * std::abs((std::pow(k0y0, 3) / (k1 * qy0 * detpar.
l1)) * common) * respar.
dl2;
152 m_resolutionSigma = std::sqrt(std::pow(wgauss, 2) + std::pow(wtheta, 2) + std::pow(wl1, 2) + std::pow(wl2, 2));
163 std::vector<double> outVec(
static_cast<int>(nData), 0);
164 const std::vector<double> xValuesVec(xValues, xValues + nData);
166 std::copy(outVec.begin(), outVec.end(), out);
177 if (
name == MASS_NAME)
191 const double lorentzPos,
const double lorentzAmp)
const {
207 const double lorentzPos,
const double lorentzAmp,
const double lorentzWidth,
208 const double gaussWidth)
const {
209 m_voigt->setParameter(0, lorentzAmp);
210 m_voigt->setParameter(1, lorentzPos);
211 m_voigt->setParameter(2, lorentzWidth);
212 m_voigt->setParameter(3, gaussWidth);
213 assert(voigt.size() == xValues.size());
214 m_voigt->functionLocal(voigt.data(), xValues.data(), xValues.size());
217 const double norm = 1.0 / (0.5 * M_PI * lorentzWidth);
218 using std::placeholders::_1;
219 std::transform(voigt.begin(), voigt.end(), voigt.begin(), std::bind(std::multiplies<double>(), _1, norm));
double value
The value of the point.
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
This is a specialization of IFunction for functions of one real argument.
Attribute is a non-fitting parameter.
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
Implements the part of IFunction interface dealing with parameters.
static DetectorParams getDetectorParameters(const API::MatrixWorkspace_const_sptr &ws, const size_t index)
Creates a POD struct containing the required detector parameters for this spectrum.
static double getComponentParameter(const Geometry::IComponent &det, const Geometry::ParameterMap &pmap, const std::string &name)
Retrieve a component parameter.
Calculate the resolution from a workspace of Vesuvio data using the mass & instrument definition.
static ResolutionParams getResolutionParameters(const API::MatrixWorkspace_const_sptr &ws, const size_t index)
Creates a POD struct containing the required resolution parameters for this spectrum.
size_t m_wsIndex
Current workspace index, required to access instrument parameters.
double m_mass
Store the mass values.
void declareAttributes() override
Declare parameters that will never participate in the fit.
void setUpForFit() override
Ensure the object is ready to be fitted.
Kernel::Logger m_log
Logger.
double m_resolutionSigma
Total resolution width.
void voigtApprox(std::vector< double > &voigt, const std::vector< double > &xValues, const double lorentzPos, const double lorentzAmp, const double lorentzWidth, const double gaussWidth) const
Compute Voigt function.
VesuvioResolution()
Default constructor required for factory.
std::string name() const override
void cacheResolutionComponents(const Algorithms::DetectorParams &detpar, const ResolutionParams &respar)
Pre-calculate the resolution components values.
void function1D(double *out, const double *xValues, const size_t nData) const override
Calculate the function.
std::shared_ptr< API::IPeakFunction > m_voigt
Voigt function.
double m_lorentzFWHM
Lorentz FWHM.
void setMatrixWorkspace(std::shared_ptr< const API::MatrixWorkspace > workspace, size_t wsIndex, double startX, double endX) override
Cache a copy of the workspace pointer and pull out the parameters.
void setAttribute(const std::string &name, const Attribute &value) override
Set an attribute value (and possibly cache its value)
void information(const std::string &msg)
Logs at information level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
const double STDDEV_TO_HWHM
static constexpr double E_mev_toNeutronWavenumberSq
Transformation coefficient to transform neutron energy into neutron wavevector: K-neutron[m^-10] = sq...
static constexpr double NeutronMassAMU
Mass of the neutron in AMU.
Helper class which provides the Collimation Length for SANS instruments.
Generate a tableworkspace to store the calibration results.
std::string to_string(const wide_integer< Bits, Signed > &n)
Simple data structure to store nominal detector values It avoids some functions taking a huge number ...
double efixed
final energy
double theta
scattering angle in radians
double l1
source-sample distance in metres
double l2
sample-detector distance in metres
Simple data structure to store resolution parameter values It avoids some functions taking a huge num...
double dl2
spread in sample-detector distance (m)
double dthe
spread in scattering angle (radians)
double dtof
spread in tof measurement (us)
double dl1
spread in source-sample distance (m)
double dEnLorentz
lorentz width in energy (meV)
double dEnGauss
gaussian width in energy (meV