CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
html.py
Go to the documentation of this file.
1 import os
2 import collections
3 
4 def _lowerFirst(s):
5  return s[0].lower()+s[1:]
6 
7 _sampleName = {
8  "RelValMinBias": "Min Bias",
9  "RelValTTbar": "TTbar",
10  "RelValQCD_Pt_600_800": "QCD Pt 600 to 800",
11  "RelValQCD_Pt_3000_3500": "QCD Pt 3000 to 3500",
12  "RelValQCD_FlatPt_15_3000": "QCD Flat Pt 15 to 3000",
13  "RelValZMM": "ZMuMu",
14  "RelValWjet_Pt_3000_3500": "Wjet Pt 3000 to 3500",
15  "RelValSingleElectronPt35": "Single Electron Pt 35",
16  "RelValSingleElectronPt10": "Single Electron Pt 10",
17  "RelValSingleMuPt10": "Single Muon Pt 10",
18  "RelValSingleMuPt100": "Single Muon Pt 100",
19 }
20 
21 _sampleFileName = {
22  "RelValMinBias": "minbias",
23  "RelValTTbar": "ttbar",
24  "RelValQCD_Pt600_800": "qcd600",
25  "RelValQCD_Pt3000_3500": "qcd3000",
26  "RelValQCD_FlatPt_15_3000": "qcdflat",
27  "RelValZMM": "zmm",
28  "RelValWjet_Pt_3000_3500": "wjet3000",
29  "RelValSingleElectronPt35": "ele35",
30  "RelValSingleElectronPt10": "ele10",
31  "RelValSingleMuPt10": "mu10",
32  "RelValSingleMuPt100": "mu100",
33 }
34 
35 _allTPEfficName = "All tracks (all TPs)"
36 _fromPVName = "Tracks from PV"
37 _fromPVAllTPName = "Tracks from PV (all TPs)"
38 _trackQualityNameOrder = collections.OrderedDict([
39  ("", "All tracks"),
40  ("highPurity", "High purity tracks"),
41  ("btvLike", "BTV-like"),
42  ("ak4PFJets", "AK4 PF jets"),
43  ("allTPEffic_", _allTPEfficName),
44  ("allTPEffic_highPurity", _allTPEfficName.replace("All", "High purity")),
45  ("fromPV_", _fromPVName),
46  ("fromPV_highPurity", "High purity "+_lowerFirst(_fromPVName)),
47  ("fromPVAllTP_", _fromPVAllTPName),
48  ("fromPVAllTP_highPurity", "High purity "+_lowerFirst(_fromPVAllTPName)),
49 ])
50 
51 _trackAlgoName = {
52  "ootb": "Out of the box"
53 }
54 
55 _trackAlgoOrder = [
56  'ootb',
57  'initialStep',
58  'lowPtTripletStep',
59  'pixelPairStep',
60  'detachedTripletStep',
61  'mixedTripletStep',
62  'pixelLessStep',
63  'tobTecStep',
64  'jetCoreRegionalStep',
65  'muonSeededStepInOut',
66  'muonSeededStepOutIn',
67 ]
68 
69 _pageNameMap = {
70  "summary": "Summary",
71  "vertex": "Vertex",
72  "miniaod": "MiniAOD"
73 }
74 
75 _sectionNameMapOrder = collections.OrderedDict([
76  # These are for the summary page
77  ("", "All tracks"),
78  ("highPurity", "High purity tracks"),
79  ("allTPEffic", _allTPEfficName),
80  ("allTPEffic_highPurity", _allTPEfficName.replace("All", "High purity")),
81  ("fromPV", _fromPVName),
82  ("fromPV_highPurity", "High purity "+_lowerFirst(_fromPVName)),
83  ("fromPVAllTP", _fromPVAllTPName),
84  ("fromPVAllTP_highPurity", "High purity "+_lowerFirst(_fromPVAllTPName)),
85  # These are for vertices
86  ("offlinePrimaryVertices", "All vertices (offlinePrimaryVertices)"),
87  ("selectedOfflinePrimaryVertices", "Selected vertices (selectedOfflinePrimaryVertices)"),
88 ])
89 _allTPEfficLegend = "All tracks, efficiency denominator contains all TrackingParticles"
90 _fromPVLegend = "Tracks from reco PV vs. TrackingParticles from gen PV (fake rate includes pileup tracks)"
91 _fromPVAllTPLegend = "Tracks from reco PV, fake rate numerator contains all TrackingParticles (separates fake tracks from pileup tracks)"
92 _sectionNameLegend = {
93  "btvLike": "BTV-like selected tracks",
94  "ak4PFJets": "Tracks from AK4 PF jets (jet corrected pT > 10 GeV)",
95  "allTPEffic": _allTPEfficLegend,
96  "allTPEffic_": _allTPEfficLegend,
97  "allTPEffic_highPurity": _allTPEfficLegend.replace("All", "High purity"),
98  "fromPV": _fromPVLegend,
99  "fromPV_": _fromPVLegend,
100  "fromPV_highPurity": "High purity "+_lowerFirst(_fromPVLegend),
101  "fromPVAllTP": _fromPVAllTPLegend,
102  "fromPVAllTP_": _fromPVAllTPLegend,
103  "fromPVAllTP_highPurity": "High purity "+_lowerFirst(_fromPVAllTPLegend),
104 }
105 
107  class TrackingIteration: pass
108  class TrackingSummary: pass
109  class Vertexing: pass
110  class MiniAOD: pass
111 
112 class Page(object):
113  def __init__(self, title, base, sampleName):
114  self._content = [
115  '<html>',
116  ' <head>',
117  ' <title>%s</title>' % title,
118  ]
119  if base is not None:
120  self._content.append(' <base href="%s"/>' % base)
121  self._content.extend([
122  ' </head>',
123  ' <body>',
124  ' '+sampleName,
125  ' <br/>',
126  ' <br/>',
127  ])
128 
129  self._plotSets = {}
130 
131  def addPlotSet(self, section, plotSet):
132  self._plotSets[section] = plotSet
133 
134  def write(self, fileName):
135  sections = self._orderSets(self._plotSets.keys())
136 
137  self._content.extend([
138  ' <table>'
139  ' <tr>',
140  ])
141 
142  fileTable = []
143  legends = []
144 
145  for isec, section in enumerate(sections):
146  leg = ""
147  if section in _sectionNameLegend:
148  legnum = len(legends)+1
149  leg = "<sup>%d</sup>" % legnum
150  leg2 = "<sup>%d</sup>" % legnum
151  legends.append("%s %s" % (leg2, _sectionNameLegend[section]))
152 
153  self._content.extend([
154  ' <td>%s%s</td>' % (self._mapSectionName(section), leg),
155  ])
156  files = [(os.path.basename(f), f) for f in self._plotSets[section]]
157  for row in fileTable:
158  found = False
159  for i, (bsf, f) in enumerate(files):
160  if bsf == row[0]:
161  row.append(f)
162  found = True
163  del files[i]
164  break
165  if not found:
166  row.append(None)
167  for bsf, f in files:
168  fileTable.append( [bsf] + [None]*isec + [f] )
169 
170  self._content.extend([
171  ' </tr>',
172  ])
173 
174  for row in fileTable:
175  self._content.append(' <tr>')
176  bs = row[0]
177  for elem in row[1:]:
178  if elem is not None:
179  self._content.append(' <td><a href="%s">%s</a></td>' % (elem, bs))
180  else:
181  self._content.append(' <td></td>')
182  self._content.append(' </tr>')
183 
184 
185  self._content.extend([
186  ' </table>',
187  ])
188  if len(legends) > 0:
189  self._content.extend([
190  ' <br/>'
191  ' Details:</br>',
192  ])
193  for leg in legends:
194  self._content.append(' %s<br/>' % leg)
195 
196  self._content.extend([
197  ' </body>',
198  '</html>',
199  ])
200 
201  #print "Writing HTML report page", fileName
202  f = open(fileName, "w")
203  for line in self._content:
204  f.write(line)
205  f.write("\n")
206  f.close()
207 
208  def _mapSectionName(self, section):
209  return _sectionNameMapOrder.get(section, section)
210 
211  def _orderSets(self, keys):
212  ret = []
213  for section in _sectionNameMapOrder.keys():
214  if section in keys:
215  ret.append(section)
216  keys.remove(section)
217  ret.extend(keys)
218  return ret
219 
221  def __init__(self, title, base, sampleName, sample, fastVsFull):
222  self._title = title
223  self._base = base
224  self._sampleName = sampleName
225  self._pages = collections.OrderedDict()
226 
227  self._prefix=""
228  if hasattr(sample, "hasPileup"):
229  self._prefix = "nopu"
230  if sample.hasPileup():
231  self._prefix = "pu"+sample.pileupType()
232  self._prefix += "_"
233 
234  if sample.fastsim():
235  self._prefix += "fast_"
236  if fastVsFull:
237  self._prefix += "full_"
238 
239  self._prefix += _sampleFileName.get(sample.label(), sample.label())+"_"
240 
241  def addPlotSet(self, plotterFolder, dqmSubFolder, plotFiles):
242  pageKey = plotterFolder.getPage()
243  if pageKey is None:
244  if dqmSubFolder is not None:
245  pageKey = dqmSubFolder.translated
246  else:
247  pageKey = plotterFolder.getName()
248 
249  if pageKey not in self._pages:
250  page = Page(self._title, self._base, self._sampleName)
251  self._pages[pageKey] = page
252  else:
253  page = self._pages[pageKey]
254  sectionName = plotterFolder.getSection()
255  if sectionName is None:
256  if plotterFolder.getPage() is not None and dqmSubFolder is not None:
257  sectionName = dqmSubFolder.translated
258  else:
259  sectionName = ""
260 
261  page.addPlotSet(sectionName, plotFiles)
262 
263  def write(self, baseDir):
264  #print "TrackingPageSet.write"
265  ret = []
266 
267  keys = self._orderPages(self._pages.keys())
268  for key in keys:
269  page = self._pages[key]
270  fileName = "%s%s.html" % (self._prefix, key)
271  page.write(os.path.join(baseDir, fileName))
272  ret.append( (self._mapPagesName(key), fileName) )
273  return ret
274 
275  def _mapPagesName(self, name):
276  return _pageNameMap.get(name, name)
277 
278  def _orderPages(self, keys):
279  return keys
280 
281 
282 
284  def __init__(self, *args, **kwargs):
285  super(TrackingIterPage, self).__init__(*args, **kwargs)
286 
287  def _mapSectionName(self, quality):
288  return _trackQualityNameOrder.get(quality, quality)
289 
290  def _orderSets(self, qualities):
291  ret = []
292  for qual in _trackQualityNameOrder.keys():
293  if qual in qualities:
294  ret.append(qual)
295  qualities.remove(qual)
296  ret.extend(qualities)
297  return ret
298 
300  def __init__(self, *args, **kwargs):
301  super(TrackingPageSet, self).__init__(*args, **kwargs)
302 
303  def addPlotSet(self, plotterFolder, dqmSubFolder, plotFiles):
304  (algo, quality) = dqmSubFolder.translated
305 
306  pageName = algo
307  sectionName = quality
308 
309  # put all non-iterative stuff under OOTB
310  if "ootb" not in algo and "Step" not in algo:
311  pageName = "ootb"
312  sectionName = algo
313 
314  folderName = plotterFolder.getName()
315  if folderName != "":
316  sectionName = folderName+"_"+sectionName
317 
318  if pageName not in self._pages:
319  page = TrackingIterPage(self._title, self._base, self._sampleName)
320  self._pages[pageName] = page
321  else:
322  page = self._pages[pageName]
323  page.addPlotSet(sectionName, plotFiles)
324 
325  def _mapPagesName(self, algo): # algo = pageName
326  return _trackAlgoName.get(algo, algo)
327 
328  def _orderPages(self, algos):
329  ret = []
330  for algo in _trackAlgoOrder:
331  if algo in algos:
332  ret.append(algo)
333  algos.remove(algo)
334  ret.extend(algos)
335  return ret
336 
337 
338 
340  def __init__(self, sample, fastVsFull, title, base):
341  self._sample = sample
342 
343  self._sampleName = ""
344  if sample.fastsim():
345  self._sampleName += "FastSim "
346  if fastVsFull:
347  self._sampleName += "vs FullSim "
348 
349  pileup = ""
350  if hasattr(sample, "hasPileup"):
351  pileup = "with no pileup"
352  if sample.hasPileup():
353  pileup = "with %s pileup" % sample.pileupType()
354  self._sampleName += "%s sample %s" % (_sampleName.get(sample.name(), sample.name()), pileup)
355 
356  params = [title, base, self._sampleName, sample, fastVsFull]
357  self._summaryPage = PageSet(*params)
359  self._vertexPage = PageSet(*params)
360  self._miniaodPage = PageSet(*params)
361  self._otherPages = PageSet(*params)
362 
363  def addPlots(self, plotterFolder, dqmSubFolder, plotFiles):
364  params = [plotterFolder, dqmSubFolder, plotFiles]
365 
366  purpose = plotterFolder.getPurpose()
367  if purpose is PlotPurpose.TrackingIteration:
368  self._iterationPages.addPlotSet(*params)
369  elif purpose is PlotPurpose.TrackingSummary:
370  self._summaryPage.addPlotSet(*params)
371  elif purpose is PlotPurpose.Vertexing:
372  self._vertexPage.addPlotSet(*params)
373  elif purpose is PlotPurpose.MiniAOD:
374  self._miniaodPage.addPlotSet(*params)
375  else:
376  self._otherPages.addPlotSet(*params)
377 
378  def write(self, baseDir):
379  ret = [
380  " "+self._sampleName,
381  " <br/>",
382  " <ul>",
383  ]
384 
385  for pages in [self._summaryPage, self._iterationPages, self._vertexPage, self._miniaodPage, self._otherPages]:
386  labelFiles = pages.write(baseDir)
387  for label, fname in labelFiles:
388  ret.append(' <li><a href="%s">%s</a></li>' % (fname, label))
389 
390  ret.extend([
391  ' </ul>',
392  ' <br/>',
393  ])
394 
395  return ret
396 
398  def __init__(self, validationName, newBaseDir, baseUrl=None):
399  self._title = "Tracking validation "+validationName
400  self._newBaseDir = newBaseDir
401  self._base = baseUrl
402 
403  self._index = [
404  '<html>',
405  ' <head>',
406  ' <title>%s</title>' % self._title,
407  ]
408  if self._base is not None:
409  self._index.append(' <base href="%s"/>' % self._base)
410  self._index.extend([
411  ' </head>',
412  ' <body>',
413  ])
414 
415  self._sections = collections.OrderedDict()
416 
417  def beginSample(self, sample, fastVsFull=False):
418  key = (sample.digest(), fastVsFull)
419  if key in self._sections:
420  self._currentSection = self._sections[key]
421  else:
422  self._currentSection = IndexSection(sample, fastVsFull, self._title, self._base)
423  self._sections[key] = self._currentSection
424 
425  def addPlots(self, *args, **kwargs):
426  self._currentSection.addPlots(*args, **kwargs)
427 
428  def write(self):
429  # Reorder sections such that Fast vs. Full becomes just after the corresponding Fast
430  keys = self._sections.iterkeys()
431  newkeys = []
432  for key in keys:
433  if not key[1]:
434  newkeys.append(key)
435  continue
436  # is fast vs full
437  ind_fast = newkeys.index( (key[0], False) )
438  newkeys.insert(ind_fast+1, key)
439 
440  for key in newkeys:
441  section = self._sections[key]
442  self._index.extend(section.write(self._newBaseDir))
443 
444  self._index.extend([
445  " </body>",
446  "</html>",
447  ])
448 
449  f = open(os.path.join(self._newBaseDir, "index.html"), "w")
450  for line in self._index:
451  f.write(line)
452  f.write("\n")
453  f.close()
454 
456  def __init__(self):
457  pass
458 
459  def beginSample(self, *args, **kwargs):
460  pass
461 
462  def addPlots(self, *args, **kwargs):
463  pass
def addPlotSet
Definition: html.py:241
_content
Definition: html.py:114
def addPlotSet
Definition: html.py:131
def beginSample
Definition: html.py:417
def _lowerFirst
Definition: html.py:4
def _orderPages
Definition: html.py:278
def addPlots
Definition: html.py:425
def _orderSets
Definition: html.py:211
def __init__
Definition: html.py:398
def write
Definition: html.py:263
_plotSets
Definition: html.py:129
def __init__
Definition: html.py:113
def _mapPagesName
Definition: html.py:275
def __init__
Definition: html.py:221
list object
Definition: dbtoconf.py:77
def write
Definition: html.py:134
def _mapSectionName
Definition: html.py:208