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 +
12
13namespace Mantid::CurveFitting {
14
15using namespace API;
16
24 const std::string &workspacePropertyName)
25 : IMWDomainCreator(&manager, workspacePropertyName) {}
26
34void HistogramDomainCreator::createDomain(std::shared_ptr<FunctionDomain> &domain,
35 std::shared_ptr<FunctionValues> &values, size_t i0) {
36
38
39 if (!m_matrixWorkspace->isHistogramData()) {
40 throw std::runtime_error("Cannot create a histogram domain from point data.");
41 }
42
43 if (m_domainType != Simple) {
44 throw std::runtime_error("Cannot create non-simple domain for histogram fitting.");
45 }
46
47 const auto &X = m_matrixWorkspace->x(m_workspaceIndex);
48
49 // find the fitting interval: from -> to
50 size_t endIndex = 0;
51 std::tie(m_startIndex, endIndex) = getXInterval();
52 auto fromX = X.begin() + m_startIndex;
53 auto toX = X.begin() + endIndex + 1;
54
55 domain.reset(new API::FunctionDomain1DHistogram(fromX, toX));
56 assert(endIndex - m_startIndex == domain->size());
57
58 if (!values) {
59 values.reset(new API::FunctionValues(*domain));
60 } else {
61 values->expand(i0 + domain->size());
62 }
63
64 // set the data to fit to
65 const auto &Y = m_matrixWorkspace->counts(m_workspaceIndex);
66 const auto &E = m_matrixWorkspace->countStandardDeviations(m_workspaceIndex);
67 if (endIndex > Y.size()) {
68 throw std::runtime_error("FitMW: Inconsistent MatrixWorkspace");
69 }
70
71 for (size_t i = m_startIndex; i < endIndex; ++i) {
72 size_t j = i - m_startIndex + i0;
73 double y = Y[i];
74 double error = E[i];
75 double weight = 0.0;
76
77 if (!std::isfinite(y)) // nan or inf data
78 {
80 throw std::runtime_error("Infinte number or NaN found in input data.");
81 y = 0.0; // leaving inf or nan would break the fit
82 } else if (!std::isfinite(error)) // nan or inf error
83 {
85 throw std::runtime_error("Infinte number or NaN found in input data.");
86 } else if (error <= 0) {
88 weight = 1.0;
89 } else {
90 weight = 1.0 / error;
91 }
92
93 values->setFitData(j, y);
94 values->setFitWeight(j, weight);
95 }
96 m_domain = std::dynamic_pointer_cast<API::FunctionDomain1D>(domain);
97 m_values = values;
98}
99
108std::shared_ptr<API::Workspace> HistogramDomainCreator::createOutputWorkspace(
109 const std::string &baseName, API::IFunction_sptr function, std::shared_ptr<API::FunctionDomain> domain,
110 std::shared_ptr<API::FunctionValues> values, const std::string &outputWorkspacePropertyName) {
111 auto ws = IMWDomainCreator::createOutputWorkspace(baseName, function, domain, values, outputWorkspacePropertyName);
112
113 if (m_matrixWorkspace->isDistribution()) {
114 // Convert the calculated values to distribution
115 auto &mws = dynamic_cast<MatrixWorkspace &>(*ws);
116 auto &bins = dynamic_cast<FunctionDomain1DHistogram &>(*domain);
117 for (size_t iSpec = 1; iSpec < mws.getNumberHistograms(); ++iSpec) {
118 if (iSpec == 2) {
119 // skip the diff spectrum
120 continue;
121 }
122 auto &y = mws.mutableY(iSpec);
123 auto &e = mws.mutableE(iSpec);
124 double left = bins.leftBoundary();
125 for (size_t i = 0; i < bins.size(); ++i) {
126 double right = bins[i];
127 double dx = right - left;
128 y[i] /= dx;
129 e[i] /= dx;
130 left = right;
131 }
132 }
133 }
134
135 return ws;
136}
137
138} // namespace Mantid::CurveFitting
double error
Definition: IndexPeaks.cpp:133
double left
Definition: LineProfile.cpp:80
double right
Definition: LineProfile.cpp:81
Implements FunctionDomain1D as a set of bins for a histogram.
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:732