Macros | Functions | Variables
CountersMap_test.cc File Reference

Tests the counter map. More...

#include <map>
#include <random>
#include <iostream>
#include "boost/test/unit_test.hpp"
#include "lardata/Utilities/CountersMap.h"

Go to the source code of this file.

Macros

#define BOOST_TEST_MODULE   ( CountersMap_test )
 

Functions

void RunHoughTransformTreeTest ()
 Tests with a vector of counter maps (Hough transfort use case) More...
 
 BOOST_AUTO_TEST_CASE (RunHoughTransformTree)
 

Variables

constexpr unsigned int RandomSeed = 12345
 The seed for the default random engine. More...
 

Detailed Description

Tests the counter map.

Author
Gianluca Petrillo (petri.nosp@m.llo@.nosp@m.fnal..nosp@m.gov)
Date
20140822
Version
1.0

See http://www.boost.org/libs/test for the Boost test library home page.

Timing: version 1.0 takes about 30" on a 3 GHz machine.

Definition in file CountersMap_test.cc.

Macro Definition Documentation

#define BOOST_TEST_MODULE   ( CountersMap_test )

Definition at line 29 of file CountersMap_test.cc.

Function Documentation

BOOST_AUTO_TEST_CASE ( RunHoughTransformTree  )

Definition at line 187 of file CountersMap_test.cc.

187  {
189  std::cout << "Done." << std::endl;
190 }
void RunHoughTransformTreeTest()
Tests with a vector of counter maps (Hough transfort use case)
QTextStream & endl(QTextStream &s)
void RunHoughTransformTreeTest ( )

Tests with a vector of counter maps (Hough transfort use case)

The test consists in filling a lot of points into a 2D sparse "image" (or histogram). Two structures are maintained, one with the standard STL map, another with the CountersMap. The test fails if the two images do not match.

Definition at line 53 of file CountersMap_test.cc.

53  {
54 
55  // the structure we are testing is a 2D "image" of integers;
56  // image is mostly empty (zero), but each abscissa has roughly the same
57  // number of non-empty pixels (NPoints), and at least one of them.
58 
59  constexpr unsigned int NPoints = 1000;
60  constexpr unsigned int NAngles = 10800;
61  constexpr unsigned int NDist = 2500; // half distance
62 
63  typedef std::map<int, int> BaseMap_t;
64 
65  // STL container
66  typedef std::vector<BaseMap_t> MapVectorI_t;
67  MapVectorI_t stl_image(NAngles);
68 
69  // CountersMap; uses chunks of 8 counters per block
70  std::vector<lar::CountersMap<int, int, 8>> cm_image(NAngles);
71  // the following should fail compilation
72 // std::vector<lar::CountersMap<int, int, 9>> cm_image_broken(NAngles);
73 
74  static std::default_random_engine random_engine(RandomSeed);
75  std::uniform_real_distribution<float> uniform(-1., 1.);
76 
77  for (unsigned int iPoint = 0; iPoint != NPoints; ++iPoint) {
78  // we add here some simple image, not to strain the test;
79  // this is a straight line
80  const float offset = uniform(random_engine) * NDist;
81  const float slope = uniform(random_engine);
82  float d = offset;
83  for (size_t iAngle = 0; iAngle < NAngles; ++iAngle) {
84  // add one entry on the (angle ; distance) plane
85  ++(stl_image[iAngle][int(d)]);
86  cm_image[iAngle].increment(int(d)); // different interface than usual map
87  // prepare for the next point; wrap in the [-NDist, NDist[ range
88  d += slope;
89  while (d >= (float) NDist) d -= 2*NDist;
90  while (d < 0) d += 2*NDist;
91  } // for iAngle
92  } // for iPoint
93 
94  std::cout << "Filling complete, now checking." << std::endl;
95 
96  // we have to provide a comparison between two "different" structures
97  // (having different allocators is enough to make them unrelated)
98  unsigned int nExtraKeys = 0, nMismatchValue = 0, nMissingKeys = 0;
99  auto stl_begin = stl_image.cbegin();
100  unsigned int iMap = 0;
101  for (const auto& cm_map: cm_image) {
102 
103  const MapVectorI_t::value_type& stl_map = *(stl_begin++);
104 
105  std::cout << "Map #" << iMap << " (" << cm_map.n_counters()
106  << " counters, " << stl_map.size() << " real)"
107  << std::endl;
108 
109  // compare the two maps; the CountersMap one has more elements,
110  // since the counters are allocated in blocks;
111  // if a key is in STL map, it must be also in the CountersMap;
112  // if a key is not in STL map, counter in CountersMap must be missing or 0
113  MapVectorI_t::value_type::const_iterator stl_iter = stl_map.begin(),
114  stl_end = stl_map.end();
115  for (auto p: cm_map) { // this should be a pair (index, counter)
116 
117  if (stl_iter != stl_end) { // we have still counters to find
118  // if counter is already beyond the next non-empty one froml STL map,
119  // then we are missing some
120  while (p.first > stl_iter->first) {
121  ++nMissingKeys;
122  std::cout << "ERROR missing key " << stl_iter->first << std::endl;
123  if (++stl_iter == stl_end) break;
124  }
125  } // if
126 
127  if (stl_iter != stl_end) { // we have still counters to find
128  if (p.first == stl_iter->first) {
129  // if the counter is in SLT map, the two counts must match
130  // std::cout << " " << p.first << " " << p.second << std::endl;
131  if (stl_iter->second != p.second) {
132  std::cout << "ERROR wrong counter value " << p.second
133  << ", expected " << stl_iter->second << std::endl;
134  ++nMismatchValue;
135  }
136  ++stl_iter; // done with it
137  }
138  else if (p.first < stl_iter->first) {
139  // if the counter is not in STL map, then it must be 0
140  if (p.second != 0) {
141  ++nExtraKeys;
142  std::cout << "ERROR extra key " << p.first << " (" << p.second << ")"
143  << std::endl;
144  }
145  // else {
146  // std::cout << " " << p.first << " " << p.second << " (not in STL)"
147  // << std::endl;
148  // }
149  }
150  }
151  else {
152  // no more keys in STL map
153  if (p.second != 0) {
154  ++nExtraKeys;
155  std::cout << "ERROR extra key " << p.first << " (" << p.second << ")"
156  << std::endl;
157  }
158  }
159  } // for element in map
160 
161  BOOST_TEST(cm_map.is_equal(stl_map));
162 
163  // if they were the same, make sure that now they differ
164  const_cast<MapVectorI_t::value_type&>(stl_map)[NDist / 2]++;
165  BOOST_TEST(!cm_map.is_equal(stl_map));
166 
167  ++iMap;
168  } // for map
169 
170  BOOST_TEST(nMismatchValue == 0U);
171  BOOST_TEST(nMissingKeys == 0U);
172  BOOST_TEST(nExtraKeys == 0U);
173 
174 
175 } // RunHoughTransformTreeTest()
constexpr unsigned int RandomSeed
The seed for the default random engine.
intermediate_table::const_iterator const_iterator
p
Definition: test.py:223
QTextStream & endl(QTextStream &s)

Variable Documentation

constexpr unsigned int RandomSeed = 12345

The seed for the default random engine.

Definition at line 37 of file CountersMap_test.cc.