All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ChargedSpacePointProxyTest_module.cc
Go to the documentation of this file.
1 /**
2  * @file ChargedSpacePointProxyTest_module.cc
3  * @brief Tests `proxy::ChargedSpacePoints` proxy.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date December 20, 2017
6  *
7  */
8 
9 
10 // LArSoft libraries
11 #include "lardata/RecoBaseProxy/ChargedSpacePoints.h" // proxy namespace
12 #include "larcorealg/Geometry/geo_vectors_utils.h" // geo::vect namespace
15 
16 // framework libraries
17 #include "art/Framework/Core/EDAnalyzer.h"
18 #include "art/Framework/Core/ModuleMacros.h"
19 #include "art/Framework/Principal/Event.h"
20 #include "art/Framework/Principal/Handle.h"
21 #include "canvas/Utilities/InputTag.h"
22 
23 // utility libraries
24 #include "messagefacility/MessageLogger/MessageLogger.h"
25 #include "fhiclcpp/types/Atom.h"
26 #include "fhiclcpp/types/Name.h"
27 #include "fhiclcpp/types/Comment.h"
28 
29 // Boost libraries
30 #include "boost/test/unit_test.hpp"
31 
32 // C/C++ libraries
33 #include <memory> // std::addressof()
34 #include <type_traits>
35 #include <cassert>
36 
37 
38 //------------------------------------------------------------------------------
39 /**
40  * @brief Runs a test of `proxy::ChargedSpacePoints` interface.
41  *
42  * This module is that it uses Boost unit test library, and as such it must be
43  * run with `lar_ut` instead of `lar`.
44  */
45 class ChargedSpacePointProxyTest: public art::EDAnalyzer {
46  public:
47 
48  struct Config {
49  using Name = fhicl::Name;
50  using Comment = fhicl::Comment;
51 
52  fhicl::Atom<art::InputTag> pointsTag{
53  Name("points"),
54  Comment
55  ("tag of the recob::SpacePoint and recob::PointCharge data products.")
56  };
57 
58  }; // struct Config
59 
60  using Parameters = art::EDAnalyzer::Table<Config>;
61 
62  explicit ChargedSpacePointProxyTest(Parameters const& config)
63  : art::EDAnalyzer(config)
64  , pointsTag(config().pointsTag())
65  {}
66 
67  // Plugins should not be copied or assigned.
71  (ChargedSpacePointProxyTest const &) = delete;
73 
74  virtual void analyze(art::Event const& event) override;
75 
76  private:
77  art::InputTag pointsTag; ///< Tag for the input.
78 
79  /// An example of how to access the information via proxy.
80  void proxyUsageExample(art::Event const& event) const;
81 
82  /// Performs the actual test.
83  void testChargedSpacePoints(art::Event const& event);
84 
85 
86 }; // class ChargedSpacePointProxyTest
87 
88 
89 //------------------------------------------------------------------------------
91  (art::Event const& event) const
92 {
93 
94  auto points = proxy::getChargedSpacePoints(event, pointsTag);
95 
96  if (points.empty()) {
97  mf::LogVerbatim("ProxyTest")
98  << "No points in '" << pointsTag.encode() << "'";
99  return;
100  }
101 
102  mf::LogVerbatim log("ProxyTest");
103  for (auto point: points) {
104  log << "\nPoint at " << point.position() << " (ID=" << point.ID()
105  << ") has ";
106  if (point.hasCharge()) log << "charge " << point.charge();
107  else log << "no charge";
108  } // for point
109 
110  mf::LogVerbatim("ProxyTest") << "Collection '" << pointsTag.encode()
111  << "' contains " << points.size() << " points.";
112 
113 } // ChargedSpacePointProxyTest::proxyUsageExample()
114 
115 
116 //------------------------------------------------------------------------------
118  (art::Event const& event)
119 {
120 
121  auto const& expectedSpacePoints
122  = *(event.getValidHandle<std::vector<recob::SpacePoint>>(pointsTag));
123 
124  auto const& expectedCharges
125  = *(event.getValidHandle<std::vector<recob::PointCharge>>(pointsTag));
126 
127  mf::LogInfo("ProxyTest")
128  << "Starting test on " << expectedSpacePoints.size() << " points and "
129  << expectedCharges.size() << " charges from '"
130  << pointsTag.encode() << "'";
131 
132  // this assertion fails on invalid input (test bug)
133  assert(expectedSpacePoints.size() == expectedCharges.size());
134 
135  auto points = proxy::getChargedSpacePoints(event, pointsTag);
136 
137  static_assert(points.has<recob::PointCharge>(), "recob::Charge not found!!!");
138 
139  BOOST_TEST(points.empty() == expectedSpacePoints.empty());
140  BOOST_TEST(points.size() == expectedSpacePoints.size());
141 
142  decltype(auto) spacePoints = points.spacePoints();
143  BOOST_TEST
144  (std::addressof(spacePoints) == std::addressof(expectedSpacePoints));
145  BOOST_TEST(spacePoints.size() == expectedSpacePoints.size());
146 
147  decltype(auto) charges = points.charges();
148  BOOST_TEST(std::addressof(charges) == std::addressof(expectedCharges));
149  BOOST_TEST(charges.size() == expectedCharges.size());
150 
151  std::size_t iExpectedPoint = 0;
152  for (auto pointProxy: points) {
153  auto const& expectedSpacePoint = expectedSpacePoints[iExpectedPoint];
154  auto const& expectedChargeInfo = expectedCharges[iExpectedPoint];
155 
156  recob::SpacePoint const& spacePointRef = *pointProxy;
157 
158  BOOST_TEST
159  (std::addressof(spacePointRef) == std::addressof(expectedSpacePoint));
160  BOOST_TEST
161  (std::addressof(pointProxy.point()) == std::addressof(expectedSpacePoint));
162  BOOST_TEST(pointProxy.position() == geo::vect::makePointFromCoords(expectedSpacePoint.XYZ()));
163  BOOST_TEST(pointProxy.ID() == expectedSpacePoint.ID());
164  BOOST_TEST(pointProxy.hasCharge() == expectedChargeInfo.hasCharge());
165  BOOST_TEST(pointProxy.charge() == expectedChargeInfo.charge());
166 
167  decltype(auto) chargeInfo = pointProxy.get<recob::PointCharge>();
168  static_assert(
169  std::is_lvalue_reference<decltype(chargeInfo)>(),
170  "Copy of parallel data element!"
171  );
172  BOOST_TEST
173  (std::addressof(chargeInfo) == std::addressof(expectedChargeInfo));
174 
175  ++iExpectedPoint;
176  } // for
177  BOOST_TEST(iExpectedPoint == expectedSpacePoints.size());
178 
179 } // ChargedSpacePointProxyTest::testChargedSpacePoints()
180 
181 
182 //------------------------------------------------------------------------------
183 void ChargedSpacePointProxyTest::analyze(art::Event const& event) {
184 
185  // usage example (supposed to be educational)
186  proxyUsageExample(event);
187 
188  // actual test
189  testChargedSpacePoints(event);
190 
191 } // ChargedSpacePointProxyTest::analyze()
192 
193 
194 //------------------------------------------------------------------------------
195 
196 DEFINE_ART_MODULE(ChargedSpacePointProxyTest)
auto getChargedSpacePoints(Event const &event, art::InputTag inputTag, Args &&...withArgs)
Creates and returns a proxy to space points with associated charge.
Runs a test of proxy::ChargedSpacePoints interface.
virtual void analyze(art::Event const &event) override
art::EDAnalyzer::Table< Config > Parameters
Information about charge reconstructed in the active volume.
art::InputTag pointsTag
Tag for the input.
Offers proxy::ChargedSpacePoints and proxy::SpacePointWithCharge class for recob::SpacePoint with rec...
ChargedSpacePointProxyTest & operator=(ChargedSpacePointProxyTest const &)=delete
void proxyUsageExample(art::Event const &event) const
An example of how to access the information via proxy.
Utilities to extend the interface of geometry vectors.
BEGIN_PROLOG vertical distance to the surface Name
void testChargedSpacePoints(art::Event const &event)
Performs the actual test.
ChargedSpacePointProxyTest(Parameters const &config)
GENVECTOR_CONSTEXPR::geo::Point_t makePointFromCoords(Coords &&coords)
Creates a geo::Point_t from its coordinates (see makeFromCoords()).
Charge reconstructed in the active volume.
Definition: PointCharge.h:31