ATLAS Offline Software
dq_defect_info_table.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 from argparse import ArgumentParser
4 from os import listdir, makedirs
5 from os.path import dirname, exists, join as pjoin
6 from pkg_resources import resource_filename
7 from shutil import copy2
8 from textwrap import dedent
9 
10 from genshi import HTML
11 from genshi.output import HTMLSerializer, encode
12 from genshi.template import MarkupTemplate
13 
14 from DQUtils import fetch_iovs
15 from DQUtils.general import timer
16 from DQUtils.logger import init_logger; init_logger(verbose=2)
17 from DQUtils.lumi import fetch_lumi_inputs, compute_lumi_many_channels
18 
19 from DQDefects import DefectsDB
20 
21 from IPython.Shell import IPShellEmbed; ip = IPShellEmbed(["-pdb"])
22 
23 GRAPH_URL = "http://atlasdqm.web.cern.ch/atlasdqm/defect_graph/HEAD"
24 
25 
28 headings = [
29  ("", "V"),
30  ("", "T"),
31  ("", "U"),
32  ("", "B"),
33  ("name_with_url", "Name"),
34  ("description", "Description"),
35  ("nruns", "# Runs"),
36  ("latest_run", "Latest Run"),
37  ("rec_lb_frac", "Potentially Recoverable LB %"),
38  ("lumi", HTML("Luminosity (pb<sup>-1</sup>)")),
39  #("nlumi", "nlumi"),
40  #("nlumi_rec", "nlumi"),
41 ]
42 
43 heading_names, heading_titles = zip(*headings)
44 
45 content_string = "".join("<td>{{d.{0}}}</td>".format(x)
46  for x in heading_names if x)
47 
48 class Defect(object):
49  """
50  A defect instance. Forms a row in the table.
51  """
52  def __init__(self, name, description, iovs, virtual, intolerable, lumi):
53  if description == name:
54  # Don't bother pretending that there is a description if it is just
55  # equal to the name
56  description = ""
57 
58  (self.name, self.description, self.iovs, self.lumi, self.virtual,
59  self.intolerable) = (
60  name, description, iovs, lumi / 1e6, virtual, intolerable)
61  self.nlumi = sum(iov.length for iov in iovs
62  if iov.since.run == iov.until.run)
63  self.nlumi_rec = sum(iov.length for iov in iovs
64  if iov.recoverable and iov.since.run == iov.until.run)
65  if self.nlumi and self.nlumi_rec:
66  self.rec_lb_frac = "{0:.0%}".format(self.nlumi_rec / self.nlumi)
67  else:
68  self.rec_lb_frac = "-"
69 
70  self.users = set(iov.user for iov in iovs)
71  self.users -= set(["sys:virtual"]) # exclude the "virtual" user.
72  self.bots = set(u for u in self.users if u.startswith("sys:"))
73  self.users -= self.bots
74 
75  runs = iovs.runs
76  self.nruns = len(runs) if runs else "-"
77  self.latest_run = max(runs) if runs else "-"
78  self.lumi = "{0:.3f}".format(self.lumi) if runs else "-"
79 
80  @property
81  def name_with_url(self):
82  if self.virtual or self.intolerable:
83  return '<a href="{0}/{1}.svg">{1}</a>'.format(GRAPH_URL, self.name)
84  else:
85  return "{0}".format(self.name)
86 
87  @property
88  def content(self):
89  td = '<td class="icon {class_}"><span>{0}</span></td>'
90  bot_cls = user_cls = ""
91  if len(self.users) == 1: user_cls = "user"
92  if len(self.users) > 1: user_cls = "users"
93  if len(self.bots): bot_cls = "bots"
94 
95  virt_class = "virtual" if self.virtual else "primary"
96  tol_class = "intolerable" if self.intolerable else "tolerable"
97  virt_sort = 1 if self.virtual else 0
98  tol_sort = 1 if self.virtual else 0
99 
100  c = [
101  td.format(virt_sort, class_=virt_class),
102  td.format(tol_sort, class_=tol_class),
103  td.format(", ".join(self.users), class_=user_cls),
104  td.format(", ".join(self.bots), class_=bot_cls),
105  content_string.format(d=self)
106  ]
107  return "".join(c)
108 
109 def build_table(**kwargs):
110  """
111  Build the HTML content
112  """
113  path = resource_filename("DQDefects.data", "table.html")
114  with open(path) as fd:
115  template = MarkupTemplate(fd, path)
116 
117  stream = template.generate(HTML=HTML, **kwargs)
118  serializer = HTMLSerializer(doctype="html5")
119  content = encode(serializer(stream))
120  return content
121 
122 def build_defects(descriptions, virtuals, intolerables, lbs, lumis, all_defects):
123 
124  with timer("Sort defects by channel"):
125  dbc = all_defects.by_channel
126 
127  with timer("Compute luminosities"):
128  lumi_by_defect = compute_lumi_many_channels(lbs, lumis, all_defects)
129 
130  defects = []
131 
132  for name, description in sorted(descriptions.iteritems()):
133  virtual, intolerable = name in virtuals, name in intolerables
134  defect = Defect(name, description, dbc[name], virtual, intolerable,
135  lumi_by_defect.get(name, 0))
136  defects.append(defect)
137 
138  defects.sort(key=lambda d: (d.virtual, not d.intolerable))
139 
140  return defects
141 
142 def copy_art(target_dir):
143  art_base = dirname(resource_filename("DQDefects.data", "table.html"))
144 
145  for filename in listdir(art_base):
146  _, _, ext = filename.rpartition(".")
147  if ext.lower() not in ("png", "js", "css"):
148  continue
149  copy2(pjoin(art_base, filename), pjoin(target_dir, filename))
150 
151 def main():
152  d = DefectsDB()
153 
154  iov_range = None, None #
155  iov_range = 185000 << 32, 185500 << 32
156  #iov_range = 177682 << 32, 200000 << 32
157 
158  with timer("Fetch defect info"):
159  all_defects = d.retrieve(*iov_range)
160 
161  with timer("fetch peripheral information"):
162  descriptions = d.all_defect_descriptions
163  intolerable = d.get_intolerable_defects()
164  virtual = d.virtual_defect_names
165 
166  with timer("Fetch lumi inputs"):
167  lbs, lumis = fetch_lumi_inputs(iov_range, "ONLINE")
168 
169  d = build_defects(descriptions, virtual, intolerable, lbs, lumis, all_defects)
170 
171  target_dir = "/afs/cern.ch/user/p/pwaller/www/defects/test"
172  art_dir = pjoin(target_dir, "extern")
173 
174  if not exists(art_dir):
175  makedirs(art_dir)
176 
177  copy_art(art_dir)
178 
179  content = build_table(headings=heading_titles, defects=d)
180  with open(pjoin(target_dir, "test.html"), "w") as fd:
181  fd.write(content)
182 
183 
184 if __name__ == "__main__":
185  main()
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename R::value_type > sorted(const R &r, PROJ proj={})
Helper function to create a sorted vector from an unsorted range.
python.lumi.compute_lumi_many_channels
def compute_lumi_many_channels(lbs, lumis, iovs, exclude_iovsets=[], good_runs=None)
Definition: lumi.py:66
dq_defect_info_table.Defect.name_with_url
def name_with_url(self)
Definition: dq_defect_info_table.py:81
dq_defect_info_table.Defect.latest_run
latest_run
Definition: dq_defect_info_table.py:77
vtune_athena.format
format
Definition: vtune_athena.py:14
dq_defect_info_table.Defect.__init__
def __init__(self, name, description, iovs, virtual, intolerable, lumi)
Definition: dq_defect_info_table.py:52
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
dq_defect_info_table.copy_art
def copy_art(target_dir)
Definition: dq_defect_info_table.py:142
python.dummyaccess.listdir
def listdir(dirname)
Definition: dummyaccess.py:6
dirname
std::string dirname(std::string name)
Definition: utils.cxx:200
dq_defect_info_table.main
def main()
Definition: dq_defect_info_table.py:151
python.lumi.fetch_lumi_inputs
def fetch_lumi_inputs(range_iov, tag="OflLumi-7TeV-002")
Definition: lumi.py:125
python.utils.AtlRunQueryTimer.timer
def timer(name, disabled=False)
Definition: AtlRunQueryTimer.py:85
dq_defect_info_table.build_table
def build_table(**kwargs)
Definition: dq_defect_info_table.py:109
dq_defect_info_table.Defect.nruns
nruns
Definition: dq_defect_info_table.py:76
dq_defect_info_table.Defect.users
users
Definition: dq_defect_info_table.py:70
dq_defect_info_table.Defect.rec_lb_frac
rec_lb_frac
Definition: dq_defect_info_table.py:66
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
AtlasMcWeight::encode
number_type encode(double weight)
Definition: AtlasMcWeight.cxx:65
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
dq_defect_info_table.Defect.nlumi
nlumi
Definition: dq_defect_info_table.py:61
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.logger.init_logger
def init_logger(verbose=False, quiet=False)
Definition: logger.py:113
dq_defect_info_table.build_defects
def build_defects(descriptions, virtuals, intolerables, lbs, lumis, all_defects)
Definition: dq_defect_info_table.py:122
Trk::open
@ open
Definition: BinningType.h:40
dq_defect_info_table.Defect.content
def content(self)
Definition: dq_defect_info_table.py:88
pickleTool.object
object
Definition: pickleTool.py:29
python.dummyaccess.exists
def exists(filename)
Definition: dummyaccess.py:9
dq_defect_info_table.Defect.nlumi_rec
nlumi_rec
Definition: dq_defect_info_table.py:63
dq_defect_info_table.Defect.bots
bots
Definition: dq_defect_info_table.py:72
dq_defect_info_table.Defect
Definition: dq_defect_info_table.py:48
dq_defect_info_table.Defect.lumi
lumi
Definition: dq_defect_info_table.py:78