CMS 3D CMS Logo

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