Mantid
Loading...
Searching...
No Matches
Plus.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 +
9
10using namespace Mantid::API;
11using namespace Mantid::Kernel;
12using namespace Mantid::DataObjects;
13
14namespace Mantid::Algorithms {
15// Register the class into the algorithm factory
17
18// ===================================== HISTOGRAM BINARY OPERATIONS
19// ==========================================
20//---------------------------------------------------------------------------------------------
21void Plus::performBinaryOperation(const HistogramData::Histogram &lhs, const HistogramData::Histogram &rhs,
22 HistogramData::HistogramY &YOut, HistogramData::HistogramE &EOut) {
23 std::transform(lhs.y().begin(), lhs.y().end(), rhs.y().begin(), YOut.begin(), std::plus<>());
24 std::transform(lhs.e().begin(), lhs.e().end(), rhs.e().begin(), EOut.begin(), VectorHelper::SumGaussError<double>());
25}
26
27//---------------------------------------------------------------------------------------------
28void Plus::performBinaryOperation(const HistogramData::Histogram &lhs, const double rhsY, const double rhsE,
29 HistogramData::HistogramY &YOut, HistogramData::HistogramE &EOut) {
30 using std::placeholders::_1;
31 std::transform(lhs.y().begin(), lhs.y().end(), YOut.begin(), [rhsY](double l) { return l + rhsY; });
32 // Only do E if non-zero, otherwise just copy
33
34 if (rhsE != 0.) {
35 double rhsE2 = rhsE * rhsE;
36 std::transform(lhs.e().begin(), lhs.e().end(), EOut.begin(),
37 [rhsE2](double l) { return std::sqrt(l * l + rhsE2); });
38 } else
39 EOut = lhs.e();
40}
41
42// ===================================== EVENT LIST BINARY OPERATIONS
43// ==========================================
52 // Easy, no? :) - This appends the event lists.
53 lhs += rhs;
54}
55
65 const MantidVec &rhsE) {
66 (void)lhs; // Avoid compiler warnings
67 (void)rhsX;
68 (void)rhsY;
69 (void)rhsE;
70 throw Exception::NotImplementedError("Plus::performEventBinaryOperation() cannot add a histogram to an event "
71 "list in an EventWorkspace. Try switching to a Workspace2D before "
72 "adding.");
73}
74
83void Plus::performEventBinaryOperation(DataObjects::EventList &lhs, const double &rhsY, const double &rhsE) {
84 (void)lhs; // Avoid compiler warnings
85 (void)rhsY;
86 (void)rhsE;
87 throw Exception::NotImplementedError("Plus::performEventBinaryOperation() "
88 "cannot add a number to an event list "
89 "in an EventWorkspace. Try switching to "
90 "a Workspace2D before adding.");
91}
92
93//---------------------------------------------------------------------------------------------
101 if (m_erhs && m_elhs) {
102 // Two EventWorkspaces! They can be concatenated.
103 // Output will be EW
105 // Histogram sizes need not match
106 m_matchXSize = false;
107 // If adding in place to the right-hand-side: flip it so you add in-place to
108 // the lhs.
111 // Special case for plus/minus: if there is only one bin on the RHS, use the
112 // 2D method (appending event lists)
113 // so that the single bin is not treated as a scalar
115 } else {
116 // either or both workspace are "other"
117 // Use the default behaviour
119
120 // Except that commutation is possible
121 // If LHS is smaller, e.g. single-value, flip sides to put it on the right
122 m_flipSides = (m_lhs->size() < m_rhs->size());
123 }
124}
125
126//---------------------------------------------------------------------------------------------
136 if (lhs->size() > 1 && rhs->size() > 1) {
137 if (lhs->YUnit() != rhs->YUnit()) {
138 g_log.error("The two workspaces are not compatible because they have "
139 "different units for the data (Y).");
140 return false;
141 }
142 if (lhs->isDistribution() != rhs->isDistribution()) {
143 g_log.error("The two workspaces are not compatible because one is "
144 "flagged as a distribution.");
145 return false;
146 }
147 }
148 return true;
149}
150
151//---------------------------------------------------------------------------------------------
161 if (!checkUnitCompatibility(lhs, rhs))
162 return false;
163
164 // Keep checking more generally.
166}
167
168//--------------------------------------------------------------------------------------------
181 if (m_erhs && m_elhs) {
182 if (lhs->getNumberHistograms() == rhs->getNumberHistograms()) {
183 return "";
184 } else {
185 return "Number of histograms not identical.";
186 }
187 } else {
188 // get the largest workspace
191 if (rhs->size() > lhs->size()) {
192 wsLarger = rhs;
193 wsSmaller = lhs;
194 } else {
195 wsLarger = lhs;
196 wsSmaller = rhs;
197 }
198 // call the base routine
199 return BinaryOperation::checkSizeCompatibility(wsLarger, wsSmaller);
200 }
201}
202
203//---------------------------------------------------------------------------------------------
210void Plus::operateOnRun(const Run &lhs, const Run &rhs, Run &ans) const {
211 // The addition operator of Run will add the proton charges, append logs, etc.
212 // If ans=lhs or ans=rhs then we need to be careful in which order we do this
213 if (&rhs == &ans) {
214 // The output is the same as the RHS workspace so needs to be set to that
215 // run object
216 ans = rhs;
217 ans += lhs;
218 } else {
219 // The output is either the same as the LHS workspace so needs to be set to
220 // that run object
221 // or it is a completely separate workspace meaning that it actually doesn't
222 // matter
223 ans = lhs;
224 ans += rhs;
225 }
226}
227} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
const std::vector< double > & rhs
This class stores information regarding an experimental run as a series of log entries.
Definition: Run.h:38
bool m_do2D_even_for_SingleColumn_on_rhs
Special case for plus/minus: if there is only one bin on the RHS, use the 2D method (appending event ...
bool m_keepEventWorkspace
Variable set to true if the operation allows the output to stay as an EventWorkspace.
virtual bool checkCompatibility(const API::MatrixWorkspace_const_sptr lhs, const API::MatrixWorkspace_const_sptr rhs) const
Checks the compatibility of the two workspaces.
DataObjects::EventWorkspace_sptr m_eout
Output EventWorkspace.
virtual std::string checkSizeCompatibility(const API::MatrixWorkspace_const_sptr lhs, const API::MatrixWorkspace_const_sptr rhs) const
Checks the overall size compatibility of two workspaces.
bool m_useHistogramForRhsEventWorkspace
Are we going to use the histogram representation of the RHS event list when performing the operation?...
bool m_matchXSize
matchXSize set to true if the X sizes of histograms must match.
bool m_flipSides
flipSides set to true if the rhs and lhs operands should be flipped - for commutative binary operatio...
DataObjects::EventWorkspace_const_sptr m_erhs
Right-hand side EventWorkspace.
DataObjects::EventWorkspace_const_sptr m_elhs
Left-hand side EventWorkspace.
API::MatrixWorkspace_const_sptr m_rhs
Right-hand side workspace.
virtual void checkRequirements()
Check what operation will be needed in order to apply the operation to these two types of workspaces.
API::MatrixWorkspace_const_sptr m_lhs
Left-hand side workspace.
Plus performs the addition of two input workspaces.
Definition: Plus.h:32
void performEventBinaryOperation(DataObjects::EventList &lhs, const DataObjects::EventList &rhs) override
Carries out the binary operation IN-PLACE on a single EventList, with another EventList as the right-...
Definition: Plus.cpp:51
bool checkUnitCompatibility(const API::MatrixWorkspace_const_sptr &lhs, const API::MatrixWorkspace_const_sptr &rhs) const
Return true if the units and distribution-type of the workspaces make them compatible.
Definition: Plus.cpp:134
std::string checkSizeCompatibility(const API::MatrixWorkspace_const_sptr lhs, const API::MatrixWorkspace_const_sptr rhs) const override
Performs a simple check to see if the sizes of two workspaces are compatible for a binary operation I...
Definition: Plus.cpp:179
void checkRequirements() override
Check what operation will be needed in order to apply the operation to these two types of workspaces.
Definition: Plus.cpp:100
void operateOnRun(const API::Run &lhs, const API::Run &rhs, API::Run &ans) const override
Adds the integrated proton currents, proton charges, of the two input workspaces together.
Definition: Plus.cpp:210
void performBinaryOperation(const HistogramData::Histogram &lhs, const HistogramData::Histogram &rhs, HistogramData::HistogramY &YOut, HistogramData::HistogramE &EOut) override
Carries out the binary operation on a single spectrum, with another spectrum as the right-hand operan...
Definition: Plus.cpp:21
bool checkCompatibility(const API::MatrixWorkspace_const_sptr lhs, const API::MatrixWorkspace_const_sptr rhs) const override
Check the given workspaces for unit, distribution and binary operation compatibility.
Definition: Plus.cpp:159
A class for holding :
Definition: EventList.h:56
Marks code as not implemented yet.
Definition: Exception.h:138
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
Definition: cow_ptr.h:172
Functor used for computing the sum of the square values of a vector, using the accumulate algorithm.
Definition: VectorHelper.h:150