13#include "MantidKernel/ANN/ANN.h"
18using namespace Geometry;
34 std::vector<specnum_t> spectrumNumbers,
35 bool ignoreMaskedDetectors)
36 : m_spectrumInfo(spectrumInfo), m_spectrumNumbers(
std::move(spectrumNumbers)), m_noNeighbours(nNeighbours),
37 m_cutoff(
std::numeric_limits<double>::lowest()), m_radius(0.), m_bIgnoreMaskedDetectors(ignoreMaskedDetectors) {
60 const double radius)
const {
62 if (radius < 0.0 || radius > 10.0) {
63 throw std::invalid_argument(
"NearestNeighbours::neighbours - Invalid radius parameter.");
66 std::map<specnum_t, V3D> result;
68 const int eightNearest = 8;
83 }
catch (std::invalid_argument &) {
95 for (std::map<specnum_t, V3D>::const_iterator cit = nearest.begin(); cit != nearest.end(); ++cit) {
96 if (cit->second.norm() <=
radius) {
97 result[cit->first] = cit->second;
113 if (indices.empty()) {
114 throw std::runtime_error(
"NearestNeighbours::build - Cannot find any spectra");
116 const auto nspectra =
static_cast<int>(indices.size());
117 if (noNeighbours >= nspectra) {
118 throw std::invalid_argument(
"NearestNeighbours::build - Invalid number of neighbours");
132 ANNpointArray dataPoints = annAllocPts(nspectra, 3);
133 MapIV pointNoToVertex;
136 for (
const auto i : indices) {
139 dataPoints[pointNo][0] = pos.
X();
140 dataPoints[pointNo][1] = pos.
Y();
141 dataPoints[pointNo][2] = pos.
Z();
143 pointNoToVertex[pointNo] = vertex;
148 auto annTree = std::make_unique<ANNkd_tree>(dataPoints, nspectra, 3);
155 for (
const auto idx : indices) {
156 ANNpoint scaledPos = dataPoints[pointNo];
157 annTree->annkSearch(scaledPos,
165 const V3D realPos =
V3D(scaledPos[0], scaledPos[1], scaledPos[2]) *
m_scale;
167 ANNidx
index = nnIndexList[i];
169 V3D distance = neighbour - realPos;
170 double separation = distance.
norm();
172 pointNoToVertex[
index],
180 annDeallocPts(dataPoints);
182 pointNoToVertex.clear();
199 std::map<specnum_t, V3D> result;
200 std::pair<Graph::adjacency_iterator, Graph::adjacency_iterator> adjacent =
201 boost::adjacent_vertices(vertex->second,
m_graph);
202 Graph::adjacency_iterator adjIt;
203 for (adjIt = adjacent.first; adjIt != adjacent.second; adjIt++) {
204 Vertex nearest = (*adjIt);
206 std::pair<Graph::edge_descriptor, bool> nrEd = boost::edge(vertex->second, nearest,
m_graph);
218 std::vector<size_t> indices;
220 indices.reserve(nSpec);
221 for (
size_t i = 0; i < nSpec; ++i) {
225 indices.emplace_back(i);
std::map< DeltaEMode::Type, std::string > index
API::SpectrumInfo is an intermediate step towards a SpectrumInfo that is part of Instrument-2....
bool isMonitor(const size_t index) const
Returns true if the detector(s) associated with the spectrum are monitors.
Kernel::V3D position(const size_t index) const
Returns the position of the spectrum with given index.
bool isMasked(const size_t index) const
Returns true if the detector(s) associated with the spectrum are masked.
const Geometry::IDetector & detector(const size_t index) const
Return a const reference to the detector or detector group of the spectrum with given index.
This class is not intended for direct use.
bool m_bIgnoreMaskedDetectors
Flag indicating that masked detectors should be ignored.
void build(const int noNeighbours)
Construct the graph based on the given number of neighbours and the current instument and spectra-det...
boost::property_map< Graph, boost::edge_name_t >::type m_edgeLength
property map holding the edge's related Distance value.
std::map< specnum_t, Mantid::Kernel::V3D > neighbours(specnum_t spectrum) const
Returns a map of the spectrum numbers to the distances for the nearest neighbours.
int m_noNeighbours
The current number of nearest neighbours.
double m_cutoff
The largest value of the distance to a nearest neighbour.
std::map< specnum_t, Mantid::Kernel::V3D > defaultNeighbours(const specnum_t spectrum) const
Query the graph for the default number of nearest neighbours to specified detector.
WorkspaceNearestNeighbours(int nNeighbours, const SpectrumInfo &spectrumInfo, std::vector< specnum_t > spectrumNumbers, bool ignoreMaskedDetectors=false)
Constructor.
boost::property_map< Graph, boost::vertex_name_t >::type m_vertexID
property map holding the node's related DetectorID's
boost::graph_traits< Graph >::vertex_descriptor Vertex
Vertex descriptor object for Graph.
Graph m_graph
boost::graph object
double m_radius
Cached radius value. used to avoid uncessary recalculations.
std::unordered_map< specnum_t, Vertex > MapIV
map object of int to Graph Vertex descriptor
std::vector< size_t > getSpectraDetectors()
Returns the list of valid spectrum indices.
MapIV m_specToVertex
map between the DetectorID and the Graph node descriptor
std::map< specnum_t, Mantid::Kernel::V3D > neighboursInRadius(specnum_t spectrum, double radius=0.0) const
Returns a map of the spectrum numbers to the distances for the nearest neighbours.
Kernel::V3D m_scale
V3D for scaling.
const SpectrumInfo & m_spectrumInfo
A reference to the SpectrumInfo.
const std::vector< specnum_t > m_spectrumNumbers
Vector of spectrum numbers.
A simple structure that defines an axis-aligned cuboid shaped bounding box for a geometrical object.
Kernel::V3D width() const
Returns the width of the box.
virtual void getBoundingBox(BoundingBox &boundingBox) const =0
Get the bounding box for this component and store it in the given argument.
Exception for when an item is not found in a collection.
constexpr double X() const noexcept
Get x.
constexpr double Y() const noexcept
Get y.
double norm() const noexcept
constexpr double Z() const noexcept
Get z.
Helper class which provides the Collimation Length for SANS instruments.
int32_t detid_t
Typedef for a detector ID.
int32_t specnum_t
Typedef for a spectrum Number.