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)
 
    7 from itertools 
import product
 
    9 from TileCalibBlobObjs.Classes 
import (
 
   10     TileCalibDrawerBch, TileBchDecoder, TileBchStatus, TileCalibUtils, TileBchPrbs)
 
   17 Blob = C.gbl.coral.Blob
 
   19 WHITE, BLACK, GREY, RED, YELLOW, GREEN = 
None, -1, 0, 1, 2, 3
 
   21 TILBA, TILBC, TIEBA, TIEBC = 232, 233, 234, 235
 
   22 N_CHANNELS_PER_MODULE = [90]*148+[64]*14+[60]+[64]*66+[60]+[64]*46
 
   32     Given a module number `chan` and a `calib_blob` string, return the number 
   33     of bad, good and affected channels in this module. 
   35     It also returns a dictionary `prob` containing as keys the problem identifier 
   36     and values the number of channels affected by that problem. 
   39     if chan == 1000 
or len(calib_blob) <= 24:
 
   48     bad, good, affected = [], [], []
 
   58     for chn, adc 
in chn_adcs:
 
   59         adcBits, chnBits = bch.getData(chn, adc, 0), bch.getData(chn, 2, 0)
 
   61         if status.isBad(): bad.append((chn, adc))
 
   62         if status.isGood(): good.append((chn, adc))
 
   63         if status.isAffected(): affected.append((chn, adc))
 
   65         if not status.isGood():
 
   66             prbs = status.getPrbs()
 
   70                 probs[key] = probs.get(key, 0) + 1
 
   72     return len(bad), len(good), len(affected), probs
 
   76     Rewrite the TileCalibBlob field to contain the result of `decode_status` 
   78     return i._replace(TileCalibBlob=
decode_status(i.channel, i.TileCalibBlob))
 
   85     Records modules which have all of their channels in the NoHV state. 
   87     input_db = 
"COOLOFL_TILE/CONDBR2" 
   88     is_config_variable = 
True 
   89     timewise_folder = 
False 
   91     fetch_args = dict(tag=
"TileOfl02StatusAdc-RUN2-HLT-UPD1-00")
 
   94         return GoodIOV(iov.since, iov.until, iov.channel, OUT_OF_CONFIG) 
 
   99         log.debug(
"Number of NHV iovs: %i", len(iovs))
 
  101         def too_many_nohv(iov):
 
  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 
  108             if not iov.TileCalibBlob: 
return False 
  109             nbad, ngood, naffected, problems = iov.TileCalibBlob
 
  111                 log.debug(
"Tile problems %i %r", iov.channel, problems)
 
  112             return problems.get((2002, 
'No HV'), 0) >= N_CHANNELS_PER_MODULE[iov.channel]
 
  114         iovs = iovs.empty(iov 
for iov 
in iovs 
if too_many_nohv(iov))
 
  116         log.debug(
"Bad high voltage channels:")
 
  117         log.debug(
"= [%r]", 
", ".
join(
str(i.channel) 
for i 
in iovs))
 
  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 
  131     folder_base = 
"/TILE/DCS" 
  148         TILBA: 
lrange(49, 52) + [65] + [55] + 
lrange(61, 64) + [16] + 
 
  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]))
 
  170         DCSC_Variable(
"STATES", 
lambda iov: iov.FORDAQ_MBHV 
in (212222, 202221)),
 
  174     dead_fraction_caution = 0.01
 
  175     dead_fraction_bad = 0.75
 
  329     dead_fraction_map = {
 
  330         TILBA: dead_fraction_caution,
 
  331         TILBC: dead_fraction_caution,
 
  332         TIEBA: dead_fraction_caution,
 
  333         TIEBC: dead_fraction_caution
 
  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.   
  343         cdf = super(Tile, self).calculate_dead_fraction
 
  344         result = cdf(since, until, output_channel, states, state_iovs)
 
  346         code, dead_fraction, thrust, n_config, n_working = result
 
  349         dead_fraction = 1 - (n_working / n_config)
 
  352         if dead_fraction == 0:
 
  356         return code, dead_fraction, thrust, n_config, n_working
 
  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'),