9 from argparse
import ArgumentParser
10 from textwrap
import dedent
11 import logging; log = logging.getLogger(
"dq_defect_summary")
13 from DQDefects
import DefectsDB
14 from DQDefects.db
import DEFAULT_CONNECTION_STRING
16 from DQUtils.general
import timer
17 from DQUtils.logger
import init_logger
18 from DQUtils.lumi
import fetch_lumi_inputs, compute_lumi, compute_lumi_many_channels
19 from DQUtils.periods
import fetch_project_period_runs
24 Class to hold all the information needed for printing DQ summary for one defect
26 def __init__(self, name, description, depends, virtual, intolerable, lumi):
27 if description == name:
32 (self.name, self.description, self.depends, self.lumi, self.virtual,
34 name, description, depends, lumi, virtual, intolerable)
41 if defect.lumi > 0
or depth == 0:
42 print(
"| "*depth + defect.lumiStr, defect.name)
44 if max_depth < 0
or depth < max_depth:
45 parents = [ all_defects[d]
for d
in defect.depends ]
48 parents.sort(key=
lambda d: d.lumi, reverse=
True)
51 for parent
in parents:
56 primary_defects =
set()
57 def recursive_search(defect):
59 for parent
in defect.depends:
60 recursive_search(all_defects[parent])
62 primary_defects.add(defect)
63 recursive_search(defect)
64 return primary_defects
68 key=
lambda d: d.lumi, reverse=
True)
69 print(defect.lumiStr, defect.name)
71 del primary_list[max_primary:]
72 for primary
in primary_list:
74 print(
" " + primary.lumiStr, primary.name)
77 parser = ArgumentParser(description=
"Summarize DQ Defects")
78 a = parser.add_argument
79 add_group = parser.add_argument_group
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")
89 a(
"-d",
"--defects", default=
None, nargs=
"*",
90 help=
"Defects to process. Use * for wildcard (default: None)")
93 a(
"-q",
"--tree", action=
"store_true",
94 help=
"Dump virtual defect tree. Set depth with -D")
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)")
115 args = parser.parse_args()
120 units = 1e3
if args.nb
else 1e6
121 unit_string =
"(1/nb)" if args.nb
else "(1/pb)"
124 with timer(
"Instantiate DefectsDB"):
125 db = DefectsDB(args.connection_string, tag=args.tag)
132 since, until = map(int, args.range.split(
"-"))
134 good_runs =
set( map(int, args.run) )
136 since, until =
min(good_runs),
max(good_runs)+1
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
147 for period, period_runs
in project_dict[args.project].
iteritems():
148 good_runs.update(period_runs)
149 since, until =
min(good_runs),
max(good_runs)+1
152 iov_range = (since, 0), (until, 0)
153 log.info(
"Processing range: " +
str(iov_range))
157 with timer(
"Fetch defects"):
158 all_defect_iovs = db.retrieve(*iov_range)
161 with timer(
"Fetch defect info"):
162 descriptions = db.all_defect_descriptions
163 intolerables = db.get_intolerable_defects()
164 virtuals = db.virtual_defect_names
167 with timer(
"Fetch lumi inputs"):
171 with timer(
"Compute luminosities"):
175 if args.require_ready:
176 exclude_iovs.append(all_defect_iovs.by_channel[
"GLOBAL_NOTREADY"])
179 exclude_iovs.append(all_defect_iovs.by_channel[
"GLOBAL_BUSY"])
181 lumi_total =
compute_lumi(lbs, lumis, lbs, exclude_iovsets=exclude_iovs,
182 good_runs=good_runs)/units
185 exclude_iovsets=exclude_iovs,
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)))
194 logics = db.virtual_defect_logics
198 for name, description
in sorted(descriptions.iteritems()):
199 virtual, intolerable = name
in virtuals, name
in intolerables
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)
207 my_defects = [ all_defects[d]
for d
in my_defect_names ]
208 my_defects.sort(key=
lambda d: d.lumi, reverse=
True)
210 print(
"\nTotal luminosity", unit_string,
"\n")
213 print(
"\nDefect luminosity", unit_string,
"\n")
216 for defect
in my_defects:
228 if __name__ ==
"__main__":