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/Utils.h"
11#include "MantidKernel/VMD.h"
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//----------------------------------------------------------------------------------------------
81//----------------------------------------------------------------------------------------------
91 Mantid::Geometry::MDImplicitFunction *function, size_t beginPos,
92 size_t endPos)
93 : m_skippingPolicy(new SkipMaskedBins(this)) {
94 this->init(workspace.get(), function, beginPos, endPos);
95}
96
106 Mantid::Geometry::MDImplicitFunction *function, size_t beginPos,
107 size_t endPos)
108 : m_skippingPolicy(new SkipMaskedBins(this)) {
109 this->init(workspace, function, beginPos, endPos);
110}
111
122 SkippingPolicy *skippingPolicy,
123 Mantid::Geometry::MDImplicitFunction *function, size_t beginPos,
124 size_t endPos)
125 : m_skippingPolicy(skippingPolicy) {
126 this->init(workspace.get(), function, beginPos, endPos);
127}
128
129//----------------------------------------------------------------------------------------------
141 Mantid::Geometry::MDImplicitFunction *function, size_t beginPos,
142 size_t endPos)
143 : m_skippingPolicy(skippingPolicy) {
144 this->init(workspace, function, beginPos, endPos);
145}
146
156 size_t beginPos, size_t endPos) {
157 m_ws = workspace;
158 if (m_ws == nullptr)
159 throw std::invalid_argument("MDHistoWorkspaceIterator::ctor(): NULL workspace given.");
160
161 m_begin = beginPos;
162 m_pos = m_begin;
163 m_function.reset(function);
164
165 m_max = endPos;
166 if (m_max > m_ws->getNPoints())
167 m_max = m_ws->getNPoints();
168 if (m_max < m_pos)
169 throw std::invalid_argument("MDHistoWorkspaceIterator::ctor(): End point "
170 "given is before the start point.");
171
172 m_nd = m_ws->getNumDims();
173 m_center = new coord_t[m_nd];
174 m_origin = new coord_t[m_nd];
175 m_binWidth = new coord_t[m_nd];
176 m_index = new size_t[m_nd];
177 m_indexMax = new size_t[m_nd];
178 m_indexMaker = new size_t[m_nd];
180 // Initalize all these values
181 for (size_t d = 0; d < m_nd; d++) {
183 m_center[d] = 0;
184 m_origin[d] = dim->getMinimum();
185 m_binWidth[d] = dim->getBinWidth();
186 m_indexMax[d] = dim->getNBins();
187 }
189
190 // Initialize the current index from the start position.
192
193 // Make sure that the first iteration is at a point inside the implicit
194 // function
195 if (m_function) {
196 // Calculate the center of the 0-th bin
197 for (size_t d = 0; d < m_nd; d++)
198 m_center[d] = m_origin[d] + 0.5f * m_binWidth[d];
199 // Skip on if the first point is NOT contained
200 if (!m_function->isPointContained(m_center)) {
201 bool didNext = next();
202 if (!didNext && this->valid()) {
203 throw std::runtime_error("Inconsistency found initializing "
204 "MDHistoWorkspace iterator: this iterator should be valid, but "
205 "when tried to skip the "
206 "first point (not contained) could not iterate to "
207 "next point.");
208 }
209 }
210 }
211
212 // --- Calculate index permutations for neighbour finding face touching ---
213 auto temp = std::vector<int64_t>(2 * m_nd);
215
216 int64_t offset = 1;
217
220
221 // Figure out what possible indexes deltas to generate indexes that are next
222 // to the current one.
223 for (size_t j = 1; j < m_nd; ++j) {
224 offset = offset * static_cast<int64_t>(m_ws->getDimension(j - 1)->getNBins());
225
226 m_permutationsFaceTouching[j * 2] = offset;
227 m_permutationsFaceTouching[(j * 2) + 1] = -offset;
228 }
229}
230
231//----------------------------------------------------------------------------------------------
235 delete[] m_center;
236 delete[] m_origin;
237 delete[] m_binWidth;
238 delete[] m_index;
239 delete[] m_indexMax;
240 delete[] m_indexMaker;
241}
242//----------------------------------------------------------------------------------------------
244size_t MDHistoWorkspaceIterator::getDataSize() const { return size_t(m_max - m_begin); }
245
246//----------------------------------------------------------------------------------------------
253
261 std::vector<size_t> indexes(m_nd);
262 coord_t sqDiff = 0;
263 for (size_t d = 0; d < m_nd; ++d) {
264 coord_t dExact = getDExact(fromLocation[d], m_origin[d], m_binWidth[d]);
265 size_t dRound = std::lround(dExact); // Round to nearest bin edge.
266 if (dRound >= m_indexMax[d]) {
267 dRound = m_indexMax[d] - 1;
268 }
269 sqDiff += (dExact - coord_t(dRound)) * (dExact - coord_t(dRound)) * m_binWidth[d] * m_binWidth[d];
270 indexes[d] = dRound;
271 }
272
273 const size_t linearIndex = Utils::NestedForLoop::GetLinearIndex(m_nd, &indexes[0], m_indexMaker);
274 this->jumpTo(linearIndex);
275 return std::sqrt(sqDiff);
276}
277
278//----------------------------------------------------------------------------------------------
283bool MDHistoWorkspaceIterator::valid() const { return (m_pos < m_max); }
284
285//----------------------------------------------------------------------------------------------
291 if (m_function) {
292 bool allIncremented;
293
294 do {
295 m_pos++;
297 // Calculate the center
298 for (size_t d = 0; d < m_nd; d++) {
299 m_center[d] = m_origin[d] + (coord_t(m_index[d]) + 0.5f) * m_binWidth[d];
300 }
301 // Keep incrementing until you are in the implicit function and not masked
302 } while (m_pos < m_max &&
303 ((!allIncremented && !m_function->isPointContained(m_center)) || m_skippingPolicy->keepGoing()));
304 } else {
305 // Keep moving to next position if the current position is masked and
306 // still valid.
307 do {
308 m_pos++;
309 } while (m_pos < m_max && m_skippingPolicy->keepGoing());
310 }
311
312 bool ret = m_pos < m_max;
313 // Go through every point;
314 return ret;
315}
316
317//----------------------------------------------------------------------------------------------
321 m_pos += skip;
322
323 return (m_pos < m_max);
324}
325
326//----------------------------------------------------------------------------------------------
329 // What is our normalization factor?
330 switch (m_normalization) {
331 case NoNormalization:
332 return m_ws->getSignalAt(m_pos);
337 }
338 // Should not reach here
339 return std::numeric_limits<signal_t>::quiet_NaN();
340}
341
342//----------------------------------------------------------------------------------------------
345 // What is our normalization factor?
346 switch (m_normalization) {
347 case NoNormalization:
348 return m_ws->getErrorAt(m_pos);
353 }
354 // Should not reach here
355 return std::numeric_limits<signal_t>::quiet_NaN();
356}
357
358//----------------------------------------------------------------------------------------------
361
364//----------------------------------------------------------------------------------------------
366std::unique_ptr<coord_t[]> MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices) const {
367 // The MDHistoWorkspace takes care of this
368 return m_ws->getVertexesArray(m_pos, numVertices);
369}
370
371std::unique_ptr<coord_t[]> MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices, const size_t outDimensions,
372 const bool *maskDim) const {
373 // Do the same thing as is done in the MDBoxBase
374 UNUSED_ARG(numVertices);
375 UNUSED_ARG(outDimensions);
376 UNUSED_ARG(maskDim);
377 throw std::runtime_error("Not Implemented At present time");
378}
379
380//----------------------------------------------------------------------------------------------
383 // Get the indices
385 // Find the center
386 for (size_t d = 0; d < m_nd; ++d) {
387 m_center[d] = m_origin[d] + (coord_t(m_index[d]) + 0.5f) * m_binWidth[d];
388 }
389 return VMD(m_nd, m_center);
390}
391
398
399 // Get the indexes.
401 VecMDExtents extents(m_nd);
402 // Find the extents.
403 for (size_t d = 0; d < m_nd; ++d) {
404 const coord_t min = m_origin[d] + coord_t(m_index[d]) * m_binWidth[d]; // Min in d
405 const coord_t max = min + m_binWidth[d]; // Max in d
406 extents[d] = MDExtentPair(min, max);
407 }
408
409 return extents;
410}
411
412//----------------------------------------------------------------------------------------------
415size_t MDHistoWorkspaceIterator::getNumEvents() const { return static_cast<size_t>(this->getNumEventsFraction()); }
416
417//----------------------------------------------------------------------------------------------
421
422//----------------------------------------------------------------------------------------------
424uint16_t MDHistoWorkspaceIterator::getInnerExpInfoIndex(size_t /*index*/) const {
425 return 0;
426 // throw std::runtime_error("MDHistoWorkspaceIterator: No events are
427 // contained, so it is not possible to return inner associated experiment-info index.");
428}
429
432 return 0;
433 // throw std::runtime_error("MDHistoWorkspaceIterator: No events are
434 // contained, so it is not possible to return inner goniometer index.");
435}
436
438int32_t MDHistoWorkspaceIterator::getInnerDetectorID(size_t /*index*/) const {
439 return 0;
440 // throw std::runtime_error("MDHistoWorkspaceIterator: No events are
441 // contained, so it is not possible to return inner detector ID.");
442}
443
445coord_t MDHistoWorkspaceIterator::getInnerPosition(size_t /*index*/, size_t dimension) const {
446 return m_ws->getCenter(m_pos)[dimension];
447}
448
451
454
456
462
479
480 return this->findNeighbourIndexesByWidth(3 /*immediate neighbours only*/);
481}
482
495
496 std::vector<size_t> neighbourIndexes; // Accumulate neighbour indexes.
497 std::vector<int> widths(m_nd, 3); // Face touching width is always 3 in each dimension
498 for (auto permutation : m_permutationsFaceTouching) {
499 if (permutation == 0) {
500 continue;
501 }
502
503 size_t neighbour_index = m_pos + permutation;
504 if (neighbour_index < m_ws->getNPoints() &&
505 Utils::isNeighbourOfSubject(m_nd, neighbour_index, m_index, m_indexMaker, m_indexMax, widths)) {
506 neighbourIndexes.emplace_back(neighbour_index);
507 }
508 }
509 return neighbourIndexes;
510}
511
518
529std::vector<int64_t> MDHistoWorkspaceIterator::createPermutations(const std::vector<int> &widths) const {
530 // look-up
531 auto it = m_permutationsVertexTouchingMap.find(widths);
532 if (it == m_permutationsVertexTouchingMap.end()) {
533
534 if (widths[0] % 2 == 0) {
535 throw std::invalid_argument("MDHistoWorkspaceIterator::"
536 "findNeighbourIndexesByWidth, width must "
537 "always be an odd number");
538 }
539 if (widths.size() != m_nd) {
540 throw std::invalid_argument("MDHistoWorkspaceIterator::"
541 "findNeighbourIndexesByWidth, size of widths "
542 "must be the same as the number of "
543 "dimensions.");
544 }
545
546 int64_t offset = 1;
547
548 // Size of block will be width ^ nd
549 std::vector<int64_t> permutationsVertexTouching;
550 // Calculate maximum permutations size.
551 int product = std::accumulate(widths.begin(), widths.end(), 1, std::multiplies<int>());
552 permutationsVertexTouching.reserve(product);
553
554 int centreIndex = widths[0] / 2; // Deliberately truncate to get centre index
555
556 for (int i = 0; i < widths[0]; ++i) {
557 // for width = 3 : -1, 0, 1
558 // for width = 5 : -2, -1, 0, 1, 2
559 permutationsVertexTouching.emplace_back(centreIndex - i);
560 }
561
562 // Figure out what possible indexes deltas to generate indexes that are next
563 // to the current one.
564 for (size_t j = 1; j < m_nd; ++j) {
565 offset = offset * static_cast<int64_t>(m_ws->getDimension(j - 1)->getNBins());
566
567 size_t nEntries = permutationsVertexTouching.size();
568 for (int k = 1; k <= widths[j] / 2; ++k) {
569 for (size_t m = 0; m < nEntries; m++) {
570 permutationsVertexTouching.emplace_back((offset * k) + permutationsVertexTouching[m]);
571 permutationsVertexTouching.emplace_back((offset * k * (-1)) + permutationsVertexTouching[m]);
572 }
573 }
574 }
575
576 m_permutationsVertexTouchingMap.insert(std::make_pair(widths, permutationsVertexTouching));
577 }
578
579 // In either case, get the result.
580 return m_permutationsVertexTouchingMap[widths];
581}
582
592std::vector<size_t> MDHistoWorkspaceIterator::findNeighbourIndexesByWidth(const int &width) const {
593
594 return this->findNeighbourIndexesByWidth(std::vector<int>(m_nd, width));
595}
596
603std::vector<size_t> MDHistoWorkspaceIterator::findNeighbourIndexesByWidth(const std::vector<int> &widths) const {
604
605 // Find existing or create required index permutations.
606 std::vector<int64_t> permutationsVertexTouching = createPermutations(widths);
607
609
610 // Filter out indexes that are are not actually neighbours.
611 // Accumulate neighbour indexes.
612 std::vector<size_t> neighbourIndexes(permutationsVertexTouching.size());
613 size_t nextFree = 0;
614 for (auto permutation : permutationsVertexTouching) {
615 if (permutation == 0) {
616 continue;
617 }
618
619 size_t neighbour_index = m_pos + permutation;
620 if (neighbour_index < m_ws->getNPoints() &&
621 Utils::isNeighbourOfSubject(m_nd, neighbour_index, m_index, m_indexMaker, m_indexMax, widths)) {
622 neighbourIndexes[nextFree++] = neighbour_index;
623 }
624 }
625 neighbourIndexes.resize(nextFree);
626
627 // Remove duplicates
628 std::sort(neighbourIndexes.begin(), neighbourIndexes.end());
629 neighbourIndexes.erase(std::unique(neighbourIndexes.begin(), neighbourIndexes.end()), neighbourIndexes.end());
630 return neighbourIndexes;
631}
632
645std::pair<std::vector<size_t>, std::vector<bool>>
646MDHistoWorkspaceIterator::findNeighbourIndexesByWidth1D(const int &width, const int &width_dimension) const {
647
648 std::vector<int> widths;
649 for (size_t dimension = 0; dimension < m_nd; ++dimension) {
650 if (static_cast<int>(dimension) == width_dimension) {
651 widths.emplace_back(width);
652 } else {
653 widths.emplace_back(1);
654 }
655 }
656
657 // Find existing or create required index permutations.
658 std::vector<int64_t> permutationsVertexTouching = createPermutations(widths);
659
660 std::vector<bool> indexValidity(permutationsVertexTouching.size(), false);
661
663
664 std::sort(permutationsVertexTouching.begin(), permutationsVertexTouching.end());
665
666 // Accumulate neighbour indexes.
667 // Record indexes as valid only if they are actually neighbours.
668 std::vector<size_t> neighbourIndexes(permutationsVertexTouching.size());
669 for (size_t i = 0; i < permutationsVertexTouching.size(); ++i) {
670
671 size_t neighbour_index = m_pos + permutationsVertexTouching[i];
672 neighbourIndexes[i] = neighbour_index;
673 if (neighbour_index < m_ws->getNPoints() &&
674 Utils::isNeighbourOfSubject(m_nd, neighbour_index, m_index, m_indexMaker, m_indexMax, widths)) {
675 indexValidity[i] = true;
676 }
677 }
678
679 return std::make_pair(neighbourIndexes, indexValidity);
680}
681
687
688} // namespace Mantid::DataObjects
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
#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:64
Mantid::API::MDNormalization m_normalization
Normalization method for getNormalizedSignal()
Definition: IMDIterator.h:125
virtual std::shared_ptr< const Mantid::Geometry::IMDDimension > getDimension(size_t index) const
Get a dimension.
Definition: MDGeometry.cpp:161
virtual size_t getNumDims() const
Definition: MDGeometry.cpp:148
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.
Definition: IMDDimension.h:101
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, size_t *index_max, size_t *index_min)
Utility function for performing arbitrarily nested for loops in a serial way.
Definition: Utils.h:165
size_t GetLinearIndex(const size_t numDims, size_t *index, size_t *index_maker)
Return a linear index from dimensional indices of a nested for loop.
Definition: Utils.h:125
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