ATLAS Offline Software
HLTResultMTMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
8 #include "eformat/DetectorMask.h"
9 #include "eformat/SourceIdentifier.h"
10 #include <unistd.h> // gethostname
11 #include <limits.h> // HOST_NAME_MAX
12 #include <sstream>
13 #include <algorithm>
14 
15 // Local helpers
16 namespace {
18  template<typename T> bool contains(const std::set<T>& set, const T& value) {
19  return set.find(value) != set.cend();
20  }
21  bool isHLT(const uint32_t robid) {
22  return eformat::helper::SourceIdentifier(robid).subdetector_id() == eformat::TDAQ_HLT;
23  }
24  bool isHLT(const eformat::SubDetector subdet) {
25  return subdet == eformat::TDAQ_HLT;
26  }
28  template<typename T> std::set<T> removeDisabled(std::set<T>& requestedIds, const std::set<T>& enabledIds) {
29  std::set<T> removedIds;
30  for (auto it=requestedIds.begin(); it!=requestedIds.end(); ) {
31  // Check if ROB/SubDet is disabled (skip HLT result ID)
32  if (!isHLT(*it) && !contains(enabledIds, *it)) {
33  removedIds.insert(*it);
34  it = requestedIds.erase(it);
35  }
36  else ++it;
37  }
38  return removedIds;
39  }
41  std::string format(const std::set<uint32_t>& set) {
42  std::ostringstream ss;
43  for (const uint32_t id : set)
44  ss << "0x" << std::hex << std::setfill('0') << std::setw(8) << id << std::dec << " ";
45  return ss.str();
46  }
48  std::string format(const std::set<eformat::SubDetector>& set) {
49  std::ostringstream ss;
50  for (const eformat::SubDetector id : set) ss << eformat::helper::SubDetectorDictionary.string(id) << " ";
51  return ss.str();
52  }
53 }
54 
55 // =============================================================================
56 // Standard constructor
57 // =============================================================================
58 HLTResultMTMaker::HLTResultMTMaker(const std::string& type, const std::string& name, const IInterface* parent)
59  : AthAlgTool(type, name, parent) {}
60 
61 // =============================================================================
62 // Implementation of IStateful::initialize
63 // =============================================================================
66  ATH_CHECK(m_runtimeMetadataWHKey.initialize());
67  ATH_CHECK(m_streamTagMaker.retrieve(DisableTool{m_streamTagMaker.name().empty()}));
68  ATH_CHECK(m_makerTools.retrieve());
69  ATH_CHECK(m_monTool.retrieve(DisableTool{m_monTool.empty()}));
70  ATH_CHECK(m_jobOptionsSvc.retrieve());
72 
73  return StatusCode::SUCCESS;
74 }
75 
76 // =============================================================================
77 // Implementation of IStateful::start
78 // Initialise the enabled ROBs/SubDets list from DataFlowConfig and extra properties.
79 // =============================================================================
81  // DataFlowConfig is a special object used online to hold DF properties passed from TDAQ to HLT as run parameters.
82  Gaudi::Property<std::vector<uint32_t>> enabledROBsProp("EnabledROBs",{});
83  if (enabledROBsProp.fromString(m_jobOptionsSvc->get("DataFlowConfig.DF_Enabled_ROB_IDs","[]")).isSuccess()) {
84  m_enabledROBs.insert(enabledROBsProp.value().begin(), enabledROBsProp.value().end());
85  ATH_MSG_DEBUG("Retrieved a list of " << m_enabledROBs.size()
86  << " ROBs from DataFlowConfig.DF_Enabled_ROB_IDs");
87  }
88  else {
89  ATH_MSG_ERROR("Could not parse DataFlowConfig.DF_Enabled_ROB_IDs from JobOptionsSvc");
90  }
91 
92  m_enabledSubDets.clear();
93  Gaudi::Property<std::vector<uint32_t>> enabledSubDetsProp("EnabledSubDets",{});
94  if (enabledSubDetsProp.fromString(m_jobOptionsSvc->get("DataFlowConfig.DF_Enabled_SubDet_IDs","[]")).isSuccess()) {
95  // Need to convert from uint32_t to eformat::SubDetector representable by uint8_t
96  for (const uint32_t id : enabledSubDetsProp.value()) {
97  m_enabledSubDets.insert( static_cast<eformat::SubDetector>(id & 0xFF) );
98  }
99  ATH_MSG_DEBUG("Retrieved a list of " << m_enabledSubDets.size()
100  << " SubDets from DataFlowConfig.DF_Enabled_SubDet_IDs");
101  }
102  else {
103  ATH_MSG_ERROR("Could not parse DataFlowConfig.DF_Enabled_SubDet_IDs from JobOptionsSvc");
104  }
105 
106  if (m_enabledROBs.empty() && m_enabledSubDets.empty()) {
107  m_skipValidatePEBInfo = true;
108  ATH_MSG_INFO("The list of enabled ROBs and SubDets was not provided by DataFlowConfig or is empty. "
109  << "StreamTag PEBInfo validation will be skipped.");
110  }
111  else {
113  m_enabledROBs.insert(m_extraEnabledROBs.value().begin(), m_extraEnabledROBs.value().end());
114  m_enabledROBs.insert(m_extraROBs.value().begin(), m_extraROBs.value().end());
115  // Need to convert from uint32_t to eformat::SubDetector representable by uint8_t
116  for (const uint32_t id : m_extraEnabledSubDets.value()) {
117  m_enabledSubDets.insert( static_cast<eformat::SubDetector>(id & 0xFF) );
118  }
119  for (const uint32_t id : m_extraSubDets.value()) {
120  m_enabledSubDets.insert( static_cast<eformat::SubDetector>(id & 0xFF) );
121  }
122  ATH_MSG_INFO("StreamTag PEBInfo will be validated against " << m_enabledROBs.size() << " enabled ROBs and "
123  << m_enabledSubDets.size() << " enabled SubDets");
124  }
125  return StatusCode::SUCCESS;
126 }
127 
128 // =============================================================================
129 // Implementation of IStateful::finalize
130 // =============================================================================
132  ATH_CHECK(m_monTool.release());
133  return StatusCode::SUCCESS;
134 }
135 
136 // =============================================================================
137 // Create, record and fill a new result
138 // =============================================================================
139 StatusCode HLTResultMTMaker::makeResult(const EventContext& eventContext) const {
140  auto hltResult = SG::makeHandle(m_hltResultWHKey,eventContext);
141  ATH_CHECK( hltResult.record(std::make_unique<HLT::HLTResultMT>()) );
142  ATH_MSG_DEBUG("Recorded HLTResultMT with key " << m_hltResultWHKey.key());
143  ATH_CHECK(fillResult(*hltResult, eventContext));
144  return StatusCode::SUCCESS;
145 }
146 
147 // =============================================================================
148 // The main method of the tool
149 // =============================================================================
150 StatusCode HLTResultMTMaker::fillResult(HLT::HLTResultMT& hltResult, const EventContext& eventContext) const {
151  auto monTime = Monitored::Timer<std::chrono::duration<float, std::milli>>("TIME_fillResult");
152 
153  // Save HLT runtime metadata
155  runtimeMetadataOutput->push_back(std::make_unique<xAOD::TrigComposite>());
156  char hostname [HOST_NAME_MAX];
157  bool errcode = !gethostname(hostname, HOST_NAME_MAX); // returns 0 on success and -1 on failure, casted to false on success, true on failure
158  std::string hostnameString = std::string(hostname); // setDetail needs a reference
159  errcode &= runtimeMetadataOutput->back()->setDetail("hostname", hostnameString);
160  if (!errcode) ATH_MSG_WARNING("Failed to append hostname to HLT Runtime Metadata TC");
161 
162  // Fill the stream tags
163  StatusCode finalStatus = StatusCode::SUCCESS;
164  if (m_streamTagMaker.isEnabled() && m_streamTagMaker->fill(hltResult, eventContext).isFailure()) {
165  ATH_MSG_ERROR(m_streamTagMaker->name() << " failed");
166  finalStatus = StatusCode::FAILURE;
167  }
168 
169  // Fill the result using all other tools if the event was accepted
170  if (hltResult.isAccepted()) {
171  for (auto& maker: m_makerTools) {
172  ATH_MSG_DEBUG("Calling " << maker->name() << " for accepted event");
173  if (StatusCode sc = maker->fill(hltResult, eventContext); sc.isFailure()) {
174  ATH_MSG_ERROR(maker->name() << " failed");
175  finalStatus = sc;
176  }
177  }
178 
179  if (!m_skipValidatePEBInfo) validatePEBInfo(hltResult);
180  }
181  else {
182  ATH_MSG_DEBUG("Rejected event, further result filling skipped after stream tag maker");
183  }
184 
185  ATH_MSG_DEBUG(hltResult);
186 
187  Monitored::Group(m_monTool, monTime);
188  return finalStatus;
189 }
190 
191 // =============================================================================
192 // Private method removing disabled ROBs/SubDets from StreamTags
193 // =============================================================================
195  std::vector<eformat::helper::StreamTag> streamTagsToRemove;
196  for (eformat::helper::StreamTag& st : hltResult.getStreamTagsNonConst()) {
197  // Skip full event building stream tags immediately
198  if (st.robs.empty() && st.dets.empty()) {continue;}
199 
200  std::set<uint32_t> removedROBs = removeDisabled(st.robs,m_enabledROBs);
201  if (!removedROBs.empty()) {
202  ATH_MSG_DEBUG("StreamTag " << st.type << "_" << st.name << " requested disabled ROBs: " << format(removedROBs)
203  << " - these ROBs were removed from the StreamTag by " << name());
204  std::vector<eformat::SubDetector> removedSubDets;
205  for (const uint32_t rob : removedROBs) {
206  eformat::SubDetector sd{eformat::helper::SourceIdentifier(rob).subdetector_id()};
207  if (std::find(removedSubDets.begin(),removedSubDets.end(),sd)==removedSubDets.end()) {
208  removedSubDets.push_back(sd);
209  }
210  }
211  auto monRemovedROBsSubDet = Monitored::Collection(
212  "PEB_RemovedROBs_SubDet", removedSubDets,
213  [](const eformat::SubDetector sd){return eformat::helper::SubDetectorDictionary.string(sd);});
214  Monitored::Group(m_monTool, monRemovedROBsSubDet);
215  } else {
216  ATH_MSG_VERBOSE("No disabled ROBs were requested by StreamTag " << st.type << "_" << st.name);
217  }
218 
219  std::set<eformat::SubDetector> removedSubDets = removeDisabled(st.dets,m_enabledSubDets);
220  if (!removedSubDets.empty()) {
221  ATH_MSG_DEBUG("StreamTag " << st.type << "_" << st.name << " requested disabled SubDets: " << format(removedSubDets)
222  << " - these SubDets were removed from the StreamTag by " << name());
223  std::vector<eformat::SubDetector> removedSubDetsVec(removedSubDets.begin(),removedSubDets.end());
224  auto monRemovedSubDets = Monitored::Collection(
225  "PEB_RemovedSubDets", removedSubDetsVec,
226  [](const eformat::SubDetector sd){return eformat::helper::SubDetectorDictionary.string(sd);});
227  Monitored::Group(m_monTool, monRemovedSubDets);
228  } else {
229  ATH_MSG_VERBOSE("No disabled SubDets were requested by StreamTag " << st.type << "_" << st.name);
230  }
231 
232  // If the PEB list now became empty, it would turn PEB into FEB - prevent this and drop the stream tag (ATR-24378)
233  if (st.robs.empty() && st.dets.empty()) {
234  bool printed{false};
235  if (m_emptyPEBInfoErrorPrinted.compare_exchange_strong(printed, true, std::memory_order_relaxed)) {
236  ATH_MSG_ERROR("Event accepted to stream " << st.type << "_" << st.name << " but the streaming to this stream "
237  << "is forcibly prevented, because all requested ROBs/SubDets in the PEB list are disabled. "
238  << "ROBs: " << format(removedROBs) << ", SubDets: " << format(removedSubDets));
239  }
240  streamTagsToRemove.push_back(st);
241  }
242  }
243  for (const eformat::helper::StreamTag& st : streamTagsToRemove) {
244  auto it =
245  std::remove(hltResult.getStreamTagsNonConst().begin(),
246  hltResult.getStreamTagsNonConst().end(),
247  st);
248  hltResult.getStreamTagsNonConst().resize (it - hltResult.getStreamTagsNonConst().begin());
249  }
250 }
251 
252 // =============================================================================
253 // Private method removing ExtraROBs/ExtraSubDets disabled by the detector mask
254 // =============================================================================
256  if (m_extraROBs.empty() && m_extraSubDets.empty()) {
257  // Nothing to check
258  return StatusCode::SUCCESS;
259  }
260 
261  // Get the detector mask
263  ATH_CHECK(bsmdc.isValid());
264  ATH_CHECK(!bsmdc->empty());
265  const ByteStreamMetadata* metadata = bsmdc->front();
266  const eformat::helper::DetectorMask detectorMask{metadata->getDetectorMask(), metadata->getDetectorMask2()};
267 
268  // Check ROBs
269  std::vector<uint32_t> validatedExtraROBs;
270  for (const uint32_t rob_id : m_extraROBs.value()) {
271  const eformat::helper::SourceIdentifier sid{rob_id};
272  const eformat::SubDetector subdet_id = sid.subdetector_id();
273  if (detectorMask.is_set(subdet_id)) {
274  validatedExtraROBs.push_back(rob_id);
275  }
276  else {
277  ATH_MSG_WARNING("Removing 0x" << MSG::hex << rob_id << MSG::dec << " from " << m_extraROBs.name()
278  << " because SubDetector " << sid.human_detector() << " is disabled in the detector mask");
279  }
280  }
281  m_extraROBs = validatedExtraROBs;
282 
283  // Check SubDets
284  std::vector<uint32_t> validatedExtraSubDets;
285  for (const uint32_t subdet_id32 : m_extraSubDets.value()) {
286  const eformat::SubDetector subdet_id = static_cast<eformat::SubDetector>(subdet_id32 & 0xFF);
287  if (detectorMask.is_set(subdet_id)) {
288  validatedExtraSubDets.push_back(subdet_id32);
289  }
290  else {
291  ATH_MSG_WARNING("Removing 0x" << MSG::hex << subdet_id << MSG::dec << " from " << m_extraSubDets.name()
292  << " because SubDetector " << eformat::helper::SourceIdentifier(subdet_id,0,0).human_detector()
293  << " is disabled in the detector mask");
294  }
295  }
296  m_extraSubDets = validatedExtraSubDets;
297 
298  return StatusCode::SUCCESS;
299 }
HLT::HLTResultMT::isAccepted
bool isAccepted() const
If there is at least one stream tag set, it means the event is accepted.
Definition: HLTResultMT.h:178
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
HLTResultMTMaker::m_enabledSubDets
std::set< eformat::SubDetector > m_enabledSubDets
List of enabled SubDets retrieved during initialisation.
Definition: HLTResultMTMaker.h:116
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
vtune_athena.format
format
Definition: vtune_athena.py:14
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
HLTResultMTMaker::m_skipValidatePEBInfo
bool m_skipValidatePEBInfo
If true, don't call validatePEBInfo.
Definition: HLTResultMTMaker.h:118
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
HLTResultMTMaker::m_monTool
ToolHandle< GenericMonitoringTool > m_monTool
Monitoring tool.
Definition: HLTResultMTMaker.h:82
HLTResultMTMaker.h
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
HLTResultMTMaker::m_extraEnabledROBs
Gaudi::Property< std::vector< uint32_t > > m_extraEnabledROBs
Extra enabled ROBs.
Definition: HLTResultMTMaker.h:92
HLTResultMTMaker::m_enabledROBs
std::set< uint32_t > m_enabledROBs
List of enabled ROBs retrieved during initialisation.
Definition: HLTResultMTMaker.h:114
HLTResultMTMaker::finalize
virtual StatusCode finalize() override
Definition: HLTResultMTMaker.cxx:131
skel.it
it
Definition: skel.GENtoEVGEN.py:396
athena.value
value
Definition: athena.py:124
HLTResultMTMaker::m_extraROBs
Gaudi::Property< std::vector< uint32_t > > m_extraROBs
Extra enabled ROBs checked against detector mask.
Definition: HLTResultMTMaker.h:97
TrigCompositeUtils::createAndStore
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
Definition: TrigCompositeUtilsRoot.cxx:30
ByteStreamMetadata
This class is the StoreGate data object for bytestream metadata.
Definition: ByteStreamMetadata.h:25
HLT::HLTResultMT
A container class for data required to build online output from HLT.
Definition: HLTResultMT.h:38
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
HLTResultMTMaker::m_jobOptionsSvc
ServiceHandle< Gaudi::Interfaces::IOptionsSvc > m_jobOptionsSvc
Handle to JobOptionsSvc used to retrieve the DataFlowConfig property.
Definition: HLTResultMTMaker.h:87
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
Monitored::Collection
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
Definition: MonitoredCollection.h:38
HLTResultMTMaker::m_streamTagMaker
ToolHandle< HLTResultMTMakerTool > m_streamTagMaker
Tool creating stream tags (defines if event is accepted)
Definition: HLTResultMTMaker.h:72
python.selector.AtlRunQuerySelectorLhcOlc.sd
sd
Definition: AtlRunQuerySelectorLhcOlc.py:612
python.checkMetadata.metadata
metadata
Definition: checkMetadata.py:175
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:270
PixelModuleFeMask_create_db.remove
string remove
Definition: PixelModuleFeMask_create_db.py:83
TrigCompositeUtils.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
HLTResultMTMaker::m_hltResultWHKey
SG::WriteHandleKey< HLT::HLTResultMT > m_hltResultWHKey
StoreGate key for the HLTResultMT.
Definition: HLTResultMTMaker.h:58
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
HLTResultMTMaker::m_bsMetaDataContRHKey
SG::ReadHandleKey< ByteStreamMetadataContainer > m_bsMetaDataContRHKey
StoreGate key for the ByteStreamMetadata container to retrieve detector mask.
Definition: HLTResultMTMaker.h:67
HLTResultMTMaker::m_extraSubDets
Gaudi::Property< std::vector< uint32_t > > m_extraSubDets
Extra enabled SubDets checked against detector mask.
Definition: HLTResultMTMaker.h:107
contains
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition: hcg.cxx:111
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
HLTResultMTMaker::makeResult
StatusCode makeResult(const EventContext &eventContext) const
Create and fill a new HLTResultMT, and record it in the event store.
Definition: HLTResultMTMaker.cxx:139
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
HLTResultMTMaker::initialize
virtual StatusCode initialize() override
Definition: HLTResultMTMaker.cxx:64
HLTResultMTMaker::validatePEBInfo
void validatePEBInfo(HLT::HLTResultMT &hltResult) const
Check ROB and SubDet lists in StreamTags and remove those which are disabled.
Definition: HLTResultMTMaker.cxx:194
Monitored.h
Header file to be included by clients of the Monitored infrastructure.
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
HLTResultMTMaker::m_runtimeMetadataWHKey
SG::WriteHandleKey< xAOD::TrigCompositeContainer > m_runtimeMetadataWHKey
StoreGate key for HLT Runtime Metadata container.
Definition: HLTResultMTMaker.h:63
HLTResultMTMaker::m_extraEnabledSubDets
Gaudi::Property< std::vector< uint32_t > > m_extraEnabledSubDets
Extra enabled SubDets.
Definition: HLTResultMTMaker.h:102
HLTResultMTMaker::m_makerTools
ToolHandleArray< HLTResultMTMakerTool > m_makerTools
Tools filling the HLTResultMT object.
Definition: HLTResultMTMaker.h:77
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
HLT::HLTResultMT::getStreamTagsNonConst
std::vector< eformat::helper::StreamTag > & getStreamTagsNonConst()
Non-const-getter for stream tags needed by the result maker to remove disabled ROBs/SubDets.
Definition: HLTResultMT.cxx:48
HLTResultMTMaker::HLTResultMTMaker
HLTResultMTMaker(const std::string &type, const std::string &name, const IInterface *parent)
Standard constructor.
Definition: HLTResultMTMaker.cxx:58
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
HLTResultMTMaker::start
virtual StatusCode start() override
Definition: HLTResultMTMaker.cxx:80
AthAlgTool
Definition: AthAlgTool.h:26
HLTResultMTMaker::m_emptyPEBInfoErrorPrinted
std::atomic_bool m_emptyPEBInfoErrorPrinted
Flag if empty PEB list error was already printed.
Definition: HLTResultMTMaker.h:120
Monitored::Timer
A monitored timer.
Definition: MonitoredTimer.h:32
HLTResultMTMaker::fillResult
StatusCode fillResult(HLT::HLTResultMT &hltResult, const EventContext &eventContext) const
Fill an existing HLTResultMT with event information.
Definition: HLTResultMTMaker.cxx:150
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35
HLTResultMTMaker::validateExtraROBsAndSubDets
StatusCode validateExtraROBsAndSubDets()
Check ExtraROBs and ExtraSubDets against the detector mask and drop the masked out IDs.
Definition: HLTResultMTMaker.cxx:255