ATLAS Offline Software
DQUtilities.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 
3 import os
4 from DQDefects import DefectsDB
5 from DQUtils.sugar import IOVSet, RunLumiType, RunLumi, define_iov_type
6 from DQUtils import fetch_iovs, process_iovs
7 
8 
9 # Exception classes
10 class DefectError(Exception):
11  """Defect exception class."""
12 
13 
14 @define_iov_type
15 def DEFECTIOV_VAL(defect, present):
16  "IOV type to solidify upon with an extra present element"
17  pass
18 
19 class IDBSDefectWriter:
20  """
21  Class for writing BS defects to an sqlite file
22  """
23 
24  def __init__(self,fileName, forceNew=False, dbName='IDBSDQ', tag='nominal', user='sys:dqBeamSpot'):
25  """
26  Initialise database connection
27  """
28  self.defect = None
29  self.iovs = IOVSet()
30  self.user = user
31 
32  #self.allowedDefects = DefectsDB('').defect_names
33 
34  if not fileName: fileName = 'tmp.'+str(os.getpid())+'.db'
35 
36  self.connect(fileName, forceNew, dbName, tag)
37 
38  pass
39 
40  def __del__(self):
41  """
42  Delete db to clear connection
43  """
44 
45  os.system('[[ -f tmp.%s.db ]] && rm tmp.%s.db' %(os.getpid(), os.getpid()))
46  del self.db
47  pass
48 
49 
50  def connect(self, fileName, forceNew=False, dbName='IDBSDQ', tag='nominal'):
51  """
52  Open connection to defect DB
53  """
54 
55  connString = 'sqlite://;schema=%s;dbname=%s' % (fileName,dbName)
56 
57  if forceNew and os.path.exists(fileName):
58  os.remove(fileName)
59 
60  self.db = DefectsDB(connString, read_only=False, create=True, tag=(tag, 'HEAD')) # Second tag is for virtual defects, which we are not interested in
61 
62  self.officialDb = DefectsDB()
63 
64  return
65 
66  def defectType(self,t):
67  """
68  Set defect type
69  """
70  self.defect = t
71 
72  def add(self,runMin=0, runMax=(1 << 31)-1, lbMin=0, lbMax=(1 << 32)-1):
73  """
74  Add iovs which are NOT defective to the list
75  Note, lbMax is exclusive here (and inclusive when shown on defect web page).
76  """
77 
78  # Make since and until and convert to syntactially nice RunLumiType
79  since = RunLumiType((runMin << 32)+lbMin)
80  until = RunLumiType((runMax << 32)+lbMax)
81 
82  # IoVs which are not defective (i.e. beamspot good)
83  self.iovs.add(since, until, self.defect, False)
84  return
85 
86 
87  def complete(self, runMin, runMax):
88  """
89  Complete a list of IoVs to cover all LBs in a run, treating empty ones as having 'emptyState'
90 
91  """
92 
93  # Create an IOV set covering the entire run(s)
94  run_lbs = fetch_iovs("EOR", runs=(runMin, runMax), what=[], with_channel=False)
95 
96 
97  # run_lbs = IOVSet()
98  # lbMin = 1
99  # lbMax = (1 << 32) -1 # Note, lbMax is exclusive
100  # since = RunLumiType((runMin << 32)+lbMin)
101  # until = RunLumiType((runMax << 32)+lbMax)
102  # run_lbs.add(since, until)
103 
104  if not len(run_lbs):
105  print ("WARNING: No LBs in run according to EOR_Params - are we running before the run has finished?")
106 
107  def lbsStartAtOne(iov):
108  "Change LBs starting at 0 to start at 1"
109  return iov._replace(since=RunLumi(iov.since.run, 1))
110 
111  # Start LBs from 1 rather than 0 (at request of P. Onyisi) as long as run has more than one LB (else skip)
112  run_lbs = [lbsStartAtOne(iov) for iov in run_lbs if iov.until.lumi > 1]
113 
114  # Empty IOV set for adding full list of LBs too
115  iovs = IOVSet()
116 
117  # Ask official DB if an IoV is currently defective so can unset only those if doing reprocessing
118  defectsCurrentlyInDb = self.officialDb.retrieve((runMin, 0), (runMax+1, 0), [self.defect])
119 
120  # Order IOVs to avoid since > until
121  self.iovs = IOVSet(sorted(self.iovs))
122 
123  #for since, until, (run_lb, iov, dbDefect) in process_iovs(run_lbs.solidify(RANGEIOV_VAL), self.iovs.solidify(DEFECTIOV_VAL), defectsCurrentlyInDb):
124  for since, until, (run_lb, iov, dbDefect) in process_iovs(run_lbs, self.iovs.solidify(DEFECTIOV_VAL), defectsCurrentlyInDb):
125  if not run_lb: continue # Check valid
126 
127 # # Start LBs from 1 rather than 0 (at request of P. Onyisi)
128 # # If this makes since==until, i.e. it was a [0->1) LB range then skip
129 # if since.lumi==0:
130 # since = RunLumiType((since.run << 32)+since.lumi+1)
131 # if since==until: continue
132 
133  # Add iovs from self.iovs treating empty ones as defective (i.e. beamspot bad/missing)
134  if iov:
135  # These are not defective
136  if dbDefect and dbDefect.present:
137  # Only store not defective IoVs if they are present on the Db so we can unset them
138  # (don't want to write not present defects to Db unless really chaning an existing defect)
139  iovs.add(since, until, self.defect, False)
140  else:
141  # These are defective
142  iovs.add(since, until, self.defect, True)
143 
144  self.iovs = iovs
145  return
146 
147  def writeDefects(self, tag='nominal', nonpresent=False):
148  """
149  Write all defects to the database. If 'nonpresent' is True then write the absent ones too
150  """
151 
152  with self.db.storage_buffer:
153  for since, until, defect, present in self.iovs:
154  if not present and not nonpresent: continue
155  #print (since, until, present)
156  self._writeDefect(defect, since, until, present = present)
157 
158  def _writeDefect(self,defect, since, until, tag='nominal', description='', comment='', present=True, recoverable=False):
159  """
160  Write a single defect to the database
161  """
162 
163  if defect not in self.db.defect_names:
164  self.db.create_defect(defect, description)
165 
166  self.db.insert(defect, since, until, comment, self.user, present, recoverable)
167 
168  return
169 
170  def dump(self, filename = None):
171  """
172  Dump defects to a file given by filename or stdout if no filename given
173  """
174 
175  from DQUtils.utils import pprint_objects
176 
177  if filename is not None:
178  f = open(filename.replace('.db', '.txt'), "w")
179  # If not defects then nothing will be in the database and we write an empty file
180  if len(self.iovs):
181  pprint_objects(self.db.retrieve(primary_only=True, nonpresent=True), f)
182  f.close()
183  else:
184  if len(self.iovs):
185  self.iovs.pprint()
186  else:
187  print ('\nNo DQ defects')
188 
189  # with open(filename.replace('.db', '.txt'), "w") as f:
190  # pprint_objects(self.db.retrieve(), f)
191 
192 
193  return
194 
195 
197  """
198  Container for beamspot DQ defects from COOL
199  """
200 
201  defectBitPos = ['UNKNOWN', 'ID_BS_2010YELLOW', 'ID_BS_RUNAVERAGE', 'ID_BS_PARAMETERSTEP',
202  'ID_BS_NOBEAMSPOT', 'ID_BS_2010RED', 'LUMI_VDM']
203 
204 
205  def __init__(self, database='COOLOFL_GLOBAL/CONDBR2', tag='HEAD', debug=False):
206  #def __init__(self, database='dqflags.db/IDBSDQ', tag='nominal', debug=False):
207  """
208  Initialise database connection
209  """
210 
211  self.database = database
212  self.tag = tag
213  self.lastRun = None
214  self.iovsets = None
215  self.debug = debug
216 
217  self.connect()
218 
219  pass
220 
221  def __del__(self):
222  """
223  Delete db to clear connection
224  """
225 
226  del self.db
227  pass
228 
229 
230  def connect(self):
231  """
232  Open connection to defect DB
233  """
234 
235  self.db = DefectsDB(self.database, read_only=True, create=False, tag=self.tag)
236  self.idbsDefects = [d for d in self.db.defect_names if d.startswith('ID_BS_') or d == 'LUMI_VDM']
237 
238  if self.debug:
239  print (self.idbsDefects)
240 
241  return
242 
243  def defectList(self):
244  """
245  List of all possible beamspot defects
246  """
247 
248  return self.idbsDefects
249 
250  def defect(self, run, lb, channels=None):
251  """
252  Get list of DQ defects for a particular run and lb, caching the result for the latest (succesful) run
253  e.g.
254  from InDetBeamSpotExample.DQUtilities import IDBSDefectData
255  idbs = IDBSDefectData()
256  idbs.defect(167661,372)
257 
258  channels is the list of defects to look for (defaults to all ID_BS defects)
259  """
260 
261  if channels is None:
262  channels = self.idbsDefects
263 
264  # Encode start and end of run
265  lbMin = 0
266  lbMax = (1 << 32)-1
267  since = (run << 32)+lbMin
268  until = (run << 32)+lbMax
269 
270  # If the run is the same at the previous one return defects from cache
271  if run == self.lastRun:
272  defects = self._defectForLB(lb)
273  if self.debug:
274  print (run, lb, defects)
275  return defects
276 
277  # Retrive info for entire run
278  iovs = self.db.retrieve(since, until, channels=channels)
279 
280  # Check if run exists
281  if not iovs:
282  print ("Unable to access folder with given parameters")
283  return []
284 
285  # If found, update last run and get list of IOVSets for each defect/channel
286  self.lastRun = run
287  chans, self.iovsets = iovs.chans_iovsets
288 
289  defects = self._defectForLB(lb)
290 
291  # Debug
292  if self.debug:
293  iovs.pprint()
294  print (run, lb, defects)
295 
296  return defects
297 
298  def _defectForLB(self, lb):
299  """
300  Get the DQ defects for the given LB from the full run info
301  """
302 
303  defects = []
304  for since, until, states in process_iovs(*self.iovsets):
305  if since.lumi <= lb < until.lumi:
306  # defects is true if set for a given run/LB
307  defects = [state.channel for state in states if state]
308 
309  return list(set(defects))
310 
311 
312  def defectsRange(self, run, lbStart, lbEnd, channels=None):
313  """
314  Return the maximal list of defects for a given range. lbEnd is exclusive
315  """
316 
317  defects = []
318  for lb in range(lbStart, lbEnd):
319  defects.extend(self.defect(run, lb, channels=channels))
320 
321  return list(set(defects))
322 
323  def dumpRun(self, run, channels=None):
324  """
325  Dump DQ info for a particular run (useful in reprocessing to compare new to old)
326  """
327 
328  if channels is None:
329  channels = self.idbsDefects
330 
331  # Encode start and end of run
332  lbMin = 0
333  lbMax = (1 << 32)-1
334  since = (run << 32)+lbMin
335  until = (run << 32)+lbMax
336 
337  # Retrive info for entire run
338  iovs = self.db.retrieve(since, until, channels=channels, nonpresent=True)
339 
340  # Check if run exists
341  if not iovs:
342  print ("Unable to access folder with given parameters")
343  return []
344 
345  iovs.pprint()
346 
347  return
348 
350  """
351  Class to enocode and decode IDBS defects. No instances fo this class can be instanciated
352  and it bascially just acts as a poor man's namespace (should really be a module)
353  """
354 
355  defectBitPos = ['UNKNOWN', 'ID_BS_2010YELLOW', 'ID_BS_RUNAVERAGE', 'ID_BS_PARAMETERSTEP',
356  'ID_BS_NOBEAMSPOT', 'ID_BS_2010RED', 'LUMI_VDM']
357 
358  @classmethod
359  def defectToInt(cls, defect):
360  """Encode defect as an int. If defect is unknown raise error"""
361 
362  if defect not in IDBSDefectEncoding.defectBitPos:
363  raise DefectError ('ERROR: Unknown defect %s encountered' % defect)
364 
365  return (1 << IDBSDefectEncoding.defectBitPos.index(defect))
366 
367  @classmethod
368  def defectListToInt(cls, defects):
369  """Encode list of defects as an int. If no defect (empty list) returns 0 for bakcward compatibility"""
370  return sum([cls.defectToInt(d) for d in defects])
371 
372  @classmethod
373  def intToDefectList(cls, dint):
374  """Decode int as list of defects. Raise error if unkown defect encountered"""
375 
376  # Convert int to binary string with correct endianess
377  binStr = bin(dint)[2:][::-1]
378 
379  if len(binStr) > len(IDBSDefectEncoding.defectBitPos):
380  raise DefectError ("ERROR: integer %s out of range" % dint)
381 
382  # If dint is odd then has the unknown bit set
383  if bool(dint & 1):
384  raise DefectError ('ERROR: Unknown defect encountered')
385 
386  return [d[0] for d in zip(IDBSDefectEncoding.defectBitPos,binStr) if d[1]=='1']
python.DQUtilities.IDBSDefectWriter.__init__
def __init__(self, fileName, forceNew=False, dbName='IDBSDQ', tag='nominal', user='sys:dqBeamSpot')
Definition: DQUtilities.py:24
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
python.DQUtilities.IDBSDefectWriter.writeDefects
def writeDefects(self, tag='nominal', nonpresent=False)
Definition: DQUtilities.py:147
python.DQUtilities.IDBSDefectWriter.dump
def dump(self, filename=None)
Definition: DQUtilities.py:170
python.DQUtilities.IDBSDefectWriter.defectType
def defectType(self, t)
Definition: DQUtilities.py:66
python.DQUtilities.IDBSDefectWriter.iovs
iovs
Definition: DQUtilities.py:29
python.DQUtilities.IDBSDefectWriter.db
db
Definition: DQUtilities.py:60
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.DQUtilities.IDBSDefectData.dumpRun
def dumpRun(self, run, channels=None)
Definition: DQUtilities.py:323
bin
Definition: BinsDiffFromStripMedian.h:43
python.DQUtilities.IDBSDefectData.debug
debug
Definition: DQUtilities.py:215
python.DQUtilities.IDBSDefectData
Definition: DQUtilities.py:196
python.DQUtilities.IDBSDefectData.db
db
Definition: DQUtilities.py:235
python.sugar.runlumi.RunLumi
RunLumi
Definition: runlumi.py:131
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
python.utils.pprint_objects
def pprint_objects(objects, where=stdout)
Definition: DataQuality/DQUtils/python/utils.py:129
python.DQUtilities.IDBSDefectWriter.user
user
Definition: DQUtilities.py:30
python.DQUtilities.IDBSDefectWriter.officialDb
officialDb
Definition: DQUtilities.py:62
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.DQUtilities.IDBSDefectWriter.connect
def connect(self, fileName, forceNew=False, dbName='IDBSDQ', tag='nominal')
Definition: DQUtilities.py:50
python.DQUtilities.IDBSDefectData.connect
def connect(self)
Definition: DQUtilities.py:230
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.events.process_iovs
def process_iovs(*iovsets)
Definition: events.py:30
python.DQUtilities.IDBSDefectData.defectList
def defectList(self)
Definition: DQUtilities.py:243
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
python.DQUtilities.IDBSDefectEncoding.defectToInt
def defectToInt(cls, defect)
Definition: DQUtilities.py:359
python.DQUtilities.IDBSDefectEncoding.defectListToInt
def defectListToInt(cls, defects)
Definition: DQUtilities.py:368
python.DQUtilities.IDBSDefectData.__del__
def __del__(self)
Definition: DQUtilities.py:221
python.DQUtilities.DEFECTIOV_VAL
def DEFECTIOV_VAL(defect, present)
Definition: DQUtilities.py:15
python.DQUtilities.IDBSDefectData.defectsRange
def defectsRange(self, run, lbStart, lbEnd, channels=None)
Definition: DQUtilities.py:312
python.DQUtilities.IDBSDefectData.defect
def defect(self, run, lb, channels=None)
Definition: DQUtilities.py:250
Trk::open
@ open
Definition: BinningType.h:40
python.DQUtilities.IDBSDefectData._defectForLB
def _defectForLB(self, lb)
Definition: DQUtilities.py:298
python.DQUtilities.IDBSDefectData.tag
tag
Definition: DQUtilities.py:212
python.DQUtilities.IDBSDefectData.lastRun
lastRun
Definition: DQUtilities.py:213
python.DQUtilities.IDBSDefectData.idbsDefects
idbsDefects
Definition: DQUtilities.py:236
python.DQUtilities.IDBSDefectWriter.add
def add(self, runMin=0, runMax=(1<< 31) -1, lbMin=0, lbMax=(1<< 32) -1)
Definition: DQUtilities.py:72
python.DQUtilities.IDBSDefectData.database
database
Definition: DQUtilities.py:211
python.DQUtilities.IDBSDefectEncoding
Definition: DQUtilities.py:349
str
Definition: BTagTrackIpAccessor.cxx:11
python.DQUtilities.IDBSDefectWriter.defect
defect
Definition: DQUtilities.py:28
python.DQUtilities.IDBSDefectWriter._writeDefect
def _writeDefect(self, defect, since, until, tag='nominal', description='', comment='', present=True, recoverable=False)
Definition: DQUtilities.py:158
python.DQUtilities.IDBSDefectWriter.complete
def complete(self, runMin, runMax)
Definition: DQUtilities.py:87
python.DQUtilities.DefectError
Definition: DQUtilities.py:10
python.DQUtilities.IDBSDefectWriter.__del__
def __del__(self)
Definition: DQUtilities.py:40
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
python.DQUtilities.IDBSDefectEncoding.intToDefectList
def intToDefectList(cls, dint)
Definition: DQUtilities.py:373
python.DQUtilities.IDBSDefectData.__init__
def __init__(self, database='COOLOFL_GLOBAL/CONDBR2', tag='HEAD', debug=False)
Definition: DQUtilities.py:205
python.DQUtilities.IDBSDefectData.iovsets
iovsets
Definition: DQUtilities.py:214