ATLAS Offline Software
Loading...
Searching...
No Matches
CTPSimulation.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "./CTPSimulation.h"
7#include "./CTPTriggerItem.h"
8#include "./CTPUtil.h"
9
10#include "TrigT1Result/CTP_RDO.h" // TODO obsolete it in favour of xAOD::CTPResult - see line below
16
20
21#include "CLHEP/Random/RandomEngine.h"
22#include "CLHEP/Random/Ranlux64Engine.h"
23
24#include "TTree.h"
25
26#include <iomanip>
27#include <algorithm>
28#include <cmath>
29
30namespace {
31 static std::mutex s_metadataMutex;
32}
33
34
35using namespace TrigConf;
36
37const std::function< CLHEP::HepRandomEngine*(void) > CTPSimRanluxFactory = [](void)->CLHEP::HepRandomEngine*{
38 return new CLHEP::Ranlux64Engine();
39};
40
41
42LVL1CTP::CTPSimulation::CTPSimulation( const std::string& name, ISvcLocator* pSvcLocator ) :
43 AthReentrantAlgorithm ( name, pSvcLocator ),
44 m_RNGEngines( CTPSimRanluxFactory, SG::getNSlots() )
45{}
46
49
50StatusCode
52
53 ATH_MSG_DEBUG("initialize");
55 ATH_MSG_INFO("Will use bunchgroup pattern 0x" << std::hex << m_bunchGroupPattern);
56 } else {
57 ATH_MSG_INFO("Will use bunchgroup definition from bunchgroup set");
58 }
59
60 if( m_isData ) {
61 if(m_useEDMxAOD){
63 } else {
65 }
67 }
69
70
71 // data links
72 ATH_CHECK( m_iKeyTopo.initialize( !m_iKeyTopo.empty() && m_doL1Topo ) );
73 ATH_CHECK( m_iKeyMuctpi.initialize( ! m_iKeyMuctpi.empty() ) );
74
75 // Legacy L1Calo
80
81 // new L1Calo
82 ATH_CHECK( m_iKeyJFexJets.initialize( ! m_iKeyJFexJets.empty() ) );
83 ATH_CHECK( m_iKeyJFexLJets.initialize( ! m_iKeyJFexLJets.empty() ) );
84 ATH_CHECK( m_iKeyGFexJets.initialize( ! m_iKeyGFexJets.empty() ) );
85 ATH_CHECK( m_iKeyGFexMETNC.initialize( ! m_iKeyGFexMETNC.empty() ) );
86 ATH_CHECK( m_iKeyGFexMETRho.initialize( ! m_iKeyGFexMETRho.empty() ) );
87 ATH_CHECK( m_iKeyGFexMETJwoJ.initialize( ! m_iKeyGFexMETJwoJ.empty() ) );
88 ATH_CHECK( m_iKeyEFexCluster.initialize( ! m_iKeyEFexCluster.empty() ) );
89 ATH_CHECK( m_iKeyEFexTau.initialize( ! m_iKeyEFexTau.empty() ) );
90 ATH_CHECK( m_oKeyCTPResult.initialize( m_useEDMxAOD && !m_oKeyCTPResult.empty() ) );
91 ATH_CHECK( m_oKeyRDO.initialize( !m_useEDMxAOD && !m_oKeyRDO.empty() ) );
92 ATH_CHECK( m_oKeySLink.initialize( ! m_oKeySLink.empty() ) );
93
94 // L1ZDC
95 ATH_CHECK( m_iKeyZDC.initialize( ! m_iKeyZDC.empty() && m_doZDC ) );
96
97 // L1TRT
98 ATH_CHECK( m_iKeyTRT.initialize( ! m_iKeyTRT.empty() && m_doTRT ) );
99
100 // services
101 ATH_CHECK( m_histSvc.retrieve() );
102
103 // tools
104 ATH_CHECK( m_resultBuilder.retrieve() );
105
106 ATH_MSG_DEBUG("Registering histograms under " << getBaseHistPath() << " in " << m_histSvc);
107
108 return StatusCode::SUCCESS;
109}
110
111StatusCode
113
114 const TrigConf::L1Menu * l1menu = nullptr;
115 ATH_CHECK( detStore()->retrieve(l1menu) );
116
117 bookHists().ignore();
118
119 // configure the CTP ResultBuilder
120 ATH_CHECK( m_resultBuilder->setConfiguration( *l1menu ) );
121 setHistLabels(*l1menu).ignore();
122
123 return StatusCode::SUCCESS;
124}
125
126StatusCode
127LVL1CTP::CTPSimulation::execute( const EventContext& context ) const {
128
129 ATH_MSG_DEBUG("execute");
130
131 fillInputHistograms(context).ignore();
132
133 std::map<std::string, unsigned int> thrMultiMap;
134
135 extractMultiplicities(thrMultiMap, context).ignore();
136
137 simulateItems(thrMultiMap, context).ignore();
138
139 return StatusCode::SUCCESS;
140}
141
142StatusCode
143LVL1CTP::CTPSimulation::createMultiplicityHist(const std::string & type, unsigned int maxMult ) {
144
145 StatusCode sc;
146 std::map<std::string,std::vector<std::string>> typeMapping = {
147 { "muon", {"MU"} },
148 { "jet", {"JET", "jJ", "jLJ", "gJ", "gLJ"} },
149 { "xe", {"XE", "gXE", "jXE"} },
150 { "te", {"TE", "jTE", "gTE"} },
151 { "xs", {"XS"} },
152 { "em", {"EM", "eEM", "jEM"} },
153 { "tau", {"TAU", "eTAU", "jTAU", "cTAU"} }
154 };
155 std::vector<TrigConf::L1Threshold> thrV;
156 for( const std::string & t : typeMapping[type] ) {
157 size_t xsize = 1;
158 TH2* hist = new TH2I( Form("%sMult", t.c_str()),
159 Form("%s threshold multiplicity", t.c_str()), xsize, 0, xsize, maxMult, 0, maxMult);
160 sc = hbook( "/multi/" + type, std::unique_ptr<TH2>(hist));
161 }
162
163 return sc;
164}
165
166StatusCode
168 StatusCode sc;
169 std::map<std::string,std::vector<std::string>> typeMapping = {
170 { "muon", {"MU"} },
171 { "jet", {"JET", "jJ", "jLJ", "gJ", "gLJ"} },
172 { "xe", {"XE", "gXE", "jXE"} },
173 { "te", {"TE", "jTE", "gTE"} },
174 { "xs", {"XS"} },
175 { "em", {"EM", "eEM", "jEM"} },
176 { "tau", {"TAU", "eTAU", "jTAU", "cTAU"} }
177 };
178
179
180 std::vector<TrigConf::L1Threshold> thrV;
181 for( const std::string & t : typeMapping[type] ) {
182 try {
183 auto hist = get2DHist( "/multi/" + type + "/" + t + "Mult" );
184 auto & thrV = l1menu.thresholds(t);
185 while( hist->GetNbinsX() < (int)thrV.size() ) {
186 hist->LabelsInflate("xaxis");
187 }
188 for(auto thr : thrV) {
189 hist->GetXaxis()->SetBinLabel(thr->mapping()+1, thr->name().c_str() );
190 }
191 } catch (std::exception & ex) {
192 ATH_MSG_DEBUG("Caught exception when setting new JSON MultiplicityHistLabel " << t << " : " << ex.what());
193 }
194 }
195 return sc;
196}
197
198std::string
200 std::string baseHistPath( m_histPath );
201 if(baseHistPath.back()!='/') baseHistPath += "/";
202 baseHistPath += name();
203 return baseHistPath;
204}
205
206StatusCode
207LVL1CTP::CTPSimulation::hbook(const std::string & path, std::unique_ptr<TH1> hist) {
208 const std::string & hname(hist->GetName());
209
210 std::string key(path);
211 if(key.back()!='/') key += "/";
212 key+=hname;
213
214 if(m_hist1D.find(key)!=m_hist1D.end()) {
215 ATH_MSG_WARNING("1D-hist " << key << " already exists, won't register it");
216 return StatusCode::RECOVERABLE;
217 }
218
219 LockedHandle<TH1> lh;
220 StatusCode sc = m_histSvc->regShared( getBaseHistPath() + key, std::move(hist), lh );
221 if( sc.isSuccess() ) {
222 ATH_MSG_DEBUG("1D-hist " << hname << " registered with key - " << key);
223 m_hist1D[key] = lh;
224 } else {
225 ATH_MSG_WARNING("Could not register histogram " << hname);
226 }
227 return sc;
228}
229
230StatusCode
231LVL1CTP::CTPSimulation::hbook(const std::string & path, std::unique_ptr<TH2> hist) {
232 const std::string & hname(hist->GetName());
233
234 std::string key(path);
235 if(key.back()!='/') key += "/";
236 key+=hname;
237
238 if(m_hist2D.find(key)!=m_hist2D.end()) {
239 ATH_MSG_WARNING("2D-hist " << key << " already exists, won't register it");
240 return StatusCode::RECOVERABLE;
241 }
242
243 LockedHandle<TH2> lh;
244 StatusCode sc = m_histSvc->regShared( getBaseHistPath() + key, std::move(hist), lh );
245 if( sc.isSuccess() ) {
246 ATH_MSG_DEBUG("2D-hist " << hname << " registered with key - " << key);
247 m_hist2D[key] = lh;
248 } else {
249 ATH_MSG_WARNING("Could not register histogram " << hname);
250 }
251 return sc;
252}
253
254LockedHandle<TH1> &
255LVL1CTP::CTPSimulation::get1DHist(const std::string & histName) const {
256 auto itr = m_hist1D.find(histName);
257 if (itr == m_hist1D.end()) {
258 throw GaudiException("1D-hist "+histName +" does not exist", name(), StatusCode::FAILURE);
259 }
260 // returning non-const LockHandle from const function is OK:
261 LockedHandle<TH1>& h ATLAS_THREAD_SAFE = const_cast<LockedHandle<TH1>&>(itr->second);
262 return h;
263}
264
265LockedHandle<TH2> &
266LVL1CTP::CTPSimulation::get2DHist(const std::string & histName) const {
267 auto itr = m_hist2D.find(histName);
268 if (itr == m_hist2D.end()) {
269 throw GaudiException("2D-hist "+histName +" does not exist", name(), StatusCode::FAILURE);
270 }
271 // returning non-const LockHandle from const function is OK:
272 LockedHandle<TH2>& h ATLAS_THREAD_SAFE = const_cast<LockedHandle<TH2>&>(itr->second);
273 return h;
274}
275
276StatusCode
278
279 ATH_MSG_DEBUG("setHistLabels(). L1 menu " << l1menu.size() << " items" );
280 // threshold multiplicities
281 ATH_CHECK ( setMultiplicityHistLabels( l1menu, "muon" ) );
282 ATH_CHECK ( setMultiplicityHistLabels( l1menu, "jet" ) );
283 ATH_CHECK ( setMultiplicityHistLabels( l1menu, "xe" ) );
284 ATH_CHECK ( setMultiplicityHistLabels( l1menu, "te" ) );
285 ATH_CHECK ( setMultiplicityHistLabels( l1menu, "xs" ) );
286 ATH_CHECK ( setMultiplicityHistLabels( l1menu, "em" ) );
287 ATH_CHECK ( setMultiplicityHistLabels( l1menu, "tau" ) );
288
289 // Topo
290 std::vector<std::string> connNames = l1menu.connectorNames();
291 for( const std::string connName : {"LegacyTopo0", "LegacyTopo1", "Topo1El", "Topo2El", "Topo3El", "Topo1Opt0", "Topo1Opt1", "Topo1Opt2", "Topo1Opt3"}) {
292 if( find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
293 continue;
294 }
295 auto hTopo = *get1DHist("/input/topo/" + connName);
296 for(uint fpga : {0,1}) {
297 for(uint clock : {0,1}) {
298 for(auto & tl : l1menu.connector(connName).triggerLines(fpga,clock)) {
299 uint flatIndex = tl.flatindex();
300 hTopo->GetXaxis()->SetBinLabel(flatIndex+1,tl.name().c_str());
301 }
302 }
303 }
304 }
305
306 std::vector<std::string> orderedItemnames;
307 orderedItemnames.reserve( l1menu.size() );
308 for( const auto & item : l1menu ) {
309 orderedItemnames.emplace_back(item.name());
310 }
311 std::sort(orderedItemnames.begin(), orderedItemnames.end());
312
313 // item decision
314 auto tbpById = *get1DHist( "/output/tbpById" );
315 auto tapById = *get1DHist( "/output/tapById" );
316 auto tavById = *get1DHist( "/output/tavById" );
317 auto tbpByName = *get1DHist( "/output/tbpByName" );
318 auto tapByName = *get1DHist( "/output/tapByName" );
319 auto tavByName = *get1DHist( "/output/tavByName" );
320 unsigned int bin = 1;
321 for ( const std::string & itemname : orderedItemnames ) {
322 unsigned int ctpId(0);
323 TrigConf::L1Item item = l1menu.item( itemname );
324 ctpId = item.ctpId();
325 tbpById->GetXaxis()->SetBinLabel( ctpId+1, itemname.c_str() );
326 tapById->GetXaxis()->SetBinLabel( ctpId+1, itemname.c_str() );
327 tavById->GetXaxis()->SetBinLabel( ctpId+1, itemname.c_str() );
328 tbpByName->GetXaxis()->SetBinLabel( bin, itemname.c_str() );
329 tapByName->GetXaxis()->SetBinLabel( bin, itemname.c_str() );
330 tavByName->GetXaxis()->SetBinLabel( bin++, itemname.c_str() );
331 }
332
333 return StatusCode::SUCCESS;
334}
335
336StatusCode
338
339 // jets
340 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("jJetPt","Jet p_{T} - jJ", 40, 0, 80) ));
341 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("jJetEta","Jet #eta - jJ", 64, -3.2, 3.2) ));
342 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("jJetPhi","Jet #phi - jJ", 64, -3.2, 3.2) ));
343 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("jLJetPt","Jet p_{T} - jLJ", 40, 0, 80) ));
344 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("jLJetEta","Jet #eta - jLJ", 64, -3.2, 3.2) ));
345 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("jLJetPhi","Jet #phi - jLJ", 64, -3.2, 3.2) ));
346 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("gJetPt","Jet p_{T} - gJ", 40, 0, 80) ));
347 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("gJetEta","Jet #eta - gJ", 64, -3.2, 3.2) ));
348 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("gJetPhi","Jet #phi - gJ", 64, -3.2, 3.2) ));
349 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("gLJetPt","Jet p_{T} - gLJ", 40, 0, 80) ));
350 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("gLJetEta","Jet #eta - gLJ", 64, -3.2, 3.2) ));
351 ATH_CHECK ( hbook( "/input/jets/", std::make_unique<TH1I>("gLJetPhi","Jet #phi - gLJ", 64, -3.2, 3.2) ));
352
353 // MET
354 ATH_CHECK ( hbook( "/input/met/", std::make_unique<TH1I>("Pufit","Missing ET from algorithm pufit", 40, 0, 80) ));
355 ATH_CHECK ( hbook( "/input/met/", std::make_unique<TH1I>("PufitPhi","Missing ET PUfit phi", 64, -3.2, 3.2) ));
356 ATH_CHECK ( hbook( "/input/met/", std::make_unique<TH1I>("Rho","Missing ET from algorithm rhosub", 40, 0, 80) ));
357 ATH_CHECK ( hbook( "/input/met/", std::make_unique<TH1I>("RhoPhi","Missing ET rhosub phi", 64, -3.2, 3.2) ));
358 ATH_CHECK ( hbook( "/input/met/", std::make_unique<TH1I>("JwoJ","Missing ET from algorithm jet without jets", 40, 0, 80) ));
359 ATH_CHECK ( hbook( "/input/met/", std::make_unique<TH1I>("JwoJPhi","Missing ET jet without jet phi", 64, -3.2, 3.2) ));
360
361 // cluster
362 ATH_CHECK ( hbook( "/input/em/", std::make_unique<TH1I>("et","Cluster et", 40, 0, 40) ));
363 ATH_CHECK ( hbook( "/input/em/", std::make_unique<TH1I>("eta","Cluster eta ", 64, -3.2, 3.2) ));
364 ATH_CHECK ( hbook( "/input/em/", std::make_unique<TH1I>("phi","Cluster phi", 64, -3.2, 3.2) ));
365
366 // tau
367 ATH_CHECK ( hbook( "/input/tau/", std::make_unique<TH1I>("et","Tau et", 40, 0, 40) ));
368 ATH_CHECK ( hbook( "/input/tau/", std::make_unique<TH1I>("eta","Tau eta ", 64, -3.2, 3.2) ));
369 ATH_CHECK ( hbook( "/input/tau/", std::make_unique<TH1I>("phi","Tau phi", 64, -3.2, 3.2) ));
370 ATH_CHECK ( hbook( "/input/tau/", std::make_unique<TH1I>("emIso","Tau em isolation", 40, 0, 1) ));
371 ATH_CHECK ( hbook( "/input/tau/", std::make_unique<TH1I>("hadIso","Tau hadronic isolation", 40, 0, 1) ));
372 ATH_CHECK ( hbook( "/input/tau/", std::make_unique<TH1I>("R3ET","Tau eT", 40, 0, 40) ));
373 ATH_CHECK ( hbook( "/input/tau/", std::make_unique<TH1I>("R3Iso","Tau isolation", 40, 0, 1) ));
374
375 // input counts
376 ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("jJets","Number of jets (jJ)", 40, 0, 40) ));
377 ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("jLJets","Number of jets (jLJ)", 40, 0, 40) ));
378 ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("gJets","Number of jets (gJ)", 40, 0, 40) ));
379 ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("gLJets","Number of jets (gLJ)", 40, 0, 40) ));
380 ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("muons","Number of muons", 10, 0, 10) ));
381 ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("emcluster","Number of EM clusters", 20, 0, 20) ));
382 ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("taus","Number of TAU candidates", 20, 0, 20) ));
383
384 // threshold multiplicities
385 ATH_CHECK ( createMultiplicityHist( "muon" ) );
387 ATH_CHECK ( createMultiplicityHist( "xe", 2) );
388 ATH_CHECK ( createMultiplicityHist( "te", 2) );
389 ATH_CHECK ( createMultiplicityHist( "xs", 2) );
392
393 ATH_CHECK ( hbook( "/multi/all", (std::unique_ptr<TH2>)std::make_unique<TH2I>("LegacyMult", "Legacy thresholds multiplicity", 1, 0, 1, 10, 0, 10) ));
394 ATH_CHECK ( hbook( "/multi/all", (std::unique_ptr<TH2>)std::make_unique<TH2I>("R3Mult", "New thresholds multiplicity", 1, 0, 1, 10, 0, 10) ));
395
396 // Topo
397 ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("LegacyTopo0","L1Topo Decision (Legacy 0)", 64, 0, 64) ));
398 ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("LegacyTopo1","L1Topo Decision (Legacy 1)", 64, 0, 64) ));
399 ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo1El","L1Topo Decision (Topo 1 electrical)", 64, 0, 64) ));
400 ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo2El","L1Topo Decision (Topo 2 electrical)", 64, 0, 64) ));
401 ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo3El","L1Topo Decision (Topo 3 electrical)", 64, 0, 64) ));
402 ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo1Opt0","L1Topo Decision (Topo 1 optical 0)", 128, 0, 128) ));
403 ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo1Opt1","L1Topo Decision (Topo 1 optical 1)", 128, 0, 128) ));
404 ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo1Opt2","L1Topo Decision (Topo 1 optical 2)", 128, 0, 128) ));
405 ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo1Opt3","L1Topo Decision (Topo 1 optical 3)", 128, 0, 128) ));
406
407 // item decision
408 ATH_CHECK ( hbook( "/output/", std::make_unique<TH1I>("tbpById", "Items decision (tbp)", 512, 0, 512) ));
409 ATH_CHECK ( hbook( "/output/", std::make_unique<TH1I>("tapById", "Items decision (tap)", 512, 0, 512) ));
410 ATH_CHECK ( hbook( "/output/", std::make_unique<TH1I>("tavById", "Items decision (tav)", 512, 0, 512) ));
411 ATH_CHECK ( hbook( "/output/", std::make_unique<TH1I>("tbpByName", "Items decision (tbp)", 512, 0, 512) ));
412 ATH_CHECK ( hbook( "/output/", std::make_unique<TH1I>("tapByName", "Items decision (tap)", 512, 0, 512) ));
413 ATH_CHECK ( hbook( "/output/", std::make_unique<TH1I>("tavByName", "Items decision (tav)", 512, 0, 512) ));
414
415 ATH_CHECK ( hbook( "/", std::make_unique<TH1I>("bcid", "Bunch crossing ID", 3564, 0, 3564)) );
416
418
419 return StatusCode::SUCCESS;
420}
421
422StatusCode
423LVL1CTP::CTPSimulation::fillInputHistograms(const EventContext& context) const {
424
425 ATH_MSG_DEBUG( "fillInputHistograms" );
426
427 // jFEX jets
428 if( not m_iKeyJFexJets.empty() ) {
429 auto jFexJets = SG::makeHandle( m_iKeyJFexJets, context );
430 if(jFexJets.isValid()) {
431 get1DHist("/input/counts/jJets")->Fill(jFexJets->size());
432 auto h0 = *get1DHist("/input/jets/jJetPt"); // calling operator* to get the Guard outside the filling loop
433 auto h1 = *get1DHist("/input/jets/jJetEta");
434 auto h2 = *get1DHist("/input/jets/jJetPhi");
435 for( const auto jet : *jFexJets ) {
436 h0->Fill(fabs(jet->et8x8()/1000.));
437 h1->Fill(jet->eta());
438 h2->Fill(jet->phi());
439 }
440 } else {
441 ATH_MSG_DEBUG("No collection " << m_iKeyJFexJets);
442 }
443 }
444
445 // jFEX large-R jets
446 if( not m_iKeyJFexLJets.empty() ) {
447 auto jFexLJets = SG::makeHandle( m_iKeyJFexLJets, context );
448 if(jFexLJets.isValid()) {
449 get1DHist("/input/counts/jLets")->Fill(jFexLJets->size());
450 auto h0 = *get1DHist("/input/jets/jLJetPt");
451 auto h1 = *get1DHist("/input/jets/jLJetEta");
452 auto h2 = *get1DHist("/input/jets/jLJetPhi");
453 for( const auto jet : *jFexLJets ) {
454 h0->Fill(fabs(jet->et8x8()/1000.));
455 h1->Fill(jet->eta());
456 h2->Fill(jet->phi());
457 }
458 } else {
459 ATH_MSG_DEBUG("No collection " << m_iKeyJFexLJets);
460 }
461 } else {
462 ATH_MSG_DEBUG("No collection " << m_iKeyJFexLJets);
463 }
464
465 // gFEX jets
466 if( not m_iKeyGFexJets.empty() ) {
467 auto gFexJets = SG::makeHandle( m_iKeyGFexJets, context );
468 if(gFexJets.isValid()) {
469 get1DHist("/input/counts/gJets")->Fill(gFexJets->size());
470 auto h0 = *get1DHist("/input/jets/gJetPt");
471 auto h1 = *get1DHist("/input/jets/gJetEta");
472 auto h2 = *get1DHist("/input/jets/gJetPhi");
473 for( const auto jet : *gFexJets ) {
474 h0->Fill(fabs(jet->et8x8()/1000.));
475 h1->Fill(jet->eta());
476 h2->Fill(jet->phi());
477 }
478 } else {
479 ATH_MSG_DEBUG("No collection " << m_iKeyGFexJets);
480 }
481 }
482
483 // MET
484 if( not m_iKeyGFexMETNC.empty() ) {
485 auto gFexMETPufit = SG::makeHandle( m_iKeyGFexMETNC, context );
486 if( gFexMETPufit.isValid() ) {
487 get1DHist("/input/met/Pufit")->Fill(gFexMETPufit->energyT()/1000.);
488 get1DHist("/input/met/PufitPhi")->Fill(atan2(gFexMETPufit->energyX(), gFexMETPufit->energyY()));
489 } else {
490 ATH_MSG_DEBUG("No collection " << m_iKeyGFexMETNC);
491 }
492 }
493
494 if( not m_iKeyGFexMETRho.empty() ) {
495 auto gFexMETRho = SG::makeHandle( m_iKeyGFexMETRho, context );
496 if( gFexMETRho.isValid() ) {
497 get1DHist("/input/met/Rho")->Fill(gFexMETRho->energyT()/1000.);
498 get1DHist("/input/met/RhoPhi")->Fill(atan2(gFexMETRho->energyX(), gFexMETRho->energyY()));
499 } else {
500 ATH_MSG_DEBUG("No collection " << m_iKeyGFexMETRho);
501 }
502 }
503
504 if( not m_iKeyGFexMETJwoJ.empty() ) {
505 auto gFexMETJwoJ = SG::makeHandle( m_iKeyGFexMETJwoJ, context );
506 if( gFexMETJwoJ.isValid() ) {
507 get1DHist("/input/met/JwoJ")->Fill(gFexMETJwoJ->energyT()/1000.);
508 get1DHist("/input/met/JwoJPhi")->Fill(atan2(gFexMETJwoJ->energyX(), gFexMETJwoJ->energyY()));
509 } else {
510 ATH_MSG_DEBUG("No collection " << m_iKeyGFexMETJwoJ);
511 }
512 }
513
514 // EM cluster
515 if( not m_iKeyEFexCluster.empty() ) {
516 auto eFexCluster = SG::makeHandle( m_iKeyEFexCluster, context );
517 if( eFexCluster.isValid() ) {
518 get1DHist( "/input/counts/emcluster")->Fill(eFexCluster->size());
519 auto h0 = *get1DHist("/input/em/et");
520 auto h1 = *get1DHist("/input/em/eta");
521 auto h2 = *get1DHist("/input/em/phi");
522 for( const auto cl : *eFexCluster ) {
523 h0->Fill(cl->et());
524 h1->Fill(cl->eta());
525 h2->Fill(cl->phi());
526 }
527 } else {
528 ATH_MSG_DEBUG("No collection " << m_iKeyEFexCluster);
529 }
530 }
531
532 // eFEX Tau
533 if( not m_iKeyEFexTau.empty() ) {
534 auto eFexTau = SG::makeHandle( m_iKeyEFexTau, context );
535 if( eFexTau.isValid() ) {
536 get1DHist( "/input/counts/taus")->Fill(eFexTau->size());
537 auto h0 = *get1DHist("/input/tau/et");
538 auto h1 = *get1DHist("/input/tau/eta");
539 auto h2 = *get1DHist("/input/tau/phi");
540 auto h3 = *get1DHist("/input/tau/emIso");
541 auto h4 = *get1DHist("/input/tau/hadIso");
542 auto h5 = *get1DHist("/input/tau/R3ClusterET");
543 auto h6 = *get1DHist("/input/tau/R3ClusterIso");
544 const static SG::AuxElement::ConstAccessor<float> accR3ClET ("R3ClusterET");
545 const static SG::AuxElement::ConstAccessor<float> accR3ClIso ("R3ClusterIso");
546 for( const auto tau : *eFexTau ) {
547 h0->Fill(tau->eT());
548 h1->Fill(tau->eta());
549 h2->Fill(tau->phi());
550 h3->Fill(tau->emIsol());
551 h4->Fill(tau->hadIsol());
552 h5->Fill(accR3ClET(*tau)/1000.);
553 h6->Fill(accR3ClIso(*tau));
554 }
555 } else {
556 ATH_MSG_DEBUG("No collection " << m_iKeyEFexTau);
557 }
558 }
559
560 // topo
561 if( not m_iKeyLegacyTopo.empty() && m_doL1CaloLegacy && m_doL1TopoLegacy ) {
562 auto legacyTopoInput = SG::makeHandle( m_iKeyLegacyTopo, context );
563 if(legacyTopoInput.isValid()) {
564 ATH_MSG_DEBUG("Retrieved input from L1Topo from StoreGate with key " << m_iKeyTopo);
565 ATH_MSG_DEBUG("L1TopoLegacy0 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << legacyTopoInput->cableWord1(0));
566 ATH_MSG_DEBUG("L1TopoLegacy0 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << legacyTopoInput->cableWord1(1));
567 ATH_MSG_DEBUG("L1TopoLegacy1 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << legacyTopoInput->cableWord2(0));
568 ATH_MSG_DEBUG("L1TopoLegacy1 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << legacyTopoInput->cableWord2(1));
569 auto h0 = *get1DHist("/input/topo/LegacyTopo0");
570 auto h1 = *get1DHist("/input/topo/LegacyTopo1");
571 for(unsigned int i=0; i<32; ++i) {
572 uint32_t mask = 0x1; mask <<= i;
573 if( (legacyTopoInput->cableWord1(0) & mask) != 0 ) h0->Fill(i); // cable 0, clock 0
574 if( (legacyTopoInput->cableWord1(1) & mask) != 0 ) h0->Fill(32 + i); // cable 0, clock 1
575 if( (legacyTopoInput->cableWord2(0) & mask) != 0 ) h1->Fill(i); // cable 1, clock 0
576 if( (legacyTopoInput->cableWord2(1) & mask) != 0 ) h1->Fill(32 + i); // cable 1, clock 1
577 }
578 }
579 }
580
581 if( not m_iKeyTopo.empty() && m_doL1Topo ) {
582 auto topoInput = SG::makeHandle( m_iKeyTopo, context );
583 if(topoInput.isValid()) {
584 ATH_MSG_DEBUG("Retrieved input from L1Topo from StoreGate with key " << m_iKeyTopo);
585 ATH_MSG_DEBUG("L1Topo0 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord1(0));
586 ATH_MSG_DEBUG("L1Topo0 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord1(1));
587 ATH_MSG_DEBUG("L1Topo1 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord2(0));
588 ATH_MSG_DEBUG("L1Topo1 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord2(1));
589 auto h0 = *get1DHist("/input/topo/Topo2El");
590 auto h1 = *get1DHist("/input/topo/Topo3El");
591 for(unsigned int i=0; i<32; ++i) {
592 uint32_t mask = 0x1; mask <<= i;
593 if( (topoInput->cableWord1(0) & mask) != 0 ) h0->Fill(i); // cable 0, clock 0
594 if( (topoInput->cableWord1(1) & mask) != 0 ) h0->Fill(32 + i); // cable 0, clock 1
595 if( (topoInput->cableWord2(0) & mask) != 0 ) h1->Fill(i); // cable 1, clock 0
596 if( (topoInput->cableWord2(1) & mask) != 0 ) h1->Fill(32 + i); // cable 1, clock 1
597 }
598 auto h2 = *get1DHist("/input/topo/Topo1Opt0");
599 auto h3 = *get1DHist("/input/topo/Topo1Opt1");
600 auto h4 = *get1DHist("/input/topo/Topo1Opt2");
601 auto h5 = *get1DHist("/input/topo/Topo1Opt3");
602 for(unsigned int i=0; i<128; i += 3) {
603 std::bitset<128> mask = 0x11; mask <<= i;
604 if( (topoInput->optcableWord("Topo1Opt0") & mask) != 0 ) h2->Fill(i); //
605 if( (topoInput->optcableWord("Topo1Opt1") & mask) != 0 ) h3->Fill(i); //
606 if( (topoInput->optcableWord("Topo1Opt2") & mask) != 0 ) h4->Fill(i); //
607 if( (topoInput->optcableWord("Topo1Opt3") & mask) != 0 ) h5->Fill(i); //
608 }
609 } else {
610 ATH_MSG_DEBUG("No collection " << m_iKeyTopo);
611 }
612 }
613
614 // bcid
615 auto bcid = context.eventID().bunch_crossing_id();
616 get1DHist( "/bcid")->Fill(bcid);
617
618 return StatusCode::SUCCESS;
619}
620
621StatusCode
622LVL1CTP::CTPSimulation::extractMultiplicities(std::map<std::string, unsigned int> & thrMultiMap, const EventContext& context) const {
623
624 const TrigConf::L1Menu * l1menu = nullptr;
625 ATH_CHECK( detStore()->retrieve(l1menu) );
626
627 thrMultiMap.clear();
628
629 std::vector<std::string> connNames = l1menu->connectorNames();
630 for (const std::string connName : {"LegacyTopo0", "LegacyTopo1", "Topo1El", "Topo2El", "Topo3El", "Topo1Opt0", "Topo1Opt1", "Topo1Opt2", "Topo1Opt3", "CTPCAL", "NIM2"})
631 {
632 if( find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
633 continue;
634 }
635 bool opt_cable = false;
636 std::bitset<128> cable128 {0};
637 uint64_t cable {0};
638 if (connName.starts_with( "Legacy")) { // legacy topo
640 {
641 continue;
642 }
643 auto topoInput = SG::makeHandle( m_iKeyLegacyTopo, context );
644 if (not topoInput.isValid()) {
645 continue;
646 }
647 if(connName == "LegacyTopo0") {
648 cable = ( (uint64_t)topoInput->cableWord1( 1 ) << 32) + topoInput->cableWord1( 0 );
649 } else if (connName == "LegacyTopo1") {
650 cable = ( (uint64_t)topoInput->cableWord2( 1 ) << 32) + topoInput->cableWord2( 0 );
651 }
652 }
653 else if (connName.starts_with( "CTPCAL") && m_doZDC) // ZDC simulation
654 {
655 auto zdcInput = SG::makeHandle(m_iKeyZDC, context);
656 if (not zdcInput.isValid())
657 {
658 continue;
659 }
660 cable = static_cast<uint64_t>(zdcInput->cableWord0());
661 auto &conn = l1menu->connector(connName);
662 for (auto &tl : conn.triggerLines()){
663 if (tl.name().find("ZDC") == std::string::npos)
664 {
665 continue;
666 }
667 uint flatIndex = tl.flatindex();
668 uint pass = (cable & (uint64_t(0x1) << flatIndex)) == 0 ? 0 : 1;
669 thrMultiMap[tl.name()] = pass;
670 ATH_MSG_DEBUG(tl.name() << " MULT calculated mult for topo " << pass);
671
672 }
673 continue;
674 }
675 else if (connName.starts_with( "NIM2"))
676 {
677 if (m_doTRT) // TRT simulation
678 {
679 auto trtInput = SG::makeHandle(m_iKeyTRT, context);
680 if (not trtInput.isValid())
681 {
682 continue;
683 }
684 cable = static_cast<uint64_t>(trtInput->cableWord0());
685 auto &conn = l1menu->connector(connName);
686 for (auto &tl : conn.triggerLines()){
687 if (tl.name().find("TRT") == std::string::npos)
688 {
689 continue;
690 }
691 uint flatIndex = tl.flatindex();
692 uint pass = (cable & (uint64_t(0x1) << flatIndex)) == 0 ? 0 : 1;
693 thrMultiMap[tl.name()] = pass;
694 ATH_MSG_DEBUG(tl.name() << " MULT calculated mult for topo " << pass);
695 }
696 }
697 if (m_doZDC) // ZDC ALT simulation
698 {
699 auto zdcInput = SG::makeHandle(m_iKeyZDC, context);
700 if (not zdcInput.isValid())
701 {
702 continue;
703 }
704 cable = static_cast<uint64_t>(zdcInput->cableWord1());
705 auto &conn = l1menu->connector(connName);
706 for (const auto &tl : conn.triggerLines()){
707 if (tl.name().find("ZDC") == std::string::npos)
708 {
709 continue;
710 }
711 uint flatIndex = tl.flatindex();
712 uint pass = (cable & (uint64_t(0x1) << flatIndex)) == 0 ? 0 : 1;
713 thrMultiMap[tl.name()] = pass;
714 ATH_MSG_DEBUG(tl.name() << " MULT calculated mult for topo " << pass);
715 }
716 }
717 continue;
718 }
719
720 else { // new topo
721 if (m_iKeyTopo.empty() || !m_doL1Topo )
722 {
723 continue;
724 }
725 auto topoInput = SG::makeHandle( m_iKeyTopo, context );
726 if (not topoInput.isValid()) {
727 continue;
728 }
729 if(connName == "Topo1El") {
730 cable = ( (uint64_t)topoInput->cableWord0( 1 ) << 32) + topoInput->cableWord0( 0 );
731 } else if(connName == "Topo2El") {
732 cable = ( (uint64_t)topoInput->cableWord1( 1 ) << 32) + topoInput->cableWord1( 0 );
733 } else if (connName == "Topo3El") {
734 cable = ( (uint64_t)topoInput->cableWord2( 1 ) << 32) + topoInput->cableWord2( 0 );
735 } else if(connName == "Topo1Opt0") {
736 ATH_MSG_DEBUG("BIT word Topo1Opt0: " << topoInput->optcableWord( connName ));
737 opt_cable = true;
738 cable128 = topoInput->optcableWord( connName );
739 } else if(connName == "Topo1Opt1") {
740 ATH_MSG_DEBUG("BIT word Topo1Opt1: " << topoInput->optcableWord( connName ));
741 opt_cable = true;
742 cable128 = topoInput->optcableWord( connName );
743 } else if(connName == "Topo1Opt2") {
744 ATH_MSG_DEBUG("BIT word Topo1Opt2: " << topoInput->optcableWord( connName ));
745 opt_cable = true;
746 cable128 = topoInput->optcableWord( connName );
747 } else if(connName == "Topo1Opt3") {
748 ATH_MSG_DEBUG("BIT word Topo1Opt3: " << topoInput->optcableWord( connName ));
749 opt_cable = true;
750 cable128 = topoInput->optcableWord( connName );
751 }
752 }
753 auto & conn = l1menu->connector(connName);
754 for(uint fpga : {0,1}) {
755 for(uint clock : {0,1}) {
756 for(auto & tl : conn.triggerLines(fpga,clock)) {
757 uint flatIndex = tl.flatindex();
758 uint pass = 0;
759 if (opt_cable) {
760 pass = ((cable128 >> flatIndex).test(0)) == 0 ? 0 : 1;
761 }
762 else {
763 pass = (cable & (static_cast<uint64_t>(0x1) << flatIndex)) == 0 ? 0 : 1;
764 }
765 if(size_t pos = tl.name().find('['); pos == std::string::npos) {
766 thrMultiMap[tl.name()] = pass;
767 ATH_MSG_DEBUG(tl.name() << " MULT calculated mult for topo " << pass);
768 } else {
769 auto thrName = tl.name().substr(0,pos);
770 int bit = std::stoi(tl.name().substr(pos+1));
771 thrMultiMap.try_emplace(thrName, 0);
772 thrMultiMap[thrName] += (pass << bit);
773 ATH_MSG_DEBUG(thrName << " MULT updated mult for topo " << pass);
774 }
775 }
776 }
777 }
778 }
779 for ( auto & thr : l1menu->thresholds() ) {
780 if (thr->type() == "TOPO" or thr->type() == "MULTTOPO" or thr->type() == "MUTOPO")
781 {
782 continue;
783 }
784 if( thr->type() == "ZDC" && m_doZDC ){
785 continue;
786 }
787 if( thr->name() == "NIMTRT" && m_doTRT ){
788 continue;
789 }
790 // get the multiplicity for each threshold
791 unsigned int multiplicity = calculateMultiplicity(*thr, l1menu, context);
792 // and record in threshold--> multiplicity map (to be used for item decision)
793 thrMultiMap[thr->name()] = multiplicity;
794 ATH_MSG_DEBUG( thr->name() << " MULT calculated mult for topo " << multiplicity);
795 }
796
797 // internal triggers
798 auto bcid = context.eventID().bunch_crossing_id();
800 // force bunch group pattern from job options
801 for ( size_t bg = 0; bg < 16; ++bg ) {
802 std::string bgName("BGRP");
803 bgName += std::to_string(bg);
804 thrMultiMap[bgName] = ( m_bunchGroupPattern & (0x1<<bg) ) ? 1 : 0;
805 }
806 } else {
807 // use bunchgroup definition from configuration and pick according to the BCID
809 ATH_CHECK(bgkey.isValid());
810 const TrigConf::L1BunchGroupSet *l1bgs = *bgkey;
811 if (l1bgs)
812 {
813 for (size_t i = 0; i < l1bgs->maxNBunchGroups(); ++i)
814 {
815 std::shared_ptr<TrigConf::L1BunchGroup> bg = l1bgs->getBunchGroup(i);
816 thrMultiMap[std::string("BGRP") + std::to_string(i)] = bg->contains(bcid) ? 1 : 0;
817 }
818 }
819 else
820 {
821 ATH_MSG_ERROR("Did not find L1BunchGroupSet in DetectorStore");
822 }
823 }
824
825 // all RNDM triggers run with 40MHz, so they are always in
826 thrMultiMap["RNDM0"] = 1;
827 thrMultiMap["RNDM1"] = 1;
828 thrMultiMap["RNDM2"] = 1;
829 thrMultiMap["RNDM3"] = 1;
830
831 return StatusCode::SUCCESS;
832}
833
834
835unsigned int
836LVL1CTP::CTPSimulation::calculateJetMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context ) const {
837 unsigned int multiplicity = 0;
838 if( confThr.type() == "JET" ) {
839 if(m_doL1CaloLegacy) {
840 auto ctpinJet = SG::makeHandle( m_iKeyCtpinJet, context );
841 if ( ctpinJet.isValid() ) {
842 if( l1menu->connector("JET1").hasLine(confThr.name()) ) {
843 auto & triggerline = l1menu->connector("JET1").triggerLine(confThr.name());
844 multiplicity = CTPUtil::getMult( ctpinJet->cableWord0(), triggerline.startbit(), triggerline.endbit() );
845 } else if( l1menu->connector("JET2").hasLine(confThr.name()) ) {
846 auto & triggerline = l1menu->connector("JET2").triggerLine(confThr.name());
847 multiplicity = CTPUtil::getMult( ctpinJet->cableWord1(), triggerline.startbit(), triggerline.endbit() );
848 }
849 }
850 }
851 }
852 get2DHist( "/multi/jet/" + confThr.type() + "Mult" )->Fill(confThr.mapping(), multiplicity);
853 ATH_MSG_DEBUG("JET MULT calculated mult for threshold " << confThr.name() << " : " << multiplicity);
854 return multiplicity;
855}
856
857
858unsigned int
859LVL1CTP::CTPSimulation::calculateEMMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context ) const {
860 unsigned int multiplicity (0);
861 if ( confThr.name()[0]=='e' ) {
862 // new EM threshold from eFEX
863 if(!m_iKeyEFexCluster.empty()) {
864 float scale = l1menu->getObject("thresholds.legacyCalo.EM.emscale").getValue<float>();
865 auto eFexCluster = SG::makeHandle( m_iKeyEFexCluster, context );
866 for ( const auto cl : *eFexCluster ) {
867 float eta = cl->eta();
868 int ieta = int((eta + (eta>0 ? 0.005 : -0.005))/0.1);
869 unsigned int thrV = confThr.thrValue( ieta );
870 bool clusterPasses = ( ((unsigned int) cl->et()) > (thrV * scale) ); // need to add cut on isolation and other variables, once available
871 multiplicity += clusterPasses ? 1 : 0;
872 }
873 }
874 } else {
875 // old EM threshold from data
876 if(m_doL1CaloLegacy) {
877 auto ctpinEM = SG::makeHandle( m_iKeyCtpinEM, context );
878 if ( ctpinEM.isValid() ) {
879 if( l1menu->connector("EM1").hasLine(confThr.name()) ) {
880 auto & triggerline = l1menu->connector("EM1").triggerLine(confThr.name());
881 multiplicity = CTPUtil::getMult( ctpinEM->cableWord0(), triggerline.startbit(), triggerline.endbit() );
882 } else if( l1menu->connector("EM2").hasLine(confThr.name()) ) {
883 auto & triggerline = l1menu->connector("EM2").triggerLine(confThr.name());
884 multiplicity = CTPUtil::getMult( ctpinEM->cableWord1(), triggerline.startbit(), triggerline.endbit() );
885 }
886 }
887 }
888 }
889 get2DHist( "/multi/em/" + confThr.type() + "Mult" )->Fill(confThr.mapping(), multiplicity);
890 ATH_MSG_DEBUG("EM MULT calculated mult for threshold " << confThr.name() << " : " << multiplicity);
891 return multiplicity;
892}
893
894
895unsigned int
896LVL1CTP::CTPSimulation::calculateTauMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context ) const {
897 unsigned int multiplicity = 0;
898 if ( confThr.name()[0]=='e' ) {
899 // new TAU threshold from eFEX
900 auto eFexTaus = SG::makeHandle( m_iKeyEFexTau, context );
901 const static SG::AuxElement::ConstAccessor<float> accR3ClET ("R3ClusterET");
902 const static SG::AuxElement::ConstAccessor<float> accR3ClIso ("R3ClusterIso");
903 if( eFexTaus.isValid() ) {
904 for ( const auto tau : *eFexTaus ) {
905 unsigned int eT = (unsigned int) (accR3ClET(*tau)/1000.); // tau eT is in MeV while the cut is in GeV - this is only temporary and needs to be made consistent for all L1Calo
906 //float iso = accR3ClIso(*tau);
907 unsigned int etCut = confThr.data().get_child("et").get_value<unsigned int>();
908 bool tauPasses = ( eT >= etCut ); // need to add cut on isolation and other variables, once available
909 multiplicity += tauPasses ? 1 : 0;
910 }
911 }
912 } else {
913 // old TAU threshold
914 if(m_doL1CaloLegacy) {
915 auto ctpinEM = SG::makeHandle( m_iKeyCtpinEM, context );
916 if ( ctpinEM.isValid() ) {
917 if( l1menu->connector("TAU1").hasLine(confThr.name()) ) {
918 auto & triggerline = l1menu->connector("TAU1").triggerLine(confThr.name());
919 multiplicity = CTPUtil::getMult( ctpinEM->cableWord2(), triggerline.startbit(), triggerline.endbit() );
920 } else if( l1menu->connector("TAU2").hasLine(confThr.name()) ) {
921 auto & triggerline = l1menu->connector("TAU2").triggerLine(confThr.name());
922 multiplicity = CTPUtil::getMult( ctpinEM->cableWord3(), triggerline.startbit(), triggerline.endbit() );
923 }
924 }
925 }
926 }
927 get2DHist( "/multi/tau/" + confThr.type() + "Mult" )->Fill(confThr.mapping(), multiplicity);
928 ATH_MSG_DEBUG("TAU MULT calculated mult for threshold " << confThr.name() << " : " << multiplicity);
929 return multiplicity;
930}
931
932
933unsigned int
934LVL1CTP::CTPSimulation::calculateMETMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context ) const {
935 unsigned int multiplicity = 0;
936 if ( confThr.type() == "XE" or confThr.type() == "TE" or confThr.type() == "XS" ) {
937 // old XE, TE, XS
938 if(m_doL1CaloLegacy) {
939 auto ctpinEnergy = SG::makeHandle( m_iKeyCtpinXE, context );
940 if ( ctpinEnergy.isValid() ) {
941 if( l1menu->connector("EN1").hasLine(confThr.name()) ) {
942 auto & triggerline = l1menu->connector("EN1").triggerLine(confThr.name());
943 multiplicity = CTPUtil::getMult( ctpinEnergy->cableWord0(), triggerline.startbit(), triggerline.endbit() );
944 } else if( l1menu->connector("EN2").hasLine(confThr.name()) ) {
945 auto & triggerline = l1menu->connector("EN2").triggerLine(confThr.name());
946 multiplicity = CTPUtil::getMult( ctpinEnergy->cableWord1(), triggerline.startbit(), triggerline.endbit() );
947 }
948 }
949 }
950 } else {
951 // new XE
952 const SG::ReadHandleKey< xAOD::EnergySumRoI > * rhk { nullptr };
953 if ( confThr.name().find("gXENC")==0 ) {
954 rhk = & m_iKeyGFexMETNC;
955 ATH_MSG_DEBUG("Using Pufit input for threshold " << confThr.name() );
956 } else if ( confThr.name().find("gXERHO")==0 ) {
957 rhk = & m_iKeyGFexMETRho;
958 ATH_MSG_DEBUG("Using Rho input for threshold " << confThr.name() );
959 } else if ( confThr.name().find("gXEJWOJ")==0 ) {
960 rhk = & m_iKeyGFexMETJwoJ;
961 ATH_MSG_DEBUG("Using JwoJ input for threshold " << confThr.name() );
962 } else {
963 rhk = & m_iKeyGFexMETJwoJ;
964 ATH_MSG_DEBUG("Using default input JwoJ for threshold " << confThr.name() );
965 }
966 if(!rhk->empty()) {
967 auto met = SG::makeHandle( *rhk, context );
968 multiplicity = ( met->energyT()/1000. < confThr.getAttribute<unsigned int>("xe") ) ? 0 : 1; // energyT value is in MeV, cut in GeV
969 }
970 }
971 if(confThr.type() == "TE") {
972 get2DHist( "/multi/te/" + confThr.type() + "Mult" )->Fill(confThr.mapping(), multiplicity);
973 ATH_MSG_DEBUG("TE MULT calculated mult for threshold " << confThr.name() << " : " << multiplicity);
974 } else if(confThr.type() == "XS") {
975 get2DHist( "/multi/xs/" + confThr.type() + "Mult" )->Fill(confThr.mapping(), multiplicity);
976 ATH_MSG_DEBUG("XS MULT calculated mult for threshold " << confThr.name() << " : " << multiplicity);
977 } else {
978 get2DHist( "/multi/xe/" + confThr.type() + "Mult" )->Fill(confThr.mapping(), multiplicity);
979 ATH_MSG_DEBUG("XE MULT calculated mult for threshold " << confThr.name() << " : " << multiplicity);
980 }
981 return multiplicity;
982}
983
984
985unsigned int
986LVL1CTP::CTPSimulation::calculateMuonMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context ) const {
987 if(m_iKeyMuctpi.empty()) {
988 return 0;
989 }
990 unsigned int multiplicity = 0;
991 auto ctpinMuon = SG::makeHandle( m_iKeyMuctpi, context );
992 if ( ctpinMuon.isValid() ) {
993 auto & triggerline = l1menu->connector("MuCTPiOpt0").triggerLine(confThr.name());
994 multiplicity = CTPUtil::getMuonMult( ctpinMuon->muCTPIWord(), triggerline.startbit() + (m_muonRun2Format ? 1 : 0), triggerline.endbit()+ (m_muonRun2Format ? 1 : 0) );
995 }
996 get2DHist( "/multi/muon/" + confThr.type() + "Mult" )->Fill(confThr.mapping(), multiplicity);
997 ATH_MSG_DEBUG("MU MULT calculated mult for threshold " << confThr.name() << " : " << multiplicity);
998 return multiplicity;
999}
1000
1001
1002unsigned int
1003LVL1CTP::CTPSimulation::calculateTopoOptMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context ) const {
1004 if(m_iKeyTopo.empty() || !m_doL1Topo ) {
1005 return 0;
1006 }
1007 unsigned int multiplicity = 0;
1008 auto topoInput = SG::makeHandle( m_iKeyTopo, context );
1009 std::string connector = "";
1010 if (topoInput.isValid()) {
1011 connector = l1menu->connectorNameFromThreshold(confThr.name());
1012 auto & triggerline = l1menu->connector(connector).triggerLine(confThr.name());
1013 std::bitset<128> bits = topoInput->optcableWord(connector);
1014 multiplicity = CTPUtil::getOptMult( bits, triggerline.startbit(), triggerline.endbit() );
1015 }
1016 std::string subfolder = "";
1017 if (confThr.type().find("XE") != std::string::npos) {
1018 subfolder = "xe";
1019 } else if (confThr.type().find("TE") != std::string::npos) {
1020 subfolder = "te";
1021 } else if (confThr.type().find("TAU") != std::string::npos) {
1022 subfolder = "tau";
1023 } else if (confThr.type().find("EM") != std::string::npos) {
1024 subfolder = "em";
1025 } else if (confThr.type().find("jJ") != std::string::npos) {
1026 subfolder = "jet";
1027 } else if (confThr.type().find("jLJ") != std::string::npos) {
1028 subfolder = "jet";
1029 } else if (confThr.type().find("gJ") != std::string::npos) {
1030 subfolder = "jet";
1031 } else if (confThr.type().find("gLJ") != std::string::npos) {
1032 subfolder = "jet";
1033 }
1034 get2DHist( "/multi/" + subfolder + "/" + confThr.type() + "Mult" )->Fill(confThr.mapping(), multiplicity);
1035 ATH_MSG_DEBUG("TOPO OPT input MULT calculated mult for threshold " << confThr.name() << " : " << multiplicity << " received via connector: " << connector);
1036 //ATH_MSG_INFO("TOPO OPT input MULT calculated mult for threshold " << confThr.name() << " : " << multiplicity << " received via connector: " << connector);
1037 return multiplicity;
1038}
1039
1040
1041unsigned int
1042LVL1CTP::CTPSimulation::calculateTopoMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context, bool UseLegacy = false ) const {
1043 unsigned int multiplicity = 0;
1044 if(UseLegacy){
1045 if (m_iKeyLegacyTopo.empty() || !m_doL1TopoLegacy )
1046 {
1047 return 0;
1048 }
1049 multiplicity = 0;
1050 auto topoInput = SG::makeHandle( m_iKeyTopo, context );
1051 if(topoInput.isValid()) {
1052 uint64_t cable = 0;
1053 std::string conn("");
1054 if( l1menu->connector("LegacyTopo0").hasLine(confThr.name()) ) {
1055 conn = "LegacyTopo0";
1056 cable = ( (uint64_t)topoInput->cableWord1( 1 ) << 32) + topoInput->cableWord1( 0 );
1057 } else if( l1menu->connector("LegacyTopo1").hasLine(confThr.name()) ) {
1058 conn = "LegacyTopo1";
1059 cable = ( (uint64_t)topoInput->cableWord2( 1 ) << 32) + topoInput->cableWord2( 0 );
1060 }
1061 if(conn != "") {
1062 auto & triggerline = l1menu->connector(conn).triggerLine(confThr.name());
1063 ATH_MSG_DEBUG( " ---> Topo input " << confThr.name() << " on module " << conn
1064 << ", cable start " << triggerline.startbit() << " and end " << triggerline.endbit()
1065 << " double word 0x" << std::setw(16) << std::setfill('0') << std::hex << cable << std::dec << std::setfill(' ') );
1066 multiplicity = CTPUtil::getMultTopo( cable, triggerline.startbit(), triggerline.endbit(), triggerline.clock() );
1067 }
1068 }
1069 }
1070 else{
1071 if (m_iKeyTopo.empty() || !m_doL1Topo )
1072 {
1073 return 0;
1074 }
1075 multiplicity = 0;
1076 auto topoInput = SG::makeHandle( m_iKeyTopo, context );
1077 if(topoInput.isValid()) {
1078 uint64_t cable = 0;
1079 std::string conn("");
1080 if( l1menu->connector("Topo2El").hasLine(confThr.name()) ) {
1081 conn = "Topo2El";
1082 cable = ( (uint64_t)topoInput->cableWord1( 1 ) << 32) + topoInput->cableWord1( 0 );
1083 } else if( l1menu->connector("Topo3El").hasLine(confThr.name()) ) {
1084 conn = "Topo3El";
1085 cable = ( (uint64_t)topoInput->cableWord2( 1 ) << 32) + topoInput->cableWord2( 0 );
1086 }
1087 if(conn != "") {
1088 auto & triggerline = l1menu->connector(conn).triggerLine(confThr.name());
1089 ATH_MSG_DEBUG( " ---> Topo input " << confThr.name() << " on module " << conn
1090 << ", cable start " << triggerline.startbit() << " and end " << triggerline.endbit()
1091 << " double word 0x" << std::setw(16) << std::setfill('0') << std::hex << cable << std::dec << std::setfill(' ') );
1092 multiplicity = CTPUtil::getMultTopo( cable, triggerline.startbit(), triggerline.endbit(), triggerline.clock() );
1093 }
1094 }
1095 }
1096 return multiplicity;
1097}
1098
1099
1100unsigned int
1101LVL1CTP::CTPSimulation::calculateMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context ) const {
1102 unsigned int multiplicity = 0;
1103 try {
1104 if ( confThr.type() == "EM" ) {
1105 multiplicity = calculateEMMultiplicity( confThr, l1menu, context );
1106 } else if ( confThr.type() == "TAU" ) {
1107 multiplicity = calculateTauMultiplicity( confThr, l1menu, context );
1108 } else if ( confThr.type() == "XE" || confThr.type() == "TE" || confThr.type() == "XS" ) {
1109 multiplicity = calculateMETMultiplicity( confThr, l1menu, context );
1110 } else if ( confThr.type() == "JET" ) {
1111 multiplicity = calculateJetMultiplicity( confThr, l1menu, context );
1112 } else if ( confThr.type() == "MU" ) {
1113 multiplicity = calculateMuonMultiplicity( confThr, l1menu, context );
1114 } else if ( confThr.type() == "R2TOPO") {
1115 multiplicity = calculateTopoMultiplicity( confThr, l1menu, context, true );
1116 } else if ( confThr.type() == "TOPO" ) {
1117 multiplicity = calculateTopoMultiplicity( confThr, l1menu, context, m_doL1TopoLegacy);
1118 } else if ( confThr.type()[0] == 'e' || confThr.type()[0] == 'c' || confThr.type()[0] == 'j' || confThr.type()[0] == 'g' ){
1119 multiplicity = calculateTopoOptMultiplicity( confThr, l1menu, context );
1120 }
1121 }
1122 catch(std::exception & ex) {
1123 ATH_MSG_FATAL("Caught exception when calculating multiplicity for threshold " << confThr.name() << ": " << ex.what());
1124 throw;
1125 }
1126 // all other thresholds are not simulated
1127 return multiplicity;
1128}
1129
1130StatusCode
1131LVL1CTP::CTPSimulation::simulateItems(const std::map<std::string, unsigned int> & thrMultiMap,
1132 const EventContext& context) const
1133{
1134
1135 std::vector<uint32_t> tip;
1136 CHECK( m_resultBuilder->constructTIPVector( thrMultiMap, tip ) );
1137
1138 std::map<std::string, unsigned int> itemDecisionMap;
1139 CLHEP::HepRandomEngine* rndmEngine = m_RNGEngines.getEngine( context );
1140 CHECK( m_resultBuilder->buildItemDecision(thrMultiMap, itemDecisionMap, rndmEngine) );
1141
1142 std::vector<uint32_t> tbp;
1143 std::vector<uint32_t> tap;
1144 std::vector<uint32_t> tav;
1145 unsigned char triggerType(0);
1146 CHECK( m_resultBuilder->constructResultVectors( itemDecisionMap, tbp, tap, tav, triggerType ) );
1147
1148 // Create a fixed vector of 6 extra words to allow for inserting prescale change information
1149 // when running a partition with preloaded data, see ATR-24654
1150 const std::vector<uint32_t> extra(size_t{6}, uint32_t{0});
1151
1152 auto eventID = context.eventID();
1153
1154 // create CTP output format and store in the event
1155 if (m_useEDMxAOD) {
1156 std::pair< std::unique_ptr<xAOD::CTPResult>, std::unique_ptr<xAOD::CTPResultAuxInfo> > ctpResultAuxPair = m_resultBuilder->constructCTPResult( eventID, tbp, tap, tav, tip, extra, triggerType);
1157 std::unique_ptr<xAOD::CTPResult> ctpResult = std::move(ctpResultAuxPair.first);
1158 std::unique_ptr<xAOD::CTPResultAuxInfo> ctpResultAux = std::move(ctpResultAuxPair.second);
1159 auto ctpResultWriteHandle = SG::makeHandle( m_oKeyCTPResult, context );
1160 ATH_CHECK( ctpResultWriteHandle.record( std::move(ctpResult), std::move(ctpResultAux) ));
1161 }
1162 else {
1163 std::unique_ptr<CTP_RDO> rdo = m_resultBuilder->constructRDOResult( eventID, tbp, tap, tav, tip, extra );
1164 auto rdoWriteHandle = SG::makeHandle( m_oKeyRDO, context );
1165 ATH_CHECK( rdoWriteHandle.record( std::move(rdo) ));
1166 }
1167 std::unique_ptr<CTPSLink> roi = m_resultBuilder->constructRoIResult( eventID, tbp, tap, tav, tip, extra, triggerType );
1168 auto sLinkWriteHandle = SG::makeHandle( m_oKeySLink, context );
1169 ATH_CHECK( sLinkWriteHandle.record( std::move(roi) ));
1170
1171 // fill histograms with item simulation results
1172 {
1173 auto tbpById = *get1DHist( "/output/tbpById" );
1174 auto tapById = *get1DHist( "/output/tapById" );
1175 auto tavById = *get1DHist( "/output/tavById" );
1176 for( unsigned int ctpId= 0; ctpId < 512; ++ctpId ) {
1177 unsigned int wordNr = ctpId / 32;
1178 unsigned int posWithinWord = ctpId % 32;
1179 auto mask = 1L << posWithinWord;
1180 if( 0 != (tbp[wordNr] & mask) ) {
1181 tbpById->Fill( ctpId );
1182 }
1183 if( 0 != (tap[wordNr] & mask) ) {
1184 tapById->Fill( ctpId );
1185 }
1186 if( 0 != (tav[wordNr] & mask) ) {
1187 tavById->Fill( ctpId );
1188 }
1189 }
1190 }
1191 return StatusCode::SUCCESS;
1192}
1193
1194
1195StatusCode
1197
1198 const TrigConf::L1Menu * l1menu = nullptr;
1199 ATH_CHECK( detStore()->retrieve(l1menu) );
1200
1201 constexpr unsigned int sizeOfCTPOutput = 512;
1202
1203 unsigned int tbp[sizeOfCTPOutput];
1204 unsigned int tap[sizeOfCTPOutput];
1205 unsigned int tav[sizeOfCTPOutput];
1206 {
1207 auto h = *get1DHist( "/output/tbpById" );
1208 for( unsigned int id = 0; id < sizeOfCTPOutput; ++id ) tbp[id] = h->GetBinContent(id+1);
1209 }
1210 {
1211 auto h = *get1DHist( "/output/tapById" );
1212 for( unsigned int id = 0; id < sizeOfCTPOutput; ++id ) tap[id] = h->GetBinContent(id+1);
1213 }
1214 {
1215 auto h = *get1DHist( "/output/tavById" );
1216 for( unsigned int id = 0; id < sizeOfCTPOutput; ++id ) tav[id] = h->GetBinContent(id+1);
1217 }
1218
1219 // fill the byName TAV histograms from the byID ones
1220 {
1221 auto htbp = *get1DHist( "/output/tbpByName" );
1222 auto htap = *get1DHist( "/output/tapByName" );
1223 auto htav = *get1DHist( "/output/tavByName" );
1224 for( auto & item : *l1menu ) {
1225 unsigned int ctpId = item.ctpId();
1226 htbp->Fill( item.name().c_str(), tbp[ctpId]);
1227 htap->Fill( item.name().c_str(), tap[ctpId]);
1228 htav->Fill( item.name().c_str(), tav[ctpId]);
1229 }
1230 htbp->Sumw2(0);
1231 htap->Sumw2(0);
1232 htav->Sumw2(0);
1233 htbp->LabelsDeflate();
1234 htap->LabelsDeflate();
1235 htav->LabelsDeflate();
1236
1237 }
1238
1239 // fill the threshold summary hists
1240 {
1241 // run 2 thresholds (legacy + muon)
1242 std::vector<std::string> thrHists{ "em/EM", "muon/MU", "tau/TAU", "jet/JET", "xe/XE", "te/TE", "xs/XS" };
1243 auto hist = * get2DHist( "/multi/all/LegacyMult" );
1244 for(const std::string & histpath : thrHists) {
1245 auto h = * get2DHist( "/multi/" + histpath + "Mult" );
1246 auto xaxis = h->GetXaxis();
1247 size_t xsize = xaxis->GetNbins();
1248 size_t ysize = h->GetNbinsY();
1249 for(size_t x = 1; x<xsize; x++) {
1250 std::string s("");
1251 for(size_t y = 1; y<=ysize; y++) {
1252 size_t binContent = h->GetBinContent(x,y);
1253 hist->Fill(xaxis->GetBinLabel(x),y-1,binContent);
1254 s += std::to_string(binContent) + " ";
1255 }
1256 ATH_MSG_DEBUG( "REGTEST CTPSim " << xaxis->GetBinLabel(x) << " MULT " << s);
1257 }
1258 }
1259 hist->Sumw2(0);
1260 hist->LabelsDeflate();
1261 }
1262 {
1263 // run 3 thresholds
1264 auto hist = * get2DHist( "/multi/all/R3Mult" );
1265 std::vector<std::string> thrHists = { "em/eEM", "em/jEM", "muon/MU", "tau/eTAU", "tau/jTAU", "tau/cTAU", "jet/jJ", "jet/jLJ", "jet/gJ", "jet/gLJ", "xe/gXE", "xe/jXE", "te/jTE", "te/gTE" };
1266 for(const std::string & histpath : thrHists) {
1267 auto h = * get2DHist( "/multi/" + histpath + "Mult" );
1268 auto xaxis = h->GetXaxis();
1269 size_t xsize = xaxis->GetNbins();
1270 size_t ysize = h->GetNbinsY();
1271 for(size_t x = 1; x<=xsize; x++) {
1272 std::string s("");
1273 for(size_t y = 1; y<=ysize; y++) {
1274 size_t binContent = h->GetBinContent(x,y);
1275 hist->Fill(xaxis->GetBinLabel(x) ,y-1, binContent);
1276 s += std::to_string(binContent) + " ";
1277 }
1278 ATH_MSG_DEBUG( "REGTEST CTPSim " << xaxis->GetBinLabel(x) << " MULT " << s);
1279 }
1280 }
1281 hist->Sumw2(0);
1282 hist->LabelsDeflate();
1283 }
1284
1285 if ( msgLvl(MSG::DEBUG) ) {
1286 for( auto & item : *l1menu ) {
1287 ATH_MSG_DEBUG( "REGTEST CTPSim " << item.name() << " " << item.ctpId() <<
1288 " TBP " << tbp[item.ctpId()] <<
1289 " TAP " << tap[item.ctpId()] <<
1290 " TAV " << tav[item.ctpId()]);
1291 }
1292 }
1293 return StatusCode::SUCCESS;
1294}
1295
1296/*
1297 stores metadata for all histograms to provide merging information
1298 adapted from @c HistogramFiller/OfflineHistogramProvider.h
1299*/
1300StatusCode
1302 std::vector<std::string> storedPaths;
1303 for( auto & entry : m_hist1D ) {
1304 storedPaths.push_back( getBaseHistPath() + entry.first);
1305 }
1306 for( auto & entry : m_hist2D ) {
1307 storedPaths.push_back( getBaseHistPath() + entry.first);
1308 }
1309 std::scoped_lock<std::mutex> metadataLock(s_metadataMutex);
1310 for (const auto & path : storedPaths) {
1311 size_t pos = path.find_last_of('/');
1312 auto splitPath = std::make_pair(path.substr(0, pos), path.substr(pos + 1));
1313 std::string treePath = splitPath.first + "/metadata";
1314 std::string interval("run");
1315 char triggerData[] = "<none>";
1316 const std::string mergeDataStr = "<default>";
1317 std::vector<char> mergeData{mergeDataStr.begin(), mergeDataStr.end()};
1318 mergeData.push_back('\0');
1319 interval = "run";
1320 if (!m_histSvc->existsTree(treePath)) {
1321 auto tree = std::make_unique<TTree>("metadata", "Monitoring Metadata");
1322 tree->SetDirectory(nullptr);
1323 tree->Branch("Name", &(splitPath.second[0]), "Name/C");
1324 tree->Branch("Interval", &(interval[0]), "Interval/C");
1325 tree->Branch("TriggerChain", triggerData, "TriggerChain/C");
1326 tree->Branch("MergeMethod", mergeData.data(), "MergeMethod/C");
1327 tree->Fill();
1328 if (!m_histSvc->regTree(treePath, std::move(tree))) {
1329 MsgStream log(Athena::getMessageSvc(), "OfflineHistogramProvider");
1330 log << MSG::ERROR
1331 << "Failed to register DQ metadata TTree " << treePath << endmsg;
1332 }
1333 } else {
1334 TTree *tree{nullptr};
1335 if (m_histSvc->getTree(treePath, tree).isSuccess()) {
1336 tree->SetBranchAddress("Name", &(splitPath.second[0]));
1337 tree->SetBranchAddress("Interval", &(interval[0]));
1338 tree->SetBranchAddress("TriggerChain", triggerData);
1339 tree->SetBranchAddress("MergeMethod", mergeData.data());
1340 tree->Fill();
1341 } else {
1342 MsgStream log(Athena::getMessageSvc(), "OfflineHistogramProvider");
1343 log << MSG::ERROR
1344 << "Failed to retrieve DQ metadata TTree " << treePath << " which is reported to exist" << endmsg;
1345 }
1346 }
1347 }
1348 return StatusCode::SUCCESS;
1349}
Scalar eta() const
pseudorapidity method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Maintain a set of objects, one per slot.
const std::function< CLHEP::HepRandomEngine *(void) > CTPSimRanluxFactory
#define CHECK(...)
Evaluate an expression and check for errors.
unsigned int uint
static Double_t sc
#define y
#define x
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
unsigned int calculateJetMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
Gaudi::Property< std::string > m_histPath
SG::ReadHandleKey< xAOD::EnergySumRoI > m_iKeyGFexMETRho
SG::ReadHandleKey< xAOD::JetRoIContainer > m_iKeyJFexLJets
virtual StatusCode stop() override
StatusCode fillInputHistograms(const EventContext &context) const
Gaudi::Property< bool > m_forceBunchGroupPattern
unsigned int calculateTopoMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context, bool UseLegacy) const
Gaudi::Property< bool > m_doL1TopoLegacy
SG::ReadHandleKey< xAOD::JetRoIContainer > m_iKeyJFexJets
Gaudi::Property< bool > m_doL1Topo
unsigned int calculateTopoOptMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
unsigned int calculateTauMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
SG::ReadHandleKey< LVL1::FrontPanelCTP > m_iKeyTopo
SG::ReadHandleKey< LVL1::FrontPanelCTP > m_iKeyLegacyTopo
SG::ReadHandleKey< LVL1::EmTauCTP > m_iKeyCtpinEM
unsigned int calculateMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
SG::WriteHandleKey< xAOD::CTPResult > m_oKeyCTPResult
virtual StatusCode start() override
StatusCode setHistLabels(const TrigConf::L1Menu &l1menu)
LockedHandle< TH2 > & get2DHist(const std::string &histName) const
LockedHandle< TH1 > & get1DHist(const std::string &histName) const
StatusCode simulateItems(const std::map< std::string, unsigned int > &thrMultiMap, const EventContext &context) const
SG::ReadHandleKey< LVL1::EnergyCTP > m_iKeyCtpinXE
unsigned int calculateMETMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
unsigned int calculateEMMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
virtual StatusCode initialize() override
unsigned int calculateMuonMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
SG::WriteHandleKey< CTP_RDO > m_oKeyRDO
std::map< std::string, LockedHandle< TH2 > > m_hist2D
std::map< std::string, LockedHandle< TH1 > > m_hist1D
SG::ReadHandleKey< LVL1::TrtCTP > m_iKeyTRT
SG::ReadHandleKey< xAOD::EnergySumRoI > m_iKeyGFexMETNC
StatusCode setMultiplicityHistLabels(const TrigConf::L1Menu &l1menu, const std::string &type)
Gaudi::Property< bool > m_useEDMxAOD
SG::ReadHandleKey< xAOD::EmTauRoIContainer > m_iKeyEFexTau
virtual StatusCode execute(const EventContext &context) const override
SG::ReadCondHandleKey< TrigConf::L1BunchGroupSet > m_bgKey
SG::ReadHandleKey< xAOD::TrigEMClusterContainer > m_iKeyEFexCluster
ATHRNG::RNGWrapper m_RNGEngines
Gaudi::Property< bool > m_muonRun2Format
ServiceHandle< ITHistSvc > m_histSvc
Gaudi::Property< unsigned int > m_bunchGroupPattern
SG::ReadHandleKey< xAOD::JetRoIContainer > m_iKeyGFexJets
Gaudi::Property< bool > m_doL1CaloLegacy
SG::ReadHandleKey< xAOD::EnergySumRoI > m_iKeyGFexMETJwoJ
SG::WriteHandleKey< CTPSLink > m_oKeySLink
StatusCode hbook(const std::string &path, std::unique_ptr< TH1 > hist)
std::string getBaseHistPath() const
SG::ReadHandleKey< LVL1::MuCTPICTP > m_iKeyMuctpi
SG::ReadHandleKey< LVL1::ZdcCTP > m_iKeyZDC
Gaudi::Property< bool > m_doTRT
Gaudi::Property< bool > m_isData
SG::ReadHandleKey< LVL1::JetCTP > m_iKeyCtpinJet
ToolHandle< LVL1CTP::ResultBuilder > m_resultBuilder
CTPSimulation(const std::string &name, ISvcLocator *pSvcLocator)
StatusCode createMultiplicityHist(const std::string &type, unsigned int maxMult=10)
StatusCode extractMultiplicities(std::map< std::string, unsigned int > &thrMultiMap, const EventContext &context) const
Gaudi::Property< bool > m_doZDC
static unsigned int getMultTopo(uint64_t word, unsigned int startbit, unsigned int endbit, unsigned int clock)
extract multiplicities from Topo words, were the encoding is different
Definition CTPUtil.cxx:83
static int getOptMult(std::bitset< 128 > bits, unsigned int startbit, unsigned int endbit)
Definition CTPUtil.cxx:77
static int getMult(uint64_t word, unsigned int startbit, unsigned int endbit)
extract multiplicities using new trigger configuration interface
Definition CTPUtil.cxx:64
static int getMuonMult(unsigned int word, int threshold)
get Muon multiplicty in legacy mode
Definition CTPUtil.cxx:22
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
Property holding a SG store/key/clid from which a ReadHandle is made.
bool empty() const
Test if the key is blank.
virtual const std::string & name() const final
const ptree & data() const
Access to the underlying data, if needed.
T getAttribute(const std::string &key, bool ignoreIfMissing=false, const T &def=T()) const
Access to simple attribute.
L1 board configuration.
constexpr std::size_t maxNBunchGroups() const
Maximum number of bunchgroups.
const std::shared_ptr< L1BunchGroup > & getBunchGroup(const std::string &name) const
Accessor to the bunchgroup by name.
L1 threshold configuration.
Definition L1Item.h:18
L1 menu configuration.
Definition L1Menu.h:28
Standard L1 threshold configuration.
virtual float thrValue(int eta=0) const
Accessor to the threshold value for eta-dependent threholds.
unsigned int mapping() const
Accessor to the mapping number The mapping is unique within a type.
const std::string & type() const
Accessor to the threshold type.
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
IMessageSvc * getMessageSvc(bool quiet=false)
static const std::string DEFAULT_RDOOutputLocation_Rerun
location of CTP RDO output in StoreGate for simulation rerun on data
static const std::string DEFAULT_CTPResultOutputLocation_Rerun
location of CTPResult output in StoreGate for simulation rerun on data
static const std::string DEFAULT_CTPSLinkLocation_Rerun
default StoreGate location for CTPSLink for simulation rerun on data
Forward declaration.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Forward iterator to traverse the main components of the trigger configuration.
Definition Config.h:22
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
TChain * tree