27 #include "canvas/Persistency/Common/FindManyP.h" 28 #include "canvas/Persistency/Common/FindOneP.h" 38 #include "boost/test/unit_test.hpp" 45 #include <type_traits> 64 Comment(
"tag of the recob::Track data products to run the test on.")
100 template <
typename Track>
109 template <
typename Cont,
typename Value>
110 std::size_t indexOf(Cont
const& cont, Value
const&
value) {
115 auto const it = std::find(
cbegin,
cend, value);
122 template <
typename T>
123 bool areSameObject(
T const&
a,
T const&
b)
124 {
return std::addressof(a) == std::addressof(b); }
126 template <
typename T>
128 areSameObject(
T&&
a,
T&&
b)
136 template <
typename Track>
142 <<
"[#" << track.index() <<
"] track " << trackRef
143 <<
" " << track->
Length() <<
" cm long, with " 144 << trackRef.
NPoints() <<
" points and " 145 << track.template get<recob::Hit>().
size()
165 auto tracks = proxy::getCollection<std::vector<recob::Track>>(
167 proxy::withAssociatedMeta<recob::Hit, recob::TrackHitMeta>()
171 mf::LogVerbatim(
"ProxyBaseTest") <<
"No tracks in '" << tracksTag.encode()
176 mf::LogVerbatim(
"ProxyBaseTest") <<
"Collection '" << tracksTag.encode()
177 <<
"' contains " <<
tracks.size() <<
" tracks.";
182 for (
auto trackInfo:
tracks) {
185 double const startTheta = track.
Theta();
187 double const length = trackInfo->Length();
190 decltype(
auto) hits = trackInfo.get<
recob::Hit>();
194 for (
auto const& hitInfo: hits) {
196 double const hitCharge = hitInfo->Integral();
199 if (onCollection(*hitInfo)) {
200 double const ds = hitInfo.data().Dx();
201 if (ds > 0.0) dQds.add(hitCharge / ds);
208 <<
"[#" << trackInfo.index() <<
"] track ID=" << track.
ID()
209 <<
" (" << length <<
" cm, starting with theta=" << startTheta
210 <<
" rad) deposited charge=" << charge
211 <<
" with " << hits.size() <<
" hits";
213 log <<
" (<dQ/ds> = " 214 << dQds.Average() <<
" +/- " << dQds.RMS() <<
" Q/cm from " 215 << dQds.N() <<
" hits in collection planes)";
232 auto tracks = proxy::getCollection<std::vector<recob::Track>>
235 std::vector<decltype(tracks)::element_proxy_t> longTracks;
236 for (
auto track:
tracks) {
237 if (track->Length() >= minLength) longTracks.push_back(track);
247 auto const& expectedTracks
248 =
event.getProduct<std::vector<recob::Track>>(
tracksTag);
251 <<
"Starting test on " << expectedTracks.size() <<
" tracks from '" 254 auto directTracks = proxy::getCollection<std::vector<recob::Track>>(
256 , proxy::withParallelData<std::vector<recob::TrackFitHitInfo>>()
259 auto tracks = proxy::getCollection<std::vector<recob::Track>>(
261 , proxy::withParallelData<std::vector<recob::TrackFitHitInfo>>()
262 , proxy::wrapParallelDataAs<tag::TrackSubproxy>(directTracks)
277 auto const& expectedFitHitInfo
278 = *(
event.getValidHandle<std::vector<std::vector<recob::TrackFitHitInfo>>>
281 std::size_t iExpectedTrack = 0;
282 for (
auto trackProxy:
tracks) {
283 auto const& expectedTrack = expectedTracks[iExpectedTrack];
284 auto const& expectedTrackFitInfo = expectedFitHitInfo[iExpectedTrack];
288 (std::addressof(*directTrackProxy) == std::addressof(expectedTrack));
289 BOOST_TEST(directTrackProxy->ID() == expectedTrack.ID());
290 BOOST_TEST(directTrackProxy->Length() == expectedTrack.Length());
294 (directTrackProxy.get<std::vector<recob::TrackFitHitInfo>>()) ==
295 std::addressof(expectedTrackFitInfo)
309 BOOST_TEST(iExpectedTrack == expectedTracks.size());
316 auto expectedTracksHandle
317 =
event.getValidHandle<std::vector<recob::Track>>(
tracksTag);
318 auto const& expectedTracks = *expectedTracksHandle;
320 auto const& expectedTrackHitAssns = *(
326 <<
"Starting test on " << expectedTracks.size() <<
" tracks from '" 329 art::FindManyP<recob::Hit, recob::TrackHitMeta> hitsPerTrack
330 (expectedTracksHandle, event,
tracksTag);
332 art::FindOneP<recob::TrackTrajectory> trajectoryPerTrack
333 (expectedTracksHandle, event,
tracksTag);
335 auto const& expectedTrackFitHitInfo
336 = *(
event.getValidHandle<std::vector<std::vector<recob::TrackFitHitInfo>>>
339 auto directTracks = proxy::getCollection<std::vector<recob::Track>>(
341 proxy::withParallelData<std::vector<recob::TrackFitHitInfo>>()
344 auto tracks = proxy::getCollection<std::vector<recob::Track>>(
346 , proxy::withAssociated<recob::Hit>()
347 , proxy::withAssociatedAs<recob::Hit, tag::SpecialHits>()
354 , proxy::wrapAssociatedAs<tag::DirectHitAssns>(expectedTrackHitAssns)
355 , proxy::wrapParallelDataAs<tag::DirectFitInfo>(expectedTrackFitHitInfo)
356 , proxy::wrapParallelDataAs<tag::TrackSubproxy>(directTracks)
357 , proxy::withZeroOrOne<recob::TrackTrajectory>(tracksTag)
364 "Track proxy does NOT have space points available!!!");
367 tracks.has<std::vector<recob::TrackFitHitInfo>>(),
368 "recob::TrackFitHitInfo not found!!!" 372 BOOST_TEST(
tracks.empty() == expectedTracks.empty());
373 BOOST_TEST(
tracks.size() == expectedTracks.size());
375 BOOST_TEST(
tracks.size() == expectedTrackFitHitInfo.size());
376 decltype(
auto) allFitHitInfo
377 =
tracks.get<std::vector<recob::TrackFitHitInfo>>();
379 std::is_lvalue_reference<decltype(allFitHitInfo)>(),
380 "Copy of parallel data!" 383 (allFitHitInfo.data() == std::addressof(expectedTrackFitHitInfo));
387 std::addressof(expectedTrackFitHitInfo)
391 directTracks.get<std::vector<recob::TrackFitHitInfo>>().data() ==
392 std::addressof(expectedTrackFitHitInfo)
397 std::addressof(directTracks)
402 BOOST_TEST(fitHitInfoSize == expectedTrackFitHitInfo.size());
405 std::size_t iExpectedTrack = 0;
406 for (
auto trackProxy:
tracks) {
407 auto const& expectedTrack = expectedTracks[iExpectedTrack];
409 { expectedTracksHandle, iExpectedTrack };
410 auto const& expectedHits = hitsPerTrack.at(iExpectedTrack);
411 auto const& expectedHitMeta = hitsPerTrack.data(iExpectedTrack);
412 auto const& expectedFitHitInfo = expectedTrackFitHitInfo[iExpectedTrack];
414 = trajectoryPerTrack.at(iExpectedTrack);
419 (!areSameObject(tracks[iExpectedTrack], tracks[iExpectedTrack]));
423 auto const trackProxyCopy = trackProxy;
424 BOOST_TEST(std::addressof(trackProxyCopy) != std::addressof(trackProxy));
427 (std::addressof(trackRef) == std::addressof(expectedTrack));
429 (std::addressof(*trackProxy) == std::addressof(expectedTrack));
432 BOOST_TEST(trackProxy.get<recob::Hit>().size() == expectedHits.size());
438 indexOf(expectedHits, hitPtr) !=
444 BOOST_TEST(trackProxy.index() == iExpectedTrack);
446 std::vector<recob::TrackFitHitInfo>
const& fitHitInfo
447 = trackProxy.get<std::vector<recob::TrackFitHitInfo>>();
449 std::is_lvalue_reference<decltype(fitHitInfo)>(),
450 "Copy of parallel data element!" 453 (std::addressof(fitHitInfo) == std::addressof(expectedFitHitInfo));
454 BOOST_TEST(fitHitInfo.size() == expectedFitHitInfo.size());
458 std::addressof(expectedTrackFitHitInfo[iExpectedTrack])
474 (std::addressof(*directTrackProxy) == std::addressof(expectedTrack));
475 BOOST_TEST(directTrackProxy->ID() == expectedTrack.ID());
476 BOOST_TEST(directTrackProxy->Length() == expectedTrack.Length());
479 (directTrackProxy.get<std::vector<recob::TrackFitHitInfo>>()) ==
480 std::addressof(fitHitInfo)
491 !std::decay_t<decltype(hitPtr)>::hasMetadata(),
492 "Expected no metadata for tag::SpecialHits" 495 BOOST_TEST(!hitPtr.hasMetadata());
500 indexOf(expectedHits, hitPtr) !=
508 BOOST_TEST(hits.size() == expectedHits.size());
510 unsigned int nSpecialHits = 0U;
511 for (
auto const& hitInfo: hits) {
518 std::decay_t<decltype(hitInfo)>::hasMetadata(),
519 "Expected metadata for tag::MetadataHits" 521 BOOST_TEST(hitInfo.hasMetadata());
528 auto const index = indexOf(expectedHits, hitPtr);
531 BOOST_TEST(&(hitInfo.main()) == &expectedTrack);
532 BOOST_TEST(hitInfo.mainPtr() == expectedTrackPtr);
534 if (
index < expectedHitMeta.size()) {
536 auto const& expectedMetadata = expectedHitMeta.at(
index);
538 BOOST_TEST(hitInfo.valuePtr() == hitPtr);
540 (std::addressof(hitInfo.value()) == std::addressof(*hitPtr));
541 BOOST_TEST(hitInfo.key() == hitPtr.key());
542 BOOST_TEST(hitInfo.id() == hitPtr.id());
544 if (expectedHitPtr) {
546 BOOST_TEST(hitInfo.operator->() == hitPtr);
547 recob::Hit
const&
hit = *expectedHitPtr;
548 BOOST_TEST(std::addressof(*hitInfo) == std::addressof(hit));
551 BOOST_TEST(hitInfo.dataPtr() == expectedMetadata);
552 BOOST_TEST(&(hitInfo.data()) == expectedMetadata);
554 auto hitInfoCopy = hitInfo;
561 BOOST_TEST(hitPtrMoved == hitPtr);
566 BOOST_TEST(nSpecialHits == expectedHits.size());
569 for (
auto iHit = hits.begin(); iHit != hits.end(); ++iHit) {
572 (iHit.hasMetadata(),
"Expected metadata for tag::MetadataHits");
579 auto const index = indexOf(expectedHits, hitPtr);
582 BOOST_TEST(&(iHit.main()) == &expectedTrack);
583 BOOST_TEST(iHit.mainPtr() == expectedTrackPtr);
585 if (
index < expectedHitMeta.size()) {
587 auto const* expectedMetadata = expectedHitMeta.at(
index);
589 BOOST_TEST(iHit.valuePtr() == hitPtr);
591 (std::addressof(iHit.value()) == std::addressof(*hitPtr));
593 BOOST_TEST(iHit.dataPtr() == expectedMetadata);
594 BOOST_TEST(std::addressof(iHit.data()) == expectedMetadata);
596 BOOST_TEST(iHit.valuePtr() == expectedHitPtr);
597 BOOST_TEST(iHit.dataPtr() == expectedMetadata);
602 BOOST_TEST(nSpecialHits == expectedHits.size());
608 BOOST_TEST(trackProxy->NPoints() == expectedTrack.NPoints());
613 if (expectedTrajPtr.
isNull()) {
622 BOOST_TEST(iExpectedTrack == expectedTracks.size());
631 const double minLength = 30.0;
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); });
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
void testProxyComposition(art::Event const &event) const
Tests proxy composition.
ProxyBaseTest & operator=(ProxyBaseTest const &)=delete
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
void testTracks(art::Event const &event) const
Performs the actual test.
ProxyBaseTest(Parameters const &config)
Runs a test of proxy::Tracks interface.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
ChannelGroupService::Name Name
virtual void analyze(art::Event const &event) override
auto withAssociatedMetaAs(Args &&...args)
Helper function to merge associated data with metadata.
EDAnalyzer(fhicl::ParameterSet const &pset)
Classes gathering simple statistics.
void processTrack(Track const &track) const
Single-track processing function example.
art::InputTag tracksTag
Tag for the input tracks.
Offers proxy::Tracks and proxy::Track class for recob::Track access.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
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 Length(size_t p=0) const
Access to various track properties.
#define DEFINE_ART_MODULE(klass)
A trajectory in space reconstructed from hits.
double Theta() const
Access to spherical or geographical angles at vertex or at any point.
bool isNull() const noexcept
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static int max(int a, int b)
fhicl::Atom< art::InputTag > tracksTag
Detector simulation of raw signals on wires.
Declaration of signal hit object.
Provides recob::Track data product.
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
void proxyUsageExample(art::Event const &event) const
An example of how to access the information via track proxy.
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
2D representation of charge deposited in the TDC/wire plane
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 "fitted" track:
Event finding and building.
Signal from collection planes.