2 """Plot timeline from TimelineSvc""" 4 __author__ =
"Frank Winklmeier" 10 from collections
import defaultdict
22 def read(f, regex='.*', skipevents=0):
24 regex = re.compile(regex)
25 for l
in open(f,
'r'): 27 names = l.lstrip(
'#').split()
30 for i, f
in enumerate(l.split()):
31 setattr(d, names[i], int(f)
if f.isdigit()
else f)
32 if d.event >= skipevents:
38 """Find event start/stop times""" 40 t = defaultdict(
lambda: [sys.maxint, 0, -1])
43 if d.start < t[d.event][0]:
44 t[d.event][0] = d.start
45 t[d.event][2] = d.slot
46 if d.end > t[d.event][1]:
55 global algcolors, evtcolors
57 from ROOT
import TColor
58 algcolors =
range(2, 10) + [20, 28, 29, 30, 33, 38, 40] +
range(41, 50)
59 evtcolors = [TColor.GetColor(0, 255 - g, g)
60 for g
in range(20, 255, (255 - 20) / nevtcolors)]
63 def plot(data, showThreads=True, batch=False, nevtcolors=10, width=1200, height=500):
66 tmin = min(f.start
for f
in data)
67 tmax = max(f.end
for f
in data)
68 slots = 1 + max(f.slot
for f
in data)
69 threads = sorted(list(set(f.thread
for f
in data)))
70 threadid = dict((k, v)
for v, k
in enumerate(threads))
71 ymax = len(threads)
if showThreads
else slots
73 c = ROOT.TCanvas(
'timeline',
'Timeline', width, height)
77 c.SetBottomMargin(0.1)
78 c.coord = ROOT.TH2I(
'coord',
';Time (ns)', 100,
79 0, tmax - tmin, ymax, 0, ymax)
80 c.coord.GetYaxis().SetTitle((
'Thread' if showThreads
else 'Slot'))
81 c.coord.GetYaxis().SetTitleOffset(0.5)
82 c.coord.GetYaxis().CenterTitle()
83 c.coord.SetStats(
False)
84 c.coord.GetYaxis().SetNdivisions(ymax)
85 c.coord.GetXaxis().CenterTitle()
95 y = (threadid[d.thread]
if showThreads
else d.slot)
97 if alg
not in colors
and len(mycolors) > 0:
98 colors[alg] = mycolors.pop(0)
99 if len(mycolors) == 0:
100 print "Too many algorithm to show" 107 l = ROOT.TBox(t0, y + .1, t1, y + .8)
108 l.SetFillColor(colors[alg])
111 l2 = ROOT.TBox(t0, y + .8, t1, y + .9)
112 l2.SetFillColor(evtcolors[d.event % nevtcolors])
121 for k, v
in tevt.iteritems():
122 y = ymax + bheight * v[2]
123 l = ROOT.TBox(v[0] - tmin, y + 0.2 * bheight, v[1] - tmin, y + bheight)
124 l.SetFillColor(evtcolors[k % nevtcolors])
129 c.leg = ROOT.TLegend(0.8, 0.4, 0.98, 0.9)
130 for alg, cl
in sorted(colors.iteritems(), key=operator.itemgetter(1)):
131 e = c.leg.AddEntry(
'', alg,
'F')
137 bwidth = 0.18 / nevtcolors
138 for cl
in range(nevtcolors):
142 l.SetLineColor(evtcolors[cl])
143 l.DrawLineNDC(0.807 + bwidth * cl, 0.37,
144 0.807 + bwidth * (cl + 1), 0.37)
146 c.t1 = ROOT.TText(0.807, 0.314,
'Events')
149 c.t1.SetTextSize(0.04)
152 c.t2 = ROOT.TText(0.02, 0.92,
'Event')
155 c.t2.SetTextSize(0.03)
156 c.t2.SetTextAngle(90)
158 c.t3 = ROOT.TText(0.03, 0.922,
'Slots')
161 c.t3.SetTextSize(0.03)
162 c.t3.SetTextAngle(90)
173 parser = argparse.ArgumentParser(description=__doc__)
175 parser.add_argument(
'timeline', nargs=1,
176 help=
'timeline file')
178 parser.add_argument(
'-s',
'--select', default=
'.*',
179 help=
'Regular expression to filter algorithms')
181 parser.add_argument(
'-b',
'--batch', action=
'store_true', default=
False,
182 help=
'Do not wait for user input')
184 parser.add_argument(
'--slots', action=
'store_true', default=
False,
185 help=
'Show slots instead of threads (leads to overlaps!)')
187 parser.add_argument(
'-p',
'--print', dest=
'outfile', nargs=
'?',
188 const=
'timeline.png',
189 help=
'Save to FILE [%(const)s]')
191 parser.add_argument(
'-n',
'--nevtcolors', default=10, type=int,
192 help=
'Number of colors used for events (10 is default)')
194 parser.add_argument(
'-e',
'--skipevents', default=0, type=int,
195 help=
'Number of events to skip at the start')
197 parser.add_argument(
'-x',
'--width', default=1200, type=int,
198 help=
'width of the output picture')
200 parser.add_argument(
'-y',
'--height', default=500, type=int,
201 help=
'height of the output picture')
203 args = parser.parse_args()
205 data =
read(args.timeline[0], args.select, args.skipevents)
206 c =
plot(data,
not args.slots, args.batch,
207 args.nevtcolors, args.width, args.height)
209 c.SaveAs(args.outfile)
214 if __name__ ==
'__main__':
def read(f, regex='.*', skipevents=0)
def plot(data, showThreads=True, batch=False, nevtcolors=10, width=1200, height=500)
decltype(auto) range(Args &&...args)
Zips multiple containers together to form a single range.
def setPalette(nevts, nevtcolors)