Mantid
Loading...
Searching...
No Matches
MDHistoWorkspaceIterator.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 +
10#include "MantidKernel/VMD.h"
11
12#include <algorithm>
13#include <boost/math/special_functions/round.hpp>
14#include <functional>
15#include <numeric>
16#include <utility>
17
18using namespace Mantid::Kernel;
19using namespace Mantid::API;
21
22namespace {
23// To get the rounded difference, we need to take into account precision issues
24// which arise when
25// the bin centres match
26Mantid::coord_t getDExact(Mantid::coord_t location, Mantid::coord_t origin, Mantid::coord_t binWidth) {
27 auto dExact = (location - origin) / binWidth;
28 const auto tolerance = Mantid::coord_t(1e-5);
29
30 // Expl. of the steps below
31 // -1 -0.5 0 0.5 1 where integer values are bin
32 // boundaries and half-values
33 // | | | | | are bin centres
34 // |
35 // Location
36 // Goal: Find distance to closest bin centre:
37 // 1. Get the predecimal value of the location: here 0
38 // 2. Add and subtract 0.5 to find two possible centres: here -0.5 adn + 0.5
39 // 3. Find the centre which minimizes the difference to the location
40 // 4. Keep the difference (distance) that was calculation in the step above
41
42 // Get the two centre indices which are the closest to dExact.
43 const auto centre1 = static_cast<Mantid::coord_t>(size_t(dExact)) + 0.5;
44 const auto centre2 = static_cast<Mantid::coord_t>(size_t(dExact)) - 0.5;
45
46 // Calculate the distance of the location to the centres
47 const auto diff1 = static_cast<Mantid::coord_t>(fabs(centre1 - dExact));
48 const auto diff2 = static_cast<Mantid::coord_t>(fabs(centre2 - dExact));
49
50 const auto difference = diff1 < diff2 ? diff1 : diff2;
51
52 // If the differnce is within the tolerance, ie the location is essentially on
53 // the centre, then
54 // we want to be on the left of that centre. The correct index for when we are
55 // on the centre,
56 // is the lower next integer value.
57 if (difference < tolerance) {
58 if (difference == 0.0f) {
59 dExact -= tolerance; // When we have an exact hit in the centre, give it a
60 // nudge to the lower bin boundary
61 } else {
62 dExact -= 2 * difference; // Need to subtract twice the differnce, in
63 // order to be guaranteed below the centre
64 }
65 }
66 return dExact;
67}
68} // namespace
69
70namespace Mantid::DataObjects {
71
72//----------------------------------------------------------------------------------------------
82 Mantid::Geometry::MDImplicitFunction *function, size_t beginPos,
83 size_t endPos)
84 : m_skippingPolicy(new SkipMaskedBins(this)) {
85 this->init(workspace.get(), function, beginPos, endPos);
86}
87
97 Mantid::Geometry::MDImplicitFunction *function, size_t beginPos,
98 size_t endPos)
99 : m_skippingPolicy(new SkipMaskedBins(this)) {
100 this->init(workspace, function, beginPos, endPos);
101}
102
113 SkippingPolicy *skippingPolicy,
114 Mantid::Geometry::MDImplicitFunction *function, size_t beginPos,
115 size_t endPos)
116 : m_skippingPolicy(skippingPolicy) {
117 this->init(workspace.get(), function, beginPos, endPos);
118}
119
120//----------------------------------------------------------------------------------------------
131 Mantid::Geometry::MDImplicitFunction *function, size_t beginPos,
132 size_t endPos)
133 : m_skippingPolicy(skippingPolicy) {
134 this->init(workspace, function, beginPos, endPos);
135}
136
146 size_t beginPos, size_t endPos) {
147 m_ws = workspace;
148 if (m_ws == nullptr)
149 throw std::invalid_argument("MDHistoWorkspaceIterator::ctor(): NULL workspace given.");
150
151 m_begin = beginPos;
152 m_pos = m_begin;
153 m_function.reset(function);
154
155 m_max = endPos;
156 if (m_max > m_ws->getNPoints())
157 m_max = m_ws->getNPoints();
158 if (m_max < m_pos)
159 throw std::invalid_argument("MDHistoWorkspaceIterator::ctor(): End point "
160 "given is before the start point.");
161
162 m_nd = m_ws->getNumDims();
163 m_center = new coord_t[m_nd];
164 m_origin = new coord_t[m_nd];
165 m_binWidth = new coord_t[m_nd];
166 m_index = new size_t[m_nd];
167 m_indexMax = new size_t[m_nd];
168 m_indexMaker = new size_t[m_nd];
170 // Initalize all these values
171 for (size_t d = 0; d < m_nd; d++) {
173 m_center[d] = 0;
174 m_origin[d] = dim->getMinimum();
175 m_binWidth[d] = dim->getBinWidth();
176 m_indexMax[d] = dim->getNBins();
177 }
179
180 // Initialize the current index from the start position.
182
183 // Make sure that the first iteration is at a point inside the implicit
184 // function
185 if (m_function) {
186 // Calculate the center of the 0-th bin
187 for (size_t d = 0; d < m_nd; d++)
188 m_center[d] = m_origin[d] + 0.5f * m_binWidth[d];
189 // Skip on if the first point is NOT contained
190 if (!m_function->isPointContained(m_center)) {
191 bool didNext = next();
192 if (!didNext && this->valid()) {
193 throw std::runtime_error("Inconsistency found initializing "
194 "MDHistoWorkspace iterator: this iterator should be valid, but "
195 "when tried to skip the "
196 "first point (not contained) could not iterate to "
197 "next point.");
198 }
199 }
200 }
201
202 // --- Calculate index permutations for neighbour finding face touching ---
203 auto temp = std::vector<int64_t>(2 * m_nd);
205
206 int64_t offset = 1;
207
210
211 // Figure out what possible indexes deltas to generate indexes that are next
212 // to the current one.
213 for (size_t j = 1; j < m_nd; ++j) {
214 offset = offset * static_cast<int64_t>(m_ws->getDimension(j - 1)->getNBins());
215
216 m_permutationsFaceTouching[j * 2] = offset;
217 m_permutationsFaceTouching[(j * 2) + 1] = -offset;
218 }
219}
220
221//----------------------------------------------------------------------------------------------
225 delete[] m_center;
226 delete[] m_origin;
227 delete[] m_binWidth;
228 delete[] m_index;
229 delete[] m_indexMax;
230 delete[] m_indexMaker;
231}
232//----------------------------------------------------------------------------------------------
234size_t MDHistoWorkspaceIterator::getDataSize() const { return size_t(m_max - m_begin); }
235
236//----------------------------------------------------------------------------------------------
243
251 std::vector<size_t> indexes(m_nd);
252 coord_t sqDiff = 0;
253 for (size_t d = 0; d < m_nd; ++d) {
254 coord_t dExact = getDExact(fromLocation[d], m_origin[d], m_binWidth[d]);
255 size_t dRound = std::lround(dExact); // Round to nearest bin edge.
256 if (dRound >= m_indexMax[d]) {
257 dRound = m_indexMax[d] - 1;
258 }
259 sqDiff += (dExact - coord_t(dRound)) * (dExact - coord_t(dRound)) * m_binWidth[d] * m_binWidth[d];
260 indexes[d] = dRound;
261 }
262
263 const size_t linearIndex = Utils::NestedForLoop::GetLinearIndex(m_nd, &indexes[0], m_indexMaker);
264 this->jumpTo(linearIndex);
265 return std::sqrt(sqDiff);
266}
267
268//----------------------------------------------------------------------------------------------
273bool MDHistoWorkspaceIterator::valid() const { return (m_pos < m_max); }
274
275//----------------------------------------------------------------------------------------------
281 if (m_function) {
282 bool allIncremented;
283
284 do {
285 m_pos++;
287 // Calculate the center
288 for (size_t d = 0; d < m_nd; d++) {
289 m_center[d] = m_origin[d] + (coord_t(m_index[d]) + 0.5f) * m_binWidth[d];
290 }
291 // Keep incrementing until you are in the implicit function and not masked
292 } while (m_pos < m_max &&
293 ((!allIncremented && !m_function->isPointContained(m_center)) || m_skippingPolicy->keepGoing()));
294 } else {
295 // Keep moving to next position if the current position is masked and
296 // still valid.
297 do {
298 m_pos++;
299 } while (m_pos < m_max && m_skippingPolicy->keepGoing());
300 }
301
302 bool ret = m_pos < m_max;
303 // Go through every point;
304 return ret;
305}
306
307//----------------------------------------------------------------------------------------------
311 m_pos += skip;
312
313 return (m_pos < m_max);
314}
315
316//----------------------------------------------------------------------------------------------
319 // What is our normalization factor?
320 switch (m_normalization) {
321 case NoNormalization:
322 return m_ws->getSignalAt(m_pos);
327 }
328 // Should not reach here
329 return std::numeric_limits<signal_t>::quiet_NaN();
330}
331
332//----------------------------------------------------------------------------------------------
335 // What is our normalization factor?
336 switch (m_normalization) {
337 case NoNormalization:
338 return m_ws->getErrorAt(m_pos);
343 }
344 // Should not reach here
345 return std::numeric_limits<signal_t>::quiet_NaN();
346}
347
348//----------------------------------------------------------------------------------------------
351
354//----------------------------------------------------------------------------------------------
356std::unique_ptr<coord_t[]> MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices) const {
357 // The MDHistoWorkspace takes care of this
358 return m_ws->getVertexesArray(m_pos, numVertices);
359}
360
361std::unique_ptr<coord_t[]> MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices, const size_t outDimensions,
362 const bool *maskDim) const {
363 // Do the same thing as is done in the MDBoxBase
364 UNUSED_ARG(numVertices);
365 UNUSED_ARG(outDimensions);
366 UNUSED_ARG(maskDim);
367 throw std::runtime_error("Not Implemented At present time");
368}
369
370//----------------------------------------------------------------------------------------------
373 // Get the indices
375 // Find the center
376 for (size_t d = 0; d < m_nd; ++d) {
377 m_center[d] = m_origin[d] + (coord_t(m_index[d]) + 0.5f) * m_binWidth[d];
378 }
379 return VMD(m_nd, m_center);
380}
381
388
389 // Get the indexes.
391 VecMDExtents extents(m_nd);
392 // Find the extents.
393 for (size_t d = 0; d < m_nd; ++d) {
394 const coord_t min = m_origin[d] + coord_t(m_index[d]) * m_binWidth[d]; // Min in d
395 const coord_t max = min + m_binWidth[d]; // Max in d
396 extents[d] = MDExtentPair(min, max);
397 }
398
399 return extents;
400}
401
402//----------------------------------------------------------------------------------------------
405size_t MDHistoWorkspaceIterator::getNumEvents() const { return static_cast<size_t>(this->getNumEventsFraction()); }
406
407//----------------------------------------------------------------------------------------------
411
412//----------------------------------------------------------------------------------------------
414uint16_t MDHistoWorkspaceIterator::getInnerExpInfoIndex(size_t /*index*/) const {
415 return 0;
416 // throw std::runtime_error("MDHistoWorkspaceIterator: No events are
417 // contained, so it is not possible to return inner associated experiment-info index.");
418}
419
422 return 0;
423 // throw std::runtime_error("MDHistoWorkspaceIterator: No events are
424 // contained, so it is not possible to return inner goniometer index.");
425}
426
428int32_t MDHistoWorkspaceIterator::getInnerDetectorID(size_t /*index*/) const {
429 return 0;
430 // throw std::runtime_error("MDHistoWorkspaceIterator: No events are
431 // contained, so it is not possible to return inner detector ID.");
432}
433
435coord_t MDHistoWorkspaceIterator::getInnerPosition(size_t /*index*/, size_t dimension) const {
436 return m_ws->getCenter(m_pos)[dimension];
437}
438
441
444
446
452
469
470 return this->findNeighbourIndexesByWidth(3 /*immediate neighbours only*/);
471}
472
485
486 std::vector<size_t> neighbourIndexes; // Accumulate neighbour indexes.
487 std::vector<int> widths(m_nd, 3); // Face touching width is always 3 in each dimension
488 for (auto permutation : m_permutationsFaceTouching) {
489 if (permutation == 0) {
490 continue;
491 }
492
493 size_t neighbour_index = m_pos + permutation;
494 if (neighbour_index < m_ws->getNPoints() &&
495 Utils::isNeighbourOfSubject(m_nd, neighbour_index, m_index, m_indexMaker, m_indexMax, widths)) {
496 neighbourIndexes.emplace_back(neighbour_index);
497 }
498 }
499 return neighbourIndexes;
500}
501
508
519std::vector<int64_t> MDHistoWorkspaceIterator::createPermutations(const std::vector<int> &widths) const {
520 // look-up
521 auto it = m_permutationsVertexTouchingMap.find(widths);
522 if (it == m_permutationsVertexTouchingMap.end()) {
523
524 if (widths[0] % 2 == 0) {
525 throw std::invalid_argument("MDHistoWorkspaceIterator::"
526 "findNeighbourIndexesByWidth, width must "
527 "always be an odd number");
528 }
529 if (widths.size() != m_nd) {
530 throw std::invalid_argument("MDHistoWorkspaceIterator::"
531 "findNeighbourIndexesByWidth, size of widths "
532 "must be the same as the number of "
533 "dimensions.");
534 }
535
536 int64_t offset = 1;
537
538 // Size of block will be width ^ nd
539 std::vector<int64_t> permutationsVertexTouching;
540 // Calculate maximum permutations size.
541 int product = std::accumulate(widths.begin(), widths.end(), 1, std::multiplies<int>());
542 permutationsVertexTouching.reserve(product);
543
544 int centreIndex = widths[0] / 2; // Deliberately truncate to get centre index
545
546 for (int i = 0; i < widths[0]; ++i) {
547 // for width = 3 : -1, 0, 1
548 // for width = 5 : -2, -1, 0, 1, 2
549 permutationsVertexTouching.emplace_back(centreIndex - i);
550 }
551
552 // Figure out what possible indexes deltas to generate indexes that are next
553 // to the current one.
554 for (size_t j = 1; j < m_nd; ++j) {
555 offset = offset * static_cast<int64_t>(m_ws->getDimension(j - 1)->getNBins());
556
557 size_t nEntries = permutationsVertexTouching.size();
558 for (int k = 1; k <= widths[j] / 2; ++k) {
559 for (size_t m = 0; m < nEntries; m++) {
560 permutationsVertexTouching.emplace_back((offset * k) + permutationsVertexTouching[m]);
561 permutationsVertexTouching.emplace_back((offset * k * (-1)) + permutationsVertexTouching[m]);
562 }
563 }
564 }
565
566 m_permutationsVertexTouchingMap.insert(std::make_pair(widths, permutationsVertexTouching));
567 }
568
569 // In either case, get the result.
570 return m_permutationsVertexTouchingMap[widths];
571}
572
582std::vector<size_t> MDHistoWorkspaceIterator::findNeighbourIndexesByWidth(const int &width) const {
583
584 return this->findNeighbourIndexesByWidth(std::vector<int>(m_nd, width));
585}
586
593std::vector<size_t> MDHistoWorkspaceIterator::findNeighbourIndexesByWidth(const std::vector<int> &widths) const {
594
595 // Find existing or create required index permutations.
596 std::vector<int64_t> permutationsVertexTouching = createPermutations(widths);
597
599
600 // Filter out indexes that are are not actually neighbours.
601 // Accumulate neighbour indexes.
602 std::vector<size_t> neighbourIndexes(permutationsVertexTouching.size());
603 size_t nextFree = 0;
604 for (auto permutation : permutationsVertexTouching) {
605 if (permutation == 0) {
606 continue;
607 }
608
609 size_t neighbour_index = m_pos + permutation;
610 if (neighbour_index < m_ws->getNPoints() &&
611 Utils::isNeighbourOfSubject(m_nd, neighbour_index, m_index, m_indexMaker, m_indexMax, widths)) {
612 neighbourIndexes[nextFree++] = neighbour_index;
613 }
614 }
615 neighbourIndexes.resize(nextFree);
616
617 // Remove duplicates
618 std::sort(neighbourIndexes.begin(), neighbourIndexes.end());
619 neighbourIndexes.erase(std::unique(neighbourIndexes.begin(), neighbourIndexes.end()), neighbourIndexes.end());
620 return neighbourIndexes;
621}
622
635std::pair<std::vector<size_t>, std::vector<bool>>
636MDHistoWorkspaceIterator::findNeighbourIndexesByWidth1D(const int &width, const int &width_dimension) const {
637
638 std::vector<int> widths;
639 for (size_t dimension = 0; dimension < m_nd; ++dimension) {
640 if (static_cast<int>(dimension) == width_dimension) {
641 widths.emplace_back(width);
642 } else {
643 widths.emplace_back(1);
644 }
645 }
646
647 // Find existing or create required index permutations.
648 std::vector<int64_t> permutationsVertexTouching = createPermutations(widths);
649
650 std::vector<bool> indexValidity(permutationsVertexTouching.size(), false);
651
653
654 std::sort(permutationsVertexTouching.begin(), permutationsVertexTouching.end());
655
656 // Accumulate neighbour indexes.
657 // Record indexes as valid only if they are actually neighbours.
658 std::vector<size_t> neighbourIndexes(permutationsVertexTouching.size());
659 for (size_t i = 0; i < permutationsVertexTouching.size(); ++i) {
660
661 size_t neighbour_index = m_pos + permutationsVertexTouching[i];
662 neighbourIndexes[i] = neighbour_index;
663 if (neighbour_index < m_ws->getNPoints() &&
664 Utils::isNeighbourOfSubject(m_nd, neighbour_index, m_index, m_indexMaker, m_indexMax, widths)) {
665 indexValidity[i] = true;
666 }
667 }
668
669 return std::make_pair(neighbourIndexes, indexValidity);
670}
671
677
678} // namespace Mantid::DataObjects
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
#define fabs(x)
Definition Matrix.cpp:22
double tolerance
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:48
Mantid::API::MDNormalization m_normalization
Normalization method for getNormalizedSignal()
virtual std::shared_ptr< const Mantid::Geometry::IMDDimension > getDimension(size_t index) const
Get a dimension.
virtual size_t getNumDims() const
coord_t * m_binWidth
Width of each bin in each dimension.
void jumpTo(size_t index) override
Jump to the index^th cell.
signal_t getInnerSignal(size_t index) const override
Returns the signal of a given event.
void init(const MDHistoWorkspace *workspace, Mantid::Geometry::MDImplicitFunction *function, size_t beginPos=0, size_t endPos=size_t(-1))
Constructor helper.
uint64_t m_pos
The linear position/index into the MDHistoWorkspace.
std::vector< int64_t > m_permutationsFaceTouching
Neigbour finding permutations for face touching neighbours (3 by 3 width).
signal_t getSignal() const override
Returns the signal for this box, same as innerSignal.
uint16_t getInnerExpInfoIndex(size_t index) const override
For a given event/point in this box, return the associated experiment-info index.
virtual signal_t getNumEventsFraction() const
Returns the number of events/points contained in this box.
uint64_t m_max
The maximum linear index in the workspace.
std::vector< int64_t > createPermutations(const std::vector< int > &widths) const
Create or fetch permutations relating to a given neighbour width.
signal_t getNormalizedSignal() const override
Returns the normalized signal for this box.
signal_t getInnerError(size_t index) const override
Returns the error of a given event.
signal_t getNormalizedError() const override
Returns the normalized error for this box.
std::unique_ptr< coord_t[]> getVertexesArray(size_t &numVertices) const override
Return a list of vertexes defining the volume pointed to.
VecMDExtents getBoxExtents() const
Get the extents in n-dimensions corresponding to the position of the box of the current iterator.
std::unique_ptr< Mantid::Geometry::MDImplicitFunction > m_function
Implicit function to limit volume searched.
std::vector< size_t > findNeighbourIndexes() const override
Gets indexes of bins/pixels/boxes neighbouring the present iterator location.
bool next() override
Advance to the next cell.
PermutationsMap m_permutationsVertexTouchingMap
Neighbour finding permutations map for vertex touching.
coord_t * m_origin
Origin (index 0,0,0) in the space = the minimum of each dimension.
virtual coord_t jumpToNearest(const Mantid::Kernel::VMD &fromLocation)
Jump the iterator to the nearest valid position correspoinding to the centre current position of the ...
size_t * m_indexMaker
Array to find indices from linear indices.
MDHistoWorkspaceIterator(const MDHistoWorkspace_const_sptr &workspace, SkippingPolicy *skippingPolicy, Mantid::Geometry::MDImplicitFunction *function=nullptr, size_t beginPos=0, size_t endPos=size_t(-1))
Constructor.
coord_t * m_center
Center of the current box. Not set until getCenter() is called.
int32_t getInnerDetectorID(size_t index) const override
For a given event/point in this box, return the detector ID.
std::vector< size_t > findNeighbourIndexesFaceTouching() const override
Find neighbor indexes, but only return those that are face-touching.
size_t getNumEvents() const override
Returns the number of events/points contained in this box.
std::pair< std::vector< size_t >, std::vector< bool > > findNeighbourIndexesByWidth1D(const int &width, const int &width_dimension) const
Find vertex-touching neighbours.
signal_t getError() const override
Returns the error for this box, same as innerError.
bool getIsMasked() const override
Returns true if masking is used.
uint16_t getInnerGoniometerIndex(size_t index) const override
For a given event/point in this box, return the goniometer index.
coord_t getInnerPosition(size_t index, size_t dimension) const override
Returns the position of a given event for a given dimension.
SkippingPolicy_scptr m_skippingPolicy
Skipping policy.
std::vector< size_t > findNeighbourIndexesByWidth(const int &width) const
Find vertex-touching neighbours.
const MDHistoWorkspace * m_ws
The MDHistoWorkspace being iterated.
Mantid::Kernel::VMD getCenter() const override
Returns the position of the center of the box pointed to.
uint64_t m_begin
The beginning linear index in the workspace.
size_t getLinearIndex() const override
Getter for the linear index.
signal_t getNumEventsAt(size_t index) const
Returns the number of contributing events from the bin at the specified index.
Kernel::VMD getCenter(size_t linearIndex) const override
Return the position of the center of a bin at a given position.
signal_t getErrorAt(size_t index) const override
Get the error of the signal at the specified index.
signal_t getSignalAt(size_t index) const override
Get the signal at the specified index.
coord_t getInverseVolume() const override
uint64_t getNPoints() const override
Get the number of points (bins in this case) associated with the workspace;.
std::unique_ptr< coord_t[]> getVertexesArray(size_t linearIndex, size_t &numVertices) const
For the volume at the given linear index, Return the vertices of every corner of the box,...
bool getIsMaskedAt(size_t index) const
Getter for the masking at a specified linear index.
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.
@ VolumeNormalization
Divide the signal by the volume of the box/bin.
Definition IMDIterator.h:29
@ NumEventsNormalization
Divide the signal by the number of events that contributed to it.
Definition IMDIterator.h:31
@ NoNormalization
Don't normalize = return raw counts.
Definition IMDIterator.h:27
boost::tuple< Mantid::coord_t, Mantid::coord_t > MDExtentPair
std::shared_ptr< const MDHistoWorkspace > MDHistoWorkspace_const_sptr
A shared pointer to a const MDHistoWorkspace.
std::vector< MDExtentPair > VecMDExtents
std::shared_ptr< const IMDDimension > IMDDimension_const_sptr
Shared Pointer to const IMDDimension.
size_t GetLinearIndex(const size_t numDims, const size_t *index, const size_t *index_maker)
Return a linear index from dimensional indices of a nested for loop.
Definition Utils.h:125
void GetIndicesFromLinearIndex(const size_t numDims, const size_t linear_index, const size_t *index_maker, const size_t *index_max, size_t *out_indices)
Set up a nested for loop by creating an array of counters.
Definition Utils.h:144
bool Increment(const size_t numDims, size_t *index, const size_t *index_max, const size_t *index_min)
Utility function for performing arbitrarily nested for loops in a serial way.
Definition Utils.h:165
void SetUp(const size_t numDims, size_t *out, const size_t value=0)
Set up a nested for loop by setting an array of counters.
Definition Utils.h:82
void SetUpIndexMaker(const size_t numDims, size_t *out, const size_t *index_max)
Set up an "index maker" for a nested for loop.
Definition Utils.h:104
bool isNeighbourOfSubject(const size_t ndims, const size_t neighbour_linear_index, const size_t *subject_indices, const size_t *num_bins, const size_t *index_max, const std::vector< int > &widths)
Determine, using an any-vertex touching type approach, whether the neighbour linear index corresponds...
Definition Utils.h:283
VMDBase< VMD_t > VMD
Define the VMD as using the double or float data type.
Definition VMD.h:86
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