Mantid
Loading...
Searching...
No Matches
HistogramDomainCreator.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 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 +
13
14namespace Mantid::CurveFitting {
15
16using namespace API;
17
25 const std::string &workspacePropertyName)
26 : IMWDomainCreator(&manager, workspacePropertyName) {}
27
35void HistogramDomainCreator::createDomain(std::shared_ptr<FunctionDomain> &domain,
36 std::shared_ptr<FunctionValues> &values, size_t i0) {
37
39
40 if (!m_matrixWorkspace->isHistogramData()) {
41 throw std::runtime_error("Cannot create a histogram domain from point data.");
42 }
43
44 if (m_domainType != Simple) {
45 throw std::runtime_error("Cannot create non-simple domain for histogram fitting.");
46 }
47
48 const auto &X = m_matrixWorkspace->x(m_workspaceIndex);
49
50 // find the fitting interval: from -> to
51 size_t endIndex = 0;
52 std::tie(m_startIndex, endIndex) = getXInterval();
53 auto fromX = X.begin() + m_startIndex;
54 auto toX = X.begin() + endIndex + 1;
55
56 domain.reset(new API::FunctionDomain1DHistogram(fromX, toX));
57 assert(endIndex - m_startIndex == domain->size());
58
59 if (!values) {
60 values.reset(new API::FunctionValues(*domain));
61 } else {
62 values->expand(i0 + domain->size());
63 }
64
65 // set the data to fit to
66 const auto &Y = m_matrixWorkspace->counts(m_workspaceIndex);
67 const auto &E = m_matrixWorkspace->countStandardDeviations(m_workspaceIndex);
68 if (endIndex > Y.size()) {
69 throw std::runtime_error("FitMW: Inconsistent MatrixWorkspace");
70 }
71
72 for (size_t i = m_startIndex; i < endIndex; ++i) {
73 size_t j = i - m_startIndex + i0;
74 double y = Y[i];
75 double error = E[i];
76 double weight = 0.0;
77
78 if (!std::isfinite(y)) // nan or inf data
79 {
81 throw std::runtime_error("Infinte number or NaN found in input data.");
82 y = 0.0; // leaving inf or nan would break the fit
83 } else if (!std::isfinite(error)) // nan or inf error
84 {
86 throw std::runtime_error("Infinte number or NaN found in input data.");
87 } else if (error <= 0) {
89 weight = 1.0;
90 } else {
91 weight = 1.0 / error;
92 }
93
94 values->setFitData(j, y);
95 values->setFitWeight(j, weight);
96 }
97 m_domain = std::dynamic_pointer_cast<API::FunctionDomain1D>(domain);
98 m_values = values;
99}
100
109std::shared_ptr<API::Workspace> HistogramDomainCreator::createOutputWorkspace(
110 const std::string &baseName, API::IFunction_sptr function, std::shared_ptr<API::FunctionDomain> domain,
111 std::shared_ptr<API::FunctionValues> values, const std::string &outputWorkspacePropertyName) {
112 auto ws = IMWDomainCreator::createOutputWorkspace(baseName, function, domain, values, outputWorkspacePropertyName);
113
114 if (m_matrixWorkspace->isDistribution()) {
115 // Convert the calculated values to distribution
116 auto &mws = dynamic_cast<MatrixWorkspace &>(*ws);
117 auto &bins = dynamic_cast<FunctionDomain1DHistogram &>(*domain);
118 for (size_t iSpec = 1; iSpec < mws.getNumberHistograms(); ++iSpec) {
119 if (iSpec == 2) {
120 // skip the diff spectrum
121 continue;
122 }
123 auto &y = mws.mutableY(iSpec);
124 auto &e = mws.mutableE(iSpec);
125 double left = bins.leftBoundary();
126 for (size_t i = 0; i < bins.size(); ++i) {
127 double right = bins[i];
128 double dx = right - left;
129 y[i] /= dx;
130 e[i] /= dx;
131 left = right;
132 }
133 }
134 }
135
136 return ws;
137}
138
139} // namespace Mantid::CurveFitting
double error
double left
double right
Implements FunctionDomain1D as a set of bins for a histogram.
double leftBoundary() const
Get the leftmost boundary.
A class to store values calculated by a function.
bool m_ignoreInvalidData
Flag to ignore nans, infinities and zero errors.
DomainType m_domainType
Domain type.
Base MatrixWorkspace Abstract Class.
std::shared_ptr< API::Workspace > createOutputWorkspace(const std::string &baseName, API::IFunction_sptr function, std::shared_ptr< API::FunctionDomain > domain, std::shared_ptr< API::FunctionValues > values, const std::string &outputWorkspacePropertyName) override
Create an output workspace with the calculated values.
void createDomain(std::shared_ptr< API::FunctionDomain > &domain, std::shared_ptr< API::FunctionValues > &values, size_t i0=0) override
Creates a domain corresponding to the assigned MatrixWorkspace.
HistogramDomainCreator(Kernel::IPropertyManager &manager, const std::string &workspacePropertyName)
Constructor.
A base class for domain creators taking 1D data from a spectrum of a matrix workspace.
std::weak_ptr< API::FunctionDomain1D > m_domain
Store the created domain and values.
std::pair< size_t, size_t > getXInterval() const
Calculate size and starting iterator in the X array.
std::shared_ptr< API::MatrixWorkspace > m_matrixWorkspace
The input MareixWorkspace.
std::weak_ptr< API::FunctionValues > m_values
virtual void setParameters() const
Set all parameters.
size_t m_workspaceIndex
The workspace index.
std::shared_ptr< API::Workspace > createOutputWorkspace(const std::string &baseName, API::IFunction_sptr function, std::shared_ptr< API::FunctionDomain > domain, std::shared_ptr< API::FunctionValues > values, const std::string &outputWorkspacePropertyName) override
Create an output workspace.
Interface to PropertyManager.
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition IFunction.h:749