CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
cmsTiming_parser.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 
4 def get_max(data,index=1):
5  max_time=-1
6  for el in data:
7  sec=el[index]
8  if max_time<sec:
9  max_time=sec
10  return max_time
11 
12 def get_min(data,index=1):
13  min_time=1e20
14  for el in data:
15  sec=el[index]
16  if min_time>sec:
17  min_time=sec
18  return min_time
19 
20 def manipulate_log(outdir,logfile_name,secsperbin):
21 
22  import time
23  import sys
24  import ROOT
25  from math import sqrt, log10, floor
26 
27  # the fundamental structure: the key is the evt number the value is a list containing
28  # VSIZE deltaVSIZE RSS deltaRSS
29  data=[]
30  report = ''
31  # open file and read it and fill the structure!
32  logfile=open(logfile_name,'r')
33  logfile_lines=logfile.readlines()
34  logfile.close()
35 
36  # we get the info we need!
37  i=0
38  parse_report=True
39  while i < len(logfile_lines):
40  line=logfile_lines[i]
41  if 'TimeEvent>' in line:
42  line=line[:-1] #no \n!
43  line_content_list=line.split(' ')
44  event_number=int(line_content_list[1])
45  seconds=float(line_content_list[3])
46  data.append((event_number,seconds))
47  elif parse_report and'TimeReport' in line:
48  # add an empty line before report's tables
49  if '[sec]' in line:
50  report+='\n'
51  report += line.replace('TimeReport', '')
52  # remove two non-informative lines
53  elif 'headings' in line:
54  i+=1
55  continue
56  # parsing last summaries
57  elif 'complete' in line:
58  report += '\n'
59  report += line.replace('TimeReport', '')
60  for k in range(12):
61  report += logfile_lines[i]
62  i+=1
63  parse_report=False
64  # add simple report line
65  else:
66  report += line.replace('TimeReport', '')
67  i+=1
68 
69  # init Graph and histo
70 
71  # The Graphs
72  __argv=sys.argv # trick for a strange behaviour of the TApp..
73  sys.argv=sys.argv[:1]
74  ROOT.gROOT.SetStyle("Plain") # style paranoia
75  sys.argv=__argv
76  #Cannot use this option when the logfile includes
77  #a large number of events... PyRoot seg-faults.
78  #Set ROOT in batch mode to avoid canvases popping up!
79  ROOT.gROOT.SetBatch(1)
80 
81  # Save in file
82  rootfilename='%s/graphs.root' %outdir
83  myfile=ROOT.TFile(rootfilename,'RECREATE')
84 
85 
86  # Set fancy limits
87  min_val=get_min(data,1)
88  max_val=get_max(data,1)
89  interval=max_val-min_val
90 
91  min_val=min_val-interval*0.2
92  max_val=max_val+interval*0.2
93  interval=max_val-min_val
94 
95  nbins=int(interval/secsperbin)
96 
97  print 'Minval =', min_val,' maxval =',max_val, ' interval =',interval
98 
99  histo=ROOT.TH1F('Seconds per event','Seconds per event',nbins,min_val,max_val)
100  histo.GetXaxis().SetTitle("s")
101 
102  npoints=len(data)
103 
104  graph=ROOT.TGraph(npoints)
105  graph.SetMarkerStyle(8)
106  graph.SetMarkerSize(.7)
107  graph.SetMarkerColor(1)
108  graph.SetLineWidth(3)
109  graph.SetLineColor(2)
110  graph.SetTitle('Seconds per event')
111  graph.SetName('SecondsPerEvent')
112  graph.GetXaxis().SetTitle("Event")
113 
114  last_event=data[-1][0]
115  print 'last event =',last_event
116  graph.GetXaxis().SetLimits(0,last_event)
117 
118  graph.GetYaxis().SetTitleOffset(1.3)
119  graph.GetYaxis().SetTitle("s")
120  graph.GetYaxis().SetRangeUser(0,max_val)
121 
122 
123 
124  # Fill them
125 
126  evt_counter=0
127  total=0
128  for evt_num,secs in data:
129  graph.SetPoint(evt_counter,evt_num,secs)
130  histo.Fill(secs)
131  total+=secs
132  evt_counter+=1
133 
134  average=total/evt_counter
135 
136  sum=0.
137  for i in range(evt_counter):
138  sum+=(data[i][1]-average)**2
139  uncertainty= sqrt(sum/(evt_counter*(evt_counter-1)))
140 
141  # round uncertainty to the most significant digit
142  #rounded_uncertainty=round(uncertainty, -int(floor(log10(uncertainty))))
143  #print 'Rounded uncertainty=' , rounded_uncertainty
144 
145  print 'Total Time =', total
146  print 'Average Time =', average
147  print 'Uncertainty of Average Time =', average, '+/-', uncertainty
148 
149  #A line which represents the average is drawn in the TGraph
150  avg=histo.GetMean()
151  avg_line=ROOT.TLine(1,avg,last_event,avg)
152  avg_line.SetLineColor(4)
153  avg_line.SetLineWidth(2)
154 
155  # draw and save!
156  graph_canvas=ROOT.TCanvas('graph_canvas')
157  graph_canvas.cd()
158  graph.Draw("ALP")
159  avg_line.Draw("Same")
160 
161  graph_canvas.Print("%s/graph.png" %outdir,"png")
162 
163  # write it on file
164  graph.Write()
165  graph_canvas.Write()
166 
167  histo_canvas=ROOT.TCanvas('histo_canvas')
168  histo_canvas.cd()
169  histo.Draw('')
170 
171  histo_canvas.Print("%s/histo.png" %outdir,"png")
172 
173  # write it on file
174  histo.Write()
175  histo_canvas.Write()
176 
177  myfile.Close()
178 
179  # The html page!------------------------------------------------------------------------------
180 
181  titlestring='<b>Report executed with release %s on %s.</b>\n<br>\n<hr>\n'\
182  %(os.environ['CMSSW_VERSION'],time.asctime())
183 
184  html_file_name='%s/%s_TimingReport.html' %(outdir,logfile_name[:-4])# a way to say the string until its last but 4th char
185  html_file=open(html_file_name,'w')
186  html_file.write('<html>\n<body>\n'+\
187  titlestring)
188  html_file.write('<table>\n'+\
189  '<tr>\n<td><img src=graph.png></img></td>\n'+\
190  '<td><img src=histo.png></img></td>\n</tr>\n'+\
191  '</table>\n')
192  html_file.write('<hr>\n<h2>Time Report</h2>\n<pre>\n' + report + '</pre>\n')
193  html_file.write('</body>\n</html>')
194  html_file.close()
195 
196 
197 #################################################################################################
198 
199 if __name__ == '__main__':
200 
201  import optparse
202  import os
203 
204  # Here we define an option parser to handle commandline options..
205  usage='timing_parser.py <options>'
206  parser = optparse.OptionParser(usage)
207  parser.add_option('-i', '--in_ profile',
208  help='The profile to manipulate' ,
209  default='',
210  dest='profile')
211 
212  parser.add_option('-o', '--outdir',
213  help='The directory of the output' ,
214  default='',
215  dest='outdir')
216 
217  parser.add_option('-n',
218  help='Number of secs per bin. Default is 1.' ,
219  default='1',
220  dest='startevt')
221 
222  (options,args) = parser.parse_args()
223 
224  # Now some fault control..If an error is found we raise an exception
225  if options.profile=='' or\
226  options.outdir=='':
227  raise('Please select a profile and an output dir!')
228 
229  if not os.path.exists(options.profile) or\
230  not os.path.exists(options.outdir):
231  raise ('Outdir or input profile not present!')
232 
233  try:
234  startevt=float(options.startevt)
235  except ValueError:
236  print 'Problems in convertng starting event value!'
237 
238 
239  #launch the function!
240  manipulate_log(options.outdir,options.profile,startevt)
241 
242 
T sqrt(T t)
Definition: SSEVec.h:46