ATLAS Offline Software
tile.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 
3 from logging import getLogger; log = getLogger("DCSCalculator2.tile")
4 from ..lib import (DCSC_DefectTranslate_Subdetector, DCSC_Variable,
5  DCSC_Variable_With_Mapping, OUT_OF_CONFIG, GoodIOV)
6 
7 from itertools import product
8 
9 from TileCalibBlobObjs.Classes import (
10  TileCalibDrawerBch, TileBchDecoder, TileBchStatus, TileCalibUtils, TileBchPrbs)
11 
12 # Magic, needed for functioning coral Blob
13 try:
14  import PyCintex as C
15 except Exception:
16  import cppyy as C
17 Blob = C.gbl.coral.Blob
18 
19 WHITE, BLACK, GREY, RED, YELLOW, GREEN = None, -1, 0, 1, 2, 3
20 
21 TILBA, TILBC, TIEBA, TIEBC = 232, 233, 234, 235
22 N_CHANNELS_PER_MODULE = [90]*148+[64]*14+[60]+[64]*66+[60]+[64]*46
23 
24 def make_blob(string):
25  b = Blob()
26  b.write(string)
27  b.seek(0)
28  return b
29 
30 def decode_status(chan, calib_blob):
31  """
32  Given a module number `chan` and a `calib_blob` string, return the number
33  of bad, good and affected channels in this module.
34 
35  It also returns a dictionary `prob` containing as keys the problem identifier
36  and values the number of channels affected by that problem.
37  """
38 
39  if chan == 1000 or len(calib_blob) <= 24:
40  # chan 1000 is a comment, and calib_blobs less than 24 in length cause
41  # a crash.
42  return None
43 
44  # Decode a Coral BLOB into a string
45  b = make_blob(calib_blob)
47 
48  bad, good, affected = [], [], []
49 
50  probs = {}
51 
52  decoder = TileBchDecoder(bch.getBitPatternVersion())
53  chn_adcs = product(list(range(TileCalibUtils.max_chan())),
55  # Stolen from near
56  # http://alxr.usatlas.bnl.gov/lxr/source/atlas/TileCalorimeter/TileCalib/
57  # TileCalibBlobPython/python/TileBchTools.py#072
58  for chn, adc in chn_adcs:
59  adcBits, chnBits = bch.getData(chn, adc, 0), bch.getData(chn, 2, 0)
60  status = TileBchStatus(decoder.decode(chnBits, adcBits))
61  if status.isBad(): bad.append((chn, adc))
62  if status.isGood(): good.append((chn, adc))
63  if status.isAffected(): affected.append((chn, adc))
64 
65  if not status.isGood():
66  prbs = status.getPrbs()
67  # Build a dictionary
68  for prb in prbs:
69  key = prb, TileBchPrbs.getDescription(prb)
70  probs[key] = probs.get(key, 0) + 1
71 
72  return len(bad), len(good), len(affected), probs
73 
75  """
76  Rewrite the TileCalibBlob field to contain the result of `decode_status`
77  """
78  return i._replace(TileCalibBlob=decode_status(i.channel, i.TileCalibBlob))
79 
80 def decode_tile_iovs(iovs):
81  return iovs.empty(decode_tile_iov(i) for i in iovs)
82 
84  """
85  Records modules which have all of their channels in the NoHV state.
86  """
87  input_db = "COOLOFL_TILE/CONDBR2"
88  is_config_variable = True
89  timewise_folder = False
90 
91  fetch_args = dict(tag="TileOfl02StatusAdc-RUN2-HLT-UPD1-00")
92 
93  def make_good_iov(self, iov):
94  return GoodIOV(iov.since, iov.until, iov.channel, OUT_OF_CONFIG)
95 
96  def make_good_iovs(self, iovs):
97  iovs = decode_tile_iovs(iovs)
98 
99  log.debug("Number of NHV iovs: %i", len(iovs))
100 
101  def too_many_nohv(iov):
102  """
103  Read the TileCalib blob to determine what problems are present.
104  If all ADCs appear to have (2002, No HV), then count this module
105  as being OUT OF CONFIG. Number of ADCs is 45*2 for LBA/LBC partitions
106  32*2 for most of the modules in EBA/EBC partitions and 30*2 for EBA15 and EBC18
107  """
108  if not iov.TileCalibBlob: return False
109  nbad, ngood, naffected, problems = iov.TileCalibBlob
110  if problems:
111  log.debug("Tile problems %i %r", iov.channel, problems)
112  return problems.get((2002, 'No HV'), 0) >= N_CHANNELS_PER_MODULE[iov.channel]
113 
114  iovs = iovs.empty(iov for iov in iovs if too_many_nohv(iov))
115 
116  log.debug("Bad high voltage channels:")
117  log.debug("= [%r]", ", ".join(str(i.channel) for i in iovs))
118 
119  iovs = super(Tile_NoHighVoltage, self).make_good_iovs(iovs)
120 
121  return iovs
122 
124  """
125  Check the TILE/DCS/STATES FORDAQ_MBHV code for modules in a good state.
126  Excludes modules which are known to be entirely bad due to No HV so that
127  shifters will notice problems with the STATE which are unrelated to this
128  known problem.
129  """
130 
131  folder_base = "/TILE/DCS"
132 
133  # Key: output_channel
134  # Value: input_channel
135  #mapping = {
136  # TILBA: range( 1, 64) + [65],
137  # TILBC: range( 66, 130),
138  # TIEBA: range(193, 257),
139  # TIEBC: [64] + range(130, 193),
140  #}
141 
142  # New mapping, ordered so that the channels match up with
143  # The channels in the next mapping, mapping2.
144  # I'm not a big fan of the way this is done, so I should
145  # come up with a better solution. I at least need to clean it up
146  def lrange(a, b): return list(range(a,b))
147  mapping = {
148  TILBA: lrange(49, 52) + [65] + [55] + lrange(61, 64) + [16] +
149  lrange(1, 16) + lrange(17, 49) + lrange(52, 55) + lrange(56, 61),
150 
151  TILBC: lrange(114, 118) + [121] + lrange(127, 130) + [81] + lrange(66, 81) +
152  lrange(82, 114) + lrange(118, 121) + lrange( 122, 127),
153 
154  TIEBA: lrange(241, 245) + [248] + lrange(254, 257) + [208] + lrange(193, 208) +
155  lrange(209, 241) + lrange(245, 248) + lrange(249, 254),
156 
157  TIEBC: lrange(177, 181) + [184] + lrange(190, 193) + [145] + lrange(131, 134) +
158  [64] + lrange(134, 145) + lrange(146, 163) + [130] + lrange(163, 177) +
159  lrange(181, 184) + lrange(185, 190)
160  }
161 
162  mapping2 = dict( list(zip(range( 20, 84), mapping[TILBA])) +
163  list(zip(range( 84, 148), mapping[TILBC])) +
164  list(zip(range(148, 212), mapping[TIEBA])) +
165  list(zip(range(212, 276), mapping[TIEBC]))
166  )
167 
168  variables = [
169  #DCSC_Variable("STATES", lambda iov: iov.FORDAQ_MBHV == 212222),
170  DCSC_Variable("STATES", lambda iov: iov.FORDAQ_MBHV in (212222, 202221)),
171  Tile_NoHighVoltage("/TILE/OFL02/STATUS/ADC", None)
172  ]
173 
174  dead_fraction_caution = 0.01
175  dead_fraction_bad = 0.75
176 
177 
178 
179 #For book keeping purposes, here is a historical summary of thresholds
180 #
181 #24/06/10
182 #Runs start of the year -
183 # dead_fraction_map = {
184 # TILBA: 0.048,
185 # TILBC: 0.048,
186 # TIEBA: dead_fraction_caution,
187 # TIEBC: 0.0314
188 # }
189 #
190 #23/07/10 - Lost EBC47
191 #Runs - 160801
192 # dead_fraction_map = {
193 # TILBA: 0.048,
194 # TILBC: 0.048,
195 # TIEBA: dead_fraction_caution,
196 # TIEBC: 0.048
197 # }
198 #
199 #
200 #11/08/10 - Lost LBA09 due to interface card issue. Lost LBC08
201 #Runs 160878 - 177167
202 # dead_fraction_map = {
203 # TILBA: 0.064,
204 # TILBC: 0.064,
205 # TIEBA: dead_fraction_caution,
206 # TIEBC: 0.048
207 # }
208 #
209 #21/03/11 - After winter maintanence, many power supplies were repaired
210 # but the frequent power cutscost us several modules
211 #Runs 177167 - 178624
212 # dead_fraction_map = {
213 # TILBA: 0.032,
214 # TILBC: 0.017,
215 # TIEBA: dead_fraction_caution,
216 # TIEBC: 0.017
217 # }
218 #
219 #08/04/11 - Lost LBC07 but gained EBC37
220 #Runs 178740 - 178908
221 # dead_fraction_map = {
222 # TILBA: 0.032,
223 # TILBC: 0.032,
224 # TIEBA: dead_fraction_caution,
225 # TIEBC: dead_fraction_caution
226 # }
227 #
228 #08/04/11 - Lost LBC02
229 #Runs 178933 - present
230 # dead_fraction_map = {
231 # TILBA: 0.032,
232 # TILBC: 0.048,
233 # TIEBA: dead_fraction_caution,
234 # TIEBC: dead_fraction_caution
235 # }
236 #
237 #
238 #27/04/11 - Lost EBC37, gained LBA24 back
239 #Runs 178933 - present
240 # dead_fraction_map = {
241 # TILBA: 0.032,
242 # TILBC: 0.048,
243 # TIEBA: dead_fraction_caution,
244 # TIEBC: dead_fraction_caution
245 # }
246 #
247 #
248 #27/04/11 - Lost EBC37, gained LBA24 back
249 # dead_fraction_map = {
250 # TILBA: 0.017, # Mask dead modules
251 # TILBC: 0.048, # Mask dead modules
252 # TIEBA: dead_fraction_caution,
253 # TIEBC: 0.017
254 # }
255 #
256 #30/04/11 - Lost LBA24 again
257 # dead_fraction_map = {
258 # TILBA: 0.032, # Mask dead modules
259 # TILBC: 0.048, # Mask dead modules
260 # TIEBA: dead_fraction_caution,
261 # TIEBC: 0.017
262 # }
263 #
264 #
265 # dead_fraction_map = {
266 # TILBA: 0.048, # Mask dead modules
267 # TILBC: 0.048, # Mask dead modules
268 # TIEBA: dead_fraction_caution,
269 # TIEBC: 0.017
270 # }
271 # 4/July/11 - EBC is back again
272 # dead_fraction_map = {
273 # TILBA: 0.048, # Mask dead modules
274 # TILBC: 0.048, # Mask dead modules
275 # TIEBA: dead_fraction_caution,
276 # TIEBC: 0.0
277 # }
278 # 10 July, EBC 37 lost again
279 # dead_fraction_map = {
280 # TILBA: 0.032, # Mask dead modules
281 # TILBC: 0.048, # Mask dead modules
282 # TIEBA: dead_fraction_caution,
283 # TIEBC: 0.017
284 # }
285 # one more module in LBC
286 # dead_fraction_map = {
287 # TILBA: 0.032, # Mask dead modules
288 # TILBC: 0.064, # Mask dead modules
289 # TIEBA: dead_fraction_caution,
290 # TIEBC: 0.017
291 # }
292 # status at 01-Sep-2014 - LBA10 dead
293 # dead_fraction_map = {
294 # TILBA: 0.017, # Mask dead modules
295 # TILBC: dead_fraction_caution,
296 # TIEBA: dead_fraction_caution,
297 # TIEBC: dead_fraction_caution
298 # }
299 # status at 2015-06-11 - EBC21 also dead
300 # dead_fraction_map = {
301 # TILBA: 0.017, # Mask dead modules
302 # TILBC: dead_fraction_caution,
303 # TIEBA: dead_fraction_caution,
304 # TIEBC: 0.017 # Mask dead modules
305 # }
306 # status at 2015-10-07 - Getting false trips in EBC, probably from 1/4 of EBC47
307 # dead_fraction_map = {
308 # TILBA: 0.017, # Mask dead modules
309 # TILBC: dead_fraction_caution,
310 # TIEBA: dead_fraction_caution,
311 # TIEBC: 0.021 # Mask dead and partially dead modules
312 # }
313 
314 # status at 2016-03-01 - All the dead modules are fixed and turned on.
315 # dead_fraction_map = {
316 # TILBA: dead_fraction_caution,
317 # TILBC: dead_fraction_caution,
318 # TIEBA: dead_fraction_caution,
319 # TIEBC: dead_fraction_caution
320 # }
321 # status at 2017-06-01 - EBA03 and LBC63 are dead
322 # dead_fraction_map = {
323 # TILBA: dead_fraction_caution,
324 # TILBC: 0.017
325 # TIEBA: 0.017,
326 # TIEBC: dead_fraction_caution
327 # }
328 # status at 2018-04-12 - all modules are fixed and turned on.
329  dead_fraction_map = {
330  TILBA: dead_fraction_caution,
331  TILBC: dead_fraction_caution,
332  TIEBA: dead_fraction_caution,
333  TIEBC: dead_fraction_caution
334  }
335 
336 
337  def calculate_dead_fraction(self, since, until, output_channel, states,
338  state_iovs):
339  """
340  This is for masking the unpowered Tile Cells. It returns the actual fraction of Tile that is off
341  but the R/Y/G is adjusted so that the unpowered modules don't hide new problems.
342  """
343  cdf = super(Tile, self).calculate_dead_fraction
344  result = cdf(since, until, output_channel, states, state_iovs)
345 
346  code, dead_fraction, thrust, n_config, n_working = result
347 
348  # Don't include channels which are "out of config" (see Tile_NoHighVoltage)
349  dead_fraction = 1 - (n_working / n_config)
350 
351  # If n_working == n_config then we're good.
352  if dead_fraction == 0:
353  # Mask dead channels
354  code = GREEN
355 
356  return code, dead_fraction, thrust, n_config, n_working
357 
358  def __init__(self, *args, **kwargs):
359  #kwargs['keep_dcsofl'] = True
360  super(Tile, self).__init__(*args, **kwargs)
361  self.translators = [Tile.color_to_defect_translator(flag, defect, [RED, YELLOW])
362  for flag, defect in ((TILBA, 'TILE_LBA_TRIP'),
363  (TILBC, 'TILE_LBC_TRIP'),
364  (TIEBA, 'TILE_EBA_TRIP'),
365  (TIEBC, 'TILE_EBC_TRIP'),
366  )]
367  self.set_input_mapping("/TILE/OFL02/STATUS/ADC", self.mapping2)
python.subdetectors.tile.Tile_NoHighVoltage
Definition: tile.py:83
python.Classes.TileBchDecoder
TileBchDecoder
Definition: TileCalib/TileCalibBlobObjs/python/Classes.py:13
TileCalibDrawerBch::getInstance
static const TileCalibDrawerBch * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerBch.
Definition: TileCalibDrawerBch.cxx:28
python.subdetectors.tile.Tile_NoHighVoltage.make_good_iov
def make_good_iov(self, iov)
Definition: tile.py:93
python.subdetector.DCSC_DefectTranslate_Subdetector.translators
translators
Definition: subdetector.py:541
python.variable.DCSC_Variable
Definition: variable.py:33
python.subdetectors.tile.Blob
Blob
Definition: tile.py:17
python.subdetectors.tile.decode_status
def decode_status(chan, calib_blob)
Definition: tile.py:30
TileCalibUtils::max_gain
static unsigned int max_gain()
Python compatibility function.
Definition: TileCalibUtils.h:114
python.subdetectors.tile.Tile.lrange
def lrange(a, b)
Definition: tile.py:146
python.subdetectors.tile.Tile.__init__
def __init__(self, *args, **kwargs)
Definition: tile.py:358
python.variable.GoodIOV
def GoodIOV(channel, good)
Definition: variable.py:18
python.subdetector.DCSC_DefectTranslate_Subdetector
Definition: subdetector.py:532
python.subdetectors.tile.Tile.mapping2
mapping2
Definition: tile.py:162
python.subdetector.DCSC_Subdetector.set_input_mapping
def set_input_mapping(self, what, mapping)
Definition: subdetector.py:52
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.subdetectors.tile.make_blob
def make_blob(string)
Definition: tile.py:24
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.subdetectors.tile.Tile_NoHighVoltage.make_good_iovs
def make_good_iovs(self, iovs)
Definition: tile.py:96
python.subdetectors.tile.decode_tile_iov
def decode_tile_iov(i)
Definition: tile.py:74
python.subdetectors.tile.decode_tile_iovs
def decode_tile_iovs(iovs)
Definition: tile.py:80
python.Classes.TileBchStatus
TileBchStatus
Definition: TileCalib/TileCalibBlobObjs/python/Classes.py:16
TileCalibUtils::max_chan
static unsigned int max_chan()
Python compatibility function.
Definition: TileCalibUtils.h:112
str
Definition: BTagTrackIpAccessor.cxx:11
python.subdetectors.tile.Tile.calculate_dead_fraction
def calculate_dead_fraction(self, since, until, output_channel, states, state_iovs)
Definition: tile.py:337
python.variable.DCSC_Variable_With_Mapping
Definition: variable.py:225
python.subdetectors.tile.Tile
Definition: tile.py:123
python.CaloCondLogger.getLogger
def getLogger(name="CaloCond")
Definition: CaloCondLogger.py:16
TileBchPrbs::getDescription
static std::string getDescription(const Prb &prb)
Get description of problem.
Definition: TileBchPrbs.cxx:11