ATLAS Offline Software
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
11 #include "xAODTrigger/CTPResult.h"
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 
30 namespace {
31  static std::mutex s_metadataMutex;
32 }
33 
34 
35 using namespace TrigConf;
36 
37 const std::function< CLHEP::HepRandomEngine*(void) > CTPSimRanluxFactory = [](void)->CLHEP::HepRandomEngine*{
38  return new CLHEP::Ranlux64Engine();
39 };
40 
41 
42 LVL1CTP::CTPSimulation::CTPSimulation( const std::string& name, ISvcLocator* pSvcLocator ) :
43  AthReentrantAlgorithm ( name, pSvcLocator ),
44  m_RNGEngines( CTPSimRanluxFactory, SG::getNSlots() )
45 {}
46 
48 {}
49 
52 
53  ATH_MSG_DEBUG("initialize");
54  if(m_forceBunchGroupPattern) {
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){
62  CHECK( m_oKeyCTPResult.assign(LVL1CTP::DEFAULT_CTPResultOutputLocation_Rerun) );
63  } else {
64  CHECK( m_oKeyRDO.assign(LVL1CTP::DEFAULT_RDOOutputLocation_Rerun) );
65  }
66  CHECK( m_oKeySLink.assign(LVL1CTP::DEFAULT_CTPSLinkLocation_Rerun) );
67  }
68  ATH_CHECK( m_bgKey.initialize( !m_forceBunchGroupPattern ) );
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
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_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 
113 
114  const TrigConf::L1Menu * l1menu = nullptr;
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 
127 LVL1CTP::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 
143 LVL1CTP::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 
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 
198 std::string
200  std::string baseHistPath( m_histPath );
201  if(baseHistPath.back()!='/') baseHistPath += "/";
202  baseHistPath += name();
203  return baseHistPath;
204 }
205 
207 LVL1CTP::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 
231 LVL1CTP::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 
254 LockedHandle<TH1> &
255 LVL1CTP::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 
265 LockedHandle<TH2> &
266 LVL1CTP::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 
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 
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" ) );
386  ATH_CHECK ( createMultiplicityHist( "jet" ) );
387  ATH_CHECK ( createMultiplicityHist( "xe", 2) );
388  ATH_CHECK ( createMultiplicityHist( "te", 2) );
389  ATH_CHECK ( createMultiplicityHist( "xs", 2) );
390  ATH_CHECK ( createMultiplicityHist( "em" ) );
391  ATH_CHECK ( createMultiplicityHist( "tau" ) );
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 
417  ATH_CHECK(storeMetadata());
418 
419  return StatusCode::SUCCESS;
420 }
421 
423 LVL1CTP::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 
622 LVL1CTP::CTPSimulation::extractMultiplicities(std::map<std::string, unsigned int> & thrMultiMap, const EventContext& context) const {
623 
624  const TrigConf::L1Menu * l1menu = nullptr;
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
639  if (m_iKeyLegacyTopo.empty() || !m_doL1CaloLegacy || !m_doL1TopoLegacy )
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();
799  if( m_forceBunchGroupPattern ) {
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
808  SG::ReadCondHandle<TrigConf::L1BunchGroupSet> bgkey(m_bgKey, context);
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 
835 unsigned int
836 LVL1CTP::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 
858 unsigned int
859 LVL1CTP::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 
895 unsigned int
896 LVL1CTP::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 
933 unsigned int
934 LVL1CTP::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 
985 unsigned int
986 LVL1CTP::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 
1002 unsigned int
1003 LVL1CTP::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 
1041 unsigned int
1042 LVL1CTP::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 
1100 unsigned int
1101 LVL1CTP::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 
1130 StatusCode
1131 LVL1CTP::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 
1195 StatusCode
1197 
1198  const TrigConf::L1Menu * l1menu = nullptr;
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 */
1300 StatusCode
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 }
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:215
TileDCSDataPlotter.h0
h0
Definition: TileDCSDataPlotter.py:875
DiTauMassTools::TauTypes::lh
@ lh
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:53
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
checkCorrelInHIST.conn
conn
Definition: checkCorrelInHIST.py:25
CTPResult.h
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
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:241
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:622
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
RoIBResult.h
dqt_zlumi_pandas.hname
string hname
Definition: dqt_zlumi_pandas.py:280
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
JetEnergyRoI.h
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
HistogramDef.h
plotmaker.hist
hist
Definition: plotmaker.py:148
tree
TChain * tree
Definition: tile_monitor.h:30
SG::ReadCondHandle::isValid
bool isValid()
Definition: ReadCondHandle.h:210
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:143
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:55
LVL1CTP::CTPSimulation::calculateEMMultiplicity
unsigned int calculateEMMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
Definition: CTPSimulation.cxx:859
TrigInDetValidation_Base.test
test
Definition: TrigInDetValidation_Base.py:142
LVL1CTP::CTPSimulation::setMultiplicityHistLabels
StatusCode setMultiplicityHistLabels(const TrigConf::L1Menu &l1menu, const std::string &type)
Definition: CTPSimulation.cxx:167
LVL1CTP::CTPSimulation::calculateTauMultiplicity
unsigned int calculateTauMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
Definition: CTPSimulation.cxx:896
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
x
#define x
xAOD::tap
setBGCode tap
Definition: TrigDecision_v1.cxx:43
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
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:266
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:459
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:274
LVL1CTP::CTPSimulation::getBaseHistPath
std::string getBaseHistPath() const
Definition: CTPSimulation.cxx:199
TrigConf
Forward iterator to traverse the main components of the trigger configuration.
Definition: Config.h:22
PyPoolBrowser.item
item
Definition: PyPoolBrowser.py:129
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
IBLCalibrationConfig.thr
thr
Definition: IBLCalibrationConfig.py:39
met
Definition: IMETSignificance.h:24
CTPSimRanluxFactory
const std::function< CLHEP::HepRandomEngine *(void) > CTPSimRanluxFactory
Definition: CTPSimulation.cxx:37
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:207
LVL1CTP::CTPSimulation::calculateTopoMultiplicity
unsigned int calculateTopoMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context, bool UseLegacy) const
Definition: CTPSimulation.cxx:1042
LVL1CTP::CTPSimulation::storeMetadata
StatusCode storeMetadata()
Definition: CTPSimulation.cxx:1301
LVL1CTP::CTPSimulation::calculateMETMultiplicity
unsigned int calculateMETMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
Definition: CTPSimulation.cxx:934
IDTPM::eT
float eT(const U &p)
Accessor utility function for getting the value of Tranverse energy.
Definition: TrackParametersHelper.h:122
LVL1CTP::CTPSimulation::calculateJetMultiplicity
unsigned int calculateJetMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
Definition: CTPSimulation.cxx:836
lumiFormat.i
int i
Definition: lumiFormat.py:85
h
CTPResultAuxInfo.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:255
extractSporadic.h
list h
Definition: extractSporadic.py:96
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
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:1003
calibdata.exception
exception
Definition: calibdata.py:495
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:337
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:521
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:1131
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:239
LVL1CTP::CTPSimulation::setHistLabels
StatusCode setHistLabels(const TrigConf::L1Menu &l1menu)
Definition: CTPSimulation.cxx:277
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
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:47
LVL1CTP::CTPSimulation::calculateMuonMultiplicity
unsigned int calculateMuonMultiplicity(const TrigConf::L1Threshold &confThr, const TrigConf::L1Menu *l1menu, const EventContext &context) const
Definition: CTPSimulation.cxx:986
LVL1CTP::CTPSimulation::stop
virtual StatusCode stop() override
Definition: CTPSimulation.cxx:1196
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
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
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
LVL1CTP::CTPSimulation::start
virtual StatusCode start() override
Definition: CTPSimulation.cxx:112
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:1101
python.XMLReader.l1menu
l1menu
Definition: XMLReader.py:73
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
RunTileMonitoring.triggerType
triggerType
Definition: RunTileMonitoring.py:162
LVL1CTP::CTPSimulation::fillInputHistograms
StatusCode fillInputHistograms(const EventContext &context) const
Definition: CTPSimulation.cxx:423
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:42
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:25
LVL1CTP::CTPSimulation::execute
virtual StatusCode execute(const EventContext &context) const override
Definition: CTPSimulation.cxx:127
TrigConf::L1Threshold
Standard L1 threshold configuration.
Definition: L1ThresholdBase.h:125
CTPTriggerThreshold.h
python.SystemOfUnits.L
float L
Definition: SystemOfUnits.py:92
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
LVL1CTP::CTPSimulation::initialize
virtual StatusCode initialize() override
Definition: CTPSimulation.cxx:51