ATLAS Offline Software
Loading...
Searching...
No Matches
dq_defect_summary.py
Go to the documentation of this file.
1#!/bin/env python
2# Author: Steve Farrell <sfarrell@cern.ch>
3# Part of the DataQuality/DQDefects package
4# June 2012
5
6import sys
7import fnmatch
8
9from argparse import ArgumentParser
10from textwrap import dedent
11import logging; log = logging.getLogger("dq_defect_summary")
12
13from DQDefects import DefectsDB
14from DQDefects.db import DEFAULT_CONNECTION_STRING
15
16from DQUtils.general import timer
17from DQUtils.logger import init_logger
18from DQUtils.lumi import fetch_lumi_inputs, compute_lumi, compute_lumi_many_channels
19from DQUtils.periods import fetch_project_period_runs
20
21
23 """
24 Class to hold all the information needed for printing DQ summary for one defect
25 """
26 def __init__(self, name, description, depends, virtual, intolerable, lumi):
27 if description == name:
28 # Don't bother pretending that there is a description if it is just
29 # equal to the name
30 description = ""
31
32 (self.name, self.description, self.depends, self.lumi, self.virtual,
33 self.intolerable) = (
34 name, description, depends, lumi, virtual, intolerable)
35
36 self.lumiStr = "{0:<.2f}".format(self.lumi)
37
38
39def print_virtual_tree(defect, all_defects, depth=0, max_depth=0):
40
41 if defect.lumi > 0 or depth == 0:
42 print("| "*depth + defect.lumiStr, defect.name)
43
44 if max_depth < 0 or depth < max_depth:
45 parents = [ all_defects[d] for d in defect.depends ]
46
47 # Sort list of parents by lumi
48 parents.sort(key=lambda d: d.lumi, reverse=True)
49
50 # Recursively call this function on defects down the tree
51 for parent in parents:
52 print_virtual_tree(parent, all_defects, depth+1, max_depth)
53
54
55def get_primary_defects(defect, all_defects):
56 primary_defects = set()
57 def recursive_search(defect):
58 if defect.virtual:
59 for parent in defect.depends:
60 recursive_search(all_defects[parent])
61 else:
62 primary_defects.add(defect)
63 recursive_search(defect)
64 return primary_defects
65
66def print_primary_defects(defect, all_defects, max_primary):
67 primary_list = sorted(get_primary_defects(defect, all_defects),
68 key=lambda d: d.lumi, reverse=True)
69 print(defect.lumiStr, defect.name)
70 if max_primary >= 0:
71 del primary_list[max_primary:]
72 for primary in primary_list:
73 if primary.lumi > 0:
74 print(" " + primary.lumiStr, primary.name)
75
76def main():
77 parser = ArgumentParser(description="Summarize DQ Defects")
78 a = parser.add_argument
79 add_group = parser.add_argument_group
80
81 # Specify range to process
82 a("-p", "--project", default="data15_13TeV",
83 help="Data project (default: data15_13TeV)")
84 a("-P", "--period", default=None, nargs="*", help="Data period(s)")
85 a("-r", "--run", default=None, nargs="*", help="Run number(s) to process")
86 a("-R", "--range", help="Inclusive run range: e.g. 150000-151000")
87
88 # Specify defects to process
89 a("-d", "--defects", default=None, nargs="*",
90 help="Defects to process. Use * for wildcard (default: None)")
91
92 # Print mode, primary or virtual tree
93 a("-q", "--tree", action="store_true",
94 help="Dump virtual defect tree. Set depth with -D")
95
96 # Other job options
97 a("-n", "--num-primary", default=-1, type=int,
98 help="Max number of primary defects to display in default mode (default: all)")
99 a("-D", "--depth", default=-1, type=int,
100 help="Max virtual defect depth to print in virtual tree mode (default: all)")
101 a("-c", "--connection-string", default=DEFAULT_CONNECTION_STRING,
102 help="Database connection to use (default: %s)" % DEFAULT_CONNECTION_STRING)
103 a("-l", "--lumi-tag", default='OflLumi-8TeV-002',
104 help="Luminosity tag (default: OflLumi-8TeV-002)")
105 a("-t", "--tag", default="HEAD",
106 help="Tag to use (default: HEAD)")
107 a("--require-ready", default=True, type=int,
108 help="Calculate luminosity with respect to ATLAS READY (default: True)")
109 a("--reject-busy", default=False, type=int,
110 help="Calculate luminosity with respect to not-busy (default: False)")
111 a("--nb", action="store_true", help="Show lumi in units of 1/nb instead of 1/pb")
112 a("-v", "--verbose", default=1, type=int,
113 help="Set verbosity (default: 1)")
114
115 args = parser.parse_args()
116
117 init_logger(verbose=args.verbose)
118
119 # Units
120 units = 1e3 if args.nb else 1e6
121 unit_string = "(1/nb)" if args.nb else "(1/pb)"
122
123 # Instantiate the database interface
124 with timer("Instantiate DefectsDB"):
125 db = DefectsDB(args.connection_string, tag=args.tag)
126
127 # Set runs to process
128 # TODO: control these via run lumi iovs, rather than a set of good_runs
129 # similar to how it is done in dq_defect_compare_tags
130 good_runs = None
131 if args.range:
132 since, until = map(int, args.range.split("-"))
133 elif args.run:
134 good_runs = set( map(int, args.run) )
135 #since, until = args.run, args.run+1
136 since, until = min(good_runs), max(good_runs)+1
137 else:
138 project_dict = fetch_project_period_runs()
139 if args.period:
140 #good_runs = set( project_dict[args.project][args.period] )
141 good_runs = set()
142 for period in args.period:
143 good_runs.update( project_dict[args.project][period] )
144 since, until = min(good_runs), max(good_runs)+1
145 else:
146 good_runs = set()
147 for period, period_runs in project_dict[args.project].items():
148 good_runs.update(period_runs)
149 since, until = min(good_runs), max(good_runs)+1
150
151
152 iov_range = (since, 0), (until, 0)
153 log.info("Processing range: " + str(iov_range))
154 #log.info(good_runs)
155
156 # Fetch all defect IOVs in range
157 with timer("Fetch defects"):
158 all_defect_iovs = db.retrieve(*iov_range)
159
160 # Grab defect information
161 with timer("Fetch defect info"):
162 descriptions = db.all_defect_descriptions
163 intolerables = db.get_intolerable_defects()
164 virtuals = db.virtual_defect_names
165
166 # Grab lbs and lumi variables in range
167 with timer("Fetch lumi inputs"):
168 lbs, lumis = fetch_lumi_inputs(iov_range, args.lumi_tag)
169
170 # Compute lumi per channel
171 with timer("Compute luminosities"):
172 # Filtering defects
173 exclude_iovs = []
174 # Defect for ATLAS READY
175 if args.require_ready:
176 exclude_iovs.append(all_defect_iovs.by_channel["GLOBAL_NOTREADY"])
177 # Defect for detector busy
178 if args.reject_busy:
179 exclude_iovs.append(all_defect_iovs.by_channel["GLOBAL_BUSY"])
180 # Compute total luminosity
181 lumi_total = compute_lumi(lbs, lumis, lbs, exclude_iovsets=exclude_iovs,
182 good_runs=good_runs)/units
183 # Compute luminosity for all defects
184 lumi_by_defect = compute_lumi_many_channels(lbs, lumis, all_defect_iovs,
185 exclude_iovsets=exclude_iovs,
186 good_runs=good_runs)
187
188 my_defect_names = []
189 if args.defects:
190 all_defect_names = db.defect_names | db.virtual_defect_names
191 for defect_arg in args.defects:
192 my_defect_names.extend(sorted(fnmatch.filter(all_defect_names, defect_arg)))
193
194 logics = db.virtual_defect_logics
195
196 # Build the defect objects
197 all_defects = {}
198 for name, description in sorted(descriptions.items()):
199 virtual, intolerable = name in virtuals, name in intolerables
200 depends = []
201 logic = logics.get(name, None)
202 if logic: depends = logic.clauses
203 all_defects[name] = Defect(name, description, depends, virtual, intolerable,
204 lumi_by_defect.get(name, 0)/units)
205
206 # My defects
207 my_defects = [ all_defects[d] for d in my_defect_names ]
208 my_defects.sort(key=lambda d: d.lumi, reverse=True)
209
210 print("\nTotal luminosity", unit_string, "\n")
211 print("{0:<.2f}".format(lumi_total))
212
213 print("\nDefect luminosity", unit_string, "\n")
214
215 #for defect_name in my_defect_names:
216 for defect in my_defects:
217
218 if args.tree:
219 # Virtual defect tree
220 print_virtual_tree(defect, all_defects, depth=0, max_depth=args.depth)
221 else:
222 # Primary defect dump
223 print_primary_defects(defect, all_defects, max_primary=args.num_primary)
224
225 print()
226
227
228if __name__ == "__main__":
229 main()
static Double_t a
void print(char *figname, TCanvas *c1)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
__init__(self, name, description, depends, virtual, intolerable, lumi)
STL class.
STL class.
print_virtual_tree(defect, all_defects, depth=0, max_depth=0)
get_primary_defects(defect, all_defects)
print_primary_defects(defect, all_defects, max_primary)