PointIsolationAlg.h
Go to the documentation of this file.
1 /**
2  * @file PointIsolationAlg.h
3  * @brief Algorithm(s) dealing with point isolation in space
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date May 27, 2016
6  * @ingroup RemoveIsolatedSpacePoints
7  *
8  * This library contains only template classes and it is header only.
9  *
10  */
11 
12 #ifndef LAREXAMPLES_ALGORITHMS_REMOVEISOLATEDSPACEPOINTS_POINTISOLATIONALG_H
13 #define LAREXAMPLES_ALGORITHMS_REMOVEISOLATEDSPACEPOINTS_POINTISOLATIONALG_H
14 
15 // LArSoft libraries
17 
18 // infrastructure and utilities
19 #include "cetlib/pow.h" // cet::sum_squares()
20 
21 // C/C++ standard libraries
22 #include <cassert> // assert()
23 #include <cmath> // std::sqrt()
24 #include <vector>
25 #include <array>
26 #include <string>
27 #include <iterator> // std::cbegin(), std::cend(), std::distance()
28 #include <stdexcept> // std::runtime_error
29 
30 
31 namespace lar {
32  namespace example {
33 
34  // BEGIN RemoveIsolatedSpacePoints group -----------------------------------
35  /// @ingroup RemoveIsolatedSpacePoints
36  /// @{
37  /**
38  * @brief Algorithm to detect isolated space points
39  * @tparam Coord type of the coordinate
40  * @see @ref RemoveIsolatedSpacePoints "RemoveIsolatedSpacePoints example overview"
41  *
42  * This algorithm returns a selection of the input points which are not
43  * isolated. Point @f$ i @f$ is defined as isolated if:
44  * @f$ \min \left\{ \left| \vec{r}_{i} - \vec{r_{j}} \right| \right\}_{i \neq j} < R @f$
45  * where @f$ \vec{r_{k}} @f$ describes the position of the point @f$ k @f$
46  * in space and @f$ R @f$ is the isolation radius.
47  *
48  * This class must be configured by providing a complete Configuration_t
49  * object. Configuration can be changed at any time after that.
50  *
51  * The configuration information (`Configuration_t`) defines the volume the
52  * points span and the square of the isolation radius.
53  * The information on the volume may be used to optimise the algorithm,
54  * and it is not checked. If that information is wrong (that means input
55  * points lie outside that volume), the result is undefined.
56  * No check is automatically performed to assess if the configuration is
57  * valid.
58  *
59  * The algorithm can be run on any collection of points, as long as the
60  * point class supports the `PositionExtractor` class.
61  * A typical cycle of use is:
62  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63  * // creation and configuration
64  * lar::examples::PointIsolationAlg<float>::Configuration_t config;
65  * config.rangeX = { -1., 1. };
66  * config.rangeY = { -1., 1. };
67  * config.rangeZ = { -5., 5. };
68  * config.radius2 = 0.25;
69  *
70  * lar::examples::PointIsolationAlg<float> algo(config);
71  *
72  * // preparation/retrieval of input
73  * std::vector<std::array<float, 3>> points;
74  * // points are filled here
75  *
76  * // execution
77  * std::vector<size_t> indices
78  * = algo.removeIsolatedPoints(points.begin(), points.end());
79  *
80  * // utilization of the result;
81  * // - e.g., create a collection of non-isolated points...
82  * std::vector<std::array<float, 3>> nonIsolatedPoints;
83  * nonIsolatedPoints.reserve(indices.size());
84  * for (size_t index: indices)
85  * nonIsolatedPoints.push_back(points[index]);
86  *
87  * // - ... or their pointers
88  * std::vector<std::array<float, 3> const*> nonIsolatedPointPtrs;
89  * nonIsolatedPointPtrs.reserve(indices.size());
90  * for (size_t index: indices)
91  * nonIsolatedPointPtrs.push_back(&(points[index]));
92  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
93  * The point type here is `std::array<float, 3>`, for which a
94  * `lar::examples::PositionExtractor<std::array<float, 3>>` is defined
95  * in this same library.
96  * The algorithm can be executed multiple times, and the configuration can
97  * be changed at any time (`reconfigure()`).
98  *
99  * Validation of the configuration is optional, and needs to be explicitly
100  * called if desired (`validateConfiguration()`).
101  *
102  *
103  * Description of the algorithm
104  * -----------------------------
105  *
106  * The basic method to determine the isolation of a point is by brute force,
107  * by computing the distance with all others and, as soon as one of them is
108  * found too close, declare the point non-isolated.
109  *
110  * A refinement is implemented: the points are grouped in cubic "cells"
111  * and points in cells that are farther than isolation radius are not
112  * checked against each other. This requires some memory to allocate the
113  * structure, that can become huge. The maximum memory parameter keeps this
114  * sane.
115  *
116  * Other refinements are not implemented. When a point is found non-isolated
117  * also the point that makes it non-isolated should also be marked so. Cell
118  * radius might be tuned to be smaller. Some of the neighbour cells may be
119  * too far and should not be checked. The grid allocates a vector for each
120  * cell, whether it's empty or not; using a sparse structure might reduce
121  * the memory; also if the grid contains pointers to vectors instead of
122  * vectors, and the grid is very sparse, there should still be some memory
123  * saving.
124  *
125  */
126  template <typename Coord = double>
128 
129  public:
130  /// Type of coordinate
131  using Coord_t = Coord;
133 
134  /// Type containing all configuration parameters of the algorithm
136  Range_t rangeX; ///< range in X of the covered volume
137  Range_t rangeY; ///< range in Y of the covered volume
138  Range_t rangeZ; ///< range in Z of the covered volume
139  Coord_t radius2; ///< square of isolation radius [cm^2]
140  size_t maxMemory = 100 * 1048576;
141  ///< grid smaller than this number of bytes (100 MiB)
142  }; // Configuration_t
143 
144 
145  /// @{
146  /// @name Configuration
147 
148  /**
149  * @brief Constructor with configuration validation
150  * @param first_config configuration parameter structure
151  *
152  * For the configuration, see `SpacePointIsolationAlg` documentation.
153  * No validation is performed on the configuration.
154  */
155  PointIsolationAlg(Configuration_t const& first_config)
156  : config(first_config)
157  {}
158 
159  /// Reconfigures the algorithm with the specified configuration
160  /// (no validation is performed)
161  /// @see configuration()
162  void reconfigure(Configuration_t const& new_config)
163  { config = new_config; }
164 
165 
166  /// Returns a constant reference to the current configuration
167  /// @see reconfigure()
168  Configuration_t& configuration() const { return config; }
169 
170  /// @}
171 
172 
173  /**
174  * @brief Returns the set of points that are not isolated
175  * @tparam PointIter random access iterator to a point type
176  * @param begin iterator to the first point to be considered
177  * @param end iterator after the last point to be considered
178  * @return a list of indices of non-isolated points in the input range
179  *
180  * This method is the operating core of the algorithm.
181  *
182  * The input is two iterators. The output is a collection of the
183  * indices of the elements that are not isolated. The index is equivalent
184  * to `std::distance(begin, point)`.
185  * The order of the elements in the collection is not specified.
186  *
187  * This method can use any collection of input data, as long as a
188  * `PositionExtractor` object is available for it.
189  */
190  template <typename PointIter>
191  std::vector<size_t> removeIsolatedPoints
192  (PointIter begin, PointIter end) const;
193 
194 
195  /**
196  * @brief Returns the set of points that are not isolated
197  * @param points list of the reconstructed space points
198  * @return a list of indices of non-isolated points in the vector
199  * @see removeIsolatedPoints(PointIter begin, PointIter end) const
200  */
201  template <typename Cont>
202  std::vector<size_t> removeIsolatedPoints (Cont const& points) const
203  { return removeIsolatedPoints(std::cbegin(points), std::cend(points)); }
204 
205 
206  /**
207  * @brief Brute-force reference algorithm
208  * @tparam PointIter random access iterator to a point type
209  * @param begin iterator to the first point to be considered
210  * @param end iterator after the last point to be considered
211  * @return a list of indices of non-isolated points in the input range
212  * @see removeIsolatedPoints
213  *
214  * This algorithm executes the task in a @f$ N^{2} @f$ way, slow and
215  * supposedly reliable.
216  * The interface is the same as `removeIsolatedPoints`.
217  * Use this only for tests.
218  */
219  template <typename PointIter>
220  std::vector<size_t> bruteRemoveIsolatedPoints
221  (PointIter begin, PointIter end) const;
222 
223 
224  /// @{
225  /// @name Configuration
226 
227  /// Throws an exception if the configuration is invalid
228  /// @throw std::runtime_error if configuration is invalid
229  static void validateConfiguration(Configuration_t const& config);
230 
231  /// @}
232 
233 
234  /// Returns the maximum optimal cell size when using a isolation radius
236  { return radius / std::sqrt(3.); }
237 
238 
239  private:
240  /// type managing cell indices
241  using Indexer_t = ::util::GridContainer3DIndices; // same in GridContainer
242 
243  /// type of neighbourhood cell offsets
244  using NeighAddresses_t = std::vector<Indexer_t::CellIndexOffset_t>;
245 
246  template <typename PointIter>
248 
249  template <typename PointIter>
250  using Point_t = decltype(*PointIter());
251 
252 
253  Configuration_t config; ///< all configuration data
254 
255 
256  /// Computes the cell size to be used
257  template <typename PointIter = std::array<double, 3> const*>
258  Coord_t computeCellSize() const;
259 
260 
261  /// Returns a list of cell offsets for the neighbourhood of given radius
263  (Indexer_t const& indexer, unsigned int neighExtent) const;
264 
265  /// Returns whether a point is isolated with respect to all the others
266  template <typename PointIter>
267  bool isPointIsolatedFrom(
268  Point_t<PointIter> const& point,
269  typename Partition_t<PointIter>::Cell_t const& otherPoints
270  ) const;
271 
272  /// Returns whether a point is isolated in the specified neighbourhood
273  template <typename PointIter>
276  Indexer_t::CellIndex_t cellIndex,
277  Point_t<PointIter> const& point,
278  NeighAddresses_t const& neighList
279  ) const;
280 
281  /// Returns whether A and B are close enough to be considered non-isolated
282  template <typename Point>
283  bool closeEnough(Point const& A, Point const& B) const;
284 
285 
286  /// Helper function. Returns a string `"(<from> to <to>)"`
287  static std::string rangeString(Coord_t from, Coord_t to);
288 
289  /// Helper function. Returns a string `"(<from> to <to>)"`
291  { return rangeString(range.lower, range.upper); }
292 
293  }; // class PointIsolationAlg
294 
295 
296  //--------------------------------------------------------------------------
297  /// @}
298  // END RemoveIsolatedSpacePoints group -------------------------------------
299 
300  } // namespace example
301 } // namespace lar
302 
303 
304 
305 //------------------------------------------------------------------------------
306 //--- template implementation
307 //------------------------------------------------------------------------------
308 template <typename Coord>
309 template <typename PointIter>
311  (PointIter begin, PointIter end) const
312 {
313 
314  std::vector<size_t> nonIsolated;
315 
316  Coord_t const R = std::sqrt(config.radius2);
317 
318  //
319  // determine space partition settings: cell size
320  //
321  // maximum: the volume of a single cell must be contained in a sphere with
322  // radius equal to the isolation radius R
323  //
324  // minimum: needs tuning
325  //
326 
327  Coord_t cellSize = computeCellSize<PointIter>();
328  assert(cellSize > 0);
330  { config.rangeX, cellSize },
331  { config.rangeY, cellSize },
332  { config.rangeZ, cellSize }
333  );
334 
335  // if a cell is contained in a sphere with
336  bool const cellContainedInIsolationSphere
337  = (cellSize <= maximumOptimalCellSize(R));
338 
339  //
340  // determine neighbourhood
341  // the neighbourhood is the number of cells that might contain points closer
342  // than R to a cell; it is equal to R in cell size units, rounded up;
343  // it's expressed as a list of coordinate shifts from a base cell to all the
344  // others in the neighbourhood; it is contained in a cube
345  //
346  unsigned int const neighExtent = (int) std::ceil(R / cellSize);
347  NeighAddresses_t neighList
348  = buildNeighborhood(partition.indexManager(), neighExtent);
349 
350  // if a cell is not fully contained in a isolation radius, we need to check
351  // the points of the cell with each other: their cell becomes part of the
352  // neighbourhood
353  if (!cellContainedInIsolationSphere)
354  neighList.insert(neighList.begin(), { 0, 0, 0 });
355 
356  //
357  // populate the partition
358  //
359  partition.fill(begin, end);
360 
361  //
362  // for each cell in the partition:
363  //
364  size_t const nCells = partition.indexManager().size();
365  for (Indexer_t::CellIndex_t cellIndex = 0; cellIndex < nCells; ++cellIndex) {
366  auto const& cellPoints = partition[cellIndex];
367 
368  //
369  // if the cell has more than one element, mark all points as non-isolated;
370  // true only if the cell is completely contained within a R rßadius
371  //
372  if (cellContainedInIsolationSphere && (cellPoints.size() > 1)) {
373  for (auto const& pointPtr: cellPoints)
374  nonIsolated.push_back(std::distance(begin, pointPtr));
375  continue;
376  } // if all non-isolated
377 
378  //
379  // brute force approach: try all the points in this cell against all the
380  // points in the neighbourhood
381  //
382  for (auto const pointPtr: cellPoints) {
383  //
384  // optimisation (speed): mark the points from other cells as non-isolated
385  // when they trigger non-isolation in points of the current one
386  //
387 
388  // TODO
389 
391  (partition, cellIndex, *pointPtr, neighList)
392  )
393  {
394  nonIsolated.push_back(std::distance(begin, pointPtr));
395  }
396  } // for points in cell
397 
398  } // for cell
399 
400  return nonIsolated;
401 } // lar::example::PointIsolationAlg::removeIsolatedPoints()
402 
403 
404 //--------------------------------------------------------------------------
405 template <typename Coord>
408 {
409  std::vector<std::string> errors;
410  if (config.radius2 < Coord_t(0)) {
411  errors.push_back
412  ("invalid radius squared (" + std::to_string(config.radius2) + ")");
413  }
414  if (!config.rangeX.valid()) {
415  errors.push_back("invalid x range " + rangeString(config.rangeX));
416  }
417  if (!config.rangeY.valid()) {
418  errors.push_back("invalid y range " + rangeString(config.rangeY));
419  }
420  if (!config.rangeZ.valid()) {
421  errors.push_back("invalid z range " + rangeString(config.rangeZ));
422  }
423 
424  if (errors.empty()) return;
425 
426  // compose the full error message as concatenation:
428  (std::to_string(errors.size()) + " configuration errors found:");
429 
430  for (auto const& error: errors) message += "\n * " + error;
431  throw std::runtime_error(message);
432 
433 } // lar::example::PointIsolationAlg::validateConfiguration()
434 
435 
436 //--------------------------------------------------------------------------
437 template <typename Coord>
438 template <typename PointIter /* = std::array<double, 3> const* */>
440 
441  Coord_t const R = std::sqrt(config.radius2);
442 
443  // maximum: the maximum distance between two points in the cell (that is,
444  // the diagonal of the cell) must be no larger than the isolation radius R;
445  // minimum: needs tuning
446  Coord_t cellSize = maximumOptimalCellSize(R); // try the minimum for now
447 
448  //
449  // optimisation (memory): determine minimum size of box
450  //
451 
452  // TODO
453 
454  if (config.maxMemory == 0) return cellSize;
455 
456  do {
457  std::array<size_t, 3> partition = details::diceVolume(
458  CoordRangeCells<Coord_t>{ config.rangeX, cellSize },
459  CoordRangeCells<Coord_t>{ config.rangeY, cellSize },
460  CoordRangeCells<Coord_t>{ config.rangeZ, cellSize }
461  );
462 
463  size_t const nCells = partition[0] * partition[1] * partition[2];
464  if (nCells <= 1) break; // we can't reduce it any further
465 
466  // is memory low enough?
467  size_t const memory
468  = nCells * sizeof(typename SpacePartition<PointIter>::Cell_t);
469  if (memory < config.maxMemory) break;
470 
471  cellSize *= 2;
472  } while (true);
473 
474  return cellSize;
475 } // lar::example::PointIsolationAlg<Coord>::computeCellSize()
476 
477 
478 //------------------------------------------------------------------------------
479 template <typename Coord>
482  (Indexer_t const& indexer, unsigned int neighExtent) const
483 {
484  unsigned int const neighSize = 1 + 2 * neighExtent;
485  NeighAddresses_t neighList;
486  neighList.reserve(neighSize * neighSize * neighSize - 1);
487 
489  using CellDimIndex_t = Indexer_t::CellDimIndex_t;
490 
491  //
492  // optimisation (speed): reshape the neighbourhood
493  // neighbourhood might cut out cells close to the vertices
494  //
495 
496  // TODO
497 
498  CellDimIndex_t const ext = neighExtent; // convert into the right signedness
499 
500  CellID_t center{{ 0, 0, 0 }}, cellID;
501  for (CellDimIndex_t ixOfs = -ext; ixOfs <= ext; ++ixOfs) {
502  cellID[0] = ixOfs;
503  for (CellDimIndex_t iyOfs = -ext; iyOfs <= ext; ++iyOfs) {
504  cellID[1] = iyOfs;
505  for (CellDimIndex_t izOfs = -ext; izOfs <= ext; ++izOfs) {
506  if ((ixOfs == 0) && (iyOfs == 0) && (izOfs == 0)) continue;
507  cellID[2] = izOfs;
508 
509  neighList.push_back(indexer.offset(center, cellID));
510 
511  } // for ixOfs
512  } // for iyOfs
513  } // for izOfs
514 
515  return neighList;
516 } // lar::example::PointIsolationAlg<Coord>::buildNeighborhood()
517 
518 
519 //--------------------------------------------------------------------------
520 template <typename Coord>
521 template <typename PointIter>
523  Point_t<PointIter> const& point,
524  typename Partition_t<PointIter>::Cell_t const& otherPoints
525 ) const
526 {
527 
528  for (auto const& otherPointPtr: otherPoints) {
529  // make sure that we did not compare the point with itself
530  if (closeEnough(point, *otherPointPtr) && (&point != &*otherPointPtr))
531  return false;
532  }
533 
534  return true;
535 
536 } // lar::example::PointIsolationAlg<Coord>::isPointIsolatedFrom()
537 
538 
539 //--------------------------------------------------------------------------
540 template <typename Coord>
541 template <typename PointIter>
544  Indexer_t::CellIndex_t cellIndex,
545  Point_t<PointIter> const& point,
546  NeighAddresses_t const& neighList
547 ) const
548 {
549 
550  // check in all cells of the neighbourhood
551  for (Indexer_t::CellIndexOffset_t neighOfs: neighList) {
552 
553  //
554  // optimisation (speed): have neighbour offsets so that the invalid ones
555  // are all at the beginning and at the end, so that skipping is faster
556  //
557 
558  if (!partition.has(cellIndex + neighOfs)) continue;
559  auto const& neighCellPoints = partition[cellIndex + neighOfs];
560 
561  if (!isPointIsolatedFrom<PointIter>(point, neighCellPoints)) return false;
562 
563  } // for neigh cell
564 
565  return true;
566 
567 } // lar::example::PointIsolationAlg<Coord>::isPointIsolatedWithinNeighborhood()
568 
569 
570 //--------------------------------------------------------------------------
571 template <typename Coord>
572 template <typename PointIter>
573 std::vector<size_t>
575  (PointIter begin, PointIter end) const
576 {
577  //
578  // reference implementation: brute force dumb one
579  //
580 
581  std::vector<size_t> nonIsolated;
582 
583  size_t i = 0;
584  for (auto it = begin; it != end; ++it, ++i) {
585 
586  for (auto ioth = begin; ioth != end; ++ioth) {
587  if (it == ioth) continue;
588 
589  if (closeEnough(*it, *ioth)) {
590  nonIsolated.push_back(i);
591  break;
592  }
593 
594  } // for oth
595 
596  } // for (it)
597 
598  return nonIsolated;
599 } // lar::example::PointIsolationAlg::bruteRemoveIsolatedPoints()
600 
601 
602 //--------------------------------------------------------------------------
603 template <typename Coord>
604 template <typename Point>
606  (Point const& A, Point const& B) const
607 {
608  return cet::sum_of_squares(
612  ) <= config.radius2;
613 } // lar::example::PointIsolationAlg<Point>::closeEnough()
614 
615 
616 //--------------------------------------------------------------------------
617 template <typename Coord>
619  (Coord_t from, Coord_t to)
620  { return "(" + std::to_string(from) + " to " + std::to_string(to) + ")"; }
621 
622 
623 //--------------------------------------------------------------------------
624 
625 #endif // LAREXAMPLES_ALGORITHMS_REMOVEISOLATEDSPACEPOINTS_POINTISOLATIONALG_H
Algorithm to detect isolated space points.
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
A container of points sorted in cells.
std::ptrdiff_t CellIndexOffset_t
type of difference between indices
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:87
CellIndexOffset_t CellDimIndex_t
type of difference between indices along a dimension
static std::string rangeString(Range_t range)
Helper function. Returns a string "(<from> to <to>)"
std::string string
Definition: nybbler.cc:12
constexpr T sum_of_squares(T x, T y)
Definition: pow.h:139
Coord_t radius2
square of isolation radius [cm^2]
size_t maxMemory
grid smaller than this number of bytes (100 MiB)
error
Definition: include.cc:26
typename IndexManager_t::LinIndex_t CellIndex_t
type of index for direct access to the cell
Range_t rangeY
range in Y of the covered volume
static std::string rangeString(Coord_t from, Coord_t to)
Helper function. Returns a string "(<from> to <to>)"
bool closeEnough(Point const &A, Point const &B) const
Returns whether A and B are close enough to be considered non-isolated.
NeighAddresses_t buildNeighborhood(Indexer_t const &indexer, unsigned int neighExtent) const
Returns a list of cell offsets for the neighbourhood of given radius.
Class to organise data into a 3D grid.
Range_t rangeX
range in X of the covered volume
bool has(CellIndexOffset_t ofs) const
Returns whether there is a cell with the specified index (signed!)
Coord_t upper
upper boundary
std::array< CellDimIndex_t, dims()> CellID_t
type of cell coordinate (x, y, z)
GridContainerIndicesBase3D<> GridContainer3DIndices
Index manager for a container of data arranged on a 3D grid.
CoordStruct Coord
Definition: restypedef.cpp:17
std::array< size_t, 3 > diceVolume(CoordRangeCells< Coord > const &rangeX, CoordRangeCells< Coord > const &rangeY, CoordRangeCells< Coord > const &rangeZ)
Returns the dimensions of a grid diced with the specified size.
Coord_t lower
lower boundary
auto extractPositionY(Point const &point)
std::vector< Indexer_t::CellIndexOffset_t > NeighAddresses_t
type of neighbourhood cell offsets
bool valid() const
Returns whether the range is valid (empty is also valid)
std::vector< size_t > bruteRemoveIsolatedPoints(PointIter begin, PointIter end) const
Brute-force reference algorithm.
decltype(*PointIter()) Point_t
PointIsolationAlg(Configuration_t const &first_config)
Constructor with configuration validation.
Type containing all configuration parameters of the algorithm.
Configuration_t & configuration() const
typename Grid_t::Cell_t Cell_t
type of cell
Index manager for a container of data arranged on a >=3-dim grid.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
CellIndexOffset_t offset(CellID_t const &origin, CellID_t const &cellID) const
Returns the difference in index of cellID respect to origin.
long long int CellID_t
Definition: CaloRawDigit.h:24
static void validateConfiguration(Configuration_t const &config)
std::vector< size_t > removeIsolatedPoints(Cont const &points) const
Returns the set of points that are not isolated.
LArSoft-specific namespace.
Range_t rangeZ
range in Z of the covered volume
def center(depos, point)
Definition: depos.py:117
auto extractPositionX(Point const &point)
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
Definition: StdUtils.h:82
bool isPointIsolatedFrom(Point_t< PointIter > const &point, typename Partition_t< PointIter >::Cell_t const &otherPoints) const
Returns whether a point is isolated with respect to all the others.
Configuration_t config
all configuration data
std::vector< size_t > removeIsolatedPoints(PointIter begin, PointIter end) const
Returns the set of points that are not isolated.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
bool isPointIsolatedWithinNeighborhood(Partition_t< PointIter > const &partition, Indexer_t::CellIndex_t cellIndex, Point_t< PointIter > const &point, NeighAddresses_t const &neighList) const
Returns whether a point is isolated in the specified neighbourhood.
void reconfigure(Configuration_t const &new_config)
static Coord_t maximumOptimalCellSize(Coord_t radius)
Returns the maximum optimal cell size when using a isolation radius.
Coord_t computeCellSize() const
Computes the cell size to be used.
auto extractPositionZ(Point const &point)
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34