view_tools.py
Go to the documentation of this file.
1 ###########################
2 # controller HTML info summary
3 def controllerInfo(controller, url):
4  import time
5 
6  html = \
7  """
8  <div class="row">
9  <div class="col-lg-6">
10  <div class="panel panel-info">
11  <div class="panel-heading">
12  <h3 class="panel-title">Controller</h3>
13  </div>
14  <div class="panel-body">
15  <!--CONTROLLER_INFO_HOOK-->
16  <a href="%s/config.html">configuration</a>
17  </div>
18  </div>
19  </div>
20  <div class="col-lg-6">
21  """%url
22 
23  body = ""
24  for attribute in ["name","version","release","creation_time","description"]:
25  if (not hasattr(controller,attribute)): continue
26  if attribute == "creation_time":
27  value = controller.creation_time.strftime("%Y-%m-%d %H:%M:%S")
28  else:
29  value = getattr(controller,attribute)
30  body += \
31  """
32  <div class="row">
33  <div class="col-lg-4">
34  <strong>%s:</strong>
35  </div>
36  <div class="col-lg-8">
37  %s
38  </div>
39  </div>
40  """%(attribute,value)
41 
42  html = html.replace("<!--CONTROLLER_INFO_HOOK-->",body)
43 
44  html += "<!--CONTROLLER_SUMMARY_HOOK--></div></div>"
45  return html
46 ###########################
47 # component HTML summary
48 def componentSummary(component, url):
49  import time
50 
51  html = "<p>"
52  html += "Component name: %s<ul>"%(component.name)
53  html += "<li>version: %s</li>"%(component.version)
54  html += "<li>dataset: %s</li>"%(component.dataset)
55  html += "<li>status: %s</li>"%(component.status)
56  html += "<li>script: %s</li>"%(component.script)
57  html += "<li>jobsub_command: %s</li>"%(component.jobsub_command)
58  if hasattr(component,"run_time"):
59  html += "<li>run time: %s</li>"%component.run_time.strftime("%Y-%m-%d %H:%M:%S")
60  html += '<li><a href="%s/%s_%s_%s_submission_log.html">submission log</a></li>'%(url, component.name, component.version, component.dataset)
61  html += '<li><a href="%s/%s_%s_%s_batch_cmd.html">batch cmd</a></li>'%(url, component.name, component.version, component.dataset)
62  html += '<li><a href="%s/%s_%s_%s_batch_out.html">batch out</a></li>'%(url, component.name, component.version, component.dataset)
63  html += '<li><a href="%s/%s_%s_%s_batch_log.html">batch log</a>: status: %s</li>'%(url, component.name, component.version, component.dataset, component.logs.log_status())
64  html += '<li><a href="%s/%s_%s_%s_batch_err.html">batch err</a>: status: %s</li>'%(url, component.name, component.version, component.dataset, component.logs.err_status())
65  html += "</ul></p>"
66  return html
67 ###########################
68 # convert some text to safe HTML
69 def toHTML(text):
70  text = text.replace("<", "&lt;")
71  text = text.replace(">", "&gt;")
72  return text
73 ###########################
74 # component status table row
75 def componentStatusRow(component, url, testing=False, sam=False):
76  import common_tools as tools
77  html = "<tr>"
78  html += "<td>%s</td>"%component.dataset
79  if hasattr(component,"run_time"):
80  html += "<td>%s</td>"%component.run_time.strftime("%Y-%m-%d %H:%M:%S")
81  else:
82  html += "<td>Not run</td>"
83  html += "<td>%s</td>"%component.logs.run_time()
84  html += '<td><a href="%s/%s_%s_%s_submission_log.html">submission log</a></td>'%(url, component.name, component.version, component.dataset)
85  html += '<td>'
86  html += '<a href="%s/%s_%s_%s_batch_cmd.html">cmd</a>, '%(url, component.name, component.version, component.dataset)
87  html += '<a href="%s/%s_%s_%s_batch_log.html">log</a>, '%(url, component.name, component.version, component.dataset)
88  html += '<a href="%s/%s_%s_%s_batch_out.html">out</a>, '%(url, component.name, component.version, component.dataset)
89  html += '<a href="%s/%s_%s_%s_batch_err.html">err</a>'%(url, component.name, component.version, component.dataset)
90  html += "</td>"
91 
92  if hasattr(component,"sam") and component.sam:
93  html += '<td><a href="%s">project</a></td>'%(tools.getStationMonitor(component.lines))
94  html += '<td>%s</td>'%(component.get_sam_status(sam))
95  html += '<td>%s</td>'%(component.get_sam_merge_status())
96  else:
97  html += '<td>%s</td>'%(component.logs.log_status())
98  html += '<td>%s</td>'%(component.logs.err_status())
99 
100  has_root_file = hasattr(component,"root_file") or (len(tools.findRootOutput(component, testing=testing)) == 1)
101  if has_root_file:
102  html += '<td>Found</td>'
103  else:
104  html += '<td>Not found</td>'
105  html += "</tr>"
106 
107  if hasattr(component,"sam") and component.sam:
108  if (component.get_sam_status(sam) == "complete") and (component.get_sam_merge_status() == "complete") and has_root_file:
109  status = "success"
110  elif (component.get_sam_status(sam) == "complete"):
111  status = "info"
112  elif (component.get_sam_merge_status() == "complete") and has_root_file:
113  status = "warning"
114  elif ("running" in component.get_sam_status(sam)):
115  status = ""
116  else:
117  status = "danger"
118  else:
119  if (component.logs.log_status() == "completed") and (component.logs.err_status() == "no error") and has_root_file:
120  status = "success"
121  elif (component.logs.log_status() == "running"):
122  status = ""
123  else:
124  status = "danger"
125 
126  html = html.replace("<tr>",'<tr class="%s">'%status)
127  return html, status
128 ###########################
129 # component status summary
130 def componentStatusSummary(status_dict, url):
131  import naming_schema
132  html = \
133  """
134  <div class="panel panel-default">
135  <table class="table table-striped">
136  <tr>
137  <th>Component</th>
138  <th>Datasets</th>
139  </tr>
140  """
141  components = status_dict.keys()
142  components.sort()
143  for component in components:
144  html += '<tr><td><a href="%s/%s/index.hmtl">%s</a></td><td>'%(url,component,naming_schema.componentName(component))
145  for status in status_dict[component]:
146  html += classToGlyphicon(status)
147  html += "</td></tr>"
148  html += "</table></div>"
149  return html
150 ###########################
151 # convert a class to a glyphicon
152 def classToGlyphicon(class_label):
153  classToGlyph = {}
154  classToGlyph["success"] = '<span class="badge alert-success"><span class="glyphicon glyphicon-ok"></span></span>'
155  classToGlyph["warning"] = '<span class="badge alert-warning"><span class="glyphicon glyphicon-flag"></span></span>'
156  classToGlyph["danger"] = '<span class="badge alert-danger"><span class="glyphicon glyphicon-wrench"></span></span>'
157  classToGlyph[""] = '<span class="badge"><span class="glyphicon glyphicon-cog"></span></span>'
158 
159  if class_label in classToGlyph.keys():
160  return classToGlyph[class_label]
161  else:
162  print "vtool: Unknown class label: %s"%class_label
163  return ""
164 ###########################
165 # normalise a histogram
166 def normaliseHistogram(histogram,area=1.,verbose=False,preserve_errors=True):
167  from ROOT import TH2D, TH2F
168  if verbose:
169  print "vtool: --- NormaliseHistogram"
170  print "vtool: - histogram: ",histogram.GetName()
171  print "vtool: - area: ",area
172  return_histogram = histogram.Clone(histogram.GetName()+"_normalised_to_%.0f"%area)
173  if ( histogram.GetSumOfWeights()):
174  scale_factor = area / histogram.GetSumOfWeights()
175  return_histogram.Scale(scale_factor)
176  else:
177  scale_factor = 1
178  if verbose: print "vtool: - histogram SumOfWeights is zero, setting to 1"
179 
180  if verbose:
181  print "vtool: - histogram SumOfWeights: %e"%histogram.GetSumOfWeights()
182  print "vtool: - scale factor: %e"%scale_factor
183  print "vtool: - final SumOfWeights: %e"%return_histogram.GetSumOfWeights()
184 
185  if preserve_errors:
186  if verbose: print "vtool: Scaling errors"
187 
188  for i in range(histogram.GetNbinsX()+1):
189  if ((type(histogram) == TH2D) or (type(histogram) == TH2F)):
190  for j in range(histogram.GetNbinsY()+1):
191  value = histogram.GetBinContent(i,j)
192  error = histogram.GetBinError(i,j)
193  if value: fractional_error = error/value
194  else: fractional_error = 0
195  new_value = return_histogram.GetBinContent(i,j)
196  new_error = fractional_error*new_value
197  #if verbose: print "vtool: - bin[%i][%i]: value: %.4f, error: %.4f, fractional error: %.4f, new value: %.4f new error: %.4f"%(i,j,value,error,fractional_error,new_value,new_error)
198  return_histogram.SetBinError(i,j,new_error)
199  else:
200  value = histogram.GetBinContent(i)
201  error = histogram.GetBinError(i)
202  if value: fractional_error = error/value
203  else: fractional_error = 0
204  new_value = return_histogram.GetBinContent(i)
205  new_error = fractional_error*new_value
206  #if verbose: print "vtool: - bin[%i]: value: %.4f, error: %.4f, fractional error: %.4f, new value: %.4f new error: %.4f"%(i,value,error,fractional_error,new_value,new_error)
207  return_histogram.SetBinError(i,new_error)
208 
209  return return_histogram
210 ###########################
211 # divide lists of histograms
212 def makeRatioHistograms(numerators, denominators, preserve_errors=True, sumw2=True, verbose=False):
213  return_histograms = []
214  if verbose:
215  print "\nvtool: --- Histogram Operations: Make Ratio Histograms"
216  print "vtool: error preservation: ",preserve_errors
217  print "vtool: %i numerators"%len(numerators)
218  print "vtool: %i denominators"%len(denominators)
219 
220  if len(denominators) == 1:
221  if verbose: print "vtool: Using the same denominator for all ratios"
222 
223  for i,n in enumerate(numerators):
224  if verbose: print "vtool: numerator[%i]: "%i,n," entries: ",n.GetSumOfWeights()
225  if len(denominators) == 1: this_denominator = denominators[0]
226  else: this_denominator = denominators[i]
227  if verbose: print "vtool: denominator: ",this_denominator," entries: ",this_denominator.GetSumOfWeights()
228 
229  e = n.Clone(n.GetName()+"_numerator_%i"%i)
230  if sumw2 and (e.GetSumw2N() == 0 ): e.Sumw2()
231  d = this_denominator.Clone(this_denominator.GetName()+"_denominator_%i"%i)
232 
233  e.Divide(d)
234  if preserve_errors:
235  fractional_errors = getHistogramStatErrors(numerators[i])
236  e = setHistogramFractionalErrors(e,fractional_errors)
237 
238  #if verbose: print e
239  for i in range(e.GetNbinsX()+2):
240  if verbose: print "vtool: - bin[%2i]: numerator: %10.4f +/- %10.4f, denominator: %10.4f +/- %10.4f, ratio: %5.4f, error: %10.4f"%(i,n.GetBinContent(i),n.GetBinError(i),d.GetBinContent(i),d.GetBinError(i),e.GetBinContent(i),e.GetBinError(i))
241  #assert False
242  return_histograms.append(e)
243 
244  if verbose: print return_histograms
245  return return_histograms
246 ###########################
247 # get the statistical errors on a histogram
248 def getHistogramStatErrors(central,verbose=False):
249  if verbose: print "ho : == GetStatErrors"
250  if verbose: print "ho : central values: ",central
251  if type(central) == list:
252  return_histograms = []
253  for hist in central:
254  return_histogram = hist.Clone(hist.GetName()+"_maximum_deviation")
255  for i in range(hist.GetNbinsX()+1):
256  if hist.GetBinContent(i):
257  fractional_error = hist.GetBinError(i) / hist.GetBinContent(i)
258  else:
259  fractional_error = 0
260  return_histogram.SetBinContent(i,fractional_error)
261  return_histogram.SetBinError(i,0)
262  return_histograms.append(return_histogram)
263  return return_histograms
264  else:
265  return_histogram = central.Clone("maximum_deviation")
266  for i in range(central.GetNbinsX()+1):
267  if central.GetBinContent(i):
268  fractional_error = central.GetBinError(i) / central.GetBinContent(i)
269  else:
270  fractional_error = 0
271  return_histogram.SetBinContent(i,fractional_error)
272  return_histogram.SetBinError(i,0)
273 
274  #assert False
275  return return_histogram
276 ###########################
277 # Set fractional errors on a histogram
278 def setHistogramFractionalErrors(original,error,error_in_percent=False,verbose=False):
279  if verbose:
280  print "vtool: --- SetFractionalErrors"
281  print "vtool: original: ",original.GetName()
282  print "vtool: errors: ",error.GetName()
283  print "vtool: errors in percent: ",error_in_percent
284 
285  return_histogram = original.Clone(original.GetName()+"_fractional_error")
286 
287  for i in range(original.GetNbinsX()+1):
288  value = original.GetBinContent(i)
289  fractional_error = error.GetBinContent(i)
290  if error_in_percent: fractional_error = fractional_error / 100.
291  absolute_error = value*fractional_error
292  if verbose: print "vtool: - bin[%i]: value: %.4f, fractional error: %.4f, absolute error: %.4f"%(i,value,fractional_error,absolute_error)
293  return_histogram.SetBinError(i,absolute_error)
294  #assert False
295  return return_histogram
def setHistogramFractionalErrors(original, error, error_in_percent=False, verbose=False)
Set fractional errors on a histogram.
Definition: view_tools.py:278
def componentStatusRow(component, url, testing=False, sam=False)
component status table row
Definition: view_tools.py:75
def getHistogramStatErrors(central, verbose=False)
get the statistical errors on a histogram
Definition: view_tools.py:248
def toHTML(text)
convert some text to safe HTML
Definition: view_tools.py:69
def controllerInfo(controller, url)
controller HTML info summary
Definition: view_tools.py:3
def componentName(name)
get a component name
def classToGlyphicon(class_label)
convert a class to a glyphicon
Definition: view_tools.py:152
def componentSummary(component, url)
component HTML summary
Definition: view_tools.py:48
def makeRatioHistograms(numerators, denominators, preserve_errors=True, sumw2=True, verbose=False)
divide lists of histograms
Definition: view_tools.py:212
def normaliseHistogram(histogram, area=1., verbose=False, preserve_errors=True)
normalise a histogram
Definition: view_tools.py:166
def componentStatusSummary(status_dict, url)
component status summary
Definition: view_tools.py:130