Mantid
Loading...
Searching...
No Matches
MDBoxBase.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 +
9#include "MantidKernel/VMD.h"
10
11#include <cstddef>
12#include <limits>
13#include <memory>
14
15namespace Mantid {
16namespace DataObjects {
17
18//-----------------------------------------------------------------------------------------------
21TMDE(MDBoxBase)::MDBoxBase(Mantid::API::BoxController *const boxController, const uint32_t depth, const size_t boxID)
22 : m_signal(0.0), m_errorSquared(0.0), m_totalWeight(0.0), m_BoxController(boxController),
23 m_inverseVolume(std::numeric_limits<coord_t>::quiet_NaN()), m_depth(depth), m_parent(nullptr), m_fileID(boxID) {
24 if (boxController) {
25 // Give it a fresh ID from the controller.
26 if (boxID == std::numeric_limits<size_t>::max()) // Give it a fresh ID from
27 // the controller.
28 this->m_fileID = boxController->getNextId();
29 }
30}
31//-----------------------------------------------------------------------------------------------
34TMDE(MDBoxBase)::MDBoxBase(Mantid::API::BoxController *const boxController, const uint32_t depth, const size_t boxID,
35 const std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> &extentsVector)
36 : m_signal(0.0), m_errorSquared(0.0), m_totalWeight(0.0), m_BoxController(boxController),
37 m_inverseVolume(UNDEF_COORDT), m_depth(depth), m_parent(nullptr), m_fileID(boxID) {
38 if (boxController) {
39 // Give it a fresh ID from the controller.
40 if (boxID == UNDEF_SIZET) // Give it a fresh ID from the controller.
41 this->m_fileID = boxController->getNextId();
42 }
43
44 // Set the extents
45 if (extentsVector.size() != nd)
46 throw std::invalid_argument("MDBoxBase::ctor(): extentsVector.size() must be == nd.");
47 for (size_t d = 0; d < nd; d++)
48 this->extents[d] = extentsVector[d];
49
50 this->calcVolume();
51}
52
53//-----------------------------------------------------------------------------------------------
59TMDE(MDBoxBase)::MDBoxBase(const MDBoxBase<MDE, nd> &box, Mantid::API::BoxController *const otherBC)
60 : m_signal(box.m_signal), m_errorSquared(box.m_errorSquared), m_totalWeight(box.m_totalWeight),
61 m_BoxController(otherBC), m_inverseVolume(box.m_inverseVolume), m_depth(box.m_depth), m_parent(box.m_parent),
62 m_fileID(box.m_fileID), m_dataMutex() {
63
64 // Copy the extents
65 for (size_t d = 0; d < nd; d++)
66 this->extents[d] = box.extents[d];
67 for (size_t d = 0; d < nd; d++)
68 this->m_centroid[d] = box.m_centroid[d];
69}
70
71//---------------------------------------------------------------------------------------------------
78TMDE(void MDBoxBase)::transformDimensions(std::vector<double> &scaling, std::vector<double> &offset) {
79 for (size_t d = 0; d < nd; d++) {
80 extents[d].scaleExtents(scaling[d], offset[d]);
81 }
82 // Re-calculate the volume of the box
83 this->calcVolume();
84}
85
86//-----------------------------------------------------------------------------------------------
91TMDE(std::vector<Mantid::Kernel::VMD> MDBoxBase)::getVertexes() const {
92 if (nd > 4)
93 throw std::runtime_error("MDBoxBase::getVertexes(): At this time, cannot "
94 "return vertexes for > 4 dimensions.");
95 std::vector<Mantid::Kernel::VMD> out;
96
97 // How many vertices does one box have? 2^nd, or bitwise shift left 1 by nd
98 // bits
99 size_t maxVertices = 1 << nd;
100
101 // For each vertex, increase an integeer
102 for (size_t i = 0; i < maxVertices; ++i) {
103 // Coordinates of the vertex
104 coord_t coords[nd];
105 for (size_t d = 0; d < nd; d++) {
106 // Use a bit mask to look at each bit of the integer we are iterating
107 // through.
108 size_t mask = size_t{1} << d;
109 if ((i & mask) > 0) {
110 // Bit is 1, use the max of the dimension
111 coords[d] = extents[d].getMax();
112 } else {
113 // Bit is 0, use the min of the dimension
114 coords[d] = extents[d].getMin();
115 }
116 } // (for each dimension)
117
118 // Create the coordinate object and add it to the vector
119 out.emplace_back(Mantid::Kernel::VMD(nd, coords));
120 }
121
122 return out;
123}
124
125//-----------------------------------------------------------------------------------------------
132TMDE(std::unique_ptr<coord_t[]> MDBoxBase)::getVertexesArray(size_t &numVertices) const {
133 // How many vertices does one box have? 2^nd, or bitwise shift left 1 by nd
134 // bits
135 numVertices = 1 << nd;
136
137 // Allocate the array of the right size
138 auto out = std::make_unique<coord_t[]>(nd * numVertices);
139
140 // For each vertex, increase an integeer
141 for (size_t i = 0; i < numVertices; ++i) {
142 // Start point index in the output array;
143 size_t outIndex = i * nd;
144
145 // Coordinates of the vertex
146 for (size_t d = 0; d < nd; d++) {
147 // Use a bit mask to look at each bit of the integer we are iterating
148 // through.
149 size_t mask = size_t{1} << d;
150 if ((i & mask) > 0) {
151 // Bit is 1, use the max of the dimension
152 out[outIndex + d] = extents[d].getMax();
153 } else {
154 // Bit is 0, use the min of the dimension
155 out[outIndex + d] = extents[d].getMin();
156 }
157 } // (for each dimension)
158 }
159 return out;
160}
161
162//-----------------------------------------------------------------------------------------------
181TMDE(std::unique_ptr<coord_t[]> MDBoxBase)::getVertexesArray(size_t &numVertices, const size_t outDimensions,
182 const bool *maskDim) const {
183 if (outDimensions == 0)
184 throw std::invalid_argument("MDBoxBase::getVertexesArray(): Must have > 0 output dimensions.");
185
186 // How many vertices does one box have? 2^numOutputDimensions
187 numVertices = (size_t)1 << outDimensions;
188
189 // Allocate the array of the right size
190 auto out = std::make_unique<coord_t[]>(outDimensions * numVertices);
191
192 // For each vertex, increase an integeer
193 for (size_t i = 0; i < numVertices; ++i) {
194 // Start point index in the output array;
195 size_t outIndex = i * outDimensions;
196
197 // The OUTPUT dimension index
198 size_t outd = 0;
199
200 // Coordinates of the vertex
201 for (size_t ind = 0; ind < nd; ind++) {
202 if (maskDim[ind]) {
203 // Use a bit mask to look at each bit of the integer we are iterating
204 // through.
205 size_t mask = (size_t)1 << outd;
206 if ((i & mask) > 0) {
207 // Bit is 1, use the max of the dimension
208 out[outIndex + outd] = extents[ind].getMax();
209 } else {
210 // Bit is 0, use the min of the dimension
211 out[outIndex + outd] = extents[ind].getMin();
212 }
213 outd++;
214 } // the dimensions is used in the output.
215 } // (for each INPUT dimension)
216 }
217 return out;
218}
219
220//-----------------------------------------------------------------------------------------------
231TMDE(size_t MDBoxBase)::addEvents(const std::vector<MDE> &events) {
232 size_t numBad = 0;
233 // --- Go event by event and add them ----
234 m_dataMutex.lock();
235 for (const auto &evnt : events) {
236 // Check out-of-bounds-ness
237 bool badEvent = false;
238 for (size_t d = 0; d < nd; d++) {
239 coord_t x = evnt.getCenter(d);
240 if (extents[d].outside(x)) {
241 badEvent = true;
242 break;
243 }
244 }
245
246 if (badEvent)
247 // Event was out of bounds. Count it
248 ++numBad;
249 else
250 // Event was in bounds; add it
251 addEventUnsafe(evnt);
252 }
253 m_dataMutex.unlock();
254 return numBad;
255}
256
257//---------------------------------------------------------------------------------------------------
264TMDE(size_t MDBoxBase)::addEventsUnsafe(const std::vector<MDE> &events) {
265 // --- Go event by event and add them ----
266 for (const auto &evnt : events) {
267 addEventUnsafe(evnt);
268 }
269
270 return 0;
271}
272
273} // namespace DataObjects
274} // namespace Mantid
#define UNDEF_SIZET
Definition MDTypes.h:61
#define TMDE(decl)
Macro TMDE to make declaring template functions faster.
Definition MDTypes.h:52
#define UNDEF_COORDT
Definition MDTypes.h:62
This class is used by MDBox and MDGridBox in order to intelligently determine optimal behavior.
Templated super-class of a multi-dimensional event "box".
Definition MDBoxBase.h:50
Mantid::Geometry::MDDimensionExtents< coord_t > extents[nd]
Array of MDDimensionStats giving the extents and other stats on the box dimensions.
Definition MDBoxBase.h:320
Simple class that holds the extents (min/max) of a given dimension in a MD workspace or MDBox.
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
STL namespace.