All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ProxyBaseTest_module.cc
Go to the documentation of this file.
1 /**
2  * @file ProxyBaseTest_module.cc
3  * @brief Tests feattures of `ProxyBase.h`.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date September 8, 2017
6  *
7  */
8 
9 
10 // LArSoft libraries
11 #include "lardata/RecoBaseProxy/Track.h" // proxy namespace
18 
19 // #include "larcorealg/CoreUtils/DebugUtils.h" // lar::debug::demangle()
20 // #include "larcorealg/CoreUtils/UncopiableAndUnmovableClass.h"
21 
22 // framework libraries
23 #include "art/Framework/Core/EDAnalyzer.h"
24 #include "art/Framework/Core/ModuleMacros.h"
25 #include "art/Framework/Principal/Event.h"
26 #include "art/Framework/Principal/Handle.h"
27 #include "canvas/Persistency/Common/FindManyP.h"
28 #include "canvas/Persistency/Common/FindOneP.h"
29 #include "canvas/Utilities/InputTag.h"
30 
31 // utility libraries
32 #include "messagefacility/MessageLogger/MessageLogger.h"
33 #include "fhiclcpp/types/Atom.h"
34 #include "fhiclcpp/types/Name.h"
35 #include "fhiclcpp/types/Comment.h"
36 
37 // Boost libraries
38 #include "boost/test/unit_test.hpp"
39 
40 // C/C++ libraries
41 #include <algorithm> // std::for_each(), std::find()
42 // #include <initializer_list>
43 #include <memory> // std::unique_ptr<>
44 #include <cstring> // std::strlen(), std::strcpy()
45 #include <type_traits> // std::is_rvalue_reference<>
46 
47 
48 //------------------------------------------------------------------------------
49 /**
50  * @brief Runs a test of `proxy::Tracks` interface.
51  *
52  * This module is that it uses Boost unit test library, and as such it must be
53  * run with `lar_ut` instead of `lar`.
54  */
55 class ProxyBaseTest : public art::EDAnalyzer {
56  public:
57 
58  struct Config {
59  using Name = fhicl::Name;
60  using Comment = fhicl::Comment;
61 
62  fhicl::Atom<art::InputTag> tracksTag{
63  Name("tracks"),
64  Comment("tag of the recob::Track data products to run the test on.")
65  };
66 
67  }; // struct Config
68 
69  using Parameters = art::EDAnalyzer::Table<Config>;
70 
71  explicit ProxyBaseTest(Parameters const& config)
72  : art::EDAnalyzer(config)
73  , tracksTag(config().tracksTag())
74  {}
75 
76  // Plugins should not be copied or assigned.
77  ProxyBaseTest(ProxyBaseTest const &) = delete;
78  ProxyBaseTest(ProxyBaseTest &&) = delete;
79  ProxyBaseTest& operator= (ProxyBaseTest const &) = delete;
81 
82  virtual void analyze(art::Event const& event) override;
83 
84  private:
85  art::InputTag tracksTag; ///< Tag for the input tracks.
86 
87  /// An example of how to access the information via track proxy.
88  void proxyUsageExample(art::Event const& event) const;
89 
90  /// Returns proxies to tracks longer than a certain length.
91  auto getLongTracks(art::Event const& event, double minLength) const;
92 
93  /// Tests proxy composition.
94  void testProxyComposition(art::Event const& event) const;
95 
96  /// Performs the actual test.
97  void testTracks(art::Event const& event) const;
98 
99  /// Single-track processing function example.
100  template <typename Track>
101  void processTrack(Track const& track) const;
102 
103 }; // class ProxyBaseTest
104 
105 
106 //------------------------------------------------------------------------------
107 namespace {
108 
109  template <typename Cont, typename Value>
110  std::size_t indexOf(Cont const& cont, Value const& value) {
111  using std::begin;
112  using std::end;
113  auto const cbegin = begin(cont);
114  auto const cend = end(cont);
115  auto const it = std::find(cbegin, cend, value);
116  return (it == cend)? std::numeric_limits<std::size_t>::max(): (it - cbegin);
117  } // indexOf()
118 
119 
120  // this is not a very good test, since it assumes that R-values are
121  // necessarily different; which may be not the case
122  template <typename T>
123  bool areSameObject(T const& a, T const& b)
124  { return std::addressof(a) == std::addressof(b); }
125 
126  template <typename T>
128  areSameObject(T&& a, T&& b)
129  { return false; }
130 
131 
132 } // local namespace
133 
134 
135 //------------------------------------------------------------------------------
136 template <typename Track>
138 
139  recob::Track const& trackRef = *track;
140 
141  mf::LogVerbatim("ProxyBaseTest")
142  << "[#" << track.index() << "] track " << trackRef
143  << " " << track->Length() << " cm long, with "
144  << trackRef.NPoints() << " points and "
145  << track.template get<recob::Hit>().size()
146  << " hits:";
147 
148 } // ProxyBaseTest::processTrack()
149 
150 
151 //------------------------------------------------------------------------------
152 namespace tag {
153  struct SpecialHits {};
154  struct MetadataHits {};
155  struct DirectHitAssns {};
156  struct DirectFitInfo {};
157  struct TrackSubproxy {};
158  struct FitInfoProxy {};
159 }
160 
161 
162 //------------------------------------------------------------------------------
163 void ProxyBaseTest::proxyUsageExample(art::Event const& event) const {
164 
165  auto tracks = proxy::getCollection<std::vector<recob::Track>>(
166  event, tracksTag,
167  proxy::withAssociatedMeta<recob::Hit, recob::TrackHitMeta>()
168  );
169 
170  if (tracks.empty()) {
171  mf::LogVerbatim("ProxyBaseTest") << "No tracks in '" << tracksTag.encode()
172  << "'";
173  return;
174  }
175 
176  mf::LogVerbatim("ProxyBaseTest") << "Collection '" << tracksTag.encode()
177  << "' contains " << tracks.size() << " tracks.";
178 
179  auto onCollection
180  = [](recob::Hit const& hit){ return hit.SignalType() == geo::kCollection; };
181 
182  for (auto trackInfo: tracks) {
183 
184  recob::Track const& track = *trackInfo; // access to the track
185  double const startTheta = track.Theta();
186 
187  double const length = trackInfo->Length(); // access to track members
188 
189  // access to associated data (returns random-access collection-like object)
190  decltype(auto) hits = trackInfo.get<recob::Hit>();
191 
193  double charge = 0.0;
194  for (auto const& hitInfo: hits) {
195  // hitInfo is equivalent to a art::Ptr<recob::Hit>
196  double const hitCharge = hitInfo->Integral();
197  charge += hitCharge;
198 
199  if (onCollection(*hitInfo)) { //
200  double const ds = hitInfo.data().Dx(); // access recob::TrackHitMeta
201  if (ds > 0.0) dQds.add(hitCharge / ds);
202  } // if on collection
203 
204  } // for hits
205 
206  mf::LogVerbatim log("ProxyBaseTest");
207  log
208  << "[#" << trackInfo.index() << "] track ID=" << track.ID()
209  << " (" << length << " cm, starting with theta=" << startTheta
210  << " rad) deposited charge=" << charge
211  << " with " << hits.size() << " hits";
212  if (dQds.N() > 0) {
213  log << " (<dQ/ds> = "
214  << dQds.Average() << " +/- " << dQds.RMS() << " Q/cm from "
215  << dQds.N() << " hits in collection planes)";
216  }
217 
218  } // for tracks
219 
220 } // ProxyBaseTest::proxyUsageExample()
221 
222 
223 //------------------------------------------------------------------------------
225  (art::Event const& event, double minLength) const
226 {
227  //
228  // this code is not a particularly good practice, but it is aimed to check
229  // that after the proxy collection is out of scope, elements copied from it
230  // are still valid
231  //
232  auto tracks = proxy::getCollection<std::vector<recob::Track>>
233  (event, tracksTag, proxy::withAssociated<recob::Hit>() );
234 
235  std::vector<decltype(tracks)::element_proxy_t> longTracks;
236  for (auto track: tracks) {
237  if (track->Length() >= minLength) longTracks.push_back(track);
238  } // for track
239  return longTracks;
240 
241 } // ProxyBaseTest::getLongTracks()
242 
243 
244 //------------------------------------------------------------------------------
245 void ProxyBaseTest::testProxyComposition(art::Event const& event) const {
246 
247  auto const& expectedTracks
248  = event.getProduct<std::vector<recob::Track>>(tracksTag);
249 
250  mf::LogInfo("ProxyBaseTest")
251  << "Starting test on " << expectedTracks.size() << " tracks from '"
252  << tracksTag.encode() << "'";
253 
254  auto directTracks = proxy::getCollection<std::vector<recob::Track>>(
255  event, tracksTag
256  , proxy::withParallelData<std::vector<recob::TrackFitHitInfo>>()
257  );
258 
259  auto tracks = proxy::getCollection<std::vector<recob::Track>>(
260  event, tracksTag
261  , proxy::withParallelData<std::vector<recob::TrackFitHitInfo>>()
262  , proxy::wrapParallelDataAs<tag::TrackSubproxy>(directTracks)
263  /*
264  , proxy::withCollectionProxyAs
265  <std::vector<recob::TrackFitHitInfo>, tag::FitInfoProxy>
266  (tracksTag, proxy::withParallelData<std::vector<recob::Track>>())
267  */
268  );
269  BOOST_TEST
270  (tracks.get<tag::TrackSubproxy>().data() == std::addressof(directTracks));
271 
272  static_assert(
273  std::is_lvalue_reference<decltype(tracks.get<tag::TrackSubproxy>())>(),
274  "Not reference!"
275  );
276 
277  auto const& expectedFitHitInfo
278  = *(event.getValidHandle<std::vector<std::vector<recob::TrackFitHitInfo>>>
279  (tracksTag));
280 
281  std::size_t iExpectedTrack = 0;
282  for (auto trackProxy: tracks) {
283  auto const& expectedTrack = expectedTracks[iExpectedTrack];
284  auto const& expectedTrackFitInfo = expectedFitHitInfo[iExpectedTrack];
285 
286  auto directTrackProxy = trackProxy.get<tag::TrackSubproxy>();
287  BOOST_TEST
288  (std::addressof(*directTrackProxy) == std::addressof(expectedTrack));
289  BOOST_TEST(directTrackProxy->ID() == expectedTrack.ID());
290  BOOST_TEST(directTrackProxy->Length() == expectedTrack.Length());
291 
292  BOOST_TEST(
293  std::addressof
294  (directTrackProxy.get<std::vector<recob::TrackFitHitInfo>>()) ==
295  std::addressof(expectedTrackFitInfo)
296  );
297  /*
298  auto fitInfoProxy = trackProxy.get<tag::FitInfoProxy>();
299  BOOST_TEST
300  (std::addressof(*fitInfoProxy) == std::addressof(expectedFitHitInfo));
301  BOOST_TEST(
302  std::addressof(fitInfoProxy.get<recob::Track>()) ==
303  std::addressof(expectedTrack)
304  );
305  */
306  ++iExpectedTrack;
307  } // for
308 
309  BOOST_TEST(iExpectedTrack == expectedTracks.size());
310 
311 } // ProxyBaseTest::testProxyComposition()
312 
313 //------------------------------------------------------------------------------
314 void ProxyBaseTest::testTracks(art::Event const& event) const {
315 
316  auto expectedTracksHandle
317  = event.getValidHandle<std::vector<recob::Track>>(tracksTag);
318  auto const& expectedTracks = *expectedTracksHandle;
319 
320  auto const& expectedTrackHitAssns = *(
321  event.getValidHandle
322  <art::Assns<recob::Track, recob::Hit, recob::TrackHitMeta>>(tracksTag)
323  );
324 
325  mf::LogInfo("ProxyBaseTest")
326  << "Starting test on " << expectedTracks.size() << " tracks from '"
327  << tracksTag.encode() << "'";
328 
329  art::FindManyP<recob::Hit, recob::TrackHitMeta> hitsPerTrack
330  (expectedTracksHandle, event, tracksTag);
331 
332  art::FindOneP<recob::TrackTrajectory> trajectoryPerTrack
333  (expectedTracksHandle, event, tracksTag);
334 
335  auto const& expectedTrackFitHitInfo
336  = *(event.getValidHandle<std::vector<std::vector<recob::TrackFitHitInfo>>>
337  (tracksTag));
338 
339  auto directTracks = proxy::getCollection<std::vector<recob::Track>>(
340  event, tracksTag,
341  proxy::withParallelData<std::vector<recob::TrackFitHitInfo>>()
342  );
343 
344  auto tracks = proxy::getCollection<std::vector<recob::Track>>(
345  event, tracksTag
346  , proxy::withAssociated<recob::Hit>()
347  , proxy::withAssociatedAs<recob::Hit, tag::SpecialHits>()
350  , proxy::withParallelData<std::vector<recob::TrackFitHitInfo>>()
351 // , proxy::withCollectionProxyAs
352 // <std::vector<recob::Track>, tag::TrackSubproxy>
353 // (tracksTag, proxy::withParallelData<std::vector<recob::TrackFitHitInfo>>())
354  , proxy::wrapAssociatedAs<tag::DirectHitAssns>(expectedTrackHitAssns)
355  , proxy::wrapParallelDataAs<tag::DirectFitInfo>(expectedTrackFitHitInfo)
356  , proxy::wrapParallelDataAs<tag::TrackSubproxy>(directTracks)
357  , proxy::withZeroOrOne<recob::TrackTrajectory>(tracksTag)
358  );
359 
360  //
361  // we try to access something we did not "register" in the proxy: space points
362  //
363  static_assert(!tracks.has<recob::SpacePoint>(),
364  "Track proxy does NOT have space points available!!!");
365 
366  static_assert(
367  tracks.has<std::vector<recob::TrackFitHitInfo>>(),
368  "recob::TrackFitHitInfo not found!!!"
369  );
370 
371 
372  BOOST_TEST(tracks.empty() == expectedTracks.empty());
373  BOOST_TEST(tracks.size() == expectedTracks.size());
374 
375  BOOST_TEST(tracks.size() == expectedTrackFitHitInfo.size());
376  decltype(auto) allFitHitInfo
377  = tracks.get<std::vector<recob::TrackFitHitInfo>>();
378  static_assert(
379  std::is_lvalue_reference<decltype(allFitHitInfo)>(),
380  "Copy of parallel data!"
381  );
382  BOOST_TEST
383  (allFitHitInfo.data() == std::addressof(expectedTrackFitHitInfo));
384 
385  BOOST_TEST(
386  tracks.get<tag::DirectFitInfo>().data() ==
387  std::addressof(expectedTrackFitHitInfo)
388  );
389 
390  BOOST_TEST(
391  directTracks.get<std::vector<recob::TrackFitHitInfo>>().data() ==
392  std::addressof(expectedTrackFitHitInfo)
393  );
394 
395  BOOST_TEST(
396  tracks.get<tag::TrackSubproxy>().data() ==
397  std::addressof(directTracks)
398  );
399 
400  auto fitHitInfoSize
401  = std::distance(allFitHitInfo.begin(), allFitHitInfo.end());
402  BOOST_TEST(fitHitInfoSize == expectedTrackFitHitInfo.size());
403 
404 
405  std::size_t iExpectedTrack = 0;
406  for (auto trackProxy: tracks) {
407  auto const& expectedTrack = expectedTracks[iExpectedTrack];
408  art::Ptr<recob::Track> const expectedTrackPtr
409  { expectedTracksHandle, iExpectedTrack };
410  auto const& expectedHits = hitsPerTrack.at(iExpectedTrack);
411  auto const& expectedHitMeta = hitsPerTrack.data(iExpectedTrack);
412  auto const& expectedFitHitInfo = expectedTrackFitHitInfo[iExpectedTrack];
413  art::Ptr<recob::TrackTrajectory> const expectedTrajPtr
414  = trajectoryPerTrack.at(iExpectedTrack);
415 
416  // proxies deliver temporary objects as elements, each time a new one
417  // (although an exceedingly smart compiler might decide otherwise)
418  BOOST_TEST
419  (!areSameObject(tracks[iExpectedTrack], tracks[iExpectedTrack]));
420 
421  recob::Track const& trackRef = *trackProxy;
422 
423  auto const trackProxyCopy = trackProxy;
424  BOOST_TEST(std::addressof(trackProxyCopy) != std::addressof(trackProxy));
425 
426  BOOST_TEST
427  (std::addressof(trackRef) == std::addressof(expectedTrack));
428  BOOST_TEST
429  (std::addressof(*trackProxy) == std::addressof(expectedTrack));
430 
431  // hits
432  BOOST_TEST(trackProxy.get<recob::Hit>().size() == expectedHits.size());
433  for (art::Ptr<recob::Hit> const& hitPtr: trackProxy.get<recob::Hit>()) {
434 
435  // with this check we just ask the hit is there
436  // (the order is not guaranteed to be the same in expected and fetched)
437  BOOST_TEST(
438  indexOf(expectedHits, hitPtr) !=
439  std::numeric_limits<std::size_t>::max()
440  );
441 
442  } // for hit
443 
444  BOOST_TEST(trackProxy.index() == iExpectedTrack);
445 
446  std::vector<recob::TrackFitHitInfo> const& fitHitInfo
447  = trackProxy.get<std::vector<recob::TrackFitHitInfo>>();
448  static_assert(
449  std::is_lvalue_reference<decltype(fitHitInfo)>(),
450  "Copy of parallel data element!"
451  );
452  BOOST_TEST
453  (std::addressof(fitHitInfo) == std::addressof(expectedFitHitInfo));
454  BOOST_TEST(fitHitInfo.size() == expectedFitHitInfo.size());
455 
456  BOOST_TEST(
457  std::addressof(trackProxy.get<tag::DirectFitInfo>()) ==
458  std::addressof(expectedTrackFitHitInfo[iExpectedTrack])
459  );
460 
461  BOOST_TEST(
462  std::addressof(trackProxyCopy.get<tag::DirectFitInfo>()) ==
463  std::addressof(trackProxy.get<tag::DirectFitInfo>())
464  );
465 
466  // subproxy elements are typically temporaries
467  BOOST_TEST(
468  std::addressof(trackProxyCopy.get<tag::TrackSubproxy>()) !=
469  std::addressof(trackProxy.get<tag::TrackSubproxy>())
470  );
471 
472  auto directTrackProxy = trackProxy.get<tag::TrackSubproxy>();
473  BOOST_TEST
474  (std::addressof(*directTrackProxy) == std::addressof(expectedTrack));
475  BOOST_TEST(directTrackProxy->ID() == expectedTrack.ID());
476  BOOST_TEST(directTrackProxy->Length() == expectedTrack.Length());
477  BOOST_TEST(
478  std::addressof
479  (directTrackProxy.get<std::vector<recob::TrackFitHitInfo>>()) ==
480  std::addressof(fitHitInfo)
481  );
482 
483  // "special" hits
484  BOOST_TEST
485  (trackProxy.get<tag::SpecialHits>().size() == expectedHits.size());
486  for (auto const& hitPtr: trackProxy.get<tag::SpecialHits>()) {
487  // hitPtr is actually not a art::Ptr, but it can be compared to one
488 
489  // the syntax of the static check is pretty horrible...
490  static_assert(
491  !std::decay_t<decltype(hitPtr)>::hasMetadata(),
492  "Expected no metadata for tag::SpecialHits"
493  );
494  // easier when non-static:
495  BOOST_TEST(!hitPtr.hasMetadata());
496 
497  // with this check we just ask the hit is there
498  // (the order is not guaranteed to be the same in expected and fetched)
499  BOOST_TEST(
500  indexOf(expectedHits, hitPtr) !=
501  std::numeric_limits<std::size_t>::max()
502  );
503 
504  } // for special hit
505 
506  // hits with metadata
507  auto const& hits = trackProxy.get<tag::MetadataHits>();
508  BOOST_TEST(hits.size() == expectedHits.size());
509  // - range-for loop
510  unsigned int nSpecialHits = 0U;
511  for (auto const& hitInfo: hits) {
512  ++nSpecialHits;
513  // hitPtr is actually not a art::Ptr,
514  // but it can be implicitly converted into one
515 
516  // the syntax of the static check is still pretty horrible...
517  static_assert(
518  std::decay_t<decltype(hitInfo)>::hasMetadata(),
519  "Expected metadata for tag::MetadataHits"
520  );
521  BOOST_TEST(hitInfo.hasMetadata());
522 
523  // conversion, as reference
524  art::Ptr<recob::Hit> const& hitPtr = hitInfo;
525 
526  // with this check we just ask the hit is there
527  // (the order is not guaranteed to be the same in expected and fetched)
528  auto const index = indexOf(expectedHits, hitPtr);
529  BOOST_TEST(index != std::numeric_limits<std::size_t>::max());
530 
531  BOOST_TEST(&(hitInfo.main()) == &expectedTrack);
532  BOOST_TEST(hitInfo.mainPtr() == expectedTrackPtr);
533 
534  if (index < expectedHitMeta.size()) {
535  art::Ptr<recob::Hit> const& expectedHitPtr = expectedHits.at(index);
536  auto const& expectedMetadata = expectedHitMeta.at(index);
537 
538  BOOST_TEST(hitInfo.valuePtr() == hitPtr);
539  BOOST_TEST
540  (std::addressof(hitInfo.value()) == std::addressof(*hitPtr));
541  BOOST_TEST(hitInfo.key() == hitPtr.key());
542  BOOST_TEST(hitInfo.id() == hitPtr.id());
543 
544  if (expectedHitPtr) {
545  BOOST_TEST(hitPtr);
546  BOOST_TEST(hitInfo.operator->() == hitPtr);
547  recob::Hit const& hit = *expectedHitPtr;
548  BOOST_TEST(std::addressof(*hitInfo) == std::addressof(hit));
549  }
550 
551  BOOST_TEST(hitInfo.dataPtr() == expectedMetadata);
552  BOOST_TEST(&(hitInfo.data()) == expectedMetadata);
553 
554  auto hitInfoCopy = hitInfo; // copy
555  BOOST_TEST
556  (static_cast<art::Ptr<recob::Hit> const&>(hitInfo) == hitPtr);
557  BOOST_TEST
558  (&(static_cast<art::Ptr<recob::Hit> const&>(hitInfo)) == &hitPtr);
559 
560  art::Ptr<recob::Hit> hitPtrMoved = std::move(hitInfoCopy);
561  BOOST_TEST(hitPtrMoved == hitPtr);
562 
563  } // if the hit is correct
564 
565  } // for special hit
566  BOOST_TEST(nSpecialHits == expectedHits.size());
567  // - iterator loop
568  nSpecialHits = 0U;
569  for (auto iHit = hits.begin(); iHit != hits.end(); ++iHit) {
570  ++nSpecialHits;
571  static_assert
572  (iHit.hasMetadata(), "Expected metadata for tag::MetadataHits");
573 
574  // conversion, as reference
575  art::Ptr<recob::Hit> const& hitPtr = *iHit;
576 
577  // with this check we just ask the hit is there
578  // (the order is not guaranteed to be the same in expected and fetched)
579  auto const index = indexOf(expectedHits, hitPtr);
580  BOOST_TEST(index != std::numeric_limits<std::size_t>::max());
581 
582  BOOST_TEST(&(iHit.main()) == &expectedTrack);
583  BOOST_TEST(iHit.mainPtr() == expectedTrackPtr);
584 
585  if (index < expectedHitMeta.size()) {
586  art::Ptr<recob::Hit> const& expectedHitPtr = expectedHits.at(index);
587  auto const* expectedMetadata = expectedHitMeta.at(index);
588 
589  BOOST_TEST(iHit.valuePtr() == hitPtr);
590  BOOST_TEST
591  (std::addressof(iHit.value()) == std::addressof(*hitPtr));
592 
593  BOOST_TEST(iHit.dataPtr() == expectedMetadata);
594  BOOST_TEST(std::addressof(iHit.data()) == expectedMetadata);
595 
596  BOOST_TEST(iHit.valuePtr() == expectedHitPtr);
597  BOOST_TEST(iHit.dataPtr() == expectedMetadata);
598 
599  } // if the hit is correct
600 
601  } // for special hit (iterator)
602  BOOST_TEST(nSpecialHits == expectedHits.size());
603 
604  BOOST_TEST
605  (trackProxy.get<tag::DirectHitAssns>().size() == expectedHits.size());
606 
607  // direct interface to recob::Track
608  BOOST_TEST(trackProxy->NPoints() == expectedTrack.NPoints());
609 
610  // trajectory?
611  BOOST_TEST
612  (trackProxy.has<recob::TrackTrajectory>() == !expectedTrajPtr.isNull());
613  if (expectedTrajPtr.isNull()) {
614  BOOST_TEST(!(trackProxy.get<recob::TrackTrajectory>()));
615  }
616  else {
617  BOOST_TEST
618  (trackProxy.get<recob::TrackTrajectory>(), expectedTrajPtr);
619  }
620  ++iExpectedTrack;
621  } // for
622  BOOST_TEST(iExpectedTrack == expectedTracks.size());
623 
624 } // ProxyBaseTest::testTracks()
625 
626 
627 //------------------------------------------------------------------------------
628 void ProxyBaseTest::analyze(art::Event const& event) {
629 
630  // "test" that track proxies survive their collection (part I)
631  const double minLength = 30.0;
632  auto const longTracks = getLongTracks(event, minLength);
633 
634  // usage example (supposed to be educational)
635  proxyUsageExample(event);
636 
637  // actual test
638  testTracks(event);
639 
640  // test proxy composition
641  testProxyComposition(event);
642 
643  // "test" that track proxies survive their collection (part II)
644  mf::LogVerbatim("ProxyBaseTest")
645  << longTracks.size() << " tracks are longer than " << minLength << " cm:";
646  std::for_each(longTracks.begin(), longTracks.end(),
647  [this](auto const& track){ this->processTrack(track); });
648 
649 } // ProxyBaseTest::analyze()
650 
651 
652 //------------------------------------------------------------------------------
653 
654 DEFINE_ART_MODULE(ProxyBaseTest)
void testProxyComposition(art::Event const &event) const
Tests proxy composition.
ProxyBaseTest & operator=(ProxyBaseTest const &)=delete
art::EDAnalyzer::Table< Config > Parameters
ClusterModuleLabel join with tracks
void testTracks(art::Event const &event) const
Performs the actual test.
ProxyBaseTest(Parameters const &config)
Runs a test of proxy::Tracks interface.
Declaration of signal hit object.
virtual void analyze(art::Event const &event) override
Class to keep data related to recob::Hit associated with recob::Track.
auto withAssociatedMetaAs(Args &&...args)
Helper function to merge associated data with metadata.
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
auto cbegin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:567
process_name use argoneut_mc_hitfinder track
Data related to recob::Hit associated with recob::Track.The purpose is to collect several variables t...
Definition: TrackHitMeta.h:43
process_name hit
Definition: cheaterreco.fcl:51
Classes gathering simple statistics.
void processTrack(Track const &track) const
Single-track processing function example.
Definition: Data.h:7
Offers proxy::Tracks and proxy::Track class for recob::Track access.
auto cend(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:579
art::InputTag tracksTag
Tag for the input tracks.
process_name gaushit a
auto withParallelData(Args &&...args)
Helper function to merge an auxiliary data product into the proxy.
auto getLongTracks(art::Event const &event, double minLength) const
Returns proxies to tracks longer than a certain length.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
A trajectory in space reconstructed from hits.
double Theta() const
Access to spherical or geographical angles at vertex or at any point.
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
BEGIN_PROLOG vertical distance to the surface Name
fhicl::Atom< art::InputTag > tracksTag
Provides recob::Track data product.
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
void proxyUsageExample(art::Event const &event) const
An example of how to access the information via track proxy.
temporary value
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
Collects statistics on a single quantity (weighted)
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a &quot;fitted&quot; track:
Signal from collection planes.
Definition: geo_types.h:146