Mantid
Loading...
Searching...
No Matches
DivideMD.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#include "MantidKernel/System.h"
13
14using namespace Mantid::Kernel;
15using namespace Mantid::API;
16using namespace Mantid::DataObjects;
17
18namespace Mantid::MDAlgorithms {
19
20// Register the algorithm into the AlgorithmFactory
21DECLARE_ALGORITHM(DivideMD)
22
23//----------------------------------------------------------------------------------------------
25const std::string DivideMD::name() const { return "DivideMD"; }
26
28int DivideMD::version() const { return 1; }
29
30//----------------------------------------------------------------------------------------------
31
32//----------------------------------------------------------------------------------------------
34bool DivideMD::commutative() const { return false; }
35
36//----------------------------------------------------------------------------------------------
39 if (m_rhs_event)
40 throw std::runtime_error("Cannot divide by a MDEventWorkspace on the RHS.");
42 throw std::runtime_error("A MDEventWorkspace can only be divided by a scalar.");
43}
44
45//----------------------------------------------------------------------------------------------
50template <typename MDE, size_t nd> void DivideMD::execEventScalar(typename MDEventWorkspace<MDE, nd>::sptr ws) {
51 // Get the scalar multiplying
52 auto scalar = float(m_rhs_scalar->y(0)[0]);
53 auto scalarError = float(m_rhs_scalar->e(0)[0]);
54 float scalarErrorSquared = scalarError * scalarError;
55 float inverseScalarSquared = 1.f / (scalar * scalar);
56
57 // Get all the MDBoxes contained
58 MDBoxBase<MDE, nd> *parentBox = ws->getBox();
59 std::vector<API::IMDNode *> boxes;
60 parentBox->getBoxes(boxes, 1000, true);
61
62 bool fileBackedTarget(false);
63 Kernel::DiskBuffer *dbuff(nullptr);
64 if (ws->isFileBacked()) {
65 fileBackedTarget = true;
66 dbuff = ws->getBoxController()->getFileIO();
67 }
68
69 for (auto &boxe : boxes) {
70 auto *box = dynamic_cast<MDBox<MDE, nd> *>(boxe);
71 if (box) {
72 size_t ic(0);
73 typename std::vector<MDE> &events = box->getEvents();
74 auto it = events.begin();
75 auto it_end = events.end();
76 for (; it != it_end; it++) {
77 // Multiply weight by a scalar, propagating error
78 float oldSignal = it->getSignal();
79 float signal = oldSignal / scalar;
80 float errorSquared = it->getErrorSquared() * inverseScalarSquared +
81 scalarErrorSquared * oldSignal * oldSignal * inverseScalarSquared * inverseScalarSquared;
82 it->setSignal(signal);
83 it->setErrorSquared(errorSquared);
84 ic++;
85 }
86
87 box->releaseEvents();
88 if (fileBackedTarget && ic > 0) {
89 Kernel::ISaveable *const pSaver(box->getISaveable());
90 dbuff->toWrite(pSaver);
91 }
92 }
93 }
94 // Recalculate the totals
95 ws->refreshCache();
96 // Mark file-backed workspace as dirty
97 ws->setFileNeedsUpdating(true);
98}
99
100//----------------------------------------------------------------------------------------------
104 throw std::runtime_error("A MDEventWorkspace can only be divided by a scalar.");
105 if (!m_out_event)
106 throw std::runtime_error("DivideMD::execEvent(): Error creating output MDEventWorkspace.");
107 // Call the method to do the dividing
109}
110
111//----------------------------------------------------------------------------------------------
115 out->divide(*operand);
116}
117
118//----------------------------------------------------------------------------------------------
122 out->divide(scalar->y(0)[0], scalar->e(0)[0]);
123}
124
125} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
#define CALL_MDEVENT_FUNCTION(funcname, workspace)
Macro that makes it possible to call a templated method for a MDEventWorkspace using a IMDEventWorksp...
void setFileNeedsUpdating(bool value)
Sets the marker set to true when a file-backed workspace needs its back-end file updated (by calling ...
virtual void getBoxes(std::vector< IMDNode * > &boxes, size_t maxDepth, bool leafOnly)=0
Fill a vector with all the boxes who are the childred of this one up to a certain depth.
Templated super-class of a multi-dimensional event "box".
Definition: MDBoxBase.h:50
Templated class for a multi-dimensional event "box".
Definition: MDBox.h:45
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
void refreshCache() override
Refresh the cache (integrated signal of each box)
Mantid::API::BoxController_sptr getBoxController() override
Returns the BoxController used in this workspace.
Buffer objects that need to be written out to disk so as to optimize writing operations.
Definition: DiskBuffer.h:42
void toWrite(ISaveable *item)
Call this method when an object is ready to be written out to disk.
Definition: DiskBuffer.cpp:47
An interface for objects that can be cached or saved to disk.
Definition: ISaveable.h:28
Mantid::API::IMDEventWorkspace_sptr m_rhs_event
Mantid::API::IMDEventWorkspace_sptr m_lhs_event
For checkInputs.
Mantid::DataObjects::WorkspaceSingleValue_sptr m_rhs_scalar
Mantid::API::IMDEventWorkspace_sptr m_out_event
Output MDEventWorkspace.
DivideMD : divide operation for MDWorkspaces.
Definition: DivideMD.h:19
void execHistoScalar(Mantid::DataObjects::MDHistoWorkspace_sptr out, Mantid::DataObjects::WorkspaceSingleValue_const_sptr scalar) override
Run the algorithm with a MDHisotWorkspace as output, scalar and operand.
Definition: DivideMD.cpp:120
void execHistoHisto(Mantid::DataObjects::MDHistoWorkspace_sptr out, Mantid::DataObjects::MDHistoWorkspace_const_sptr operand) override
Run the algorithm with a MDHisotWorkspace as output and operand.
Definition: DivideMD.cpp:113
void execEventScalar(typename Mantid::DataObjects::MDEventWorkspace< MDE, nd >::sptr ws)
Perform the operation with MDEventWorkpsace as LHS and a scalar as RHS Will do "ws /= scalar".
Definition: DivideMD.cpp:50
bool commutative() const override
Is the operation commutative?
Definition: DivideMD.cpp:34
void checkInputs() override
Check the inputs and throw if the algorithm cannot be run.
Definition: DivideMD.cpp:38
void execEvent() override
Run the algorithm with an MDEventWorkspace as output.
Definition: DivideMD.cpp:102
int version() const override
Algorithm's version for identification.
Definition: DivideMD.cpp:28
std::shared_ptr< const WorkspaceSingleValue > WorkspaceSingleValue_const_sptr
std::shared_ptr< MDHistoWorkspace > MDHistoWorkspace_sptr
A shared pointer to a MDHistoWorkspace.
std::shared_ptr< const MDHistoWorkspace > MDHistoWorkspace_const_sptr
A shared pointer to a const MDHistoWorkspace.
STL namespace.