Mantid
Loading...
Searching...
No Matches
MDBoxBase.h
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 +
7#pragma once
8
11#include "MantidAPI/IMDNode.h"
17#include "MantidKernel/VMD.h"
18#include <iosfwd>
19#include <mutex>
20
22#define MDBOX_TRACK_CENTROID
23
24namespace Mantid {
25namespace DataObjects {
26
27#ifndef __INTEL_COMPILER // As of July 13, the packing has no effect for the
28 // Intel compiler and produces a warning
29#pragma pack(push, 4) // Ensure the structure is no larger than it needs to
30#endif
31
32//===============================================================================================
49class MANTID_DATAOBJECTS_DLL MDBoxBase : public Mantid::API::IMDNode {
50public:
51 //-----------------------------------------------------------------------------------------------
52 MDBoxBase(Mantid::API::BoxController *const boxController = nullptr, const uint32_t depth = 0,
53 const size_t boxID = UNDEF_SIZET);
54
55 MDBoxBase(Mantid::API::BoxController *const boxController, const uint32_t depth, const size_t boxID,
56 const std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> &extentsVector);
57
59
61 std::string getEventType() const override { return MDE::getTypeName(); }
64 unsigned int getCoordType() const override { return sizeof(coord_t); }
65
66 bool isLeaf() const override final { return getNumChildren() == 0; }
67
70 size_t getID() const override { return m_fileID; }
73 void setID(const size_t &newID) override { m_fileID = newID; }
74 // -------------------------------- Parents/Children-Related
75 // -------------------------------------------
77 void setParent(IMDNode *parent) override { m_parent = parent; }
78
80 IMDNode *getParent() override { return m_parent; }
81
83 const IMDNode *getParent() const override { return m_parent; }
84
86 const IMDNode *getBoxAtCoord(const coord_t * /*coords*/) override { return this; }
87
88 // -------------------------------- Events-Related
89 // -------------------------------------------
93 void getEventsData(std::vector<coord_t> & /*coordTable*/, size_t &nColumns) const override { nColumns = 0; }
99 void setEventsData(const std::vector<coord_t> & /*coordTable*/) override {}
101 virtual std::vector<MDE> *getEventsCopy() = 0;
102
103 //----------------------------------------------------------------------------------------------------------------------
105 virtual size_t addEvent(const MDE &point) = 0;
107 virtual size_t addEventUnsafe(const MDE &point) = 0;
108 //----------------------------------------------------------------------------------------------------------------------
109 // add range of events
110 virtual size_t addEvents(const std::vector<MDE> &events);
111 virtual size_t addEventsUnsafe(const std::vector<MDE> &events);
112 //----------------------------------------------------------------------------------------------------------------------
114 void integrateSphere(Mantid::API::CoordTransform &radiusTransform, const coord_t radiusSquared, signal_t &signal,
115 signal_t &errorSquared, const coord_t innerRadiusSquared = 0.0,
116 const bool useOnePercentBackgroundCorrection = true) const override = 0;
117
119 void centroidSphere(Mantid::API::CoordTransform &radiusTransform, const coord_t radiusSquared, coord_t *centroid,
120 signal_t &signal) const override = 0;
121
123 void integrateCylinder(Mantid::API::CoordTransform &radiusTransform, const coord_t radius, const coord_t length,
124 signal_t &signal, signal_t &errorSquared,
125 std::vector<signal_t> &signal_fit) const override = 0;
126
127 // -------------------------------------------------------------------------------------------
129 Mantid::API::BoxController *getBoxController() const override { return m_BoxController; }
131 Mantid::API::BoxController *getBoxController() override { return m_BoxController; }
132
133 // -------------------------------- Geometry/vertexes-Related
134 // -------------------------------------------
135
136 std::vector<Mantid::Kernel::VMD> getVertexes() const override;
137 std::unique_ptr<coord_t[]> getVertexesArray(size_t &numVertices) const override;
138 std::unique_ptr<coord_t[]> getVertexesArray(size_t &numVertices, const size_t outDimensions,
139 const bool *maskDim) const override;
140 void transformDimensions(std::vector<double> &scaling, std::vector<double> &offset) override;
141
142 //-----------------------------------------------------------------------------------------------
152 void setExtents(size_t dim, double min, double max) {
153 if (dim >= nd)
154 throw std::invalid_argument("Invalid dimension passed to MDBox::setExtents");
155
156 extents[dim].setExtents(min, max);
157 // volume has to be recalculated as extents have changed;
158 this->calcVolume();
159 }
164 void setExtents(double min[nd], double max[nd]) {
165 for (size_t dim = 0; dim < nd; dim++) {
166 this->extents[dim].setExtents(min[dim], max[dim]);
167 }
168 this->calcVolume();
169 }
170
171 //-----------------------------------------------------------------------------------------------
173 Mantid::Geometry::MDDimensionExtents<coord_t> &getExtents(size_t dim) override { return extents[dim]; }
174
175 //-----------------------------------------------------------------------------------------------
177 std::string getExtentsStr() const {
178 std::string mess;
179 size_t ndm1 = nd - 1;
180 if (ndm1 > 32)
181 return mess;
182
183 for (size_t d = 0; d < ndm1; ++d)
184 mess += extents[d].extentsStr() + ",";
185
186 mess += extents[ndm1].extentsStr();
187 return mess;
188 }
189
192 coord_t getBoxSize(size_t d) { return extents[d].getSize(); }
193
194 //-----------------------------------------------------------------------------------------------
199 void getCenter(coord_t *const center) const override {
200 for (size_t d = 0; d < nd; ++d)
201 center[d] = extents[d].getCentre();
202 }
203
204 //-----------------------------------------------------------------------------------------------
208 inline void calcVolume() override {
209 double volume(1);
210 for (size_t d = 0; d < nd; d++) {
211 volume *= double(extents[d].getSize());
212 }
215 m_inverseVolume = coord_t(1. / volume);
216 }
217
218 //-----------------------------------------------------------------------------------------------
221 signal_t getSignal() const override { return m_signal; }
222
223 //-----------------------------------------------------------------------------------------------
226 signal_t getError() const override { return sqrt(m_errorSquared); }
227
228 //-----------------------------------------------------------------------------------------------
231 signal_t getErrorSquared() const override { return m_errorSquared; }
232
233 //-----------------------------------------------------------------------------------------------
237 virtual signal_t getTotalWeight() const { return m_totalWeight; }
238
239 //-----------------------------------------------------------------------------------------------
244 void setSignal(const signal_t signal) override { m_signal = signal; }
245
246 //-----------------------------------------------------------------------------------------------
251 void setErrorSquared(const signal_t ErrorSquared) override { m_errorSquared = ErrorSquared; }
252
253 //-----------------------------------------------------------------------------------------------
257 virtual void setTotalWeight(const signal_t total) { m_totalWeight = total; }
258
259 //-----------------------------------------------------------------------------------------------
263 signal_t getSignalNormalized() const override { return m_signal * m_inverseVolume; }
264
265 //-----------------------------------------------------------------------------------------------
269 virtual signal_t getErrorSquaredNormalized() const { return m_errorSquared * m_inverseVolume; }
270
271 //-----------------------------------------------------------------------------------------------
275 uint32_t getDepth() const override { return m_depth; }
276
277 //-----------------------------------------------------------------------------------------------
281 void setDepth(uint32_t depth) { m_depth = depth; }
282
283 //-----------------------------------------------------------------------------------------------
285 coord_t getVolume() const { return 1.0f / m_inverseVolume; }
286
287 //-----------------------------------------------------------------------------------------------
289 coord_t getInverseVolume() const override { return m_inverseVolume; }
290
291 //-----------------------------------------------------------------------------------------------
294 void setInverseVolume(const coord_t invVolume) override { m_inverseVolume = invVolume; }
295
296 virtual void calculateGridCaches() {}
297
298protected:
305 template <typename EventIterator> void calcCaches(const EventIterator &begin, const EventIterator &end);
310
311 mutable coord_t m_centroid[nd];
315
319
323
326
329
331 uint32_t m_depth;
332
335
338 size_t m_fileID;
340 std::mutex m_dataMutex;
341
342private:
344
345public:
347 using sptr = std::shared_ptr<MDBoxBase<MDE, nd>>;
348
349}; //(end class MDBoxBase)
350
351#ifndef __INTEL_COMPILER
352#pragma pack(pop) // Return to default packing size
353#endif
354
355template <typename MDE, size_t nd>
356template <typename EventIterator>
357void MDBoxBase<MDE, nd>::calcCaches(const EventIterator &begin, const EventIterator &end) {
358 m_signal = 0;
359 m_errorSquared = 0;
360 m_totalWeight = 0;
361 coord_t *centroid = m_centroid;
362 std::fill_n(centroid, nd, 0.0f);
363 for (auto it = begin; it != end; ++it) {
364 auto evSignal = it->getSignal();
365 m_signal += evSignal;
366 m_errorSquared += it->getErrorSquared();
368 ++m_totalWeight;
369 for (auto d = 0u; d < nd; d++) {
370 // Total up the coordinate weighted by the signal.
371 centroid[d] += it->getCenter(d) * static_cast<coord_t>(evSignal);
372 }
373 }
374
375 // Normalize by the total signal
376 const coord_t reciprocal = 1.0f / static_cast<coord_t>(m_signal);
377 for (size_t d = 0; d < nd; ++d) {
378 centroid[d] *= reciprocal;
379 }
380}
381
382} // namespace DataObjects
383} // namespace Mantid
#define UNDEF_SIZET
Definition MDTypes.h:61
#define TMDE_CLASS
Macro to make declaring template classes faster.
Definition MDTypes.h:59
This class is used by MDBox and MDGridBox in order to intelligently determine optimal behavior.
Unique SingleValueParameter Declaration for InputNDimensions.
Templated super-class of a multi-dimensional event "box".
Definition MDBoxBase.h:49
virtual size_t addEventUnsafe(const MDE &point)=0
Add a single event, with no mutex locking.
virtual signal_t getTotalWeight() const
Returns the total weight of all events within.
Definition MDBoxBase.h:237
const IMDNode * getBoxAtCoord(const coord_t *) override
Returns the lowest-level box at the given coordinates.
Definition MDBoxBase.h:86
void setExtents(double min[nd], double max[nd])
Set the extents of this box.
Definition MDBoxBase.h:164
std::string getExtentsStr() const
Returns the extents as a string, for convenience.
Definition MDBoxBase.h:177
virtual std::vector< MDE > * getEventsCopy()=0
Return a copy of contained events.
void setID(const size_t &newID) override
sets the special id, which specify the position of this node in the chain linearly ordered nodes
Definition MDBoxBase.h:73
void setSignal(const signal_t signal) override
Sets the integrated signal from all points within (mostly used for testing)
Definition MDBoxBase.h:244
signal_t getSignal() const override
Returns the integrated signal from all points within.
Definition MDBoxBase.h:221
std::shared_ptr< MDBoxBase< MDE, nd > > sptr
Convenience typedef for a shared pointer to a this type of class.
Definition MDBoxBase.h:347
signal_t m_errorSquared
Cached total error (squared) from all points within.
Definition MDBoxBase.h:318
void calcCaches(const EventIterator &begin, const EventIterator &end)
Calculates caches if the events are known.
Definition MDBoxBase.h:357
virtual signal_t getErrorSquaredNormalized() const
Returns the integrated error squared from all points within, normalized for the cell volume.
Definition MDBoxBase.h:269
void setParent(IMDNode *parent) override
Return a pointer to the parent box.
Definition MDBoxBase.h:77
void getCenter(coord_t *const center) const override
Get the center of the box.
Definition MDBoxBase.h:199
coord_t getInverseVolume() const override
Return the inverse of the volume of the cell.
Definition MDBoxBase.h:289
virtual void calculateGridCaches()
Definition MDBoxBase.h:296
void setDepth(uint32_t depth)
For testing, mostly: set the recursion depth of this box.
Definition MDBoxBase.h:281
bool isLeaf() const override final
Is this node a leaf: getNumChildren() == 0.
Definition MDBoxBase.h:66
uint32_t getDepth() const override
For testing, mostly: return the recursion depth of this box.
Definition MDBoxBase.h:275
signal_t getErrorSquared() const override
Returns the integrated error squared from all points within.
Definition MDBoxBase.h:231
IMDNode * getParent() override
Return a pointer to the parent box.
Definition MDBoxBase.h:80
std::mutex m_dataMutex
Mutex for modifying the event list or box averages.
Definition MDBoxBase.h:340
coord_t getBoxSize(size_t d)
For testing: return the internal-stored size of each box in each dimension.
Definition MDBoxBase.h:192
signal_t m_signal
Cached total signal from all points within.
Definition MDBoxBase.h:314
signal_t getError() const override
Returns the integrated error from all points within.
Definition MDBoxBase.h:226
virtual void setTotalWeight(const signal_t total)
Sets the total weight from all points within (mostly used for testing)
Definition MDBoxBase.h:257
size_t m_fileID
The id which specify location of this box in a linear chain of ordered boxes (e.g.
Definition MDBoxBase.h:338
void setEventsData(const std::vector< coord_t > &) override
The method to convert the table of data into vector of events Used to convert from a vector of values...
Definition MDBoxBase.h:99
void calcVolume() override
Compute the volume of the box by simply multiplying each dimension range.
Definition MDBoxBase.h:208
void centroidSphere(Mantid::API::CoordTransform &radiusTransform, const coord_t radiusSquared, coord_t *centroid, signal_t &signal) const override=0
Find the centroid around a sphere.
Mantid::API::BoxController * getBoxController() const override
Definition MDBoxBase.h:129
coord_t m_inverseVolume
Inverse of the volume of the cell, to be used for normalized signal.
Definition MDBoxBase.h:328
coord_t getVolume() const
Return the volume of the cell.
Definition MDBoxBase.h:285
void integrateSphere(Mantid::API::CoordTransform &radiusTransform, const coord_t radiusSquared, signal_t &signal, signal_t &errorSquared, const coord_t innerRadiusSquared=0.0, const bool useOnePercentBackgroundCorrection=true) const override=0
Sphere (peak) integration.
virtual size_t addEvent(const MDE &point)=0
Add a single event.
void integrateCylinder(Mantid::API::CoordTransform &radiusTransform, const coord_t radius, const coord_t length, signal_t &signal, signal_t &errorSquared, std::vector< signal_t > &signal_fit) const override=0
Cylinder (peak) integration.
std::string getEventType() const override
Definition MDBoxBase.h:61
void setErrorSquared(const signal_t ErrorSquared) override
Sets the integrated error squared from all points within (mostly used for testing)
Definition MDBoxBase.h:251
const IMDNode * getParent() const override
Return a pointer to the parent box (const)
Definition MDBoxBase.h:83
signal_t getSignalNormalized() const override
Returns the integrated signal from all points within, normalized for the cell volume.
Definition MDBoxBase.h:263
uint32_t m_depth
Recursion depth.
Definition MDBoxBase.h:331
size_t getID() const override
Definition MDBoxBase.h:70
Mantid::API::BoxController * getBoxController() override
Definition MDBoxBase.h:131
void setInverseVolume(const coord_t invVolume) override
Sets the inverse of the volume of the cell.
Definition MDBoxBase.h:294
Mantid::API::BoxController *const m_BoxController
The box splitting controller, shared with all boxes in the hierarchy.
Definition MDBoxBase.h:325
Mantid::Geometry::MDDimensionExtents< coord_t > & getExtents(size_t dim) override
Get the extents for this box.
Definition MDBoxBase.h:173
void setExtents(size_t dim, double min, double max)
Set the extents of this box.
Definition MDBoxBase.h:152
void getEventsData(std::vector< coord_t > &, size_t &nColumns) const override
The method to convert events in a box into a table of coodrinates/signal/errors casted into coord_t t...
Definition MDBoxBase.h:93
MDBoxBase(const MDBoxBase< MDE, nd > &box)
unsigned int getCoordType() const override
Definition MDBoxBase.h:64
Mantid::API::IMDNode * m_parent
Pointer to the parent of this box. NULL if no parent.
Definition MDBoxBase.h:334
signal_t m_totalWeight
Cached total weight of all events Set when refreshCache() is called.
Definition MDBoxBase.h:322
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
double signal_t
Typedef for the signal recorded in a MDBox, etc.
Definition MDTypes.h:36