19 #include "art/Framework/Core/EDAnalyzer.h"
20 #include "art/Framework/Core/ModuleMacros.h"
21 #include "art/Framework/Principal/Event.h"
22 #include "art/Framework/Principal/Handle.h"
23 #include "canvas/Persistency/Common/FindManyP.h"
24 #include "canvas/Persistency/Common/FindOneP.h"
25 #include "canvas/Utilities/InputTag.h"
28 #include "messagefacility/MessageLogger/MessageLogger.h"
29 #include "fhiclcpp/types/Atom.h"
30 #include "fhiclcpp/types/Name.h"
31 #include "fhiclcpp/types/Comment.h"
34 #include "boost/test/unit_test.hpp"
38 #include <initializer_list>
59 Comment(
"tag of the recob::Track data products to run the test on.")
67 : art::EDAnalyzer(config)
77 virtual void analyze(art::Event
const& event)
override;
86 auto getLongTracks(art::Event
const& event,
double minLength)
const;
92 template <
typename Track>
96 template <
typename TrackPo
int>
103 template <
typename TrackPo
int>
106 mf::LogVerbatim log(
"TrackProxyTest");
108 " [#" << point.index() <<
"] at " << point.position()
109 <<
" (momentum: " << point.momentum() <<
"), flags: "
114 log <<
" with a Q=" << hit->
Integral() <<
" hit on channel "
116 <<
", measured: " << point.fitInfoPtr()->hitMeas();
119 log <<
" (no associated hit)";
125 template <
typename Track>
130 mf::LogVerbatim(
"TrackProxyTest")
131 <<
"[#" << track.index() <<
"] track " << trackRef
132 <<
" " << track->Length() <<
" cm long, with "
133 << trackRef.
NPoints() <<
" points and " << track.nHits()
136 for (
auto point: track.points()) {
146 auto tracks = proxy::getCollection<proxy::Tracks>
150 mf::LogVerbatim(
"TrackProxyTest") <<
"No tracks in '" << tracksTag.encode()
155 mf::LogVerbatim(
"TrackProxyTest") <<
"Collection '" << tracksTag.encode()
156 <<
"' contains " <<
tracks.size() <<
" tracks.";
163 (art::Event
const& event,
double minLength)
const
170 auto tracks = proxy::getCollection<proxy::Tracks>
173 std::vector<decltype(tracks)::element_proxy_t> longTracks;
175 if (
track->Length() >= minLength) longTracks.push_back(
track);
184 struct SpecialHits {};
189 auto expectedTracksHandle
190 =
event.getValidHandle<std::vector<recob::Track>>(
tracksTag);
191 auto const& expectedTracks = *expectedTracksHandle;
193 mf::LogInfo(
"TrackProxyTest")
194 <<
"Starting test on " << expectedTracks.size() <<
" tracks from '"
197 art::FindManyP<recob::Hit> hitsPerTrack
198 (expectedTracksHandle, event,
tracksTag);
200 art::FindOneP<recob::TrackTrajectory> trajectoryPerTrack
201 (expectedTracksHandle, event,
tracksTag);
203 auto const& expectedTrackFitHitInfo
204 = *(
event.getValidHandle<std::vector<std::vector<recob::TrackFitHitInfo>>>
208 , proxy::withAssociatedAs<recob::Hit, tag::SpecialHits>()
217 "Track proxy does NOT have space points available!!!");
221 "recob::TrackFitHitInfo not found!!!"
225 BOOST_TEST(
tracks.empty() == expectedTracks.empty());
226 BOOST_TEST(
tracks.size() == expectedTracks.size());
228 BOOST_TEST(
tracks.size() == expectedTrackFitHitInfo.size());
231 std::is_lvalue_reference<decltype(allFitHitInfo)>(),
232 "Copy of parallel data!"
235 (allFitHitInfo.data() == std::addressof(expectedTrackFitHitInfo));
239 BOOST_TEST(fitHitInfoSize == expectedTrackFitHitInfo.size());
241 std::size_t iExpectedTrack = 0;
242 for (
auto const& trackProxy:
tracks) {
243 BOOST_TEST_CHECKPOINT(
"Track #" << trackProxy.index());
245 auto const& expectedTrack = expectedTracks[iExpectedTrack];
246 auto const& expectedHits = hitsPerTrack.at(iExpectedTrack);
247 auto const& expectedFitHitInfo = expectedTrackFitHitInfo[iExpectedTrack];
248 auto const& expectedTrajPtr = trajectoryPerTrack.at(iExpectedTrack);
250 = expectedTrajPtr.isNull()?
nullptr: expectedTrajPtr.get();
255 (std::addressof(trackRef) == std::addressof(expectedTrack));
257 (std::addressof(trackProxy.track()) == std::addressof(expectedTrack));
258 BOOST_TEST(trackProxy.nHits() == expectedHits.size());
259 BOOST_TEST(trackProxy.index() == iExpectedTrack);
263 std::is_lvalue_reference<decltype(fitHitInfo)>(),
264 "Copy of parallel data element!"
267 (std::addressof(fitHitInfo), std::addressof(expectedFitHitInfo));
268 BOOST_TEST(fitHitInfo.size() == expectedFitHitInfo.size());
275 (trackProxy.hasOriginalTrajectory() == !expectedTrajPtr.isNull());
276 if (expectedTrajCPtr) {
277 BOOST_TEST(trackProxy.originalTrajectoryPtr() == expectedTrajPtr);
278 BOOST_TEST(&trackProxy.originalTrajectory() == expectedTrajPtr.get());
281 BOOST_TEST(!(trackProxy.originalTrajectoryPtr()));
286 std::addressof(expectedTrack.Trajectory())
292 BOOST_TEST(trackProxy->NPoints() == expectedTrack.NPoints());
295 std::array<unsigned int, recob::TrajectoryPointFlagTraits::maxFlags()>
298 std::size_t iPoint = 0;
299 for (
auto const& pointInfo: trackProxy.points()) {
300 BOOST_TEST_CHECKPOINT(
" point #" << pointInfo.index());
302 decltype(
auto) expectedPointFlags = expectedTrack.FlagsAtPoint(iPoint);
304 BOOST_TEST(pointInfo.index() == iPoint);
306 pointInfo.position() ==
307 expectedTrack.Trajectory().LocationAtPoint(iPoint)
310 (pointInfo.momentum() == expectedTrack.MomentumVectorAtPoint(iPoint));
311 BOOST_TEST(pointInfo.flags() == expectedPointFlags);
312 if (expectedPointFlags.hasOriginalHitIndex()) {
314 (pointInfo.hitPtr().key() == expectedPointFlags.fromHit());
317 BOOST_TEST(!pointInfo.hitPtr());
328 if (!expectedPointFlags.isDefined(
flag))
continue;
329 if (expectedPointFlags.isSet(
flag)) ++flagCounts[
flag.index()];
333 (fitHitInfo[iPoint].WireId() == expectedFitHitInfo[iPoint].WireId());
335 (pointInfo.fitInfoPtr() == std::addressof(expectedFitHitInfo[iPoint]));
337 std::addressof(fitHitInfo[iPoint]) ==
338 std::addressof(expectedFitHitInfo[iPoint])
343 BOOST_TEST(iPoint == expectedTrack.NPoints());
353 BOOST_TEST_CHECKPOINT(
" flag: " <<
flag);
354 unsigned int flagCount = 0U;
355 for (
auto const& pointInfo: trackProxy.pointsWithFlags(
flag)) {
357 BOOST_TEST_CHECKPOINT(
" point #" << pointInfo.index());
358 BOOST_TEST(pointInfo.flags().isDefined(
flag));
359 BOOST_TEST(pointInfo.flags().isSet(
flag));
363 BOOST_TEST(flagCount == flagCounts[
flag.index()]);
368 BOOST_TEST(iExpectedTrack == expectedTracks.size());
377 const double minLength = 30.0;
387 mf::LogVerbatim(
"TrackProxyTest")
388 << longTracks.size() <<
" tracks are longer than " << minLength <<
" cm:";
389 std::for_each(longTracks.begin(), longTracks.end(),
auto withOriginalTrajectory(art::InputTag const &inputTag)
Adds recob::TrackTrajectory information to the proxy.
static constexpr Flag_t Suspicious
The point reconstruction is somehow questionable.
ClusterModuleLabel join with tracks
void testTracks(art::Event const &event)
Performs the actual test.
TrackProxyTest & operator=(TrackProxyTest const &)=delete
static constexpr Flag_t NoPoint
The trajectory point is not defined.
art::EDAnalyzer::Table< Config > Parameters
then echo unknown compiler flag
fhicl::Atom< art::InputTag > tracksTag
Declaration of signal hit object.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
process_name use argoneut_mc_hitfinder track
Runs a test of proxy::Tracks interface.
Offers proxy::Tracks and proxy::Track class for recob::Track access.
void proxyUsageExample(art::Event const &event) const
An example of how to access the information via track 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.
Object storing per-hit information from a track fit.
BEGIN_PROLOG vertical distance to the surface Name
Data product for reconstructed trajectory in space.
static constexpr Flag_t HitIgnored
Hit was not included for the computation of the trajectory.
virtual void analyze(art::Event const &event) override
Provides recob::Track data product.
TrackProxyTest(Parameters const &config)
float PeakTime() const
Time of the signal peak, in tick units.
Represents a track trajectory before the final fit.
art::InputTag tracksTag
Tag for the input tracks.
static constexpr Flag_t DetectorIssue
The hit is associated to a problematic channel.
auto withFitHitInfo(art::InputTag const &inputTag)
Adds recob::TrackFitHitInfo information to the proxy.
2D representation of charge deposited in the TDC/wire plane
Represents a track trajectory from the final fit.
Number of supported track types.
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
void processTrack(Track const &track) const
Single-track processing function example.
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
void processPoint(TrackPoint const &point) const
Single-track-point processing function example.