13 #ifdef USE_ATOMICPASSCOUNTER
15 #else // !USE_ATOMICPASSCOUNTER
17 #endif // USE_ATOMICPASSCOUNTER
25 #include "art/Framework/Core/SharedFilter.h"
26 #include "art/Framework/Core/ModuleMacros.h"
27 #include "art/Framework/Principal/Event.h"
28 #include "art/Framework/Principal/Handle.h"
29 #include "canvas/Persistency/Common/Assns.h"
30 #include "canvas/Persistency/Common/Ptr.h"
31 #include "canvas/Utilities/InputTag.h"
32 #include "fhiclcpp/types/Sequence.h"
33 #include "fhiclcpp/types/Atom.h"
34 #include "messagefacility/MessageLogger/MessageLogger.h"
44 namespace sbn {
class TimedTrackSelector; }
115 static constexpr
double NoMinTime { std::numeric_limits<double>::lowest() };
116 static constexpr
double NoMaxTime { std::numeric_limits<double>::max() };
119 { std::numeric_limits<unsigned int>::max() };
130 Name{
"TrackTimeTags" },
131 Comment{
"data products with trach time information (and associations)" }
136 Comment{
"Select only tracks not earlier than this time [ns]" },
142 Comment{
"Select only tracks earlier than this time [ns]" },
148 Comment{
"Pass only events with at least these many selected tracks" },
154 Comment{
"Pass only events with at most these many selected tracks" },
159 Name{
"OnlyPandoraTracks" },
161 "Select a \"track\" only if its particle flow object"
162 " has the particle ID of a track"
168 Name{
"SaveTracks" },
169 Comment{
"Whether to write the list of selected tracks" },
174 Name{
"LogCategory" },
175 Comment{
"name of a message facility stream for this module" },
185 (
Parameters const& params, art::ProcessingFrame
const&);
187 bool filter(art::Event& event, art::ProcessingFrame
const&)
override;
190 void endJob(art::ProcessingFrame
const&)
override;
216 #ifdef USE_ATOMICPASSCOUNTER
218 #else // !USE_ATOMICPASSCOUNTER
220 #endif // USE_ATOMICPASSCOUNTER
230 art::Assns<anab::T0, recob::PFParticle>
const& timeTracks,
std::vector<art::Ptr<recob::PFParticle>>& selectedTracks
256 : art::SharedFilter{ params }
257 , fTrackTimeTags{ params().TrackTimeTags() }
258 , fMinT0{ params().MinT0() }
259 , fMaxT0{ params().MaxT0() }
260 , fMinTracks{ params().MinTracks() }
261 , fMaxTracks{ params().MaxTracks() }
262 , fOnlyPandoraTracks{ params().OnlyPandoraTracks() }
263 , fSaveTracks{ params().SaveTracks() }
266 async<art::InEvent>();
269 produces<std::vector<art::Ptr<recob::PFParticle>>>();
276 log <<
"Configuration:"
277 <<
"\n * tracks required to be associated to a time (cathode-crossers)"
279 log <<
"\n * track time:";
280 if (fMinT0 == NoMinTime) {
281 if (fMaxT0 == NoMaxTime) log <<
" any";
282 else log <<
" before " << fMaxT0;
285 log <<
" from " << fMinT0;
286 if (fMaxT0 == NoMaxTime) log <<
" on";
287 else log <<
" to " << fMaxT0;
290 log <<
"\n * selected tracks per event: ";
291 if (fMinTracks == NoMinTracks) {
292 if (fMaxTracks == NoMaxTracks) log <<
"any";
293 else log << fMaxTracks <<
" or less";
296 if (fMaxTracks == NoMaxTracks) log << fMinTracks <<
" or more";
297 else log <<
"between " << fMinTracks <<
" and " << fMaxTracks;
299 log <<
"\n * selected tracks will" << (fSaveTracks?
"":
" not")
308 (art::Event& event, art::ProcessingFrame
const&)
311 mf::LogDebug(
fLogCategory) <<
"Processing " <<
event.id();
316 std::vector<art::Ptr<recob::PFParticle>> selectedTracks;
317 for (art::InputTag
const& inputTag: fTrackTimeTags) {
318 auto const& T0toTrack
319 =
event.getProduct<art::Assns<anab::T0, recob::PFParticle>>(inputTag);
320 unsigned int const newTracks = selectTracks(T0toTrack, selectedTracks);
323 <<
"From '" << inputTag.encode() <<
"': "
324 << newTracks <<
" tracks selected"
329 unsigned int const nSelectedTracks = selectedTracks.size();
339 std::make_unique<
std::vector<art::Ptr<recob::PFParticle>>>(selectedTracks)
341 if(selectedTracks.size() > 0)
344 <<
"InputTag for this product is: "
345 <<
event.getProductDescription(selectedTracks[0].
id())->inputTag();
354 bool const passed = selectedTracksRequirement(nSelectedTracks);
355 fPassRate.add(passed);
357 <<
' ' << (passed?
"passed":
"rejected") <<
" (" << nSelectedTracks
358 <<
" selected tracks).";
361 mf::LogDebug(
fLogCategory) <<
"Completed " <<
event.id();
381 art::Assns<anab::T0, recob::PFParticle>
const& timeTracks,
std::vector<art::Ptr<recob::PFParticle>>& selectedTracks
384 unsigned int nSelectedTracks { 0U };
385 for (
auto const& [ t0Ptr, trackPtr ]: timeTracks) {
392 if (!isTrackSelected(*track, *t0Ptr))
continue;
394 MF_LOG_TRACE(
fLogCategory) <<
"Track #" << trackPtr.key() <<
" selected.";
396 selectedTracks.push_back(trackPtr);
401 return nSelectedTracks;
411 double const T0 = time.
Time();
414 if (fOnlyPandoraTracks && !isTrack(track)) {
416 <<
") => discarded!";
420 if ((T0 < fMinT0) || (T0 >= fMaxT0)) {
421 MF_LOG_TRACE(
fLogCategory) <<
"Time out of range [ " << fMinT0 <<
"; "
422 << fMaxT0 <<
" ] => discarded!";
448 (
unsigned int nTracks)
const
450 return (nTracks >= fMinTracks) && (nTracks <= fMaxTracks);
std::string const fLogCategory
Message facility stream name.
icarus::ns::util::PassCounter fPassRate
Counter of passed events (not thread-safe).
bool filter(art::Event &event, art::ProcessingFrame const &) override
static constexpr unsigned int NoMinTracks
const double & Time() const
bool selectedTracksRequirement(unsigned int nTracks) const
Returns if the number of tracks nTracks satisfies filter requirements.
fhicl::Atom< double > MinT0
unsigned int const fMaxTracks
Maximum selected tracks for event selection.
void endJob(art::ProcessingFrame const &) override
Prints end-job summary.
int PdgCode() const
Return the type of particle as a PDG ID.
process_name use argoneut_mc_hitfinder track
Class to keep count of a pass/fail result.
bool isTrackSelected(recob::PFParticle const &track, anab::T0 const &time) const
Returns whether the specified track (with specified time) qualifies.
fhicl::Atom< bool > OnlyPandoraTracks
Count_t total() const
Returns the total number of registered events.
Selects tracks with time information.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
double const fMinT0
Minimum track time for track selection.
fhicl::Atom< std::string > LogCategory
double const fMaxT0
Maximum track time for track selection.
fhicl::Atom< unsigned int > MinTracks
std::vector< art::InputTag > const fTrackTimeTags
List of track-time association input tags.
bool const fOnlyPandoraTracks
Save only tracks identified as such.
fhicl::Atom< bool > SaveTracks
fhicl::Sequence< art::InputTag > TrackTimeTags
static bool isTrack(recob::PFParticle const &particle)
Returns whether the specified particle flow object is a track.
bool const fSaveTracks
Whether to save selected tracks into the event.
Module configuration parameters.
BEGIN_PROLOG vertical distance to the surface Name
Class to keep count of a pass/fail result (thread-safe).
static constexpr double NoMaxTime
Hierarchical representation of particle flow.
TimedTrackSelector(Parameters const ¶ms, art::ProcessingFrame const &)
unsigned int const fMinTracks
Minimum selected tracks for event selection.
fhicl::Atom< unsigned int > MaxTracks
static constexpr double NoMinTime
Count_t passed() const
Returns the number of events which "passed".
unsigned int selectTracks(art::Assns< anab::T0, recob::PFParticle > const &timeTracks, std::vector< art::Ptr< recob::PFParticle >> &selectedTracks) const
Adds to selectedTracks qualifying tracks from timeTracks.
Class counting pass/fail events.
static constexpr unsigned int NoMaxTracks
art::SharedFilter::Table< Config > Parameters
fhicl::Atom< double > MaxT0
Class counting pass/fail events.
process_name opdaq physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator T0