1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#!/bin/env python3
from builtins import range
import ROOT as R
import os, re
class DQMReader(object):
"""
Reader for DQM IO and DQM root files.
"""
#defined DQMIO types, index is important!
DQMIO_TYPES = ["Ints","Floats","Strings",
"TH1Fs","TH1Ss","TH1Ds",
"TH2Fs", "TH2Ss", "TH2Ds",
"TH3Fs", "TProfiles","TProfile2Ds", "kNIndicies"]
def __init__(self, input_filename):
self._root_file = R.TFile.Open(input_filename)
ioTest = self._root_file.Get("Indices")
if bool(ioTest):
self.type = "DQMIO"
else:
self.type = "ROOT"
def read_objects(self):
if (self.type == "DQMIO"):
return self.read_objects_dqmio()
else:
return self.read_objects_root()
def read_objects_dqmio(self):
indices = self._root_file.Get("Indices")
for y in range(indices.GetEntries()):
indices.GetEntry(y)
# print indices.Run, indices.Lumi, indices.Type
if indices.Type == 1000:
# nothing is stored here
# see https://github.com/cms-sw/cmssw/blob/8be445ac6fd9983d69156199d4d1fd3350f05d92/DQMServices/FwkIO/plugins/DQMRootOutputModule.cc#L437
continue
object_type = self.DQMIO_TYPES[indices.Type]
t_tree = self._root_file.Get(object_type)
for i in range(indices.FirstIndex, indices.LastIndex + 1):
t_tree.GetEntry(i)
fullname = str(t_tree.FullName)
yield (fullname, t_tree.Value, )
def read_objects_root(self):
xml_re = re.compile(r"^<(.+)>(.+)=(.*)<\/\1>$")
def parse_directory(di):
directory = self._root_file.GetDirectory(di)
for key in directory.GetListOfKeys():
entry = key.GetName()
rtype = key.GetClassName()
fullpath = "%s/%s" % (di, entry)
if (rtype == "TDirectoryFile"):
for k, v in parse_directory(fullpath):
yield (k, v, )
else:
obj = self._root_file.Get(fullpath)
if obj:
yield (fullpath, obj, )
else:
# special case to parse the xml abomination
m = xml_re.search(entry)
if m:
name = m.group(1)
typecode = m.group(2)
value = m.group(3)
fp = "%s/%s" % (di, name)
yield (fp, value, )
else:
raise Exception("Invalid xml:" + entry)
path_fix = re.compile(r"^\/Run \d+")
for fullname, obj in parse_directory(""):
f = fullname.replace("/DQMData", "")
f = f.replace("/Run summary", "")
f = path_fix.sub(r"", f)
if f[0] == "/":
f = f[1:]
yield f, obj
def close(self):
self._root_file.Close()
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", help = "Input DQMIO ROOT file")
args = parser.parse_args()
reader = DQMReader(args.input)
for (fn, v) in reader.read_objects():
if (hasattr(v, "ClassName")):
print(fn, v.ClassName())
else:
print(fn, type(v))
reader.close()
|