PointIsolationAlgStress_test.cc File Reference

Stress test for PointIsolationAlg. More...

#include "larexamples/Algorithms/RemoveIsolatedSpacePoints/PointIsolationAlg.h"
#include <cmath>
#include <stdexcept>
#include <chrono>
#include <sstream>
#include <iostream>
#include <array>

Go to the source code of this file.

Functions

template<typename T >
cube (T side)
 
template<typename Point >
std::vector< PointcreatePointsInCube (unsigned int pointsPerSide)
 
template<typename T >
void PrintConfiguration (typename lar::example::PointIsolationAlg< T >::Configuration_t const &config, std::ostream &out=std::cout)
 
template<typename T >
void StressTest (unsigned int pointsPerSide, typename lar::example::PointIsolationAlg< T >::Configuration_t const &config)
 
int main (int argc, char **argv)
 

Detailed Description

Stress test for PointIsolationAlg.

Author
Gianluca Petrillo (petri.nosp@m.llo@.nosp@m.fnal..nosp@m.gov)
Date
May 27, 2016
See also
PointIsolationAlg.h

Usage

Runs a isolation removal algorithm on a set of points distributed in a cubic grid.

Usage:

PointIsolationAlg_test NumberOfPoints[+|-] IsolationRadius

where NumberOfPoints is an approximation of the number of points to be generated on a grid and processed. Due to the strict geometric pattern, only perfect cubes are allowed as number of points. The perfect cube closest to NumberOfPoints be effectively used, unless "+" or "-" are specified, in which cases the next non-smaller or non-larger cube will be used, respectively. The points are places in a simple grid, with a distance of 1 (arbitrary unit) one from the next on each direction. The IsolationRadius parameter is measured in the same unit.

On configuration failure, the test returns with exit code 1. On test failure, the test returns with exit code 2.

Definition in file PointIsolationAlgStress_test.cc.

Function Documentation

template<typename Point >
std::vector<Point> createPointsInCube ( unsigned int  pointsPerSide)

Definition at line 55 of file PointIsolationAlgStress_test.cc.

55  {
56 
57  std::vector<Point> points;
58  points.reserve(cube(pointsPerSide));
59 
60  Point p;
61  for (unsigned int i = 0; i < pointsPerSide; ++i) {
62  p[0] = i;
63  for (unsigned int j = 0; j < pointsPerSide; ++j) {
64  p[1] = j;
65  for (unsigned int k = 0; k < pointsPerSide; ++k) {
66  p[2] = k;
67  points.push_back(p);
68  } // for k
69  } // for j
70  } // for i
71 
72  return points;
73 } // createPointsInCube()
p
Definition: test.py:223
T cube(T side)
template<typename T >
T cube ( side)

Definition at line 52 of file PointIsolationAlgStress_test.cc.

52 { return side * side * side; }
int main ( int  argc,
char **  argv 
)

Definition at line 153 of file PointIsolationAlgStress_test.cc.

153  {
154  using Coord_t = double;
155 
156  //
157  // argument parsing
158  //
159  if (argc != 3) {
160  std::cerr << "Usage: " << argv[0]
161  << " NumberOfPoints[+|-] IsolationRadius"
162  << std::endl;
163  return 1;
164  }
165 
166  std::istringstream sstr;
167 
168  enum RoundMode_t { rmNearest, rmCeil, rmFloor, rmDefault = rmNearest };
169 
170  unsigned int requestedPoints = 0;
171  RoundMode_t roundMode = rmDefault;
172  sstr.str(argv[1]);
173  sstr >> requestedPoints;
174  if (!sstr) {
175  std::cerr << "Error: expected number of points as first argument, got '"
176  << argv[1] << "' instead." << std::endl;
177  return 1;
178  }
179  char c;
180  sstr >> c;
181  if (sstr.eof()) roundMode = rmDefault;
182  else {
183  switch (c) {
184  case '+': roundMode = rmCeil; break;
185  case '-': roundMode = rmFloor; break;
186  default:
187  std::cerr << "Invalid round mode specification '" << c
188  << "' (must be '+', '-' or omitted)" << std::endl;
189  return 1;
190  } // switch round mode spec
191  } // if has round mode spec
192 
193  Coord_t radius;
194  sstr.clear();
195  sstr.str(argv[2]);
196  sstr >> radius;
197  if (!sstr) {
198  std::cerr << "Error: expected isolation radius as second argument, got '"
199  << argv[2] << "' instead." << std::endl;
200  return 1;
201  }
202 
203 
204  //
205  // prepare the configuration
206  //
207 
208  // decide on the points per side
209  double sideLength = std::pow(double(requestedPoints), 1./3.);
210  unsigned int pointsPerSide = (unsigned int) std::floor(sideLength);
211  switch (roundMode) {
212  case rmFloor: break;
213  case rmCeil: pointsPerSide = (unsigned int) std::ceil(sideLength); break;
214  case rmNearest: {
215  unsigned int const nFloorPoints = cube(pointsPerSide),
216  nCeilPoints = cube(pointsPerSide + 1);
217  if ((requestedPoints - nFloorPoints) >= (nCeilPoints - requestedPoints))
218  ++pointsPerSide;
219  break;
220  } // case rmNearest
221  } // switch roundMode
222  if (pointsPerSide < 1) pointsPerSide = 1; // sanity check
223 
224  // enclosing volume has a 0.5 margin
225  constexpr Coord_t margin = 0.5;
227  config.radius2 = cet::square(radius);
228  config.rangeX = { -margin, pointsPerSide - 1.0 + margin };
229  config.rangeY = config.rangeX;
230  config.rangeZ = config.rangeX;
231 
232  try {
233  StressTest<Coord_t>(pointsPerSide, config);
234  }
235  catch (std::logic_error const& e) {
236  std::cerr << "Test failure!\n" << e.what() << std::endl;
237  return 2;
238  }
239 
240  return 0;
241 } // main()
constexpr T pow(T x)
Definition: pow.h:72
Coord_t radius2
square of isolation radius [cm^2]
Range_t rangeY
range in Y of the covered volume
enum geo::coordinates Coord_t
constexpr T square(T x)
Definition: pow.h:21
Range_t rangeX
range in X of the covered volume
const double e
static Config * config
Definition: config.cpp:1054
Type containing all configuration parameters of the algorithm.
Range_t rangeZ
range in Z of the covered volume
QTextStream & endl(QTextStream &s)
T cube(T side)
template<typename T >
void PrintConfiguration ( typename lar::example::PointIsolationAlg< T >::Configuration_t const &  config,
std::ostream &  out = std::cout 
)

Definition at line 78 of file PointIsolationAlgStress_test.cc.

81  {
82  out << "PointIsolationAlg algorithm configuration:"
83  << "\n radius: " << std::sqrt(config.radius2)
84  << "\n bounding box:"
85  << "\n x: " << config.rangeX.lower << " -- " << config.rangeX.upper
86  << "\n y: " << config.rangeY.lower << " -- " << config.rangeY.upper
87  << "\n z: " << config.rangeZ.lower << " -- " << config.rangeZ.upper
88  << std::endl;
89 } // PrintConfiguration()
static Config * config
Definition: config.cpp:1054
QTextStream & endl(QTextStream &s)
template<typename T >
void StressTest ( unsigned int  pointsPerSide,
typename lar::example::PointIsolationAlg< T >::Configuration_t const &  config 
)

Definition at line 94 of file PointIsolationAlgStress_test.cc.

97  {
98 
99  using Coord_t = T;
100  using PointIsolationAlg_t = lar::example::PointIsolationAlg<Coord_t>;
101 
102  using Point_t = std::array<Coord_t, 3U>;
103 
104  //
105  // creation of the input points
106  //
107  auto start_init_time = std::chrono::high_resolution_clock::now();
108 
109  // create the points in a cube
110  std::vector<Point_t> points = createPointsInCube<Point_t>(pointsPerSide);
111 
112  auto stop_init_time = std::chrono::high_resolution_clock::now();
113  auto elapsed_init = std::chrono::duration_cast<std::chrono::duration<float>>
114  (stop_init_time - start_init_time); // seconds
115 
116  unsigned int const expected = (config.radius2 >= 1.)? points.size(): 0;
117  std::cout << "Processing " << points.size() << " points." << std::endl;
118 
119  //
120  // algorithm initialisation and execution
121  //
122  PointIsolationAlg_t::validateConfiguration(config);
123  PointIsolationAlg_t algo(config);
124  auto start_run_time = std::chrono::high_resolution_clock::now();
125  std::vector<size_t> result = algo.removeIsolatedPoints(points);
126  auto stop_run_time = std::chrono::high_resolution_clock::now();
127 
128  auto elapsed_run = std::chrono::duration_cast<std::chrono::duration<float>>
129  (stop_run_time - start_run_time); // seconds
130 
131  //
132  // report results on screen
133  //
134  PrintConfiguration<Coord_t>(config);
135  std::cout << "Found " << result.size() << "/" << points.size()
136  << " non-isolated points in " << (elapsed_run.count()*1000.) << " ms"
137  << " (" << (elapsed_init.count()*1000.) << " ms for initialization)"
138  << std::endl;
139 
140  if (result.size() != expected) {
141  throw std::logic_error(
142  "Expected " + std::to_string(expected) + " non-isolated points, found "
143  + std::to_string(points.size()) + "."
144  );
145  }
146 
147 } // StressTest()
Algorithm to detect isolated space points.
static QCString result
const char expected[]
Definition: Exception_t.cc:22
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >> Point_t
enum geo::coordinates Coord_t
static Config * config
Definition: config.cpp:1054
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
QTextStream & endl(QTextStream &s)