12 """Plot timeline from TimelineSvc""" 
   14 __author__ = 
"Frank Winklmeier" 
   20 from collections 
import defaultdict
 
   32 def read(f, regex=".*", skipevents=0):
 
   34     regex = re.compile(regex)
 
   35     for l 
in open(f, 
"r"):
 
   37             names = l.lstrip(
"#").split()
 
   40         for i, f 
in enumerate(l.split()):
 
   41             setattr(d, names[i], int(f) 
if f.isdigit() 
else f)
 
   42         if d.event >= skipevents:
 
   48     """Find event start/stop times""" 
   50     t = defaultdict(
lambda: [sys.maxsize, 0, -1])  
 
   53         if d.start < t[d.event][0]:
 
   54             t[d.event][0] = d.start
 
   55             t[d.event][2] = d.slot
 
   56         if d.end > t[d.event][1]:
 
   65     global algcolors, evtcolors
 
   67     from ROOT 
import TColor
 
   69     algcolors = list(
range(2, 10)) + [20, 28, 29, 30, 33, 38, 40] + list(
range(41, 50))
 
   71         TColor.GetColor(0, 255 - g, g) 
for g 
in range(20, 255, (255 - 20) // nevtcolors)
 
   75 def plot(data, showThreads=True, batch=False, nevtcolors=10, width=1200, height=500):
 
   78     tmin = min(f.start 
for f 
in data)
 
   79     tmax = max(f.end 
for f 
in data)
 
   80     slots = 1 + max(f.slot 
for f 
in data)
 
   81     threads = sorted(list(set(f.thread 
for f 
in data)))
 
   82     threadid = dict((k, v) 
for v, k 
in enumerate(threads))  
 
   83     ymax = len(threads) 
if showThreads 
else slots
 
   85     c = ROOT.TCanvas(
"timeline", 
"Timeline", width, height)
 
   89     c.SetBottomMargin(0.1)
 
   90     c.coord = ROOT.TH2I(
"coord", 
";Time (ns)", 100, 0, tmax - tmin, ymax, 0, ymax)
 
   91     c.coord.GetYaxis().SetTitle((
"Thread" if showThreads 
else "Slot"))
 
   92     c.coord.GetYaxis().SetTitleOffset(0.5)
 
   93     c.coord.GetYaxis().CenterTitle()
 
   94     c.coord.SetStats(
False)
 
   95     c.coord.GetYaxis().SetNdivisions(ymax)
 
   96     c.coord.GetXaxis().CenterTitle()
 
  106         y = threadid[d.thread] 
if showThreads 
else d.slot
 
  108         if alg 
not in colors 
and len(mycolors) > 0:
 
  109             colors[alg] = mycolors.pop(0)
 
  110             if len(mycolors) == 0:
 
  111                 print(
"Too many algorithm to show")
 
  118             l = ROOT.TBox(t0, y + 0.1, t1, y + 0.8)
 
  119             l.SetFillColor(colors[alg])
 
  122             l2 = ROOT.TBox(t0, y + 0.8, t1, y + 0.9)
 
  123             l2.SetFillColor(evtcolors[d.event % nevtcolors])
 
  132     for k, v 
in tevt.items():
 
  133         y = ymax + bheight * v[2]
 
  134         l = ROOT.TBox(v[0] - tmin, y + 0.2 * bheight, v[1] - tmin, y + bheight)
 
  135         l.SetFillColor(evtcolors[k % nevtcolors])
 
  140     c.leg = ROOT.TLegend(0.8, 0.4, 0.98, 0.9)
 
  141     for alg, cl 
in sorted(colors.items(), key=operator.itemgetter(1)):
 
  142         e = c.leg.AddEntry(
"", alg, 
"F")
 
  148     bwidth = 0.18 / nevtcolors
 
  149     for cl 
in range(nevtcolors):
 
  153         l.SetLineColor(evtcolors[cl])
 
  154         l.DrawLineNDC(0.807 + bwidth * cl, 0.37, 0.807 + bwidth * (cl + 1), 0.37)
 
  156     c.t1 = ROOT.TText(0.807, 0.314, 
"Events")
 
  159     c.t1.SetTextSize(0.04)
 
  162     c.t2 = ROOT.TText(0.02, 0.92, 
"Event")
 
  165     c.t2.SetTextSize(0.03)
 
  166     c.t2.SetTextAngle(90)
 
  168     c.t3 = ROOT.TText(0.03, 0.922, 
"Slots")
 
  171     c.t3.SetTextSize(0.03)
 
  172     c.t3.SetTextAngle(90)
 
  183     parser = argparse.ArgumentParser(description=__doc__)
 
  185     parser.add_argument(
"timeline", nargs=1, help=
"timeline file")
 
  188         "-s", 
"--select", default=
".*", help=
"Regular expression to filter algorithms" 
  196         help=
"Do not wait for user input",
 
  203         help=
"Show slots instead of threads (leads to overlaps!)",
 
  211         const=
"timeline.png",
 
  212         help=
"Save to FILE [%(const)s]",
 
  220         help=
"Number of colors used for events (10 is default)",
 
  228         help=
"Number of events to skip at the start",
 
  232         "-x", 
"--width", default=1200, type=int, help=
"width of the output picture" 
  236         "-y", 
"--height", default=500, type=int, help=
"height of the output picture" 
  239     args = parser.parse_args()
 
  241     data = 
read(args.timeline[0], args.select, args.skipevents)
 
  242     c = 
plot(data, 
not args.slots, args.batch, args.nevtcolors, args.width, args.height)
 
  244         c.SaveAs(args.outfile)
 
  249 if __name__ == 
"__main__":