23 #include "canvas/Persistency/Common/FindManyP.h" 24 #include "canvas/Persistency/Common/FindOneP.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.")
92 template <
typename Track>
96 template <
typename TrackPo
int>
103 template <
typename TrackPo
int>
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>
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.";
170 auto tracks = proxy::getCollection<proxy::Tracks>
173 std::vector<decltype(tracks)::element_proxy_t> longTracks;
174 for (
auto track:
tracks) {
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;
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;
388 << longTracks.size() <<
" tracks are longer than " << minLength <<
" cm:";
389 std::for_each(longTracks.begin(), longTracks.end(),
390 [
this](
auto const& track){ this->
processTrack(track); });
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
auto withOriginalTrajectory(art::InputTag const &inputTag)
Adds recob::TrackTrajectory information to the proxy.
static constexpr Flag_t Suspicious
The point reconstruction is somehow questionable.
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.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
fhicl::Atom< art::InputTag > tracksTag
ChannelGroupService::Name Name
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
EDAnalyzer(fhicl::ParameterSet const &pset)
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 Length(size_t p=0) const
Access to various track properties.
#define DEFINE_ART_MODULE(klass)
A trajectory in space reconstructed from hits.
Object storing per-hit information from a track fit.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static constexpr Flag_t HitIgnored
Hit was not included for the computation of the trajectory.
virtual void analyze(art::Event const &event) override
Detector simulation of raw signals on wires.
TrackProxyTest(Parameters const &config)
float PeakTime() const
Time of the signal peak, in tick units.
Declaration of signal hit object.
Represents a track trajectory before the final fit.
Provides recob::Track data product.
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.
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
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.
Event finding and building.