ATLAS Offline Software
Loading...
Searching...
No Matches
PrescalingTool Class Reference

#include <PrescalingTool.h>

Inheritance diagram for PrescalingTool:
Collaboration diagram for PrescalingTool:

Public Member Functions

 PrescalingTool ()=delete
 PrescalingTool (const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode initialize () override
virtual StatusCode start () override
virtual StatusCode prescaleChains (const EventContext &ctx, const HLT::IDVec &initiallyActive, HLT::IDVec &remainActive, bool forExpressStream=false) const override
 The method to prescale chains.

Private Types

using ChainSet = std::set<HLT::Identifier>

Private Attributes

SG::ReadCondHandleKey< TrigConf::HLTPrescalesSetm_hltPrescaleSetInputKey
SG::ReadHandleKey< TrigConf::HLTMenum_HLTMenuKey
SG::ReadHandleKey< xAOD::EventInfom_eventInfoKey
Gaudi::Property< bool > m_keepUnknownChains
ToolHandle< GenericMonitoringToolm_monTool
ATHRNG::RNGWrapper m_RNGEngines
 Random engine for calculating prescales.
ChainSet m_nonCPSChains
std::map< std::string, HLT::IDVecm_CPSGroups
TrigConf::HLTPrescalesSet::HLTPrescale m_prescaleForUnknownChain
HLT::Identifier m_costChainID {""}

Detailed Description

Definition at line 33 of file PrescalingTool.h.

Member Typedef Documentation

◆ ChainSet

using PrescalingTool::ChainSet = std::set<HLT::Identifier>
private

Definition at line 79 of file PrescalingTool.h.

Constructor & Destructor Documentation

◆ PrescalingTool() [1/2]

PrescalingTool::PrescalingTool ( )
delete

◆ PrescalingTool() [2/2]

PrescalingTool::PrescalingTool ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 19 of file PrescalingTool.cxx.

21 :
22 base_class(type, name, parent),
const std::function< CLHEP::HepRandomEngine *(void) > PSTRanluxFactory
ATHRNG::RNGWrapper m_RNGEngines
Random engine for calculating prescales.
size_t getNSlots()
Return the number of event slots.

Member Function Documentation

◆ initialize()

StatusCode PrescalingTool::initialize ( )
overridevirtual

Definition at line 26 of file PrescalingTool.cxx.

26 {
27 ATH_CHECK(m_hltPrescaleSetInputKey.initialize( ! m_hltPrescaleSetInputKey.key().empty() ));
28 ATH_CHECK( m_HLTMenuKey.initialize() );
29 ATH_CHECK( m_eventInfoKey.initialize() );
30
31 if ( !m_monTool.empty() ) {
32 ATH_CHECK(m_monTool.retrieve());
33 }
34
35 if (m_keepUnknownChains.value()) {
36 ATH_MSG_WARNING(m_keepUnknownChains.name() << " is set to True. "
37 << "This is OK for testing but do not use this in production");
38 }
39 m_prescaleForUnknownChain = { m_keepUnknownChains.value(), (m_keepUnknownChains.value() ? 1.0 : -1.0) };
40 m_costChainID = HLT::Identifier("HLT_noalg_CostMonDS_L1All");
41 return StatusCode::SUCCESS;
42}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
HLT::Identifier m_costChainID
SG::ReadCondHandleKey< TrigConf::HLTPrescalesSet > m_hltPrescaleSetInputKey
ToolHandle< GenericMonitoringTool > m_monTool
TrigConf::HLTPrescalesSet::HLTPrescale m_prescaleForUnknownChain
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Gaudi::Property< bool > m_keepUnknownChains
SG::ReadHandleKey< TrigConf::HLTMenu > m_HLTMenuKey

◆ prescaleChains()

StatusCode PrescalingTool::prescaleChains ( const EventContext & ctx,
const HLT::IDVec & initiallyActive,
HLT::IDVec & remainActive,
bool forExpressStream = false ) const
overridevirtual

The method to prescale chains.

If the prescale set input key is not defined or the chain does not exist in the prescale set, then the chains (or all chains) are kept according to the property KeepUnknownChains

Parameters
[in]ctxevent context is needed for accessing the random engine
[in]initiallyActivevector of HLTIdentifiers of initially active chains (because they were seeded by L1)
[out]remainActivevector that is being filled with HLTIdentifiers of chains surviving the prescaling

Note: the event time needs to be taken from the EventInfo instead EventContext.eventID, which is commonly done! This is due to the special case when the trigger is run in a partition with preloaded data and the parameter HltEventLoopMgr.forceStartOfRunTime is set >0. In that case the EventContext.EventID is forced to the be the SOR time for each event. Using the EventContext.eventID would lead to a constant seed and a skewed prescaling.

Definition at line 93 of file PrescalingTool.cxx.

96 {
97 if ( initiallyActive.empty() ) {
98 return StatusCode::SUCCESS;
99 }
100
101 // clear the output just in case
102 remainActive.clear();
103
104 if ( m_hltPrescaleSetInputKey.key().empty() ) {
105 // if no prescaling key is configured, treat all prescales according to the property KeepUnknownChains
106 if( m_keepUnknownChains ) {
107 remainActive.reserve( initiallyActive.size() );
108 for( const auto & ch : initiallyActive ) {
109 remainActive.push_back(ch);
110 }
111 }
112 return StatusCode::SUCCESS;
113 }
114
115 SG::ReadCondHandle<TrigConf::HLTPrescalesSet> hltPrescaleSet{m_hltPrescaleSetInputKey, ctx};
116 ATH_CHECK(hltPrescaleSet.isValid());
117
118 // access to psk
119 ATH_MSG_DEBUG("Using HLT PSK " << hltPrescaleSet->psk());
120 auto mon_lb = Monitored::Scalar<int>("LB", [&](){ return ctx.eventID().lumi_block(); });
121 auto mon_psk = Monitored::Scalar<std::string>("HLTPSK", [&](){ return std::to_string(hltPrescaleSet->psk()); });
122 auto mon = Monitored::Group(m_monTool, mon_lb, mon_psk);
123
124 // prepare the result
125 remainActive.reserve( initiallyActive.size() );
126
127 // create the seed from the event time
134 auto eventInfoHandle = SG::makeHandle( m_eventInfoKey, ctx );
135 CHECK( eventInfoHandle.isValid() );
136 size_t seed = eventInfoHandle->timeStamp() ^ eventInfoHandle->timeStampNSOffset();
137
138 CLHEP::HepRandomEngine* engine = m_RNGEngines.getEngine( ctx );
139 engine->setSeed( seed, 0 );
140
141 auto getPrescale = [&](const HLT::Identifier& ch) -> const TrigConf::HLTPrescalesSet::HLTPrescale& {
142 try {
143 if (forExpressStream) {
144 return hltPrescaleSet->prescale_express( ch.numeric() );
145 } else {
146 return hltPrescaleSet->prescale( ch.numeric() );
147 }
148 } catch(const std::out_of_range & ex) {
149 // if chain with that name is not found in the prescale set
150 if (m_keepUnknownChains.value()) {
151 ATH_MSG_DEBUG("No prescale value for chain " << ch << ", keeping it because "
152 << m_keepUnknownChains.name() << "=" << m_keepUnknownChains.value());
153 } else {
154 ATH_MSG_ERROR("No prescale value for chain " << ch);
155 }
156 }
158 };
159
160 auto decisionPerChain = [&](const HLT::Identifier& ch, double prescaleValue ) -> bool {
161 auto flat = engine->flat();
162 if(ch == m_costChainID) { // this is to explicitly monitor the cost chain
163 auto mon_rndm = Monitored::Scalar<double>("Random", flat);
164 Monitored::Group(m_monTool, mon_rndm);
165 }
166 return flat < 1./ prescaleValue;
167 };
168
169 struct ChainAndPrescale {
170 HLT::Identifier id;
171 TrigConf::HLTPrescalesSet::HLTPrescale ps;
172 double relativePrescale{};
173 };
174
175 for ( auto [groupName, chainIDs]: m_CPSGroups) {
176 // check if this group is seeded
177 // only need to find one CPS chain if initiallyActive is L1seeded HLT id's
178 if ( forExpressStream || std::find(initiallyActive.begin(), initiallyActive.end(), chainIDs.front()) != initiallyActive.end() ) {
179 std::vector<ChainAndPrescale> psValueSorted;
180 for ( const HLT::Identifier& ch: chainIDs ) {
181 // in express stream initiallyActive are HLT accept id's, but chainIDs contain all chains in the group
182 // regardless of HLT accept; skip the HLT reject id's to ensure remainActive is a subset of initiallyActive
183 if ( forExpressStream && std::find(initiallyActive.begin(), initiallyActive.end(), ch) == initiallyActive.end() ) {
184 continue;
185 }
186 auto ps = getPrescale(ch);
187 if ( ps.enabled ) // exclude prescaled out chains
188 psValueSorted.emplace_back( ChainAndPrescale({ch, ps}) );
189 }
190 if ( psValueSorted.empty() ) { // sometimes all chains may be presscaled out/disabled
191 continue;
192 }
193 std::sort(psValueSorted.begin(), psValueSorted.end(), [](const ChainAndPrescale& a, const ChainAndPrescale& b){
194 return a.ps.prescale < b.ps.prescale;
195 });
196 // setup relative prescales
197 // the first chain (with the lowest PS is relative w.r.t the all events)
198 psValueSorted.front().relativePrescale = psValueSorted.front().ps.prescale;
199 if ( psValueSorted.size() > 1 ) {
200 for ( auto i = psValueSorted.begin()+1; i < psValueSorted.end(); ++i ) {
201 i->relativePrescale = i->ps.prescale / (i-1)->ps.prescale ;
202 }
203 }
204 if (msgLvl(MSG::DEBUG)) {
205 ATH_MSG_DEBUG("Chains in CPS group '"<< groupName <<"' sorted by PS : ");
206 for ( const ChainAndPrescale& ch: psValueSorted ) {
207 ATH_MSG_DEBUG(" " << ch.id << " " << (ch.ps.enabled ?
208 "prescale relative to the above " + std::to_string(ch.relativePrescale) :
209 "disabled"));
210 }
211 }
212 // do actual prescaling
213 for ( const ChainAndPrescale& ch: psValueSorted ) {
214 const bool decision = decisionPerChain(ch.id, ch.relativePrescale);
215 if ( not decision ) {break;}
216 remainActive.push_back( ch.id );
217 }
218 }
219 }
220
221 // go through all active chains that are not in CPS groups
222 for ( const HLT::Identifier& ch: m_nonCPSChains ) {
223 if ( std::find( initiallyActive.begin(), initiallyActive.end(), ch ) != initiallyActive.end() ) {
224 auto prescale = getPrescale(ch);
225 if ( prescale.enabled ) {
226 const bool decision = decisionPerChain(ch, prescale.prescale);
227 if ( decision ) {
228 remainActive.push_back( ch );
229 }
230 ATH_MSG_DEBUG("Prescaling decision for chain " << ch << " " << decision);
231 } else {
232 ATH_MSG_DEBUG("Chain " << ch << " is disabled, won't keep" );
233 }
234 }
235 }
236
237 return StatusCode::SUCCESS;
238}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
static Double_t a
std::map< std::string, HLT::IDVec > m_CPSGroups
ChainSet m_nonCPSChains
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ start()

StatusCode PrescalingTool::start ( )
overridevirtual

Definition at line 45 of file PrescalingTool.cxx.

45 {
46
47 // Cleanup in case there was a stop/start transition
48 m_CPSGroups.clear();
49 m_nonCPSChains.clear();
50
51 SG::ReadHandle<TrigConf::HLTMenu> hltMenuHandle = SG::makeHandle( m_HLTMenuKey );
52 ATH_CHECK( hltMenuHandle.isValid() );
53
54 std::map<std::string, std::set<std::string>> l1SeedsCheckForCPS;
55 for ( const TrigConf::Chain& chain: *hltMenuHandle ) {
56 HLT::Identifier chainID{ chain.name() };
57 int isCPS = 0;
58 for ( const auto& group: chain.groups() ) {
59 if ( group.find("CPS") != std::string::npos) {
60 m_CPSGroups[group].push_back( chainID );
61 l1SeedsCheckForCPS[group].insert(chain.l1item());
62 isCPS++;
63 }
64 }
65 if ( isCPS ==0 ) {
66 m_nonCPSChains.insert( chainID );
67 }
68 if ( isCPS > 1 ) {
69 ATH_MSG_ERROR("Chain " << chainID << " belongs to more than one CPS groups");
70 return StatusCode::FAILURE;
71 }
72 }
73
74 for ( auto [group, chains]: m_CPSGroups ) {
75 if ( chains.size() == 1 ) {
76 ATH_MSG_ERROR("Only one chain " << chains.front() << " in CPS group " << group << " that makes no sense");
77 return StatusCode::FAILURE;
78 }
79 }
80
81 for ( auto [group, l1SeedsSet]: l1SeedsCheckForCPS) {
82 if ( l1SeedsSet.size() != 1 ) {
83 ATH_MSG_ERROR("Chains in CPS group " << group << " have several different L1 seeds "
84 << std::vector<std::string>(l1SeedsSet.begin(), l1SeedsSet.end()));
85 return StatusCode::FAILURE;
86 }
87 }
88
89 return StatusCode::SUCCESS;
90}
virtual bool isValid() override final
Can the handle be successfully dereferenced?

Member Data Documentation

◆ m_costChainID

HLT::Identifier PrescalingTool::m_costChainID {""}
private

Definition at line 84 of file PrescalingTool.h.

84{""};

◆ m_CPSGroups

std::map<std::string, HLT::IDVec> PrescalingTool::m_CPSGroups
private

Definition at line 81 of file PrescalingTool.h.

◆ m_eventInfoKey

SG::ReadHandleKey<xAOD::EventInfo> PrescalingTool::m_eventInfoKey
private
Initial value:
{
this, "EventInfo", "EventInfo", "Event Info Object Key"}

Definition at line 67 of file PrescalingTool.h.

67 {
68 this, "EventInfo", "EventInfo", "Event Info Object Key"};

◆ m_HLTMenuKey

SG::ReadHandleKey<TrigConf::HLTMenu> PrescalingTool::m_HLTMenuKey
private
Initial value:
{
this, "HLTTriggerMenu", "DetectorStore+HLTTriggerMenu", "HLT Menu"}

Definition at line 64 of file PrescalingTool.h.

64 {
65 this, "HLTTriggerMenu", "DetectorStore+HLTTriggerMenu", "HLT Menu"};

◆ m_hltPrescaleSetInputKey

SG::ReadCondHandleKey<TrigConf::HLTPrescalesSet> PrescalingTool::m_hltPrescaleSetInputKey
private
Initial value:
{
this, "HLTPrescales", "HLTPrescales", "HLT prescales set"}

Definition at line 61 of file PrescalingTool.h.

61 {
62 this, "HLTPrescales", "HLTPrescales", "HLT prescales set"};

◆ m_keepUnknownChains

Gaudi::Property<bool> PrescalingTool::m_keepUnknownChains
private
Initial value:
{
this, "KeepUnknownChains", false, "If True then chains for which prescaling information is not set are kept"}

Definition at line 70 of file PrescalingTool.h.

70 {
71 this, "KeepUnknownChains", false, "If True then chains for which prescaling information is not set are kept"};

◆ m_monTool

ToolHandle<GenericMonitoringTool> PrescalingTool::m_monTool
private
Initial value:
{
this, "MonTool", "", "Monitoring tool"}

Definition at line 73 of file PrescalingTool.h.

73 {
74 this, "MonTool", "", "Monitoring tool"};

◆ m_nonCPSChains

ChainSet PrescalingTool::m_nonCPSChains
private

Definition at line 80 of file PrescalingTool.h.

◆ m_prescaleForUnknownChain

TrigConf::HLTPrescalesSet::HLTPrescale PrescalingTool::m_prescaleForUnknownChain
private

Definition at line 83 of file PrescalingTool.h.

◆ m_RNGEngines

ATHRNG::RNGWrapper PrescalingTool::m_RNGEngines
private

Random engine for calculating prescales.

Definition at line 77 of file PrescalingTool.h.


The documentation for this class was generated from the following files: