ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
DataQuality
DCSCalculator2
python
variable.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2
3
4
import
logging; log = logging.getLogger(
"DCSCalculator2.variable"
)
5
6
from
DQUtils
import
fetch_iovs
7
from
DQUtils.general
import
timer
8
from
DQUtils.sugar
import
define_iov_type, RunLumi, IOVSet, RANGEIOV_VAL
9
from
DQUtils.events
import
quantize_iovs_slow_mc
10
11
import
DCSCalculator2.config
as
config
12
from
DCSCalculator2.libcore
import
map_channels
13
from
DCSCalculator2.consts
import
( RED, YELLOW, GREEN )
14
15
16
@define_iov_type
17
def
GoodIOV
(channel, good):
18
"Stores the state of a single input channel, whether it is working or not"
19
20
@define_iov_type
21
def
CodeIOV
(channel, Code):
22
"Similar to GoodIOV but stores a DQ code instead of good/bad state"
23
24
@define_iov_type
25
def
DefectIOV
(channel, present, comment):
26
"Stores a defect IOV"
27
28
@define_iov_type
29
def
DefectIOVFull
(channel, present, comment, recoverable=False, user='sys:defectcalculator
'):
30
"Stores a defect IOV with all fields"
31
32
class
DCSC_Variable
(object):
33
"""
34
Class which encapsulates logic behind an input variable.
35
36
This class is responsible for:
37
38
* Reading data from COOL / CoraCOOL
39
* Evaluating the 'good' state of a variable once read from the database
40
* Quantizing the state from time-based intervals of validity to lumiblock
41
42
It is subclassed for configuration variables and "global" variables.
43
"""
44
45
# defaults for a variable
46
is_global =
False
47
is_config_variable =
False
48
timewise_folder =
True
49
50
def
__init__
(self, folder_name, evaluator, **kwargs):
51
if
not
hasattr(self,
'input_db'
):
52
self.
input_db
=
'COOLOFL_DCS/CONDBR2'
53
self.
folder_name
= folder_name
54
self.
evaluator
= evaluator
55
if
not
hasattr(self,
"fetch_args"
):
56
self.
fetch_args
= {}
57
self.__dict__.update(kwargs)
58
self.
input_hashes
= []
59
60
def
__hash__
(self):
61
"""
62
Useful for verifying if input variables have changed.
63
"""
64
# Consider the fact that hash((hash(x), hash(y))) == hash((x, y)) where
65
# x and y are tuples.
66
return
hash(tuple(self.
input_hashes
))
67
68
def
__repr__
(self):
69
return
"<DCSCVariable %s>"
% self.
folder_name
70
71
def
read
(self, query_range, folder_base, folder_name):
72
"""
73
Read the relevant data from COOL for this variable
74
"""
75
if
folder_name.startswith(
"/"
):
76
folder_path = folder_name
77
else
:
78
# For relative folders prepend the folder_base
79
folder_path =
"/"
.join((folder_base, folder_name))
80
81
log.info(
"Querying COOL folder %s"
, folder_path)
82
83
if
config.opts.check_input_time:
84
self.
fetch_args
[
"with_time"
] =
True
85
86
# Massage DB access
87
if
'/'
in
self.
input_db
:
88
newdbstring = self.
input_db
.rsplit(
'/'
, 1)[0]
89
else
:
90
newdbstring = self.
input_db
91
if
config.opts.input_database.startswith(
'sqlite'
):
92
self.
fetch_args
[
'database'
] = config.opts.input_database
93
else
:
94
self.
fetch_args
[
'database'
] = (
'%s/%s'
% (newdbstring, config.opts.input_database))
95
if
self.
fetch_args
:
96
log.debug(
"Fetching with args: %r"
, self.
fetch_args
)
97
98
iovs = fetch_iovs(folder_path, *query_range, **self.
fetch_args
)
99
100
# Prints even when not doing debug.
101
# TODO: fix this. Might be broken in DQUtils.logger
102
#if log.isEnabledFor(logging.DEBUG):
103
# log.debug("Dumping input IOVs:")
104
# for iov in iovs:
105
# print iov
106
107
#Remove Old TGC Chambers
108
original_length=len(list(iovs))
109
if
folder_path==
'/TGC/DCS/PSHVCHSTATE'
:
110
for
i
in
range(original_length-1, -1, -1):
111
if
list(iovs)[i].channel
in
range(5504,5552)
or
list(iovs)[i].channel
in
range(7362,7411):
112
iovs.pop(i)
113
114
if
config.opts.check_input_time:
115
self.
print_time_info
(iovs)
116
117
if
log.isEnabledFor(logging.INFO):
118
input_hash = hash(iovs)
119
self.
input_hashes
.append(input_hash)
120
log.info(
" -> Input hash: % 09x (len=%i)"
, input_hash, len(iovs))
121
122
return
iovs
123
124
def
print_time_info
(self, iovs):
125
"""
126
Logs the first and last insertion times of the IoVs, and their ranges.
127
"""
128
first_value, last_value = iovs.range_iov
129
130
log.info(
"Times for %s:"
, self)
131
log.info(
" IoV : (first)%26s (last)%26s"
,
132
first_value.date, last_value.date)
133
134
if
not
hasattr(iovs.first,
"insertion_time"
):
135
log.info(
"Insertion time not available"
)
136
else
:
137
insertion_times = [iov.insertion_time
for
iov
in
iovs]
138
log.info(
" Insertion: (first)%26s (last)%26s"
,
139
min
(insertion_times),
max
(insertion_times))
140
141
def
map_input_channels
(self, iovs):
142
"""
143
By default, do nothing. Overloaded by DCSC_Variable_With_Mapping.
144
"""
145
return
iovs
146
147
def
quantize
(self, lbtime, iovs):
148
"""
149
Quantize "good state" timewise-iovs to lumiblocks.
150
OUT_OF_CONFIG gets priority over BAD if BAD and OUT_OF_CONFIG overlap
151
the same lumiblock.
152
"""
153
IOVSet = iovs.empty
154
iovs = [iovs_
for
c, iovs_
in
sorted(iovs.by_channel.items())]
155
156
def
quantizer (iovs):
157
return
min
(i.good
for
i
in
iovs)
if
iovs
else
None
158
159
result = quantize_iovs_slow_mc(lbtime, iovs, quantizer)
160
return
IOVSet(
GoodIOV
(*iov)
161
for
iovs
in
result
162
for
iov
in
iovs
if
iov[0].run == iov[1].run)
163
164
def
make_good_iov
(self, iov):
165
"""
166
Determine if one input iov is good.
167
"""
168
giov =
GoodIOV
(iov.since, iov.until, iov.channel, self.
evaluator
(iov))
169
giov._orig_iov = iov
170
return
giov
171
172
def
make_good_iovs
(self, iovs):
173
"""
174
Determine whether each iov signifies a good or bad state.
175
"""
176
make_good_iov = self.
make_good_iov
177
return
IOVSet(
make_good_iov
(iov)
for
iov
in
iovs)
178
179
def
calculate_good_iovs
(self, lbtime, subdetector):
180
"""
181
Calculate LB-wise "good" states
182
"""
183
184
self.
subdetector
= subdetector
185
186
if
self.
timewise_folder
:
187
query_range = RANGEIOV_VAL(lbtime.first.since, lbtime.last.until)
188
else
:
189
a, b = lbtime.first, lbtime.last
190
query_range = RANGEIOV_VAL(RunLumi(a.Run, a.LumiBlock),
191
RunLumi(b.Run, b.LumiBlock))
192
193
# Read the database
194
iovs = self.
read
(query_range, subdetector.folder_base, self.
folder_name
)
195
#iovs.pprint()
196
197
# Decide the states of the input iovs
198
iovs = self.
make_good_iovs
(iovs)
199
#iovs.pprint()
200
201
# Apply a mapping for input channels if necessary
202
# This only does something for variables that require additional mapping
203
# i.e., if the channel numbers for different DCS variables don't match up
204
iovs = self.
map_input_channels
(iovs)
205
206
if
self.
timewise_folder
and
not
config.opts.timewise:
207
# we might already know the defect mapping
208
with
timer(
"Quantize %s (%i iovs over %i lbs)"
%
209
(self.
folder_name
, len(iovs), len(lbtime))):
210
# Quantize to luminosity block
211
iovs = self.
quantize
(lbtime, iovs)
212
#iovs.pprint()
213
214
# Debug printout of problematic channels
215
# DQUtils messes with the logging and isEnabledFor doesn't work
216
#if log.isEnabledFor(logging.DEBUG):
217
#log.verbose("Bad input channels for %s:", self.folder_name)
218
#log.verbose("= [%r]", ", ".join(str(i.channel) for i in iovs if not i.good))
219
220
self.
iovs
= iovs
221
222
return
self
223
224
class
DCSC_Variable_With_Mapping
(
DCSC_Variable
):
225
"""
226
A variable which needs channel ids to be remapped before further use
227
"""
228
def
map_input_channels
(self, iovs):
229
return
map_channels(iovs, self.
input_channel_map
, self.
folder_name
)
230
231
class
DCSC_Global_Variable
(
DCSC_Variable
):
232
"""
233
A global variable.
234
235
This class over-rides the behaviour for evaluating the "goodness" of an
236
input channel. It allows for an intermediate state (caution) between good
237
and bad.
238
"""
239
is_global =
True
240
241
def
__init__
(self, folder_name, evaluator, caution_evaluator=None, **kwargs):
242
super(DCSC_Global_Variable, self).
__init__
(folder_name, evaluator, **kwargs)
243
244
self.
caution_evaluator
= caution_evaluator
245
246
def
make_good_iov
(self, iov):
247
"""
248
Determine DQ colour for this global variable iov.
249
"""
250
251
if
self.
evaluator
(iov):
252
state = GREEN
253
254
elif
self.
caution_evaluator
and
self.
caution_evaluator
(iov):
255
state = YELLOW
256
257
else
:
258
state = RED
259
260
return
CodeIOV
(iov.since, iov.until, iov.channel, state)
261
262
def
quantize
(self, lbtime, iovs):
263
"""
264
Needs a different quantizer. (The default DQ quantizer will do)
265
"""
266
iovs = [iovs_
for
c, iovs_
in
sorted(iovs.by_channel.items())]
267
# Custom quantizer not needed
268
result = quantize_iovs_slow_mc(lbtime, iovs)
269
return
IOVSet(
CodeIOV
(*iov)
270
for
iovs
in
result
271
for
iov
in
iovs
272
if
iov[0].run == iov[1].run)
273
274
class
DCSC_Defect_Global_Variable
(
DCSC_Variable
):
275
"""
276
Global variable which emits defects
277
"""
278
is_global =
True
279
280
def
__init__
(self, folder_name, evaluator, **kwargs):
281
super(DCSC_Defect_Global_Variable, self).
__init__
(folder_name, evaluator, **kwargs)
282
283
@staticmethod
284
def
quantizing_function
(current_events):
285
if
len(current_events) == 0:
286
return
None
287
else
:
288
return
True
289
# Ideally, here we would somehow choose a comment to use, however
290
# there is no general way to do this at the moment which makes sense.
291
#return (True, list(current_events)[0].comment)
292
293
def
quantize
(self, lbtime, iovs):
294
iovs = [iovs_
for
c, iovs_
in
sorted(iovs.by_channel.items())]
295
result = quantize_iovs_slow_mc(lbtime, iovs,
296
DCSC_Defect_Global_Variable.quantizing_function)
297
return
IOVSet(
DefectIOV
(*iov, comment=
'Automatically set'
)
298
for
iovi
in
result
299
for
iov
in
iovi
300
if
iov[0].run == iov[1].run)
min
#define min(a, b)
Definition
cfImp.cxx:40
max
#define max(a, b)
Definition
cfImp.cxx:41
python.variable.DCSC_Defect_Global_Variable
Definition
variable.py:274
python.variable.DCSC_Defect_Global_Variable.quantize
quantize(self, lbtime, iovs)
Definition
variable.py:293
python.variable.DCSC_Defect_Global_Variable.quantizing_function
quantizing_function(current_events)
Definition
variable.py:284
python.variable.DCSC_Defect_Global_Variable.__init__
__init__(self, folder_name, evaluator, **kwargs)
Definition
variable.py:280
python.variable.DCSC_Global_Variable
Definition
variable.py:231
python.variable.DCSC_Global_Variable.make_good_iov
make_good_iov(self, iov)
Definition
variable.py:246
python.variable.DCSC_Global_Variable.__init__
__init__(self, folder_name, evaluator, caution_evaluator=None, **kwargs)
Definition
variable.py:241
python.variable.DCSC_Global_Variable.caution_evaluator
caution_evaluator
Definition
variable.py:244
python.variable.DCSC_Global_Variable.quantize
quantize(self, lbtime, iovs)
Definition
variable.py:262
python.variable.DCSC_Variable_With_Mapping
Definition
variable.py:224
python.variable.DCSC_Variable_With_Mapping.input_channel_map
input_channel_map
Definition
variable.py:229
python.variable.DCSC_Variable_With_Mapping.map_input_channels
map_input_channels(self, iovs)
Definition
variable.py:228
python.variable.DCSC_Variable
Definition
variable.py:32
python.variable.DCSC_Variable.quantize
quantize(self, lbtime, iovs)
Definition
variable.py:147
python.variable.DCSC_Variable.__init__
__init__(self, folder_name, evaluator, **kwargs)
Definition
variable.py:50
python.variable.DCSC_Variable.map_input_channels
map_input_channels(self, iovs)
Definition
variable.py:141
python.variable.DCSC_Variable.folder_name
folder_name
Definition
variable.py:53
python.variable.DCSC_Variable.__repr__
__repr__(self)
Definition
variable.py:68
python.variable.DCSC_Variable.calculate_good_iovs
calculate_good_iovs(self, lbtime, subdetector)
Definition
variable.py:179
python.variable.DCSC_Variable.evaluator
evaluator
Definition
variable.py:54
python.variable.DCSC_Variable.read
read(self, query_range, folder_base, folder_name)
Definition
variable.py:71
python.variable.DCSC_Variable.__hash__
__hash__(self)
Definition
variable.py:60
python.variable.DCSC_Variable.input_hashes
list input_hashes
Definition
variable.py:58
python.variable.DCSC_Variable.print_time_info
print_time_info(self, iovs)
Definition
variable.py:124
python.variable.DCSC_Variable.make_good_iov
make_good_iov(self, iov)
Definition
variable.py:164
python.variable.DCSC_Variable.iovs
iovs
Definition
variable.py:220
python.variable.DCSC_Variable.fetch_args
dict fetch_args
Definition
variable.py:56
python.variable.DCSC_Variable.input_db
str input_db
Definition
variable.py:52
python.variable.DCSC_Variable.make_good_iovs
make_good_iovs(self, iovs)
Definition
variable.py:172
python.variable.DCSC_Variable.timewise_folder
bool timewise_folder
Definition
variable.py:48
python.variable.DCSC_Variable.subdetector
subdetector
Definition
variable.py:184
python.variable.DefectIOVFull
DefectIOVFull(channel, present, comment, recoverable=False, user='sys:defectcalculator')
Definition
variable.py:29
python.variable.CodeIOV
CodeIOV(channel, Code)
Definition
variable.py:21
python.variable.DefectIOV
DefectIOV(channel, present, comment)
Definition
variable.py:25
python.variable.GoodIOV
GoodIOV(channel, good)
Definition
variable.py:17
Generated on
for ATLAS Offline Software by
1.17.0