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  "RelValH125GGgluonfusion": "Higgs to gamma gamma",
16  "RelValSingleElectronPt35": "Single Electron Pt 35",
17  "RelValSingleElectronPt35Extended": "Single Electron Pt 35 (extended eta)",
18  "RelValSingleElectronPt10": "Single Electron Pt 10",
19  "RelValSingleMuPt10": "Single Muon Pt 10",
20  "RelValSingleMuPt10Extended": "Single Muon Pt 10 (extended eta)",
21  "RelValSingleMuPt100": "Single Muon Pt 100",
22  "RelValTenMuE_0_200": "Ten muon Pt 0-200",
23 }
24 
25 _sampleFileName = {
26  "RelValMinBias": "minbias",
27  "RelValTTbar": "ttbar",
28  "RelValQCD_Pt_600_800": "qcd600",
29  "RelValQCD_Pt_3000_3500": "qcd3000",
30  "RelValQCD_FlatPt_15_3000": "qcdflat",
31  "RelValZMM": "zmm",
32  "RelValWjet_Pt_3000_3500": "wjet3000",
33  "RelValH125GGgluonfusion": "hgg",
34  "RelValSingleElectronPt35": "ele35",
35  "RelValSingleElectronPt35Extended": "ele35ext",
36  "RelValSingleElectronPt10": "ele10",
37  "RelValSingleMuPt10": "mu10",
38  "RelValSingleMuPt10Extended": "mu10ext",
39  "RelValSingleMuPt100": "mu100",
40  "RelValTenMuE_0_200": "tenmu200",
41 }
42 
43 _allTPEfficName = "All tracks (all TPs)"
44 _fromPVName = "Tracks from PV"
45 _fromPVAllTPName = "Tracks from PV (all TPs)"
46 _conversionName = "Tracks for conversions"
47 _gsfName = "Electron GSF tracks"
48 def _toHP(s):
49  return "High purity "+_lowerFirst(s)
50 def _allToHP(s):
51  return s.replace("All", "High purity")
52 def _ptCut(s):
53  return s.replace("Tracks", "Tracks pT > 0.9 GeV").replace("tracks", "tracks pT > 0.9 GeV")
54 _trackQualityNameOrder = collections.OrderedDict([
55  ("seeding_seeds", "Seeds"),
56  ("seeding_seedsa", "Seeds A"),
57  ("seeding_seedsb", "Seeds B"),
58  ("seeding_seedstripl", "Seeds triplets"),
59  ("seeding_seedspair", "Seeds pairs"),
60  ("building_", "Built tracks"),
61  ("", "All tracks"),
62  ("highPurity", "High purity tracks"),
63  ("Pt09", "Tracks pT > 0.9 GeV"),
64  ("highPurityPt09", "High purity tracks pT > 0.9 GeV"),
65  ("ByOriginalAlgo", "All tracks by originalAlgo"),
66  ("highPurityByOriginalAlgo", "High purity tracks by originalAlgo"),
67  ("ByAlgoMask", "All tracks by algoMask"),
68  ("highPurityByAlgoMask", "High purity tracks by algoMask"),
69  ("btvLike", "BTV-like"),
70  ("ak4PFJets", "AK4 PF jets"),
71  ("allTPEffic_", _allTPEfficName),
72  ("allTPEffic_highPurity", _allToHP(_allTPEfficName)),
73  ("fromPV_", _fromPVName),
74  ("fromPV_highPurity", _toHP(_fromPVName)),
75  ("fromPV_Pt09", _ptCut(_fromPVName)),
76  ("fromPV_highPurityPt09", _toHP(_ptCut(_fromPVName))),
77  ("fromPVAllTP_", _fromPVAllTPName),
78  ("fromPVAllTP_highPurity", _toHP(_fromPVAllTPName)),
79  ("fromPVAllTP_Pt09", _ptCut(_fromPVAllTPName)),
80  ("fromPVAllTP_highPurityPt09", _toHP(_ptCut(_fromPVAllTPName))),
81  ("fromPVAllTP2_", _fromPVAllTPName.replace("PV", "PV v2")),
82  ("fromPVAllTP2_highPurity", "High purity "+_lowerFirst(_fromPVAllTPName).replace("PV", "PV v2")),
83  ("fromPVAllTP2_Pt09", _fromPVAllTPName.replace("Tracks", "Tracks pT > 0.9 GeV").replace("PV", "PV v2")),
84  ("fromPVAllTP2_highPurityPt09", _toHP(_ptCut(_fromPVAllTPName)).replace("PV", "PV v2")),
85  ("conversion_", _conversionName),
86  ("gsf_", _gsfName),
87 ])
88 
89 _trackAlgoName = {
90  "ootb": "Out of the box",
91  "iter0" : "Iterative Step 0",
92  "iter1" : "Iterative Step 1",
93  "iter2" : "Iterative Step 2",
94  "iter3" : "Iterative Step 3",
95  "iter4" : "Iterative Step 4",
96  "iter5" : "Iterative Step 5",
97  "iter6" : "Iterative Step 6",
98  "iter7" : "Iterative Step 7",
99  "iter9" : "Iterative Step 9",
100  "iter10": "Iterative Step 10",
101 }
102 
103 _trackAlgoOrder = [
104  'ootb',
105  'initialStepPreSplitting',
106  'initialStep',
107  'highPtTripletStep',
108  'detachedQuadStep',
109  'detachedTripletStep',
110  'lowPtQuadStep',
111  'lowPtTripletStep',
112  'pixelPairStep',
113  'mixedTripletStep',
114  'pixelLessStep',
115  'tobTecStep',
116  'jetCoreRegionalStep',
117  'muonSeededStepInOut',
118  'muonSeededStepOutIn',
119  'duplicateMerge',
120  'convStep',
121  'conversionStep',
122  'ckfInOutFromConversions',
123  'ckfOutInFromConversions',
124  'electronGsf',
125  'iter0',
126  'iter1',
127  'iter2',
128  'iter3',
129  'iter4',
130  'iter5',
131  'iter6',
132  'iter7',
133  'iter9',
134  'iter10',
135 ]
136 
137 _pageNameMap = {
138  "summary": "Summary",
139  "vertex": "Vertex",
140  "v0": "V0",
141  "miniaod": "MiniAOD",
142  "timing": "Timing",
143 }
144 
145 _sectionNameMapOrder = collections.OrderedDict([
146  # These are for the summary page
147  ("seeding_seeds", "Seeds"),
148  ("building", "Built tracks"),
149  ("", "All tracks"),
150  ("highPurity", "High purity tracks"),
151  ("btvLike", "BTV-like"),
152  ("ak4PFJets", "AK4 PF jets"),
153  ("allTPEffic", _allTPEfficName),
154  ("allTPEffic_highPurity", _allTPEfficName.replace("All", "High purity")),
155  ("fromPV", _fromPVName),
156  ("fromPV_highPurity", "High purity "+_lowerFirst(_fromPVName)),
157  ("fromPVAllTP", _fromPVAllTPName),
158  ("fromPVAllTP_highPurity", "High purity "+_lowerFirst(_fromPVAllTPName)),
159  ("conversion", _conversionName),
160  ("gsf", _gsfName),
161  # These are for vertices
162  ("genvertex", "Gen vertices"),
163  ("pixelVertices", "Pixel vertices"),
164  ("selectedPixelVertices", "Selected pixel vertices"),
165  ("firstStepPrimaryVerticesPreSplitting", "firstStepPrimaryVerticesPreSplitting"),
166  ("firstStepPrimaryVertices", "firstStepPrimaryVertices"),
167  ("offlinePrimaryVertices", "All vertices (offlinePrimaryVertices)"),
168  ("selectedOfflinePrimaryVertices", "Selected vertices (selectedOfflinePrimaryVertices)"),
169  ("offlinePrimaryVerticesWithBS", "All vertices with BS constraint"),
170  ("selectedOfflinePrimaryVerticesWithBS", "Selected vertices with BS constraint"),
171  # These are for V0
172  ("k0", "K0"),
173  ("lambda", "Lambda"),
174 ])
175 _allTPEfficLegend = "All tracks, efficiency denominator contains all TrackingParticles"
176 _fromPVLegend = "Tracks from reco PV vs. TrackingParticles from gen PV (fake rate includes pileup tracks)"
177 _fromPVPtLegend = "Tracks (pT > 0.9 GeV) from reco PV vs. TrackingParticles from gen PV (fake rate includes pileup tracks)"
178 _fromPVAllTPLegend = "Tracks from reco PV, fake rate numerator contains all TrackingParticles (separates fake tracks from pileup tracks)"
179 _fromPVAllTPPtLegend = "Tracks (pT > 0.9 GeV) from reco PV, fake rate numerator contains all TrackingParticles (separates fake tracks from pileup tracks)"
180 _fromPVAllTP2Legend = "Tracks from reco PV (another method), fake rate numerator contains all TrackingParticles (separates fake tracks from pileup tracks)"
181 _fromPVAllTPPt2Legend = "Tracks (pT > 0.9 GeV) from reco PV (another method), fake rate numerator contains all TrackingParticles (separates fake tracks from pileup tracks)"
182 
184  return {
185  "btvLike": "BTV-like selected tracks",
186  "ak4PFJets": "Tracks from AK4 PF jets (jet corrected pT > 10 GeV)",
187  "allTPEffic": _allTPEfficLegend,
188  "allTPEffic_": _allTPEfficLegend,
189  "allTPEffic_highPurity": _allToHP(_allTPEfficLegend),
190  "fromPV": _fromPVLegend,
191  "fromPV_": _fromPVLegend,
192  "fromPV_highPurity": _toHP(_fromPVLegend),
193  "fromPV_Pt09": _fromPVPtLegend,
194  "fromPV_highPurity_Pt09": _toHP(_fromPVPtLegend),
195  "fromPVAllTP": _fromPVAllTPLegend,
196  "fromPVAllTP_": _fromPVAllTPLegend,
197  "fromPVAllTP_highPurity": _toHP(_fromPVAllTPLegend),
198  "fromPVAllTP_Pt09": _fromPVAllTPPtLegend,
199  "fromPVAllTP_highPurityPt09": _toHP(_fromPVAllTPPtLegend),
200  "fromPVAllTP2_": _fromPVAllTP2Legend,
201  "fromPVAllTP2_highPurity": _toHP(_fromPVAllTP2Legend),
202  "fromPVAllTP2_Pt09": _fromPVAllTPPt2Legend,
203  "fromPVAllTP2_highPurityPt09": _toHP(_fromPVAllTPPt2Legend),
204  }
205 
206 class Table:
207  # table [column][row]
208  def __init__(self, columnHeaders, rowHeaders, table, purpose, page, section):
209  if len(columnHeaders) != len(table):
210  raise Exception("Got %d columnHeaders for table with %d columns for page %s, section %s" % (len(columnHeaders), len(table), page, section))
211  lenRow = len(table[0])
212  for icol, column in enumerate(table):
213  if len(column) != lenRow:
214  raise Exception("Got non-square table, first column has %d rows, column %d has %d rows" % (lenRow, icol, len(column)))
215  if len(rowHeaders) != lenRow:
216  raise Exception("Got %d rowHeaders for table with %d rows" % (len(rowHeaders), lenRow))
217 
218  self._columnHeaders = columnHeaders
219  self._rowHeaders = rowHeaders
220  self._table = table
221 
222  self._purpose = purpose
223  self._page = page
224  self._section = section
225 
226  def getPurpose(self):
227  return self._purpose
228 
229  def getPage(self):
230  return self._page
231 
232  def getSection(self):
233  return self._section
234 
235  def ncolumns(self):
236  return len(self._table)
237 
238  def nrows(self):
239  return len(self._table[0])
240 
241  def columnHeaders(self):
242  return self._columnHeaders
243 
244  def rowHeaders(self):
245  return self._rowHeaders
246 
247  def tableAsColumnRow(self):
248  return self._table
249 
250  def tableAsRowColumn(self):
251  return map(list, zip(*self._table))
252 
254  class TrackingIteration: pass
255  class TrackingSummary: pass
256  class Vertexing: pass
257  class MiniAOD: pass
258  class Timing: pass
259 
260 class Page(object):
261  def __init__(self, title, sampleName):
262  self._content = [
263  '<html>',
264  ' <head>',
265  ' <title>%s</title>' % title,
266  ' </head>',
267  ' <body>',
268  ' '+sampleName,
269  ' <br/>',
270  ' <br/>',
271  ]
272 
273  self._plotSets = {}
274  self._tables = {}
275 
276  def addPlotSet(self, section, plotSet):
277  if section in self._plotSets:
278  self._plotSets[section].extend(plotSet)
279  else:
280  self._plotSets[section] = plotSet
281 
282  def addTable(self, section, table):
283  self._tables[section] = table
284 
285  def isEmpty(self):
286  for plotSet in self._plotSets.itervalues():
287  if len(plotSet) > 0:
288  return False
289 
290  if len(self._tables) > 0:
291  return False
292 
293  return True
294 
295  def write(self, fileName):
296  self._legends = []
298  self._columnHeaders = []
300  self._formatPlotSets()
301  self._formatTables()
302  self._formatLegend()
303 
304  self._content.extend([
305  ' </body>',
306  '</html>',
307  ])
308 
309  #print "Writing HTML report page", fileName
310  f = open(fileName, "w")
311  for line in self._content:
312  f.write(line)
313  f.write("\n")
314  f.close()
315 
316  def _appendLegend(self, section):
317  leg = ""
318  legends = _sectionNameLegend()
319  if section in legends:
320  if section in self._sectionLegendIndex:
321  leg = self._sectionLegendIndex[section]
322  else:
323  legnum = len(self._legends)+1
324  leg = "<sup>%d</sup>" % legnum
325  leg2 = "<sup>%d)</sup>" % legnum
326  self._legends.append("%s %s" % (leg2, legends[section]))
327  self._sectionLegendIndex[section] = leg
328  return leg
329 
330  def _formatPlotSets(self):
331  self._content.extend([
332  ' <table>'
333  ' <tr>',
334  ])
335 
336  fileTable = []
337 
338  sections = self._orderSets(self._plotSets.keys())
339  for isec, section in enumerate(sections):
340  leg = self._appendLegend(section)
341 
342  self._content.extend([
343  ' <td>%s%s</td>' % (self._mapSectionName(section), leg),
344  ])
345  files = [(os.path.basename(f), f) for f in self._plotSets[section]]
346  for row in fileTable:
347  found = False
348  for i, (bsf, f) in enumerate(files):
349  if bsf == row[0]:
350  row.append(f)
351  found = True
352  del files[i]
353  break
354  if not found:
355  row.append(None)
356  for bsf, f in files:
357  fileTable.append( [bsf] + [None]*isec + [f] )
358 
359  self._content.extend([
360  ' </tr>',
361  ])
362 
363  for row in fileTable:
364  self._content.append(' <tr>')
365  bs = row[0]
366  for elem in row[1:]:
367  if elem is not None:
368  self._content.append(' <td><a href="%s">%s</a></td>' % (elem, bs))
369  else:
370  self._content.append(' <td></td>')
371  self._content.append(' </tr>')
372 
373 
374  self._content.extend([
375  ' </table>',
376  ])
377 
378  def _appendColumnHeader(self, header):
379  leg = ""
380  if header in self._columnHeadersIndex:
381  leg = self._columnHeadersIndex[header]
382  else:
383  leg = str(chr(ord('A')+len(self._columnHeaders)))
384  self._columnHeaders.append("%s: %s" % (leg, header))
385  self._columnHeadersIndex[header] = leg
386  return leg
387 
388  def _formatTables(self):
389  def _allNone(row):
390  for item in row:
391  if item is not None:
392  return False
393  return True
394 
395  sections = self._orderSets(self._tables.keys())
396  for isec, section in enumerate(sections):
397  leg = self._appendLegend(section)
398 
399  table = self._tables[section]
400  self._content.extend([
401  ' <br/>',
402  ' %s%s' % (self._mapSectionName(section), leg),
403  ' <table border="1">'
404  ])
405 
406  # table is stored in column-row, need to transpose
407  data = table.tableAsRowColumn()
408 
409  self._content.extend([
410  ' <tr>'
411  ' <td></td>'
412  ])
413  heads = table.columnHeaders()
414  if max(map(lambda h: len(h), heads)) > 20:
415  heads = [self._appendColumnHeader(h) for h in heads]
416  for head in heads:
417  self._content.append(' <td>%s</td>' % head)
418  self._content.append(' </tr>')
419 
420  for irow, row in enumerate(data):
421  # Skip row if all values are non-existent
422  if _allNone(row):
423  continue
424 
425  self._content.extend([
426  ' <tr>'
427  ' <td>%s</td>' % table.rowHeaders()[irow]
428  ])
429  # align the number columns to right
430  for icol, item in enumerate(row):
431  formatted = str(item) if item is not None else ""
432  self._content.append(' <td align="right">%s</td>' % formatted)
433  self._content.append(' </tr>')
434 
435  self._content.append(' </table>')
436 
437  for shortenedColumnHeader in self._columnHeaders:
438  self._content.append(' %s<br/>' % shortenedColumnHeader)
439  self._columnHeaders = []
440  self._columnHeadersIndex = {}
441 
442  def _formatLegend(self):
443  if len(self._legends) > 0:
444  self._content.extend([
445  ' <br/>'
446  ' Details:</br>',
447  ])
448  for leg in self._legends:
449  self._content.append(' %s<br/>' % leg)
450 
451 
452  def _mapSectionName(self, section):
453  return _sectionNameMapOrder.get(section, section)
454 
455  def _orderSets(self, keys):
456  ret = []
457  for section in _sectionNameMapOrder.keys():
458  if section in keys:
459  ret.append(section)
460  keys.remove(section)
461  ret.extend(keys)
462  return ret
463 
464 class PageSet(object):
465  def __init__(self, title, sampleName, sample, fastVsFull, pileupComparison):
466  self._title = title
467  self._sampleName = sampleName
468  self._pages = collections.OrderedDict()
469 
470  self._prefix = ""
471  if sample.fastsim():
472  self._prefix += "fast_"
473  if fastVsFull:
474  self._prefix += "full_"
475 
476  self._prefix += _sampleFileName.get(sample.label(), sample.label())+"_"
477  if hasattr(sample, "hasScenario") and sample.hasScenario():
478  self._prefix += sample.scenario()+"_"
479 
480  if hasattr(sample, "hasPileup"):
481  if sample.hasPileup():
482  self._prefix += "pu"+str(sample.pileupNumber())+"_"+sample.pileupType()+"_"
483  else:
484  self._prefix += "nopu_"
485  if pileupComparison:
486  self._prefix += "vspu_"
487 
488 
489  def _getPage(self, key, pageClass):
490  if key not in self._pages:
491  page = pageClass(self._title, self._sampleName)
492  self._pages[key] = page
493  else:
494  page = self._pages[key]
495  return page
496 
497  def addPlotSet(self, plotterFolder, dqmSubFolder, plotFiles):
498  pageKey = plotterFolder.getPage()
499  if pageKey is None:
500  if dqmSubFolder is not None:
501  pageKey = dqmSubFolder.translated
502  else:
503  pageKey = plotterFolder.getName()
504 
505  page = self._getPage(pageKey, Page)
506  sectionName = plotterFolder.getSection()
507  if sectionName is None:
508  if plotterFolder.getPage() is not None and dqmSubFolder is not None:
509  sectionName = dqmSubFolder.translated
510  else:
511  sectionName = ""
512 
513  page.addPlotSet(sectionName, plotFiles)
514 
515  def addTable(self, table):
516  if table is None:
517  return
518 
519  page = self._getPage(table.getPage(), Page)
520  page.addTable(table.getSection(), table)
521 
522  def write(self, baseDir):
523  #print "TrackingPageSet.write"
524  ret = []
525 
526  keys = self._orderPages(self._pages.keys())
527  for key in keys:
528  page = self._pages[key]
529  if page.isEmpty():
530  continue
531 
532  fileName = "%s%s.html" % (self._prefix, key)
533  page.write(os.path.join(baseDir, fileName))
534  ret.append( (self._mapPagesName(key), fileName) )
535  return ret
536 
537  def _mapPagesName(self, name):
538  return _pageNameMap.get(name, name)
539 
540  def _orderPages(self, keys):
541  return keys
542 
543 
544 
546  def __init__(self, *args, **kwargs):
547  super(TrackingIterPage, self).__init__(*args, **kwargs)
548 
549  def _mapSectionName(self, quality):
550  return _trackQualityNameOrder.get(quality, quality)
551 
552  def _orderSets(self, qualities):
553  ret = []
554  for qual in _trackQualityNameOrder.keys():
555  if qual in qualities:
556  ret.append(qual)
557  qualities.remove(qual)
558  ret.extend(qualities)
559  return ret
560 
562  def __init__(self, *args, **kwargs):
563  super(TrackingPageSet, self).__init__(*args, **kwargs)
564 
565  def addPlotSet(self, plotterFolder, dqmSubFolder, plotFiles):
566  (algo, quality) = dqmSubFolder.translated
567 
568  pageName = algo
569  sectionName = quality
570 
571  # put all non-iterative stuff under OOTB
572  #
573  # it is bit of a hack to access trackingPlots.TrackingPlotFolder this way,
574  # but it was simple and it works
575  if algo != "ootb" and not plotterFolder._plotFolder.isAlgoIterative(algo):
576  pageName = "ootb"
577  sectionName = algo
578 
579  folderName = plotterFolder.getName()
580  if folderName != "":
581  sectionName = folderName+"_"+sectionName
582 
583  page = self._getPage(pageName, TrackingIterPage)
584  page.addPlotSet(sectionName, plotFiles)
585 
586  def _mapPagesName(self, algo): # algo = pageName
587  return _trackAlgoName.get(algo, algo)
588 
589  def _orderPages(self, algos):
590  ret = []
591  for algo in _trackAlgoOrder:
592  if algo in algos:
593  ret.append(algo)
594  algos.remove(algo)
595  ret.extend(algos)
596  return ret
597 
598 
599 
601  def __init__(self, sample, title, fastVsFull, pileupComparison):
602  self._sample = sample
603 
604  self._sampleName = ""
605  if sample.fastsim():
606  self._sampleName += "FastSim "
607  if fastVsFull:
608  self._sampleName += "vs FullSim "
609 
610  pileup = ""
611  if hasattr(sample, "hasPileup"):
612  pileup = "with no pileup"
613  if sample.hasPileup():
614  pileup = "with %d pileup (%s)" % (sample.pileupNumber(), sample.pileupType())
615  if pileupComparison is not None:
616  pileup += " "+pileupComparison
617  if hasattr(sample, "customPileupLabel"):
618  pileup = sample.customPileupLabel()
619 
620  scenario = ""
621  if hasattr(sample, "hasScenario") and sample.hasScenario():
622  scenario = " (\"%s\")" % sample.scenario()
623  self._sampleName += "%s sample%s %s" % (_sampleName.get(sample.name(), sample.name()), scenario, pileup)
624 
625  params = [title, self._sampleName, sample, fastVsFull, pileupComparison is not None]
626  self._summaryPage = PageSet(*params)
628  self._vertexPage = PageSet(*params)
629  self._miniaodPage = PageSet(*params)
630  self._timingPage = PageSet(*params)
631  self._otherPages = PageSet(*params)
632 
639  }
640 
641  def addPlots(self, plotterFolder, dqmSubFolder, plotFiles):
642  page = self._purposePageMap.get(plotterFolder.getPurpose(), self._otherPages)
643  page.addPlotSet(plotterFolder, dqmSubFolder, plotFiles)
644 
645  def addTable(self, table):
646  if table is None:
647  return
648 
649  page = self._purposePageMap.get(table.getPurpose(), self._otherPages)
650  page.addTable(table)
651  params = []
652 
653  def write(self, baseDir):
654  ret = [
655  " "+self._sampleName,
656  " <br/>",
657  " <ul>",
658  ]
659 
660  for pages in [self._summaryPage, self._iterationPages, self._vertexPage, self._miniaodPage, self._timingPage, self._otherPages]:
661  labelFiles = pages.write(baseDir)
662  for label, fname in labelFiles:
663  ret.append(' <li><a href="%s">%s</a></li>' % (fname, label))
664 
665  ret.extend([
666  ' </ul>',
667  ' <br/>',
668  ])
669 
670  return ret
671 
673  def __init__(self, validationName, newBaseDir):
674  self._title = "Tracking validation "+validationName
675  self._newBaseDir = newBaseDir
676 
677  self._index = [
678  '<html>',
679  ' <head>',
680  ' <title>%s</title>' % self._title,
681  ' </head>',
682  ' <body>',
683  ]
684 
685  self._sections = collections.OrderedDict()
686 
687  def addNote(self, note):
688  self._index.append(' <p>%s</p>'%note)
689 
690  def beginSample(self, sample, fastVsFull=False, pileupComparison=None):
691  # Fast vs. Full becomes just after the corresponding Fast
692  # Same for PU
693  rightAfterRefSample = fastVsFull or (pileupComparison is not None)
694 
695  key = (sample.digest(), rightAfterRefSample)
696  if key in self._sections:
697  self._currentSection = self._sections[key]
698  else:
699  self._currentSection = IndexSection(sample, self._title, fastVsFull, pileupComparison)
700  self._sections[key] = self._currentSection
701 
702  def addPlots(self, *args, **kwargs):
703  self._currentSection.addPlots(*args, **kwargs)
704 
705  def addTable(self, *args, **kwargs):
706  self._currentSection.addTable(*args, **kwargs)
707 
708  def write(self):
709  # Reorder sections such that Fast vs. Full becomes just after the corresponding Fast
710  keys = self._sections.iterkeys()
711  newkeys = []
712  for key in keys:
713  if not key[1]:
714  newkeys.append(key)
715  continue
716  # is fast vs full
717  ind_fast = newkeys.index( (key[0], False) )
718  newkeys.insert(ind_fast+1, key)
719 
720  for key in newkeys:
721  section = self._sections[key]
722  self._index.extend(section.write(self._newBaseDir))
723 
724  self._index.extend([
725  " </body>",
726  "</html>",
727  ])
728 
729  f = open(os.path.join(self._newBaseDir, "index.html"), "w")
730  for line in self._index:
731  f.write(line)
732  f.write("\n")
733  f.close()
734 
736  def __init__(self):
737  pass
738 
739  def beginSample(self, *args, **kwargs):
740  pass
741 
742  def addPlots(self, *args, **kwargs):
743  pass
744 
745  def addTable(self, *args, **kwargs):
746  pass
def _formatPlotSets
Definition: html.py:330
_purpose
Definition: html.py:222
def addTable
Definition: html.py:705
def ncolumns
Definition: html.py:235
_legends
Definition: html.py:296
def addPlotSet
Definition: html.py:497
def rowHeaders
Definition: html.py:244
_content
Definition: html.py:262
def _allToHP
Definition: html.py:50
_rowHeaders
Definition: html.py:219
def addPlotSet
Definition: html.py:276
def _sectionNameLegend
Definition: html.py:183
def getPurpose
Definition: html.py:226
def tableAsRowColumn
Definition: html.py:250
def columnHeaders
Definition: html.py:241
_columnHeaders
Definition: html.py:218
def addNote
Definition: html.py:687
def __init__
Definition: html.py:208
def _formatTables
Definition: html.py:388
def beginSample
Definition: html.py:690
def _lowerFirst
Definition: html.py:4
def _getPage
Definition: html.py:489
def _formatLegend
Definition: html.py:442
def getPage
Definition: html.py:229
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
def _orderPages
Definition: html.py:540
def addPlots
Definition: html.py:702
_columnHeaders
Definition: html.py:298
def _orderSets
Definition: html.py:455
def __init__
Definition: html.py:673
def write
Definition: html.py:522
_plotSets
Definition: html.py:273
def __init__
Definition: html.py:261
def _mapPagesName
Definition: html.py:537
def addTable
Definition: html.py:515
def __init__
Definition: html.py:465
def tableAsColumnRow
Definition: html.py:247
def nrows
Definition: html.py:238
def getSection
Definition: html.py:232
def _appendLegend
Definition: html.py:316
def write
Definition: html.py:295
_columnHeadersIndex
Definition: html.py:299
def _ptCut
Definition: html.py:52
_section
Definition: html.py:224
def _mapSectionName
Definition: html.py:452
_tables
Definition: html.py:274
def _toHP
Definition: html.py:48
def isEmpty
Definition: html.py:285
def addTable
Definition: html.py:282
_sectionLegendIndex
Definition: html.py:297
def _appendColumnHeader
Definition: html.py:378