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