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