5 @file TileTBPulseMonitorAlgorithm.py 
    6 @brief Python configuration of TileTBPulseMonitorAlgorithm algorithm for the Run III 
    9 from AthenaConfiguration.Enums 
import Format
 
   10 from TileMonitoring.TileMonitoringCfgHelper 
import getLegacyChannelForDemonstrator
 
   14     ''' Function to get PMT number: 0,1 ''' 
   18         0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,
 
   19         0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,
 
   20         0,  1,  0,  1,  0,  1, -1, -1,  0,  1,  0,  1,
 
   21         0,  1,  0,  1,  0,  1,  0, -1,  0,  1,  0,  1,
 
   23         0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,
 
   24         0,  0,  0,  1,  0,  1, -1, -1,  0,  1,  0,  1,
 
   25         -1, -1, -1, -1, -1, -1,  0,  0,  1, -1, -1,  1,
 
   26         1,  1,  0,  0,  1,  0, -1, -1, -1, -1, -1, -1 ]
 
   29     if partition 
in [
'EBA', 
'EBC'] 
and channel 
in [0, 1, 12, 13]:
 
   32         pmt = channelToPMT[channel+48] 
if partition 
in [
'EBA', 
'EBC'] 
else channelToPMT[channel]
 
   36         if (pmt != -1 
and partition 
in [
'LBC', 
'EBC']):
 
   42 def TileTBPulseMonitoringConfig(flags, timeRange=[-100, 100], fragIDs=[0x100, 0x101, 0x200, 0x201, 0x402], useDemoCabling=2018, useFELIX=False, **kwargs):
 
   44     ''' Function to configure TileTBPulseMonitorAlgorithm algorithm in the monitoring system.''' 
   46     suffix = 
"Flx" if useFELIX 
else "" 
   47     topPath = 
'TestBeam/' + (
'Felix' if useFELIX 
else 'Legacy')
 
   49     from AthenaConfiguration.ComponentAccumulator 
import ComponentAccumulator
 
   52     from TileGeoModel.TileGMConfig 
import TileGMCfg
 
   55     from TileConditions.TileCablingSvcConfig 
import TileCablingSvcCfg
 
   58     from TileConditions.TileInfoLoaderConfig 
import TileInfoLoaderCfg
 
   61     from AthenaMonitoring 
import AthMonitorCfgHelper
 
   62     helper = AthMonitorCfgHelper(flags, f
'TileTBPulse{suffix}Monitoring')
 
   64     from AthenaConfiguration.ComponentFactory 
import CompFactory
 
   65     tileTBPulseMonAlg = helper.addAlgorithm(CompFactory.TileTBPulseMonitorAlgorithm, f
'TileTBPulse{suffix}MonAlg')
 
   67     tileTBPulseMonAlg.TriggerChain = 
'' 
   69     from TileCalibBlobObjs.Classes 
import TileCalibUtils 
as Tile
 
   73         for fragID 
in fragIDs:
 
   75             drawer = fragID & 0x3F
 
   76             modules += [Tile.getDrawerString(ros, drawer)]
 
   78         for ros 
in range(1, Tile.MAX_ROS):
 
   79             for drawer 
in range(0, Tile.MAX_DRAWER):
 
   80                 fragIDs += [(ros << 8) | drawer]
 
   81                 modules += [Tile.getDrawerString(ros, drawer)]
 
   83     tileTBPulseMonAlg.TileFragIDs = fragIDs
 
   85     kwargs.setdefault(
'TileDigitsContainer', f
'TileDigits{suffix}Cnt')
 
   86     kwargs.setdefault(
'TileRawChannelContainer', flags.Tile.RawChannelContainer.replace(
'TileRawChannel', f
'TileRawChannel{suffix}'))
 
   87     for k, v 
in kwargs.items():
 
   88         setattr(tileTBPulseMonAlg, k, v)
 
   90     run = 
str(flags.Input.RunNumbers[0])
 
   93     executeTimeGroup = helper.addGroup(tileTBPulseMonAlg, 
'TileTBPulseMonExecuteTime', topPath)
 
   94     executeTimeGroup.defineHistogram(
'TIME_execute', path=
'PulseShape', type=
'TH1F',
 
   95                                      title=
'Time for execute TileTBPulseMonAlg algorithm;time [#mus]',
 
   96                                      xbins=100, xmin=0, xmax=10000)
 
   98     from TileMonitoring.TileMonitoringCfgHelper 
import getCellName
 
  100     def addPulseShapeHistogramsArray(helper, modules, algorithm, name, title, path, type='TH2D',
 
  101                                      xbins=100, xmin=-100, xmax=100, ybins=100, ymin=-0.2, ymax=1.5,
 
  102                                      run='', value='', aliasPrefix='', useDemoCabling=2018):
 
  103         ''' This function configures 2D (or 1D Profile) histograms with Tile pulse shape per module, channel, gain  ''' 
  105         pulseShapeArray = helper.addArray([modules], algorithm, name, topPath=path)
 
  106         for postfix, tool 
in pulseShapeArray.Tools.items():
 
  107             moduleName = postfix[1:]
 
  108             partition = moduleName[:3]
 
  109             module = 
int(moduleName[3:]) - 1
 
  110             for channel 
in range(0, Tile.MAX_CHAN):
 
  112                 pmt = 
getPMT(partition, legacyChannel)
 
  113                 pmtName = f
'Channel_{channel}' if pmt < 0 
else {0 : 
'PMT_Up', 1 : 
'PMT_Down'}[pmt]
 
  115                 cellName = cell.replace(
'B', 
'BC') 
if (partition 
in [
'LBA',
'LBC'] 
and cell 
and cell[0] == 
'B' and cell != 
'B9') 
else cell
 
  116                 for gain 
in range(0, Tile.MAX_GAIN):
 
  117                     gainName = {0 : 
'lo', 1 : 
'hi'}[gain]
 
  118                     fullPath = f
'{partition}/{moduleName}' 
  119                     name = f
'time_{channel}_{gain},amplitude_{channel}_{gain};{aliasPrefix}{cellName}_{moduleName}_{pmtName}_{gainName}' 
  120                     fullTitle = f
'Run {run} {moduleName} Channel {channel} Gain {gainName}: {title};time [ns];Normalized Units' 
  121                     tool.defineHistogram(name, title=fullTitle, path=fullPath, type=type,
 
  122                                          xbins=xbins, xmin=xmin, xmax=xmax, ybins=ybins, ymin=ymin, ymax=ymax)
 
  123         return pulseShapeArray
 
  125     addPulseShapeHistogramsArray(helper, modules, tileTBPulseMonAlg, name=
'TilePulseShape', title=
'Pulse shape',
 
  126                                  path=f
'{topPath}/PulseShape', xbins=abs(timeRange[1]), xmin=timeRange[0], xmax=timeRange[1],
 
  127                                  run=run, aliasPrefix=
'pulseShape_', useDemoCabling=useDemoCabling)
 
  129     addPulseShapeHistogramsArray(helper, modules, tileTBPulseMonAlg, name=
'TilePulseShapeProfile',
 
  130                                  title=
'Pulse shape profile', path=f
'{topPath}/PulseShape', type=
'TProfile',
 
  131                                  xbins=abs(timeRange[1]), xmin=timeRange[0], xmax=timeRange[1],
 
  132                                  ybins=
None, ymin=
None, ymax=
None, run=run, aliasPrefix=
'pulseShapeProfile_',
 
  133                                  useDemoCabling=useDemoCabling)
 
  135     accumalator = helper.result()
 
  136     result.merge(accumalator)
 
  140 if __name__==
'__main__':
 
  143     from AthenaCommon.Logging 
import log
 
  148     from AthenaConfiguration.AllConfigFlags 
import initConfigFlags
 
  149     from AthenaConfiguration.TestDefaults 
import defaultGeometryTags, defaultTestFiles
 
  152     parser = flags.getArgumentParser()
 
  153     parser.add_argument(
'--postExec', help=
'Code to execute after setup')
 
  154     parser.add_argument(
'--digits', default=
"TileDigitsCnt", help=
'Tile digits container')
 
  155     parser.add_argument(
'--channels', default=
"TileRawChannelCnt",
 
  156                         help=
'Tile raw channel container, if empty they will be reconstructed from digits')
 
  157     parser.add_argument(
'--time-range', dest=
'timeRange', nargs=2, default=[-200, 200], help=
'Time range for pulse shape histograms')
 
  158     parser.add_argument(
'--frag-ids', dest=
'fragIDs', nargs=
"*", default=[
'0x100', 
'0x101', 
'0x200', 
'0x201', 
'0x402'],
 
  159                         help=
'Tile Frag IDs of modules to be monitored. Empty=ALL')
 
  160     parser.add_argument(
'--demo-cabling', dest=
'demoCabling', type=int, default=2018, help=
'Time Demonatrator cabling to be used')
 
  161     parser.add_argument(
'--nsamples', type=int, default=15, help=
'Number of samples')
 
  162     parser.add_argument(
'--use-sqlite', dest=
'useSqlite', default=
'/afs/cern.ch/user/t/tiledemo/public/efmon/condb/tileSqlite.db',
 
  163                         help=
'Providing local SQlite file, conditions constants will be used from it')
 
  164     args, _ = parser.parse_known_args()
 
  166     fragIDs = [
int(fragID, base=16) 
for fragID 
in args.fragIDs]
 
  167     timeRange = [
int(time) 
for time 
in args.timeRange]
 
  169     flags.Input.Files = defaultTestFiles.RAW_RUN2
 
  170     flags.GeoModel.AtlasVersion = defaultGeometryTags.RUN2
 
  171     flags.Output.HISTFileName = 
'TileTBPulseMonitorOutput.root' 
  172     flags.DQ.useTrigger = 
False 
  173     flags.DQ.enableLumiAccess = 
False 
  174     flags.Exec.MaxEvents = 3
 
  175     flags.Common.isOnline = 
True 
  177     flags.Tile.doFit = 
True 
  178     flags.Tile.useDCS = 
False 
  179     flags.Tile.NoiseFilter = 0
 
  180     flags.Tile.correctTime = 
False 
  181     flags.Tile.correctTimeJumps = 
False 
  182     flags.Tile.BestPhaseFromCOOL = 
False 
  183     flags.Tile.doOverflowFit = 
False 
  186         flags.Tile.RawChannelContainer = args.channels
 
  188     flags.fillFromArgs(parser=parser)
 
  191     flags.dump(pattern=
'Tile.*|Input.*|Exec.*|IOVDb.[D|G].*', evaluate=
True)
 
  194     from AthenaConfiguration.MainServicesConfig 
import MainServicesCfg
 
  197     rawChannels = args.channels
 
  198     if flags.Input.Format 
is Format.BS:
 
  199         readDigitsFlx = 
'Flx' in args.digits
 
  200         from TileByteStream.TileByteStreamConfig 
import TileRawDataReadingCfg
 
  202                                          readDigits=(
not readDigitsFlx),
 
  203                                          readDigitsFlx=readDigitsFlx) )
 
  206         from AthenaPoolCnvSvc.PoolReadConfig 
import PoolReadCfg
 
  211         rawChannels = flags.Tile.RawChannelContainer
 
  213         from TileRecUtils.TileRawChannelMakerConfig 
import TileRawChannelMakerCfg
 
  215         if args.threads 
and (args.threads > 1):
 
  216             rawChMaker = cfg.getEventAlgo(
'TileRChMaker')
 
  217             rawChMaker.Cardinality = args.threads
 
  220             cfg.getService(
'IOVDbSvc').overrideTags += [
 
  221                 f
'<prefix>/TILE</prefix> <db>sqlite://;schema={args.useSqlite};dbname={flags.IOVDb.DatabaseInstance}</db>' 
  227                                           useDemoCabling=args.demoCabling,
 
  228                                           TileRawChannelContainer=rawChannels,
 
  229                                           TileDigitsContainer=args.digits))
 
  231     tileInfoLoader = cfg.getService(
'TileInfoLoader')
 
  232     tileInfoLoader.NSamples = args.nsamples
 
  233     tileInfoLoader.TrigSample = (args.nsamples - 1) // 2  
 
  237         log.info(
'Executing postExec: %s', args.postExec)
 
  240     cfg.printConfig(withDetails=
True, summariseProps=
True)
 
  242     cfg.store(
open(
'TileTBPulseMonitorAlgorithm.pkl', 
'wb'))
 
  248     sys.exit(
not sc.isSuccess())