37 return StatusCode::SUCCESS;
50 std::unordered_map<std::string,std::string> mapStrNameToTypeName;
52 const std::string nameStr{
"name"};
53 const std::string typeStr{
"type"};
55 mapStrNameToTypeName.insert({stream.getAttribute(nameStr), stream.getAttribute(typeStr)+
"_"+stream.getAttribute(nameStr)});
57 }
catch (
const std::exception& ex) {
58 ATH_MSG_ERROR(
"Exception reading stream tag configuration from the HLT menu: " << ex.what());
59 return StatusCode::FAILURE;
63 for (
const std::string& group : chain.groups()) {
65 if (group.starts_with(
"RATE")){
71 for (
const std::string& streamName : chain.streams()){
72 const auto it = mapStrNameToTypeName.find(streamName);
73 if (it==mapStrNameToTypeName.cend()) {
74 ATH_MSG_ERROR(
"Stream name " << streamName <<
" assigned to chain " << chain.name()
75 <<
" is missing from menu streams definition");
76 return StatusCode::FAILURE;
78 if (it->second ==
"express_express") {
90 const int x {
nBinsX(hltMenuHandle)};
93 std::unique_ptr<TH2> hSA = std::make_unique<TH2I>(
"SignatureAcceptance",
"Raw acceptance of signatures in;chain;step",
x, 1,
x + 1,
y, 1,
y + 1);
94 std::unique_ptr<TH2> hDC = std::make_unique<TH2I>(
"DecisionCount",
"Positive decisions count per step;chain;step",
x, 1,
x + 1,
y, 1,
y + 1);
105 const std::string outputRateName = std::format(
"Rate{:d}s",
m_duration.value());
114 std::set<std::string> sequencesSet;
116 ctool->getSequencesNames(sequencesSet);
118 const int xc = sequencesSet.size();
121 const std::string outputSequenceName = std::format(
"SequencesExecutionRate{:d}s",
m_duration.value());
122 m_sequenceHistogram.init(outputSequenceName,
"Rate of sequences execution;sequence;rate", xc, yc,
129 return StatusCode::SUCCESS;
137 ATH_MSG_INFO(
"No chains configured, no counts to print" );
138 return StatusCode::SUCCESS;
145 std::unordered_map<std::string, std::set<int>> chainToStepsId;
148 for (
const std::string& seqName : chain.sequencers()){
150 std::smatch stepNameMatch;
151 std::regex_search(seqName.begin(), seqName.end(), stepNameMatch, std::regex(
"[Ss]tep[0-9]+"));
153 std::string stepName = stepNameMatch[0];
154 stepName[0] = std::toupper(stepName[0]);
156 if (std::format(
"Step{:d}", nstep) == stepName) {
157 chainToStepsId[chain.name()].insert(nstep);
159 for (
size_t legID = 0; legID < chain.legMultiplicities().
size(); ++ legID) {
161 chainToStepsId[legName].insert(nstep);
165 ATH_MSG_DEBUG(
"Missing counts for step" << nstep <<
" in chain " << chain.name());
171 auto collToString = [&](
int xbin,
const LockedHandle<TH2>& hist,
int startOfset=0,
int endOffset=0){
173 const int stepsSize = hist->GetYaxis()->GetNbins() -
N_BINS;
174 for (
int ybin = 1; ybin <= hist->GetYaxis()->GetNbins()-endOffset; ++ybin) {
175 if (ybin > startOfset) {
178 const std::string chainName = m_passHistogram->GetXaxis()->GetBinLabel(xbin);
180 if (ybin < 3 || ybin > stepsSize + 2 || chainToStepsId[chainName].
contains(ybin - 2)) {
181 v += std::format(
"{:<11d}",
static_cast<int>(hist->GetBinContent(xbin, ybin)));
183 v += std::format(
"{:<11s}",
"-");
186 v += std::format(
"{:<11s}",
" ");
193 v += std::format(
"{:<11s}",
"L1");
194 v += std::format(
"{:<11s}",
"AfterPS");
195 for (
int bin = 1;
bin <= m_passHistogram->GetYaxis()->GetNbins()-
N_BINS; ++
bin) {
196 v += std::format(
"Step{:<7d}",
bin);
198 v += std::format(
"{:<11s}",
"Output");
199 v += std::format(
"{:<11s}",
"Express");
201 ATH_MSG_INFO(
"Chains passing step (1st row events & 2nd row decision counts):");
202 ATH_MSG_INFO(
" Feature counts reflect the number of unique objects contributing to a positive chain decision (0 if step fails), including L1RoI for empty steps.");
204 ATH_MSG_INFO(
" Leg feature counts indicate the number of unique objects that pass the leg's step selection (regardless of multiplicity), which may overlap with other legs.");
205 ATH_MSG_INFO(
" 'PROBE' L1 RoIs are counted separately.");
211 for (
int bin = 1;
bin <= (*m_passHistogram)->GetXaxis()->GetNbins(); ++
bin) {
212 const std::string chainName = m_passHistogram->GetXaxis()->GetBinLabel(
bin);
213 const std::string chainID = std::to_string(
HLT::Identifier(chainName));
214 if (chainName.starts_with(
"HLT")) {
215 ATH_MSG_INFO( std::format(
"{:s} #{:s}", chainName, chainID) );
216 ATH_MSG_INFO( std::format(
"{:<30s}", std::format(
"-- #{} Events", chainID)) << collToString(
bin, m_passHistogram) );
217 ATH_MSG_INFO( std::format(
"{:<30s}", std::format(
"-- #{} Features", chainID)) << collToString(
bin, m_countHistogram , 2, 1 ) );
219 if (chainName.starts_with(
"All")){
220 ATH_MSG_INFO( std::format(
"{:<30s}", chainName) << collToString(
bin, m_passHistogram) );
222 if (chainName.starts_with(
"leg")) {
223 const std::string legID = chainName.substr(0,6);
224 ATH_MSG_INFO( std::format(
"{:<30s}", std::format(
"-- #{} Features", legID)) << collToString(
bin, m_countHistogram , 2, 1 ) );
228 return StatusCode::SUCCESS;
246 lockedHist->Fill( id2bin->second,
static_cast<double>(row) );
249 return StatusCode::SUCCESS;
268 m_countHistogram->Fill(id2bin->second,
static_cast<double>(row));
272 return StatusCode::SUCCESS;
276 for (
const std::string& seq : sequences) {
280 return StatusCode::SUCCESS;
286 int rowWithSteps = row;
289 for (
const auto& [name, decisions] : nameToChainsMap) {
291 if (decisions.contains(
id)) {
294 m_countHistogram->Fill(
bin, rowWithSteps);
295 m_passHistogram->Fill(
bin, rowWithSteps);
300 return StatusCode::SUCCESS;
307 ATH_MSG_WARNING(
"Timer is already running. UpdateAfterFork incident called more than once?");
328 [[maybe_unused]]
static const bool sanityCheckDone = [&] {
329 if (l1Decisions->at(
INPUT-1)->name() ==
"l1seeded" &&
330 l1Decisions->at(
AFTER_PS-1)->name() ==
"unprescaled") {
333 throw GaudiException(
m_l1DecisionsKey.key() +
" does not contain the expected entries",
334 name(), StatusCode::FAILURE);
337 auto fillL1 = [&](
int index) -> StatusCode {
345 m_passHistogram->Fill(1,
static_cast<double>(
index));
348 return StatusCode::SUCCESS;
357 std::vector<TrigCompositeUtils::DecisionID> stepSum;
358 std::set<std::string> stepSequences;
360 ctool->getDecisions( stepSum, stepSequences, context );
361 ATH_MSG_DEBUG(
" Step " << step <<
" decisions (for decisions): " << stepSum.size() );
367 stepSequences.clear();
373 ctool->getDecisions( stepSum, context );
374 ATH_MSG_DEBUG(
" Step " << step <<
" decisions (for features): " << stepSum.size() );
384 if (!decisionObject) {
385 ATH_MSG_WARNING(
"Unable to locate trigger navigation terminus node. Cannot tell which chains passed the event.");
393 if (!expressDecisionObject) {
394 ATH_MSG_WARNING(
"Unable to locate trigger navigation express terminus node. Cannot tell which chains passed the express stream in this event.");
415 if (!finalIDs.empty()) {
416 m_passHistogram->Fill(1,
static_cast<double>(countOutputRow));
419 if (!expressFinalIDs.empty()) {
420 m_passHistogram->Fill(1,
static_cast<double>(countExpressRow));
424 return StatusCode::SUCCESS;
436 int nchains = hltMenuHandle->size();
440 std::vector<size_t> legs = chain.legMultiplicities();
441 if(legs.size()>1) {nchains += legs.size();}
452 TAxis*
x = hist->GetXaxis();
453 x->SetBinLabel(1,
"All");
456 std::set<std::string> sortedChainsList;
457 std::map<unsigned int,size_t> chainMultiplicities;
459 sortedChainsList.insert( chain.name() );
462 std::vector<size_t> legs = chain.legMultiplicities();
465 ATH_MSG_DEBUG(
"For chain " << chain.name() <<
", also recording feature counts for " << legs.size() <<
" legs.");
470 for (
const std::string& chainName: sortedChainsList ) {
471 x->SetBinLabel(
bin, chainName.c_str() );
477 size_t nlegs = chainMultiplicities[chainID];
479 for (
size_t legID = 0; legID < nlegs; ++ legID) {
482 x->SetBinLabel(
bin, legName.c_str() );
491 x->SetBinLabel(
bin, (
"str_"+stream.first).c_str());
497 x->SetBinLabel(
bin, (
"str_"+stream.first).c_str());
503 x->SetBinLabel(
bin, (
"grp_"+group.first.substr(group.first.find(
':')+1)).c_str() );
509 TAxis*
y = hist->GetYaxis();
510 y->SetBinLabel(
INPUT, steps ?
"L1" :
"Input");
513 y->SetBinLabel(3 + i, std::format(
"Step {:d}", i).c_str());
515 y->SetBinLabel(
y->GetNbins()-1,
"Output");
516 y->SetBinLabel(
y->GetNbins(),
"Express");
518 return StatusCode::SUCCESS;
522 TAxis*
x = hist->GetXaxis();
526 for (
const std::string& seqName : sequenceSet) {
527 x->SetBinLabel(
bin, seqName.c_str());
532 TAxis*
y = hist->GetYaxis();
533 y->SetBinLabel(1,
"Rate");
535 return StatusCode::SUCCESS;
540 delete m_bufferHistogram.get();
545 std::unique_ptr<TH2>
h = std::make_unique<TH2F>(histoName.c_str(), histoTitle.c_str(),
x, 1,
x + 1,
y, 1,
y + 1);
546 ATH_CHECK( histSvc->regShared( registerPath.c_str(), std::move(
h), m_histogram));
548 TH2I * hB =
new TH2I( (histoName +
"Buffer").c_str(), histoTitle.c_str(),
x, 1,
x + 1,
y, 1,
y + 1);
549 m_bufferHistogram.set(hB, &
m_mutex);
550 m_bufferHistogram->SetDirectory(0);
552 return StatusCode::SUCCESS;
560 return m_bufferHistogram;
568 m_bufferHistogram->Fill(
x,
y);
576 std::chrono::milliseconds(duration*1000/20));
583 unsigned int interval;
584 unsigned int duration =
m_timeDivider->forcePassed(t, interval);
591 m_histogram->Reset(
"ICES");
592 m_histogram->Add(m_bufferHistogram.get(), 1./duration);
593 m_bufferHistogram->Reset(
"ICES");
600 unsigned int newinterval;
601 unsigned int oldinterval;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
size_t size() const
Number of registered mappings.
#define ATLAS_NOT_CONST_THREAD_SAFE
Header file for AthHistogramAlgorithm.
static const std::string & type()
Incident type.
TrigCompositeUtils::DecisionID numeric() const
numeric ID
std::string name() const
reports human redable name
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Base class for Trigger configuration data and wrapper around underlying representation.
void updatePublished(unsigned int duration) const
std::unique_ptr< Gaudi::Utils::PeriodicAction > m_timer
void startTimer(unsigned int duration, unsigned int intervals)
void fill(const double x, const double y) const
StatusCode init(const std::string &histoName, const std::string &histoTitle, const int x, const int y, const std::string ®isterPath, const ServiceHandle< ITHistSvc > &histSvc)
std::unique_ptr< Gaudi::Utils::PeriodicAction > & getTimer()
std::unique_ptr< TimeDivider > m_timeDivider
std::unordered_map< std::string, int > m_sequenceToBinMap
Sequence to bin map for sequence histogram.
int nChains(SG::ReadHandle< TrigConf::HLTMenu > &) const
StatusCode initHist(LockedHandle< TH2 > &, SG::ReadHandle< TrigConf::HLTMenu > &, bool=true)
Gaudi::Property< unsigned int > m_intervals
StatusCode fillPassEvents(const TrigCompositeUtils::DecisionIDContainer &, int) const
Gaudi::Property< unsigned int > m_duration
StatusCode initSeqHist(LockedHandle< TH2 > &, std::set< std::string > &)
virtual StatusCode start() override
StatusCode fillRate(const TrigCompositeUtils::DecisionIDContainer &, int) const
std::map< std::string, TrigCompositeUtils::DecisionIDContainer > m_streamToChainMap
Stream name to chain objects map, excluding express.
virtual StatusCode initialize() override
StatusCode fillDecisionCount(const std::vector< TrigCompositeUtils::DecisionID > &, int) const
virtual StatusCode execute(const EventContext &context) const override
RateHistogram m_sequenceHistogram
SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > m_l1DecisionsKey
ServiceHandle< ITHistSvc > m_histSvc
std::map< std::string, TrigCompositeUtils::DecisionIDContainer > m_expressChainMap
Stream name to chain objects map, including only express.
StatusCode fillHistogram(const TrigCompositeUtils::DecisionIDContainer &, int, LockedHandle< TH2 > &) const
std::map< std::string, TrigCompositeUtils::DecisionIDContainer > m_groupToChainMap
Group name to chain objects map.
SG::ReadHandleKey< TrigConf::L1Menu > m_L1MenuKey
StatusCode fillSequences(const std::set< std::string > &) const
ServiceHandle< IIncidentSvc > m_incidentSvc
RateHistogram m_rateHistogram
SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > m_finalDecisionKey
Gaudi::Property< bool > m_countLegFeatures
Gaudi::Property< std::string > m_bookingPath
std::unordered_map< std::string, int > m_nameToBinMap
Sequence/group/bunchgroup name to bin map.
SG::ReadHandleKey< TrigConf::HLTMenu > m_HLTMenuKey
StatusCode fillStreamsAndGroups(const std::map< std::string, TrigCompositeUtils::DecisionIDContainer > &, const TrigCompositeUtils::DecisionIDContainer &, int) const
virtual StatusCode stop() override
virtual void handle(const Incident &incident) override
ToolHandleArray< DecisionCollectorTool > m_decisionCollectorTools
ToolHandleArray< DecisionCollectorTool > m_featureCollectorTools
std::unordered_map< unsigned int, int > m_chainIDToBinMap
Chain id to histogram bin map.
bool contains(const std::string &s, const std::string ®x)
does a string contain the substring
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
HLT::Identifier createLegName(const HLT::Identifier &chainIdentifier, size_t counter)
Generate the HLT::Identifier which corresponds to a specific leg of a given chain.
xAOD::TrigComposite Decision
const Decision * getExpressTerminusNode(const DecisionContainer &container)
Returns the express-accept navigation node from a collection or nullptr if missing.
std::set< DecisionID > DecisionIDContainer
const Decision * getTerminusNode(SG::ReadHandle< DecisionContainer > &container)
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.