Mantid
Loading...
Searching...
No Matches
MDBoxIterator.hxx
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 +
10#include <cstddef>
11
12namespace Mantid {
13namespace DataObjects {
14
15//----------------------------------------------------------------------------------------------
28TMDE(MDBoxIterator)::MDBoxIterator(API::IMDNode *topBox, size_t maxDepth, bool leafOnly,
29 Mantid::Geometry::MDImplicitFunction *function)
30 : m_pos(0), m_current(nullptr), m_currentMDBox(nullptr), m_events(nullptr),
31 m_skippingPolicy(new SkipMaskedBins(this)) {
32 commonConstruct(topBox, maxDepth, leafOnly, function);
33}
34
35//----------------------------------------------------------------------------------------------
49TMDE(MDBoxIterator)::MDBoxIterator(API::IMDNode *topBox, size_t maxDepth, bool leafOnly, SkippingPolicy *skippingPolicy,
50 Mantid::Geometry::MDImplicitFunction *function)
51 : m_pos(0), m_current(nullptr), m_currentMDBox(nullptr), m_events(nullptr), m_skippingPolicy(skippingPolicy) {
52 commonConstruct(topBox, maxDepth, leafOnly, function);
53}
54
55//----------------------------------------------------------------------------------------------
68TMDE(void MDBoxIterator)::commonConstruct(API::IMDNode *topBox, size_t maxDepth, bool leafOnly,
69 Mantid::Geometry::MDImplicitFunction *function) {
70 if (!topBox)
71 throw std::invalid_argument("MDBoxIterator::ctor(): NULL top-level box given.");
72
73 if (topBox->getDepth() > maxDepth)
74 throw std::invalid_argument("MDBoxIterator::ctor(): The maxDepth parameter "
75 "must be >= the depth of the topBox.");
76
77 // Use the "getBoxes" to get all the boxes in a vector.
78 m_boxes.clear();
79 if (function)
80 topBox->getBoxes(m_boxes, maxDepth, leafOnly, function);
81 else
82 topBox->getBoxes(m_boxes, maxDepth, leafOnly);
83
84 // We avoid copying by NOT calling the init() method
85 m_max = m_boxes.size();
86 // Get the first box
87 if (m_max > 0)
88 m_current = dynamic_cast<MDBoxBase<MDE, nd> *>(m_boxes[0]);
89}
90
91//----------------------------------------------------------------------------------------------
98TMDE(MDBoxIterator)::MDBoxIterator(std::vector<API::IMDNode *> &boxes, size_t begin, size_t end)
99 : m_pos(0), m_current(nullptr), m_currentMDBox(nullptr), m_events(nullptr),
100 m_skippingPolicy(new SkipMaskedBins(this))
101
102{
103 this->init(boxes, begin, end);
104}
105
106//----------------------------------------------------------------------------------------------
112TMDE(void MDBoxIterator)::init(std::vector<API::IMDNode *> &boxes, size_t begin, size_t end) {
113 if (begin >= boxes.size())
114 throw std::runtime_error("MDBoxIterator::ctor(): invalid beginning position.");
115 size_t theEnd = end;
116 if (theEnd < begin)
117 throw std::runtime_error("MDBoxIterator::ctor(): end position is before the position.");
118 if (theEnd > boxes.size())
119 theEnd = boxes.size();
120
121 // Copy the pointers to boxes in the range.
122 m_boxes.clear();
123 m_boxes.insert(m_boxes.begin(), boxes.begin() + begin, boxes.begin() + theEnd);
124
125 m_max = m_boxes.size();
126 // Get the first box
127 if (m_max > 0)
128 m_current = dynamic_cast<MDBoxBase<MDE, nd> *>(m_boxes[0]);
129}
130
131//----------------------------------------------------------------------------------------------
135
136//----------------------------------------------------------------------------------------------
141TMDE(void MDBoxIterator)::jumpTo(size_t index) {
142 releaseEvents();
143 m_pos = index;
144 if (m_pos < m_max) {
145 m_current = dynamic_cast<MDBoxBase<MDE, nd> *>(m_boxes[m_pos]);
146 }
147}
148
149//----------------------------------------------------------------------------------------------
151TMDE(bool MDBoxIterator)::valid() const { return m_current != nullptr; }
152
153//----------------------------------------------------------------------------------------------
158TMDE(bool MDBoxIterator)::next() {
159 bool result = this->next(1);
160 while (m_skippingPolicy->keepGoing()) {
161 result = this->next(1);
162 if (!result) {
163 return result;
164 }
165 }
166 return result;
167}
168
169//----------------------------------------------------------------------------------------------
172TMDE(inline bool MDBoxIterator)::next(size_t skip) {
173 releaseEvents();
174 m_pos += skip;
175 if (m_pos < m_max) {
176 // Move up.
177 m_current = dynamic_cast<MDBoxBase<MDE, nd> *>(m_boxes[m_pos]);
178 return true;
179 } else
180 // Done - can't iterate
181 return false;
182}
183
184//----------------------------------------------------------------------------------------------
189TMDE(void MDBoxIterator)::getEvents() const {
190 if (!m_events) {
191 if (!m_currentMDBox)
192 m_currentMDBox = dynamic_cast<MDBox<MDE, nd> *>(m_current);
193 if (m_currentMDBox) {
194 // Retrieve the event vector.
195 m_events = &m_currentMDBox->getConstEvents();
196 } else
197 throw std::runtime_error("MDBoxIterator: requested the event list from a "
198 "box that is not a MDBox!");
199 }
200}
201
202//----------------------------------------------------------------------------------------------
206TMDE(void MDBoxIterator)::releaseEvents() const {
207 if (m_events) {
208 m_currentMDBox->releaseEvents();
209 m_events = nullptr;
210 m_currentMDBox = nullptr;
211 }
212}
213
214//----------------------------------------------------------------------------------------------
216TMDE(size_t MDBoxIterator)::getDataSize() const { return m_max; }
217
218//----------------------------------------------------------------------------------------------
220TMDE(signal_t MDBoxIterator)::getNormalizedSignal() const {
221 // What is our normalization factor?
222 switch (m_normalization) {
223 case API::NoNormalization:
224 return m_current->getSignal();
225 case API::VolumeNormalization:
226 return m_current->getSignal() * m_current->getInverseVolume();
227 case API::NumEventsNormalization:
228 return m_current->getSignal() / double(m_current->getNPoints());
229 }
230 return std::numeric_limits<signal_t>::quiet_NaN();
231}
232
234TMDE(signal_t MDBoxIterator)::getNormalizedError() const {
235 // What is our normalization factor?
236 switch (m_normalization) {
237 case API::NoNormalization:
238 return m_current->getError();
239 case API::VolumeNormalization:
240 return m_current->getError() * m_current->getInverseVolume();
241 case API::NumEventsNormalization:
242 return m_current->getError() / double(m_current->getNPoints());
243 }
244 return std::numeric_limits<signal_t>::quiet_NaN();
245}
246
248TMDE(signal_t MDBoxIterator)::getSignal() const { return m_current->getSignal(); }
249
251TMDE(signal_t MDBoxIterator)::getError() const { return m_current->getError(); }
252
254TMDE(std::unique_ptr<coord_t[]> MDBoxIterator)::getVertexesArray(size_t &numVertices) const {
255 return m_current->getVertexesArray(numVertices);
256}
257
258TMDE(std::unique_ptr<coord_t[]> MDBoxIterator)::getVertexesArray(size_t &numVertices, const size_t outDimensions,
259 const bool *maskDim) const {
260 return m_current->getVertexesArray(numVertices, outDimensions, maskDim);
261}
262
265 coord_t center[nd];
266 m_current->getCenter(center);
267 return Mantid::Kernel::VMD(nd, center);
268}
269
270//----------------------------------------------------------------------------------------------
272TMDE(size_t MDBoxIterator)::getNumEvents() const {
273 // Do we have a MDBox?
274 m_currentMDBox = dynamic_cast<MDBox<MDE, nd> *>(m_current);
275 if (m_currentMDBox)
276 return m_current->getNPoints();
277 else
278 return 0;
279}
280
282TMDE(uint16_t MDBoxIterator)::getInnerExpInfoIndex(size_t index) const {
283 getEvents();
284 return (*m_events)[index].getExpInfoIndex();
285}
286
288TMDE(uint16_t MDBoxIterator)::getInnerGoniometerIndex(size_t index) const {
289 getEvents();
290 return (*m_events)[index].getGoniometerIndex();
291}
292
294TMDE(int32_t MDBoxIterator)::getInnerDetectorID(size_t index) const {
295 getEvents();
296 return (*m_events)[index].getDetectorID();
297}
298
300TMDE(coord_t MDBoxIterator)::getInnerPosition(size_t index, size_t dimension) const {
301 getEvents();
302 return (*m_events)[index].getCenter(dimension);
303}
304
306TMDE(signal_t MDBoxIterator)::getInnerSignal(size_t index) const {
307 getEvents();
308 return (*m_events)[index].getSignal();
309}
310
312TMDE(signal_t MDBoxIterator)::getInnerError(size_t index) const {
313 getEvents();
314 return (*m_events)[index].getError();
315}
316
318TMDE(bool MDBoxIterator)::getIsMasked() const {
319 if (m_current) {
320 return m_current->getIsMasked();
321 }
322 return false;
323}
324
325TMDE(std::vector<size_t> MDBoxIterator)::findNeighbourIndexes() const {
326 throw std::runtime_error("MDBoxIterator does not implement findNeighbourIndex");
327}
328
329TMDE(std::vector<size_t> MDBoxIterator)::findNeighbourIndexesFaceTouching() const {
330 throw std::runtime_error("MDBoxIterator does not implement findNeighbourIndexesFaceTouching");
331}
332
333TMDE(size_t MDBoxIterator)::getLinearIndex() const {
334 throw std::runtime_error("MDBoxIterator does not implement getLinearIndex");
335}
336
337TMDE(bool MDBoxIterator)::isWithinBounds(size_t) const {
338 throw std::runtime_error("MDBoxIterator does not implement isWithinBounds");
339}
340
341} // namespace DataObjects
342} // namespace Mantid
std::map< DeltaEMode::Type, std::string > index
specnum_t m_max
#define TMDE(decl)
Macro TMDE to make declaring template functions faster.
Definition MDTypes.h:52
Templated super-class of a multi-dimensional event "box".
Definition MDBoxBase.h:50
MDBoxIterator: iterate through MDBoxBase hierarchy down to a given maximum depth.
Templated class for a multi-dimensional event "box".
Definition MDBox.h:45
const std::vector< MDE > & getConstEvents() const
Get vector of constant events to use.
Definition MDBox.hxx:269
Policy that indicates skipping of masked bins.
SkippingPolicy : Policy types for skipping in MDiterators.
An "ImplicitFunction" defining a hyper-cuboid-shaped region in N dimensions.
VMDBase< VMD_t > VMD
Define the VMD as using the double or float data type.
Definition VMD.h:86
Helper class which provides the Collimation Length for SANS instruments.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition MDTypes.h:27
double signal_t
Typedef for the signal recorded in a MDBox, etc.
Definition MDTypes.h:36
STL namespace.