ATLAS Offline Software
Loading...
Searching...
No Matches
TimeBurner.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "TimeBurner.h"
6
9
10#include "CLHEP/Random/RandFlat.h"
11#include "CLHEP/Random/RandLandau.h"
12#include "CLHEP/Random/RandomEngine.h"
13
14#include <algorithm>
15#include <chrono>
16#include <thread>
17
18namespace {
19 // MPV of the standard Landau (peak of CLHEP::RandLandau::shoot()).
20 constexpr double s_standardLandauMPV = -0.22278298;
21}
22
23TimeBurner::TimeBurner(const std::string& name, ISvcLocator* pSvcLocator)
24: ::HypoBase(name, pSvcLocator) {}
25
28 ATH_MSG_ERROR("AcceptFraction must be in [0,1], got " << m_acceptFraction);
29 return StatusCode::FAILURE;
30 }
31
32 // Map the TimeDistribution string to the internal enum.
33 // This would make easy to add new distributions in the future.
34 if (m_timeDistribution == "fixed") {
36 } else if (m_timeDistribution == "landau") {
38 if (m_landauSigma <= 0.0) {
39 ATH_MSG_ERROR("LandauSigma must be > 0 for TimeDistribution=\"landau\", got "
40 << m_landauSigma);
41 return StatusCode::FAILURE;
42 }
43 } else {
44 ATH_MSG_ERROR("Unknown TimeDistribution \"" << m_timeDistribution
45 << "\". Allowed values: \"fixed\", \"landau\".");
46 return StatusCode::FAILURE;
47 }
48
49 // we don't actually need the HypoTool
50 for (auto& tool : m_hypoTools) tool.disable();
51
52 // Only retrieve the CPU cruncher if we actually use it.
53 if (m_burnCPU) {
54 ATH_CHECK(m_cpuCrunchSvc.retrieve());
55 }
56
57 ATH_CHECK(m_rngSvc.retrieve());
58
59 ATH_MSG_INFO("TimeDistribution = " << m_timeDistribution);
61 ATH_MSG_INFO("SleepTimeMillisec = " << m_sleepTimeMillisec << " ms");
62 } else {
63 ATH_MSG_INFO("LandauMPV = " << m_landauMPV << " ms");
64 ATH_MSG_INFO("LandauSigma = " << m_landauSigma << " ms");
65 }
66 ATH_MSG_INFO("AcceptFraction = " << m_acceptFraction);
67 ATH_MSG_INFO("BurnCPU = " << (m_burnCPU ? "true (busy-wait)" : "false (sleep)"));
68 ATH_MSG_INFO("MaxTimeMs = " << m_maxTimeMs << " ms"
69 << (m_maxTimeMs > 0.0 ? "" : " (cap disabled)"));
70
71 return StatusCode::SUCCESS;
72}
73
74StatusCode TimeBurner::execute(const EventContext& eventContext) const {
75 using namespace TrigCompositeUtils;
76
77 ++m_nSeen;
78
79 // Determine the per-event duration and accept/reject roll.
80 ATHRNG::RNGWrapper* rngWrapper = m_rngSvc->getEngine(this);
81 rngWrapper->setSeed(name(), eventContext);
82 CLHEP::HepRandomEngine* engine = rngWrapper->getEngine(eventContext);
83
84 double sleepMs = 0.0;
85 switch (m_timeDist) {
87 // CLHEP::RandLandau samples the standard Landau. Transforming it to MVP and sigma from properties.
88 sleepMs = m_landauMPV + m_landauSigma * (CLHEP::RandLandau::shoot(engine) - s_standardLandauMPV);
89 break;
90 case TimeDist::Fixed:
91 sleepMs = static_cast<double>(m_sleepTimeMillisec);
92 break;
93 }
94
95 bool accept = false;
96 if (m_acceptFraction > 0.0) {
97 accept = (CLHEP::RandFlat::shoot(engine) < m_acceptFraction);
98 }
99
100 // Landau is unbounded below; clip to non-negative.
101 sleepMs = std::max(0.0, sleepMs);
102 // Optionally cap from above to avoid HLT timeouts.
103 if (m_maxTimeMs > 0.0) {
104 sleepMs = std::min(sleepMs, m_maxTimeMs.value());
105 }
106 const auto duration = std::chrono::duration<double, std::milli>(sleepMs);
107 if (m_burnCPU) {
108 ATH_MSG_DEBUG("Burning CPU for " << sleepMs << " ms");
109 m_cpuCrunchSvc->crunch_for(
110 std::chrono::duration_cast<std::chrono::milliseconds>(duration));
111 } else {
112 ATH_MSG_DEBUG("Sleeping for " << sleepMs << " ms");
113 std::this_thread::sleep_for(duration);
114 }
115
116 // Read the previous-step decisions and create the output decision container.
117 // Since TimeBurner does not produce its own physics object, reproduced
118 // PEBInfoWriterAlg behaviour: attach a dummy self-link into the output
119 // DecisionContainer as the feature, and disable downstream ComboHypo
120 // multiplicity checks.
121 SG::ReadHandle<DecisionContainer> previousDecisionsHandle(decisionInput(),
122 eventContext);
123 ATH_CHECK(previousDecisionsHandle.isValid());
124
126 createAndStore(decisionOutput(), eventContext);
127 DecisionContainer* outputDecisions = outputHandle.ptr();
128 for (const Decision* previous : *previousDecisionsHandle) {
129 Decision* newD =
130 newDecisionIn(outputDecisions, previous, hypoAlgNodeName(), eventContext);
131
132 // Dummy self-link as feature, to satisfy navigation/runtimeValidation.
133 ElementLink<DecisionContainer> dummyLink(*outputDecisions,
134 outputDecisions->size() - 1,
135 eventContext);
136 newD->setObjectLink(featureString(), dummyLink);
137
138 // Disable ComboHypo checks on the output of this terminal step.
139 newD->setDetail<int32_t>("noCombo", 1);
140
141 if (accept) {
142 insertDecisionIDs(previous, newD);
143 }
144 }
145
146 if (accept) {
147 ++m_nAccepted;
148 ATH_MSG_DEBUG("Event accepted");
149 } else {
150 ++m_nRejected;
151 ATH_MSG_DEBUG("Event rejected");
152 }
153
154 ATH_CHECK(hypoBaseOutputProcessing(outputHandle));
155 return StatusCode::SUCCESS;
156}
157
159 ATH_MSG_INFO("Summary: seen=" << m_nSeen.load()
160 << " accepted=" << m_nAccepted.load()
161 << " rejected=" << m_nRejected.load());
162 return StatusCode::SUCCESS;
163}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
Decision * newDecisionIn(DecisionContainer *dc, const std::string &name="")
Helper method to create a Decision object, place it in the container and return a pointer to it.
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
const std::string & hypoAlgNodeName()
xAOD::TrigCompositeContainer DecisionContainer
const std::string & featureString()
void insertDecisionIDs(const Decision *src, Decision *dest)
Appends the decision IDs of src to the dest decision object.
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:169
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:134
size_type size() const noexcept
Returns the number of elements in the collection.
const SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > & decisionInput() const
methods for derived classes to access handles of the base class input other read/write handles may be...
Definition HypoBase.cxx:18
const SG::WriteHandleKey< TrigCompositeUtils::DecisionContainer > & decisionOutput() const
methods for derived classes to access handles of the base class output other read/write handles may b...
Definition HypoBase.cxx:22
StatusCode hypoBaseOutputProcessing(SG::WriteHandle< TrigCompositeUtils::DecisionContainer > &outputHandle, MSG::Level lvl=MSG::DEBUG) const
Base class function to be called once slice specific code has finished. Handles debug printing and va...
Definition HypoBase.cxx:35
HypoBase(const std::string &name, ISvcLocator *pSvcLocator)
constructor, to be called by sub-class constructors
Definition HypoBase.cxx:12
virtual bool isValid() override final
Can the handle be successfully dereferenced?
pointer_type ptr()
Dereference the pointer.
TimeBurner(const std::string &name, ISvcLocator *svcLoc)
Standard constructor.
Gaudi::Property< double > m_landauMPV
Definition TimeBurner.h:63
virtual StatusCode execute(const EventContext &eventContext) const override
Gaudi::Property< unsigned int > m_sleepTimeMillisec
Definition TimeBurner.h:58
TimeDist m_timeDist
Definition TimeBurner.h:50
Gaudi::Property< double > m_maxTimeMs
Definition TimeBurner.h:85
Gaudi::Property< double > m_acceptFraction
Definition TimeBurner.h:75
ServiceHandle< IAthRNGSvc > m_rngSvc
Definition TimeBurner.h:97
Gaudi::Property< bool > m_burnCPU
Definition TimeBurner.h:80
ToolHandleArray< IAlgTool > m_hypoTools
Definition TimeBurner.h:103
std::atomic< unsigned long > m_nSeen
Definition TimeBurner.h:105
virtual StatusCode finalize() override
ServiceHandle< ICPUCrunchSvc > m_cpuCrunchSvc
Definition TimeBurner.h:91
Gaudi::Property< std::string > m_timeDistribution
Definition TimeBurner.h:52
std::atomic< unsigned long > m_nAccepted
Definition TimeBurner.h:106
virtual StatusCode initialize() override
Gaudi::Property< double > m_landauSigma
Definition TimeBurner.h:69
std::atomic< unsigned long > m_nRejected
Definition TimeBurner.h:107
bool setObjectLink(const std::string &name, const ElementLink< CONTAINER > &link)
Set the link to an object.
bool setDetail(const std::string &name, const TYPE &value)
Set an TYPE detail on the object.