13#include <boost/math/special_functions/round.hpp>
27 auto dExact = (location - origin) / binWidth;
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;
50 const auto difference = diff1 < diff2 ? diff1 : diff2;
58 if (difference == 0.0f) {
62 dExact -= 2 * difference;
125 : m_skippingPolicy(skippingPolicy) {
143 : m_skippingPolicy(skippingPolicy) {
156 size_t beginPos,
size_t endPos) {
159 throw std::invalid_argument(
"MDHistoWorkspaceIterator::ctor(): NULL workspace given.");
169 throw std::invalid_argument(
"MDHistoWorkspaceIterator::ctor(): End point "
170 "given is before the start point.");
181 for (
size_t d = 0;
d <
m_nd;
d++) {
197 for (
size_t d = 0;
d <
m_nd;
d++)
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 "
213 auto temp = std::vector<int64_t>(2 *
m_nd);
223 for (
size_t j = 1; j <
m_nd; ++j) {
224 offset = offset *
static_cast<int64_t
>(
m_ws->
getDimension(j - 1)->getNBins());
261 std::vector<size_t> indexes(
m_nd);
263 for (
size_t d = 0;
d <
m_nd; ++
d) {
265 size_t dRound = std::lround(dExact);
274 this->
jumpTo(linearIndex);
275 return std::sqrt(sqDiff);
298 for (
size_t d = 0;
d <
m_nd;
d++) {
309 }
while (m_pos < m_max && m_skippingPolicy->keepGoing());
339 return std::numeric_limits<signal_t>::quiet_NaN();
355 return std::numeric_limits<signal_t>::quiet_NaN();
372 const bool *maskDim)
const {
377 throw std::runtime_error(
"Not Implemented At present time");
386 for (
size_t d = 0;
d <
m_nd; ++
d) {
403 for (
size_t d = 0;
d <
m_nd; ++
d) {
496 std::vector<size_t> neighbourIndexes;
497 std::vector<int> widths(
m_nd, 3);
499 if (permutation == 0) {
503 size_t neighbour_index =
m_pos + permutation;
504 if (neighbour_index < m_ws->getNPoints() &&
506 neighbourIndexes.emplace_back(neighbour_index);
509 return neighbourIndexes;
534 if (widths[0] % 2 == 0) {
535 throw std::invalid_argument(
"MDHistoWorkspaceIterator::"
536 "findNeighbourIndexesByWidth, width must "
537 "always be an odd number");
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 "
549 std::vector<int64_t> permutationsVertexTouching;
551 int product = std::accumulate(widths.begin(), widths.end(), 1, std::multiplies<int>());
552 permutationsVertexTouching.reserve(product);
554 int centreIndex = widths[0] / 2;
556 for (
int i = 0; i < widths[0]; ++i) {
559 permutationsVertexTouching.emplace_back(centreIndex - i);
564 for (
size_t j = 1; j <
m_nd; ++j) {
565 offset = offset *
static_cast<int64_t
>(
m_ws->
getDimension(j - 1)->getNBins());
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]);
612 std::vector<size_t> neighbourIndexes(permutationsVertexTouching.size());
614 for (
auto permutation : permutationsVertexTouching) {
615 if (permutation == 0) {
619 size_t neighbour_index =
m_pos + permutation;
620 if (neighbour_index < m_ws->getNPoints() &&
622 neighbourIndexes[nextFree++] = neighbour_index;
625 neighbourIndexes.resize(nextFree);
628 std::sort(neighbourIndexes.begin(), neighbourIndexes.end());
629 neighbourIndexes.erase(std::unique(neighbourIndexes.begin(), neighbourIndexes.end()), neighbourIndexes.end());
630 return neighbourIndexes;
645std::pair<std::vector<size_t>, std::vector<bool>>
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);
653 widths.emplace_back(1);
660 std::vector<bool> indexValidity(permutationsVertexTouching.size(),
false);
664 std::sort(permutationsVertexTouching.begin(), permutationsVertexTouching.end());
668 std::vector<size_t> neighbourIndexes(permutationsVertexTouching.size());
669 for (
size_t i = 0; i < permutationsVertexTouching.size(); ++i) {
671 size_t neighbour_index =
m_pos + permutationsVertexTouching[i];
672 neighbourIndexes[i] = neighbour_index;
673 if (neighbour_index < m_ws->getNPoints() &&
675 indexValidity[i] =
true;
679 return std::make_pair(neighbourIndexes, indexValidity);
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
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.
size_t getDataSize() const override
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.
~MDHistoWorkspaceIterator() override
Destructor.
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.
size_t m_nd
Number of dimensions.
size_t * m_index
Index into each dimension.
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.
bool valid() const override
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 isWithinBounds(size_t index) const override
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.
size_t * m_indexMax
Index into each dimension.
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.
size_t permutationCacheSize() const
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.
@ NumEventsNormalization
Divide the signal by the number of events that contributed to it.
@ NoNormalization
Don't normalize = return raw counts.
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.
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.
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.
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.
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.
void SetUpIndexMaker(const size_t numDims, size_t *out, const size_t *index_max)
Set up an "index maker" for a nested for loop.
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...
VMDBase< VMD_t > VMD
Define the VMD as using the double or float data type.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
double signal_t
Typedef for the signal recorded in a MDBox, etc.