diff --git a/Filters/src/TriggerResultsFilter_module.cc b/Filters/src/TriggerResultsFilter_module.cc index 3c84a3dcb2..aef812aeaf 100644 --- a/Filters/src/TriggerResultsFilter_module.cc +++ b/Filters/src/TriggerResultsFilter_module.cc @@ -7,8 +7,8 @@ #include #include #include -// root -#include "TString.h" +#include + // art includes #include "art/Framework/Core/EDFilter.h" #include "art/Framework/Principal/Event.h" @@ -16,6 +16,7 @@ #include "canvas/Persistency/Common/TriggerResults.h" #include "cetlib_except/exception.h" #include "fhiclcpp/types/Sequence.h" + // mu2e includes #include "Offline/Mu2eUtilities/inc/TriggerResultsNavigator.hh" @@ -29,12 +30,14 @@ namespace mu2e { using Name=fhicl::Name; using Comment=fhicl::Comment; struct Config { - fhicl::Atom diagLevel{ Name("DiagLevel"), Comment("Diagonstic Level"), 0}; - fhicl::Atom printFirst{ Name("PrintFirst"), - Comment("Print the TriggerResults on the first event"), false}; + fhicl::Atom diagLevel{ Name("DiagLevel"), Comment("Diagonstic Level"), 0}; + fhicl::Atom printFirst{ Name("PrintFirst"), Comment("Print the TriggerResults on the first event"), false}; + fhicl::Atom noFilter{ Name("NoFilter"), Comment("If true, do not filter any events"), false}; fhicl::Atom processName{Name("ProcessName"), Comment("Process which generated TriggerResults")}; fhicl::Sequence triggerNames{ Name("TriggerNames"), - Comment("Trigger line names to test; if any of these are set the event will pass the filter")}; + Comment("Trigger line names to test; if any of these are set the event will pass the filter"), vector()}; + fhicl::Sequence triggerBits{ Name("TriggerBits"), + Comment("Trigger line bits to test; if any of these are set the event will pass the filter"), vector()}; }; using Parameters = art::EDFilter::Table; @@ -46,7 +49,9 @@ namespace mu2e { int _diag; string _pname; // process name for the TriggerResults object to test bool _pfirst; // print lines on first event + bool _noFilter; // if true, do not filter any events std::vector _tnames; // trigger line names; if any of these lines are set, accept the event + std::vector _tbits; // trigger line bits; if any of these lines are set, accept the event std::vector _nset; // number of events passing each line unsigned _nevts, _npassed; }; @@ -57,47 +62,70 @@ namespace mu2e { _diag(config().diagLevel()), _pname(config().processName()), _pfirst(config().printFirst()), + _noFilter(config().noFilter()), _tnames(config().triggerNames()), - _nset(_tnames.size(),0), + _tbits(config().triggerBits()), + _nset(max(_tnames.size(), _tbits.size()),0), _nevts(0),_npassed(0) - {} + { + // Only filter on trigger bits or trigger names, not both + if(_tnames.size()>0 && _tbits.size()>0){ + throw cet::exception("CONFIG")<<"mu2e::TriggerResultsFilter: cannot specify both trigger names and trigger bits to filter on"; + } + if(_tnames.empty() && _tbits.empty() && !_noFilter){ + throw cet::exception("CONFIG")<<"mu2e::TriggerResultsFilter: must specify at least one trigger name or bit to filter on, or set NoFilter to true"; + } + } //================================================================ bool TriggerResultsFilter::filter(art::Event& event) { _nevts++; // find the TriggerResults object for the requested process name - art::InputTag const tag{Form("TriggerResults::%s", _pname.c_str())}; + art::InputTag const tag{format("TriggerResults::{}", _pname.c_str())}; auto trigResultsH = event.getValidHandle(tag); const art::TriggerResults* trigResults = trigResultsH.product(); TriggerResultsNavigator tnav(trigResults); - if(_pfirst){ + if(_pfirst || _diag > 2){ _pfirst = false; tnav.print(); } // loop over all the lines in this TriggerResults and see if any of the requested are set. // Count each line separately for diagnostics bool passed(false); - for(size_t iname=0;iname < _tnames.size(); iname++){ - auto const& tname = _tnames[iname]; - size_t itrig = tnav.findTrigPath(tname); - // require that the line exist - if(itrig == trigResults->size())throw cet::exception("Filter")<<"mu2e::TriggerResultsFilter: cannot find TriggerResults value for trigger " << tname << endl; - if(_diag>0) cout << "trigger line " << itrig << " found for name " << tname << " with value " << tnav.getTrigPath(itrig) << " status " - << trigResults->accept(itrig) << endl; - - if(trigResults->accept(itrig)){ - passed = true; - _nset[iname]++; + const bool use_bits = _tnames.empty(); + const size_t nbits = (use_bits) ? _tbits.size() : _tnames.size(); + for(size_t itrig = 0; itrig < nbits; itrig++) { + try { + auto const& tname = (use_bits) ? tnav.getTrigNameByBit(_tbits[itrig]) : _tnames[itrig]; + const bool accepted = tnav.accepted(tname); + if(_diag>1) printf("[TriggerResultsFilter::%s] Trigger %s (bit %zu) accepted = %o\n", + __func__, tname.c_str(), tnav.getTrigBit(tname), accepted); + if(accepted) { + passed = true; + _nset[itrig]++; + } + } catch (...) { // don't require the trigger to exist, as it may only appear in some runs + if(_diag>0) printf("[TriggerResultsFilter::%s] Trigger list index %zu not found\n", + __func__, itrig); } } - if(passed)_npassed++; - return passed; + if(passed) _npassed++; + return passed || _noFilter; } void TriggerResultsFilter::endJob() { - cout << "filter passed " << _npassed << " of " << _nevts << " events" << endl; - for(size_t iname=0;iname<_tnames.size(); iname++){ - cout << "Trigger Line " << _tnames[iname] << " set for " << _nset[iname] << " events" << endl; + printf("[TriggerResultFilter::%s] Processed %u events, accepted %u events (%8.4f%%)\n", + __func__, _nevts, _npassed, _nevts > 0 ? _npassed*100./_nevts : 0.); + if(_diag > 0) { + if(_tnames.size()>0) { + for(size_t iname=0;iname<_tnames.size(); iname++){ + cout << " Trigger Line " << _tnames[iname] << " set for " << _nset[iname] << " events" << endl; + } + } else if(_tbits.size()>0) { + for(size_t ibit=0;ibit<_tbits.size(); ibit++){ + cout << " Trigger Bit " << _tbits[ibit] << " set for " << _nset[ibit] << " events" << endl; + } + } } } diff --git a/Mu2eUtilities/inc/TriggerResultsNavigator.hh b/Mu2eUtilities/inc/TriggerResultsNavigator.hh index 095aff6933..a738b12bae 100644 --- a/Mu2eUtilities/inc/TriggerResultsNavigator.hh +++ b/Mu2eUtilities/inc/TriggerResultsNavigator.hh @@ -43,8 +43,21 @@ namespace mu2e { return findTrigPathID(name); } + std::string const& getTrigNameByBit(size_t const bit) const { + for (const auto& pair : _trigPathMap) { + if (pair.second == bit) { + return pair.first; + } + } + throw cet::exception("TRIGGER") << "TriggerResultsNavigator: Bit " << bit << " not found"; + } + // Has ith path accepted the event? bool accepted(std::string const& name) const; + bool accepted(unsigned int const bit) const { + auto name = getTrigNameByBit(bit); + return accepted(name); + } bool wasrun(std::string const& name) const;