37 return StatusCode::SUCCESS;
50 std::unordered_map<std::string,std::string> mapStrNameToTypeName;
53 mapStrNameToTypeName.insert({stream.getAttribute(
"name"), stream.getAttribute(
"type")+
"_"+stream.getAttribute(
"name")});
55 }
catch (
const std::exception& ex) {
56 ATH_MSG_ERROR(
"Exception reading stream tag configuration from the HLT menu: " << ex.what());
57 return StatusCode::FAILURE;
61 for (
const std::string& group : chain.groups()) {
63 if (group.starts_with(
"RATE")){
69 for (
const std::string& streamName : chain.streams()){
70 const auto it = mapStrNameToTypeName.find(streamName);
71 if (it==mapStrNameToTypeName.cend()) {
72 ATH_MSG_ERROR(
"Stream name " << streamName <<
" assigned to chain " << chain.name()
73 <<
" is missing from menu streams definition");
74 return StatusCode::FAILURE;
76 if (it->second ==
"express_express") {
88 const int x {
nBinsX(hltMenuHandle)};
91 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);
92 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);
103 const std::string outputRateName = std::format(
"Rate{:d}s",
m_duration.value());
112 std::set<std::string> sequencesSet;
114 ctool->getSequencesNames(sequencesSet);
116 const int xc = sequencesSet.size();
119 const std::string outputSequenceName = std::format(
"SequencesExecutionRate{:d}s",
m_duration.value());
120 m_sequenceHistogram.init(outputSequenceName,
"Rate of sequences execution;sequence;rate", xc, yc,
127 return StatusCode::SUCCESS;
135 ATH_MSG_INFO(
"No chains configured, no counts to print" );
136 return StatusCode::SUCCESS;
143 std::unordered_map<std::string, std::set<int>> chainToStepsId;
146 for (
const std::string& seqName : chain.sequencers()){
148 std::smatch stepNameMatch;
149 std::regex_search(seqName.begin(), seqName.end(), stepNameMatch, std::regex(
"[Ss]tep[0-9]+"));
151 std::string stepName = stepNameMatch[0];
152 stepName[0] = std::toupper(stepName[0]);
154 if (std::format(
"Step{:d}", nstep) == stepName) {
155 chainToStepsId[chain.name()].insert(nstep);
157 ATH_MSG_DEBUG(
"Missing counts for step" << nstep <<
" in chain " << chain.name());
163 auto collToString = [&](
int xbin,
const LockedHandle<TH2>& hist,
int startOfset=0,
int endOffset=0){
165 const int stepsSize = hist->GetYaxis()->GetNbins() -
N_BINS;
166 for (
int ybin = 1; ybin <= hist->GetYaxis()->GetNbins()-endOffset; ++ybin) {
167 if (ybin > startOfset) {
170 const std::string chainName = m_passHistogram->GetXaxis()->GetBinLabel(xbin);
172 if (ybin < 3 || ybin > stepsSize + 2 || chainToStepsId[chainName].
contains(ybin - 2)) {
173 v += std::format(
"{:<11d}",
static_cast<int>(hist->GetBinContent(xbin, ybin)));
175 v += std::format(
"{:<11s}",
"-");
178 v += std::format(
"{:<11s}",
" ");
185 v += std::format(
"{:<11s}",
"L1");
186 v += std::format(
"{:<11s}",
"AfterPS");
187 for (
int bin = 1;
bin <= m_passHistogram->GetYaxis()->GetNbins()-
N_BINS; ++
bin) {
188 v += std::format(
"Step{:<7d}",
bin);
190 v += std::format(
"{:<11s}",
"Output");
191 v += std::format(
"{:<11s}",
"Express");
193 ATH_MSG_INFO(
"Chains passing step (1st row events & 2nd row decision counts):");
201 for (
int bin = 1;
bin <= (*m_passHistogram)->GetXaxis()->GetNbins(); ++
bin) {
202 const std::string chainName = m_passHistogram->GetXaxis()->GetBinLabel(
bin);
203 const std::string chainID = std::to_string(
HLT::Identifier(chainName));
204 if (chainName.starts_with(
"HLT")) {
205 ATH_MSG_INFO( std::format(
"{:s} #{:s}", chainName, chainID) );
206 ATH_MSG_INFO( std::format(
"{:<30s}", std::format(
"-- #{} Events", chainID)) << collToString(
bin, m_passHistogram) );
207 ATH_MSG_INFO( std::format(
"{:<30s}", std::format(
"-- #{} Features", chainID)) << collToString(
bin, m_countHistogram , 2, 1 ) );
209 if (chainName.starts_with(
"All")){
210 ATH_MSG_INFO( std::format(
"{:<30s}", chainName) << collToString(
bin, m_passHistogram) );
214 return StatusCode::SUCCESS;
226 lockedHist->Fill( id2bin->second,
static_cast<double>(row) );
233 return StatusCode::SUCCESS;
252 m_countHistogram->Fill(id2bin->second,
static_cast<double>(row));
256 return StatusCode::SUCCESS;
260 for (
const std::string& seq : sequences) {
264 return StatusCode::SUCCESS;
270 int rowWithSteps = row;
273 for (
const auto& [name, decisions] : nameToChainsMap) {
275 if (decisions.contains(
id)) {
278 m_countHistogram->Fill(
bin, rowWithSteps);
279 m_passHistogram->Fill(
bin, rowWithSteps);
284 return StatusCode::SUCCESS;
291 ATH_MSG_WARNING(
"Timer is already running. UpdateAfterFork incident called more than once?");
312 [[maybe_unused]]
static const bool sanityCheckDone = [&] {
313 if (l1Decisions->at(
INPUT-1)->name() ==
"l1seeded" &&
314 l1Decisions->at(
AFTER_PS-1)->name() ==
"unprescaled") {
317 throw GaudiException(
m_l1DecisionsKey.key() +
" does not contain the expected entries",
318 name(), StatusCode::FAILURE);
321 auto fillL1 = [&](
int index) -> StatusCode {
329 m_passHistogram->Fill(1,
static_cast<double>(
index));
332 return StatusCode::SUCCESS;
341 std::vector<TrigCompositeUtils::DecisionID> stepSum;
342 std::set<std::string> stepSequences;
344 ctool->getDecisions( stepSum, stepSequences, context );
345 ATH_MSG_DEBUG(
" Step " << step <<
" decisions (for decisions): " << stepSum.size() );
351 stepSequences.clear();
357 ctool->getDecisions( stepSum, context );
358 ATH_MSG_DEBUG(
" Step " << step <<
" decisions (for features): " << stepSum.size() );
368 if (!decisionObject) {
369 ATH_MSG_WARNING(
"Unable to locate trigger navigation terminus node. Cannot tell which chains passed the event.");
377 if (!expressDecisionObject) {
378 ATH_MSG_WARNING(
"Unable to locate trigger navigation express terminus node. Cannot tell which chains passed the express stream in this event.");
399 if (!finalIDs.empty()) {
400 m_passHistogram->Fill(1,
static_cast<double>(countOutputRow));
403 if (!expressFinalIDs.empty()) {
404 m_passHistogram->Fill(1,
static_cast<double>(countExpressRow));
408 return StatusCode::SUCCESS;
420 return hltMenuHandle->size() + 1;
428 TAxis*
x = hist->GetXaxis();
429 x->SetBinLabel(1,
"All");
432 std::set<std::string> sortedChainsList;
434 sortedChainsList.insert( chain.name() );
437 for (
const std::string& chainName: sortedChainsList ) {
438 x->SetBinLabel(
bin, chainName.c_str() );
445 x->SetBinLabel(
bin, (
"str_"+stream.first).c_str());
451 x->SetBinLabel(
bin, (
"str_"+stream.first).c_str());
457 x->SetBinLabel(
bin, (
"grp_"+group.first.substr(group.first.find(
':')+1)).c_str() );
463 TAxis*
y = hist->GetYaxis();
464 y->SetBinLabel(
INPUT, steps ?
"L1" :
"Input");
467 y->SetBinLabel(3 + i, std::format(
"Step {:d}", i).c_str());
469 y->SetBinLabel(
y->GetNbins()-1,
"Output");
470 y->SetBinLabel(
y->GetNbins(),
"Express");
472 return StatusCode::SUCCESS;
476 TAxis*
x = hist->GetXaxis();
480 for (
const std::string& seqName : sequenceSet) {
481 x->SetBinLabel(
bin, seqName.c_str());
486 TAxis*
y = hist->GetYaxis();
487 y->SetBinLabel(1,
"Rate");
489 return StatusCode::SUCCESS;
494 delete m_bufferHistogram.get();
499 std::unique_ptr<TH2>
h = std::make_unique<TH2F>(histoName.c_str(), histoTitle.c_str(),
x, 1,
x + 1,
y, 1,
y + 1);
500 ATH_CHECK( histSvc->regShared( registerPath.c_str(), std::move(
h), m_histogram));
502 TH2I * hB =
new TH2I( (histoName +
"Buffer").c_str(), histoTitle.c_str(),
x, 1,
x + 1,
y, 1,
y + 1);
503 m_bufferHistogram.set(hB, &
m_mutex);
504 m_bufferHistogram->SetDirectory(0);
506 return StatusCode::SUCCESS;
514 return m_bufferHistogram;
522 m_bufferHistogram->Fill(
x,
y);
530 std::chrono::milliseconds(duration*1000/20));
537 unsigned int interval;
538 unsigned int duration =
m_timeDivider->forcePassed(t, interval);
545 m_histogram->Reset(
"ICES");
546 m_histogram->Add(m_bufferHistogram.get(), 1./duration);
547 m_bufferHistogram->Reset(
"ICES");
554 unsigned int newinterval;
555 unsigned int oldinterval;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATLAS_NOT_CONST_THREAD_SAFE
Header file for AthHistogramAlgorithm.
static const std::string & type()
Incident type.
TrigCompositeUtils::DecisionID numeric() const
numeric ID
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< 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())
xAOD::TrigComposite Decision
const Decision * getExpressTerminusNode(const DecisionContainer &container)
Returns the express-accept navigation node from a collection or nullptr if missing.
HLT::Identifier getIDFromLeg(const HLT::Identifier &legIdentifier)
Generate the HLT::Identifier which corresponds to the chain name from the leg name.
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.