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