CMS 3D CMS Logo

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