CMS 3D CMS Logo

haddnano.py
Go to the documentation of this file.
1 #!/bin/env python3
2 import ROOT
3 import numpy
4 import sys
5 
6 if len(sys.argv) < 3:
7  print("Syntax: haddnano.py out.root input1.root input2.root ...")
8 ofname = sys.argv[1]
9 files = sys.argv[2:]
10 
11 
12 def zeroFill(tree, brName, brObj, allowNonBool=False):
13  # typename: (numpy type code, root type code)
14  branch_type_dict = {'Bool_t': ('?', 'O'), 'Float_t': ('f4', 'F'), 'UInt_t': (
15  'u4', 'i'), 'Long64_t': ('i8', 'L'), 'Double_t': ('f8', 'D')}
16  brType = brObj.GetLeaf(brName).GetTypeName()
17  if (not allowNonBool) and (brType != "Bool_t"):
18  print(("Did not expect to back fill non-boolean branches", tree, brName, brObj.GetLeaf(br).GetTypeName()))
19  else:
20  if brType not in branch_type_dict:
21  raise RuntimeError('Impossible to backfill branch of type %s' % brType)
22  buff = numpy.zeros(1, dtype=numpy.dtype(branch_type_dict[brType][0]))
23  b = tree.Branch(brName, buff, brName + "/" +
24  branch_type_dict[brType][1])
25  # be sure we do not trigger flushing
26  b.SetBasketSize(tree.GetEntries() * 2)
27  for x in range(0, tree.GetEntries()):
28  b.Fill()
29  b.ResetAddress()
30 
31 
32 fileHandles = []
33 goFast = True
34 for fn in files:
35  print("Adding file", str(fn))
36  fileHandles.append(ROOT.TFile.Open(fn))
37  if fileHandles[-1].GetCompressionSettings() != fileHandles[0].GetCompressionSettings():
38  goFast = False
39  print("Disabling fast merging as inputs have different compressions")
40 of = ROOT.TFile(ofname, "recreate")
41 if goFast:
42  of.SetCompressionSettings(fileHandles[0].GetCompressionSettings())
43 of.cd()
44 
45 for e in fileHandles[0].GetListOfKeys():
46  name = e.GetName()
47  print("Merging", str(name))
48  obj = e.ReadObj()
49  cl = ROOT.TClass.GetClass(e.GetClassName())
50  inputs = ROOT.TList()
51  isTree = obj.IsA().InheritsFrom(ROOT.TTree.Class())
52  if isTree:
53  obj = obj.CloneTree(-1, "fast" if goFast else "")
54  branchNames = set([x.GetName() for x in obj.GetListOfBranches()])
55  for fh in fileHandles[1:]:
56  if isTree and obj.GetName() == 'Events' and obj.GetEntries() == 0 :
57  # Zero-events first file. Skip to avoid messing up branches.
58  print(" 'Events' tree contsins no events; skipping")
59  obj = fh.GetListOfKeys().FindObject(name).ReadObj()
60  obj = obj.CloneTree(-1, "fast" if goFast else "")
61  branchNames = set([x.GetName() for x in obj.GetListOfBranches()])
62  continue
63  otherObj = fh.GetListOfKeys().FindObject(name).ReadObj()
64  if isTree and obj.GetName() == 'Events' and otherObj.GetEntries() == 0 :
65  # Zero-events file; skip
66  print(" 'Events' tree contains no events; skipping")
67  continue
68  inputs.Add(otherObj)
69  if isTree and obj.GetName() == 'Events':
70  otherObj.SetAutoFlush(0)
71  otherBranches = set([x.GetName()
72  for x in otherObj.GetListOfBranches()])
73  missingBranches = list(branchNames - otherBranches)
74  additionalBranches = list(otherBranches - branchNames)
75  print("missing: " + str(missingBranches) + "\n Additional: " + str(additionalBranches))
76  for br in missingBranches:
77  # fill "Other"
78  zeroFill(otherObj, br, obj.GetListOfBranches().FindObject(br))
79  for br in additionalBranches:
80  # fill main
81  branchNames.add(br)
82  zeroFill(obj, br, otherObj.GetListOfBranches().FindObject(br))
83  # merge immediately for trees
84  if isTree and obj.GetName() == 'Runs':
85  otherObj.SetAutoFlush(0)
86  otherBranches = set([x.GetName()
87  for x in otherObj.GetListOfBranches()])
88  missingBranches = list(branchNames - otherBranches)
89  additionalBranches = list(otherBranches - branchNames)
90  print("missing: " + str(missingBranches) + "\n Additional: " + str(additionalBranches))
91  for br in missingBranches:
92  # fill "Other"
93  zeroFill(otherObj, br, obj.GetListOfBranches(
94  ).FindObject(br), allowNonBool=True)
95  for br in additionalBranches:
96  # fill main
97  branchNames.add(br)
98  zeroFill(obj, br, otherObj.GetListOfBranches(
99  ).FindObject(br), allowNonBool=True)
100  # merge immediately for trees
101  if isTree:
102  obj.Merge(inputs, "fast" if goFast else "")
103  inputs.Clear()
104 
105  if isTree:
106  obj.Write()
107  elif obj.IsA().InheritsFrom(ROOT.TH1.Class()):
108  obj.Merge(inputs)
109  obj.Write()
110  elif obj.IsA().InheritsFrom(ROOT.TObjString.Class()):
111  for st in inputs:
112  if st.GetString() != obj.GetString():
113  print("Strings are not matching")
114  obj.Write()
115  elif obj.IsA().InheritsFrom(ROOT.THnSparse.Class()):
116  obj.Merge(inputs)
117  obj.Write()
118  else:
119  print("Cannot handle " + str(obj.IsA().GetName()))
def zeroFill(tree, brName, brObj, allowNonBool=False)
Definition: haddnano.py:12
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
#define str(s)