ATLAS Offline Software
xAODDigest.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 
4 from __future__ import print_function
5 import sys
6 import os
7 import ROOT
8 import argparse
9 
10 
11 def safeRetrieve(evt, typ, key):
12  if evt.contains(typ, key):
13  return evt.retrieve(typ, key)
14  print(f'WARNING: Cannot find object {typ}/{key}')
15  return []
16 
17 
18 def xAODDigest(evt, counter=False, extravars=False):
19  result = list()
20 
21  for i in range(0, evt.getEntries()):
22  if (counter and (i % 100) == 0):
23  print("Processing event %s" % i)
24 
25  evt.getEntry(i)
26  ei = evt.retrieve("xAOD::EventInfo", "EventInfo")
27  runnbr = ei.runNumber()
28  evtnbr = ei.eventNumber()
29 
30  clusters = safeRetrieve(
31  evt, "xAOD::CaloClusterContainer", "CaloCalTopoClusters")
32  nclus = len(clusters)
33 
34  idTracks = safeRetrieve(evt,
35  "xAOD::TrackParticleContainer", "InDetTrackParticles")
36  nIdTracks = len(idTracks)
37 
38  tautracks = safeRetrieve(evt, "xAOD::TauTrackContainer", "TauTracks")
39  nTauTracks = len(tautracks)
40  taus = safeRetrieve(evt, "xAOD::TauJetContainer", "TauJets")
41  nTaus = len(taus)
42  if taus:
43  tau1pt = taus[0].pt()
44  tau1eta = taus[0].eta()
45  tau1phi = taus[0].phi()
46  else:
47  tau1pt = tau1eta = tau1phi = 0
48 
49  muons = safeRetrieve(evt, "xAOD::MuonContainer", "Muons")
50  nMuons = len(muons)
51  if muons:
52  muon1pt = muons[0].pt()
53  muon1eta = muons[0].eta()
54  muon1phi = muons[0].phi()
55  else:
56  muon1pt = muon1eta = muon1phi = 0
57 
58  electrons = safeRetrieve(evt, "xAOD::ElectronContainer", "Electrons")
59  nElec = len(electrons)
60  if electrons:
61  elec1pt = electrons[0].pt()
62  elec1eta = electrons[0].eta()
63  elec1phi = electrons[0].phi()
64  else:
65  elec1pt = elec1eta = elec1phi = 0
66 
67  photons = safeRetrieve(evt, "xAOD::PhotonContainer", "Photons")
68  nPhot = len(photons)
69  if photons:
70  phot1pt = photons[0].pt()
71  phot1eta = photons[0].eta()
72  phot1phi = photons[0].phi()
73  else:
74  phot1pt = phot1eta = phot1phi = 0
75 
76  if extravars:
77  jets = safeRetrieve(evt,"xAOD::JetContainer", "AntiKt4EMPFlowJets")
78  nJet = len(jets)
79  if jets:
80  jet1pt = jets[0].pt()
81  jet1eta = jets[0].eta()
82  jet1phi = jets[0].phi()
83  else:
84  jet1pt = jet1eta = jet1phi = 0
85 
86  met = safeRetrieve(evt,"xAOD::MissingETContainer", "MET_Reference_AntiKt4EMPFlow")
87  nmet = len(met)
88  if met:
89  metx = met[nmet-1].mpx()
90  mety = met[nmet-1].mpy()
91  sumet = met[nmet-1].sumet()
92  else:
93  metx = mety = sumet = 0
94 
95  nTrueElectrons = 0
96  nTruePhotons = 0
97  acc = ROOT.SG.ConstAccessor(
98  'ElementLink< xAOD::TruthParticleContainer>')('truthParticleLink')
99 
100  if nElec > 0 and acc.isAvailable(electrons.at(0)):
101  for i in range(nElec):
102  truthLink = acc(electrons.at(i))
103  if(truthLink.isValid()):
104  pdgId = truthLink.pdgId()
105  if abs(pdgId) == 11:
106  nTrueElectrons += 1
107 
108  if nPhot > 0 and acc.isAvailable(photons.at(0)):
109  for i in range(nPhot):
110  truthLink = acc(photons.at(i))
111  if(truthLink.isValid()):
112  pdgId = truthLink.pdgId()
113  if (pdgId == 22):
114  nTruePhotons += 1
115 
116  nFakeElectrons = nElec - nTrueElectrons
117  nFakePhotons = nPhot - nTruePhotons
118 
119  if extravars:
120  result.append((runnbr, evtnbr, nclus, nIdTracks,
121  nTauTracks, nTaus, tau1pt, tau1eta, tau1phi,
122  nMuons, muon1pt, muon1eta, muon1phi,
123  nElec, elec1pt, elec1eta, elec1phi, nTrueElectrons, nFakeElectrons,
124  nPhot, phot1pt, phot1eta, phot1phi ,nTruePhotons, nFakePhotons,
125  nJet, jet1pt, jet1eta, jet1phi, nmet, metx, mety, sumet))
126  else:
127  result.append((runnbr, evtnbr, nclus, nIdTracks, nTauTracks, nTaus, nMuons,
128  nElec, nTrueElectrons, nFakeElectrons,
129  nPhot, nTruePhotons, nFakePhotons))
130 
131  pass
132 
133  # Sort by run/event number
134  result.sort(key=lambda er: er[0] << 32 | er[1])
135  return result
136 
137 
138 def main():
139  parser = argparse.ArgumentParser(
140  description="Extracts a few basic quantities from the xAOD file and dumps them into a text file")
141  parser.add_argument("xAODFile", nargs='?', type=str,
142  help="xAOD filename", action="store")
143  parser.add_argument("outfilename", nargs='?',
144  help="output text file for results", action="store", default=None)
145  parser.add_argument(
146  "--outputfilename", help="output text file for results", action="store", default=None)
147  parser.add_argument("--extravars", help="Extract extra variables: pt/eta/phi",
148  action="store_true", default=False)
149  parser.add_argument("--counter", help="Print event counter mod 100",
150  action="store_true", default=False)
151  parser.add_argument("--inputlist", help="Optional list of xAOD file instead of xAODFile parameter",
152  nargs='+', action="store", default=False)
153  parser.add_argument("--inputisESD", help="Set if input is ESD",
154  action="store_true", default=False)
155 
156  args = parser.parse_args()
157 
158  if len(sys.argv) < 2:
159  parser.print_help()
160  sys.exit(1)
161 
162  # Check input file existance
163  if not args.inputlist and not os.access(args.xAODFile, os.R_OK):
164  print("ERROR, can't access file {}".format(args.xAODFile))
165  sys.exit(1)
166 
167  # Check output file ...
168  outfilename = ''
169  if args.outfilename:
170  outfilename = args.outfilename
171  elif args.outputfilename:
172  outfilename = args.outputfilename
173 
174  if outfilename:
175  print("Writing to file ", outfilename)
176 
177  # Create TChain or single inputfile
178  if args.inputlist:
179  filelist = ROOT.TChain()
180  for filename in args.inputlist:
181  filelist.AddFile(filename)
182  else:
183  filelist = args.xAODFile
184 
185  # Setup TEvent object and add inputs
186  evt = ROOT.POOL.TEvent(
187  ROOT.POOL.TEvent.kPOOLAccess if args.inputisESD else ROOT.POOL.TEvent.kClassAccess)
188  stat = evt.readFrom(filelist)
189  if not stat:
190  print("ERROR, failed to open file {} with POOL.TEvent".format(
191  args.xAODFile))
192  sys.exit(1)
193  pass
194 
195  digest = xAODDigest(evt, args.counter, args.extravars)
196 
197  if outfilename:
198  outstr = open(outfilename, "w")
199  else:
200  outstr = sys.stdout
201 
202  if args.extravars:
203  header = ("run", "event", "nTopo", "nIdTracks",
204  "nTauTracks", "nTaus", "tau1pt", "tau1eta", "tau1phi",
205  "nMuons", "muon1pt", "muon1eta", "muon1phi",
206  "nElec", "elec1pt", "elec1eta", "elec1phi", "nTrueElec", "nFakeElec",
207  "nPhot", "phot1pt", "phot1eta", "phot1phi", "nTruePhot", "nFakePhot",
208  "nJet", "jet1pt", "jet1eta", "jet1phi", "nmet", "metx", "mety", "sumet" )
209  row_format_header = "{:>20}" * len(header)
210  row_format_header += os.linesep
211  row_format_data = "{:d} {:d} " + "{:20.4f}" * (len(header)-2)
212  row_format_data += os.linesep
213  else:
214  header = ("run", "event", "nTopo", "nIdTracks", "nTauTracks", "nTaus", "nMuons",
215  "nElec", "nTrueElec", "nFakeElec",
216  "nPhot", "nTruePhot", "nFakePhot")
217  row_format_header = "{:>12}" * len(header)
218  row_format_header += os.linesep
219  row_format_data = "{:>12}" * len(header)
220  row_format_data += os.linesep
221 
222  outstr.write(row_format_header.format(*header))
223  for evt in digest:
224  outstr.write(row_format_data.format(*evt))
225 
226  if outfilename:
227  outstr.close()
228 
229  return 0
230 
231 
232 if __name__ == "__main__":
233 
234  main()
vtune_athena.format
format
Definition: vtune_athena.py:14
python.xAODDigest.xAODDigest
def xAODDigest(evt, counter=False, extravars=False)
Definition: xAODDigest.py:18
python.xAODDigest.safeRetrieve
def safeRetrieve(evt, typ, key)
Definition: xAODDigest.py:11
property_tree
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
AthenaPoolTestRead.acc
acc
Definition: AthenaPoolTestRead.py:16
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:25
python.xAODDigest.main
def main()
Definition: xAODDigest.py:138
Trk::open
@ open
Definition: BinningType.h:40
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567