PointIsolationAlgRandom_test.cc
Go to the documentation of this file.
1 /**
2  * @file PointIsolationAlgRandom_test.cc
3  * @brief Unit test with random data for PointIsolationAlg
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date June 30, 2016
6  * @see PointIsolationAlg.h
7  * @ingroup RemoveIsolatedSpacePoints
8  *
9  * This test populate datasets with random data and tests the isolation
10  * algorithm with them.
11  *
12  * The test accepts one optional argument:
13  *
14  * PointIsolationAlg_test [seed]
15  *
16  * to set the random seed to a particular value.
17  *
18  */
19 
20 // LArSoft libraries
23 
24 // infrastructure and utilities
25 #include "cetlib/pow.h" // cet::sum_squares()
26 
27 // Boost libraries
28 #define BOOST_TEST_MODULE ( PointIsolationAlg_test )
29 #include <cetlib/quiet_unit_test.hpp> // BOOST_AUTO_TEST_CASE()
30 #include <boost/test/test_tools.hpp> // BOOST_CHECK(), BOOST_CHECK_EQUAL()
31 
32 // C/C++ standard libraries
33 #include <array>
34 #include <random>
35 #include <chrono>
36 #include <ratio> // std::milli
37 #include <iostream>
38 #include <algorithm> // std::sort()
39 
40 
41 // BEGIN RemoveIsolatedSpacePoints group ---------------------------------------
42 /// @ingroup RemoveIsolatedSpacePoints
43 /// @{
44 //------------------------------------------------------------------------------
45 //--- Test code
46 //---
47 /**
48  * @fn PointIsolationTest
49  * @brief Tests various isolation radii on a random-distributed set of points
50  * @param generator engine used to create the random input sample
51  * @param nPoints points in the input sample
52  * @param radii list of isolation radii to test
53  *
54  *
55  */
56 template <typename Engine, typename Coord = float>
58  Engine& generator, unsigned int nPoints, std::vector<Coord> const& radii
59 ) {
60 
61  using Coord_t = Coord;
62 
63  //
64  // create the input sample
65  //
66  std::uniform_real_distribution<Coord_t> uniform(-1., +1.);
67  auto randomCoord = std::bind(uniform, generator);
68 
69  using Point_t = std::array<Coord_t, 3U>;
70  std::vector<Point_t> points;
71 
72  points.reserve(nPoints);
73  for (unsigned int i = 0; i < nPoints; ++i)
74  points.push_back({{ randomCoord(), randomCoord(), randomCoord() }});
75  std::cout
76  << "\n" << std::string(75, '=')
77  << "\nTest with " << nPoints << " points"
78  << "\n" << std::string(72, '-')
79  << std::endl;
80 
81  //
82  // create the algorithm
83  //
84  using PointIsolationAlg_t = lar::example::PointIsolationAlg<Coord_t>;
85 
86  typename PointIsolationAlg_t::Configuration_t config;
87  config.rangeX = { -2., +2. };
88  config.rangeY = { -2., +2. };
89  config.rangeZ = { -2., +2. };
90  config.radius2 = 1.;
91 // config.maxMemory = 100 * 1048576; // we keep the default memory setting
92  PointIsolationAlg_t algo(config);
93 
94  //
95  // for each isolation radius:
96  //
97 
98  // measurement in milliseconds, double precision:
100  for (Coord_t radius: radii) {
101 
102  //
103  // set up the algorithm
104  //
105  config.radius2 = cet::square(radius);
106  algo.reconfigure(config);
107 
108  std::cout << "Isolation radius: " << radius << std::endl;
109 
110  //
111  // run the algorithm with the brute force approach
112  //
113  timer.restart();
114  auto expected
115  = algo.bruteRemoveIsolatedPoints(points.begin(), points.end());
116  auto elapsed = timer.elapsed();
117  std::sort(expected.begin(), expected.end());
118  std::cout << " brute force: " << elapsed << " ms"
119  << std::endl;
120 
121  //
122  // run the algorithm with the default approach
123  //
124  timer.restart();
125  auto actual = algo.removeIsolatedPoints(points);
126  elapsed = timer.elapsed();
127  std::sort(actual.begin(), actual.end());
128  std::cout << " regular: " << elapsed << " ms"
129  << std::endl;
130 
131  //
132  // sort and compare the results
133  //
134  BOOST_TEST(actual == expected, boost::test_tools::per_element());
135 
136  } // for isolation radius
137 
138  std::cout << std::string(72, '-') << std::endl;
139 
140 } // PointIsolationTest()
141 
142 
143 //------------------------------------------------------------------------------
144 //--- tests
145 //
146 struct ArgsFixture {
148  : argc(boost::unit_test::framework::master_test_suite().argc)
149  , argv(boost::unit_test::framework::master_test_suite().argv)
150  {}
151  int argc;
152  char **argv;
153 }; // ArgsFixture
154 
155 
156 BOOST_FIXTURE_TEST_CASE(PointIsolationTestCase, ArgsFixture) {
157 
158  // we explicitly set the seed, even if with a default value
159  auto seed = std::default_random_engine::default_seed;
160 
161  if (argc > 1) {
162  std::istringstream sstr;
163  sstr.str(argv[1]);
164  sstr >> seed;
165  if (!sstr) {
166  throw std::runtime_error
167  ("Invalid seed specified: " + std::string(argv[1]));
168  }
169  } // if seed specified
170 
171  // this engine can be arbitrarily crappy; don't use it for real physics!
172  std::default_random_engine generator(seed);
173  std::cout << "Random seed: " << seed << std::endl;
174 
175  // try all these isolation radii
176  std::vector<float> const Radii { 0.05, 0.1, 0.5, 2.0 };
177  std::vector<unsigned int> const DataSizes { 100, 10000 };
178 
179  for (unsigned int nPoints: DataSizes)
180  PointIsolationTest(generator, nPoints, Radii);
181 
182 } // PointIsolationTestCase()
183 
184 
185 /// @}
186 // END RemoveIsolatedSpacePoints group -----------------------------------------
Algorithm to detect isolated space points.
const char expected[]
Definition: Exception_t.cc:22
std::string string
Definition: nybbler.cc:12
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >> Point_t
ElapsedTime_t elapsed() const
Returns the total time spent running since the last restart.
Definition: StopWatch.h:254
enum geo::coordinates Coord_t
constexpr T square(T x)
Definition: pow.h:21
void restart()
Restarts the watch; previous time is forgotten.
Definition: StopWatch.h:218
CoordStruct Coord
Definition: restypedef.cpp:17
Provides time interval measurements.
Definition: StopWatch.h:79
static Config * config
Definition: config.cpp:1054
generator
Definition: train.py:468
Algorithm(s) dealing with point isolation in space.
void PointIsolationTest(Engine &generator, unsigned int nPoints, std::vector< Coord > const &radii)
BOOST_FIXTURE_TEST_CASE(PointIsolationTestCase, ArgsFixture)
QTextStream & endl(QTextStream &s)