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