From 0563c6f105608fcc45a88e721e372a333bb0ffa7 Mon Sep 17 00:00:00 2001 From: Owen Arnold <owen.arnold@stfc.ac.uk> Date: Fri, 7 Mar 2014 16:56:29 +0000 Subject: [PATCH] refs #9155. Start applying neighbour finding to iterator. --- .../inc/MantidCrystal/DisjointElement.h | 3 +- .../Framework/Crystal/src/DisjointElement.cpp | 10 ++++ .../Framework/Kernel/inc/MantidKernel/Utils.h | 26 +++++++++ .../MantidMDEvents/MDHistoWorkspaceIterator.h | 6 +- .../MDEvents/src/MDHistoWorkspaceIterator.cpp | 57 +++++++++++++++++++ .../test/MDHistoWorkspaceIteratorTest.h | 22 +++++++ 6 files changed, 121 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/DisjointElement.h b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/DisjointElement.h index e92895b5e22..d6e0e417302 100644 --- a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/DisjointElement.h +++ b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/DisjointElement.h @@ -68,8 +68,7 @@ namespace Crystal }; - - + void unionElements(DisjointElement* a, DisjointElement* b); } // namespace Crystal } // namespace Mantid diff --git a/Code/Mantid/Framework/Crystal/src/DisjointElement.cpp b/Code/Mantid/Framework/Crystal/src/DisjointElement.cpp index 098a9151646..a836bca11a0 100644 --- a/Code/Mantid/Framework/Crystal/src/DisjointElement.cpp +++ b/Code/Mantid/Framework/Crystal/src/DisjointElement.cpp @@ -148,5 +148,15 @@ namespace Mantid } + /** + * Convenience non-member function. + * @param a : Pointer to first disjoint element to join + * @param b : Pointer to second disjoint element to join + */ + void unionElements(DisjointElement* a, DisjointElement* b) + { + a->unionWith(b); + } + } // namespace Crystal } // namespace Mantid diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h index 005ece79d82..7c6aedff8c8 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h @@ -255,6 +255,32 @@ namespace Utils } + /** + * Determine, using an any-vertex touching type approach, whether the neighbour linear index corresponds to a true neighbour of the subject, which is already + * decomposed into it's constituent dimension indices. subject is already expressed in it's constituent indices for speed. + * + * The approach used here is to determine if a dimension index differ by any more than 1 in any dimension. If it does, then the neighbour does not represent + * a valid neighbour of the subject. + * @param ndims + * @param neighbour_linear_index + * @param subject_indices + * @param num_bins + * @return True if the are neighbours, otherwise false. + */ + inline 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) + { + size_t neighbour_indices[ndims]; + Utils::NestedForLoop::GetIndicesFromLinearIndex(ndims, neighbour_linear_index, num_bins, index_max, neighbour_indices); + for(size_t ind = 0; ind < ndims; ++ind) + { + auto diff = std::abs(static_cast<int>(subject_indices[ind] - neighbour_indices[ind])); + if (diff > 1) + { + return false; + } + } + return true; + } } // namespace Utils diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspaceIterator.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspaceIterator.h index 94e52403ef8..f9b1b291c0e 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspaceIterator.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspaceIterator.h @@ -96,6 +96,8 @@ namespace MDEvents size_t getLinearIndex() const; + std::vector<size_t> findNeighbourIndexes() const; + protected: /// The MDHistoWorkspace being iterated. const MDHistoWorkspace * m_ws; @@ -133,9 +135,11 @@ namespace MDEvents /// Array to find indices from linear indices size_t * m_indexMaker; + /// Neighbour finding permutations. + mutable std::vector<long> m_permutations; + /// Skipping policy. SkippingPolicy_scptr m_skippingPolicy; - }; diff --git a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspaceIterator.cpp b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspaceIterator.cpp index 02e037593d1..cd8220bd791 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspaceIterator.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspaceIterator.cpp @@ -137,6 +137,14 @@ namespace MDEvents if (!m_function->isPointContained(m_center)) next(); } + + const size_t neighbourSpan = 3; + size_t totalNeighbours = neighbourSpan; + for (size_t i = 1; i < m_nd; i++) + { + totalNeighbours = totalNeighbours * neighbourSpan; + } + m_permutations.resize(totalNeighbours); } //---------------------------------------------------------------------------------------------- @@ -365,6 +373,55 @@ namespace MDEvents return m_pos; } + /** + * Gets indexes of bins/pixels/boxes neighbouring the present iterator location. + * The number of neighbour indexes returned will depend upon the dimensionality of the workspace as well as the presence + * of boundaries and edges. + * @return vector of linear indexes to neighbour locations. + */ + std::vector<size_t> MDHistoWorkspaceIterator::findNeighbourIndexes() const + { + + Utils::NestedForLoop::GetIndicesFromLinearIndex(m_nd, m_pos, m_indexMaker, m_indexMax, + m_index); + + size_t offset = 1; + const int base = 3; + + m_permutations[0] = 0; + m_permutations[1] = 1; + m_permutations[2] = -1; + size_t n_permutations = 3; + + for(size_t j = 0; j < m_nd; ++j) + { + offset = offset * m_indexMaker[j-1]; + + for(size_t k = 0; k < m_permutations.size(); ++k) + { + long newVariant = m_permutations[k] + long(offset); + m_permutations[j] = newVariant; + m_permutations[j+1] = -newVariant; + n_permutations += 2; + } + } + + std::vector<size_t> neighbourIndexes; + for(size_t i = 0; i < n_permutations; ++i) + { + if (m_permutations[i] == 0) + { + continue; + } + size_t neighbour_index = m_pos + m_permutations[i]; + if( Utils::isNeighbourOfSubject(m_nd, neighbour_index, m_index, m_indexMaker, m_indexMax ) ) + { + neighbourIndexes.push_back(neighbour_index); + } + } + return neighbourIndexes; + } + } // namespace Mantid } // namespace MDEvents diff --git a/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceIteratorTest.h b/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceIteratorTest.h index d9e3e8b5ef1..c6dac263787 100644 --- a/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceIteratorTest.h +++ b/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceIteratorTest.h @@ -247,6 +247,28 @@ public: TSM_ASSERT_EQUALS("The first index hit should be 2 since that is the first unmasked one", 5, histoIt->getLinearIndex()); } + void test_neighours_1d() + { + const size_t nd = 1; + MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, nd, 10); + + MDHistoWorkspaceIterator * it = new MDHistoWorkspaceIterator(ws); + + // At first position + std::vector<size_t> neighbourIndexes = it->findNeighbourIndexes(); + TS_ASSERT_EQUALS(1, neighbourIndexes.size()); // should be on edge + + // Go to intermediate position + it->next(); + neighbourIndexes = it->findNeighbourIndexes(); + TS_ASSERT_EQUALS(2, neighbourIndexes.size()); // should be on edge + + // Go to last position + it->jumpTo(10); + neighbourIndexes = it->findNeighbourIndexes(); + TS_ASSERT_EQUALS(1, neighbourIndexes.size()); // should be on edge + } + }; -- GitLab