ATLAS Offline Software
TileTBPulseMonitorAlgorithm.py
Go to the documentation of this file.
1 #
2 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 #
4 '''
5 @file TileTBPulseMonitorAlgorithm.py
6 @brief Python configuration of TileTBPulseMonitorAlgorithm algorithm for the Run III
7 '''
8 
9 from AthenaConfiguration.Enums import Format
10 from TileMonitoring.TileMonitoringCfgHelper import getLegacyChannelForDemonstrator
11 
12 
13 def getPMT(partition, channel):
14  ''' Function to get PMT number: 0,1 '''
15 
16  channelToPMT = [
17  # LBA,LBC:
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,
22  # EBA,EBC:
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 ]
27 
28  # In gap scintillators (E3,E4,E1,E2) there is only one pmt per cell
29  if partition in ['EBA', 'EBC'] and channel in [0, 1, 12, 13]:
30  pmt = 0
31  else:
32  pmt = channelToPMT[channel+48] if partition in ['EBA', 'EBC'] else channelToPMT[channel]
33 
34  # Mirroring of odd/even numbers in negative side
35  # (central symmetry of negative/positive drawers)
36  if (pmt != -1 and partition in ['LBC', 'EBC']):
37  pmt = 1 - pmt
38 
39  return pmt
40 
41 
42 def TileTBPulseMonitoringConfig(flags, timeRange=[-100, 100], fragIDs=[0x100, 0x101, 0x200, 0x201, 0x402], useDemoCabling=2018, useFELIX=False, **kwargs):
43 
44  ''' Function to configure TileTBPulseMonitorAlgorithm algorithm in the monitoring system.'''
45 
46  suffix = "Flx" if useFELIX else ""
47  topPath = 'TestBeam/' + ('Felix' if useFELIX else 'Legacy')
48 
49  from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
50  result = ComponentAccumulator()
51 
52  from TileGeoModel.TileGMConfig import TileGMCfg
53  result.merge(TileGMCfg(flags))
54 
55  from TileConditions.TileCablingSvcConfig import TileCablingSvcCfg
56  result.merge(TileCablingSvcCfg(flags))
57 
58  from TileConditions.TileInfoLoaderConfig import TileInfoLoaderCfg
59  result.merge(TileInfoLoaderCfg(flags))
60 
61  from AthenaMonitoring import AthMonitorCfgHelper
62  helper = AthMonitorCfgHelper(flags, f'TileTBPulse{suffix}Monitoring')
63 
64  from AthenaConfiguration.ComponentFactory import CompFactory
65  tileTBPulseMonAlg = helper.addAlgorithm(CompFactory.TileTBPulseMonitorAlgorithm, f'TileTBPulse{suffix}MonAlg')
66 
67  tileTBPulseMonAlg.TriggerChain = ''
68 
69  from TileCalibBlobObjs.Classes import TileCalibUtils as Tile
70 
71  modules = []
72  if fragIDs:
73  for fragID in fragIDs:
74  ros = fragID >> 8
75  drawer = fragID & 0x3F
76  modules += [Tile.getDrawerString(ros, drawer)]
77  else:
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)]
82 
83  tileTBPulseMonAlg.TileFragIDs = fragIDs
84 
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)
89 
90  run = str(flags.Input.RunNumbers[0])
91 
92  # Configure histogram with TileTBPulseMonAlg algorithm execution time
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)
97 
98  from TileMonitoring.TileMonitoringCfgHelper import getCellName
99 
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 '''
104 
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):
111  legacyChannel = getLegacyChannelForDemonstrator(useDemoCabling, partition, module, channel)
112  pmt = getPMT(partition, legacyChannel)
113  pmtName = f'Channel_{channel}' if pmt < 0 else {0 : 'PMT_Up', 1 : 'PMT_Down'}[pmt]
114  cell = getCellName(partition, legacyChannel)
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
124 
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)
128 
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)
134 
135  accumalator = helper.result()
136  result.merge(accumalator)
137  return result
138 
139 
140 if __name__=='__main__':
141 
142  # Setup logs
143  from AthenaCommon.Logging import log
144  from AthenaCommon.Constants import INFO
145  log.setLevel(INFO)
146 
147  # Set the Athena configuration flags
148  from AthenaConfiguration.AllConfigFlags import initConfigFlags
149  from AthenaConfiguration.TestDefaults import defaultGeometryTags, defaultTestFiles
150 
151  flags = initConfigFlags()
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()
165 
166  fragIDs = [int(fragID, base=16) for fragID in args.fragIDs]
167  timeRange = [int(time) for time in args.timeRange]
168 
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
176 
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
184 
185  if args.channels:
186  flags.Tile.RawChannelContainer = args.channels
187 
188  flags.fillFromArgs(parser=parser)
189  flags.lock()
190 
191  flags.dump(pattern='Tile.*|Input.*|Exec.*|IOVDb.[D|G].*', evaluate=True)
192 
193  # Initialize configuration object, add accumulator, merge, and run.
194  from AthenaConfiguration.MainServicesConfig import MainServicesCfg
195  cfg = MainServicesCfg(flags)
196 
197  rawChannels = args.channels
198  if flags.Input.Format is Format.BS:
199  readDigitsFlx = 'Flx' in args.digits
200  from TileByteStream.TileByteStreamConfig import TileRawDataReadingCfg
201  cfg.merge( TileRawDataReadingCfg(flags, readMuRcv=False,
202  readDigits=(not readDigitsFlx),
203  readDigitsFlx=readDigitsFlx) )
204 
205  else:
206  from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
207  cfg.merge(PoolReadCfg(flags))
208 
209  if not rawChannels:
210  # Run reconstruction to produce Tile raw channels
211  rawChannels = flags.Tile.RawChannelContainer
212 
213  from TileRecUtils.TileRawChannelMakerConfig import TileRawChannelMakerCfg
214  cfg.merge( TileRawChannelMakerCfg(flags) )
215  if args.threads and (args.threads > 1):
216  rawChMaker = cfg.getEventAlgo('TileRChMaker')
217  rawChMaker.Cardinality = args.threads
218 
219  if args.useSqlite:
220  cfg.getService('IOVDbSvc').overrideTags += [
221  f'<prefix>/TILE</prefix> <db>sqlite://;schema={args.useSqlite};dbname={flags.IOVDb.DatabaseInstance}</db>'
222  ]
223 
224  cfg.merge(TileTBPulseMonitoringConfig(flags,
225  fragIDs=fragIDs,
226  timeRange=timeRange,
227  useDemoCabling=args.demoCabling,
228  TileRawChannelContainer=rawChannels,
229  TileDigitsContainer=args.digits))
230 
231  tileInfoLoader = cfg.getService('TileInfoLoader')
232  tileInfoLoader.NSamples = args.nsamples
233  tileInfoLoader.TrigSample = (args.nsamples - 1) // 2 # Floor division
234 
235  # Any last things to do?
236  if args.postExec:
237  log.info('Executing postExec: %s', args.postExec)
238  exec(args.postExec)
239 
240  cfg.printConfig(withDetails=True, summariseProps=True)
241 
242  cfg.store(open('TileTBPulseMonitorAlgorithm.pkl', 'wb'))
243 
244  sc = cfg.run()
245 
246  import sys
247  # Success should be 0
248  sys.exit(not sc.isSuccess())
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
TileMonitoringCfgHelper.getLegacyChannelForDemonstrator
def getLegacyChannelForDemonstrator(useDemoCabling, partition, drawer, channel)
Definition: TileMonitoringCfgHelper.py:201
python.TileInfoLoaderConfig.TileInfoLoaderCfg
def TileInfoLoaderCfg(flags, **kwargs)
Definition: TileInfoLoaderConfig.py:12
LArG4FSStartPointFilter.exec
exec
Definition: LArG4FSStartPointFilter.py:103
python.MainServicesConfig.MainServicesCfg
def MainServicesCfg(flags, LoopMgr='AthenaEventLoopMgr')
Definition: MainServicesConfig.py:256
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
Constants
some useful constants -------------------------------------------------—
Trk::open
@ open
Definition: BinningType.h:40
TileTBPulseMonitorAlgorithm.int
int
Definition: TileTBPulseMonitorAlgorithm.py:160
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
TileByteStreamConfig.TileRawDataReadingCfg
def TileRawDataReadingCfg(flags, readDigits=True, readRawChannel=True, readMuRcv=None, readMuRcvDigits=False, readMuRcvRawCh=False, readBeamElem=None, readLaserObj=None, readDigitsFlx=False, readL2=False, stateless=False, **kwargs)
Definition: TileByteStreamConfig.py:87
TileRawChannelMakerConfig.TileRawChannelMakerCfg
def TileRawChannelMakerCfg(flags, **kwargs)
Definition: TileRawChannelMakerConfig.py:10
TileMonitoringCfgHelper.getCellName
def getCellName(partition, channel)
Definition: TileMonitoringCfgHelper.py:29
str
Definition: BTagTrackIpAccessor.cxx:11
python.PoolReadConfig.PoolReadCfg
def PoolReadCfg(flags)
Definition: PoolReadConfig.py:69
TileTBPulseMonitorAlgorithm.TileTBPulseMonitoringConfig
def TileTBPulseMonitoringConfig(flags, timeRange=[-100, 100], fragIDs=[0x100, 0x101, 0x200, 0x201, 0x402], useDemoCabling=2018, useFELIX=False, **kwargs)
Definition: TileTBPulseMonitorAlgorithm.py:42
python.TileCablingSvcConfig.TileCablingSvcCfg
def TileCablingSvcCfg(flags)
Definition: TileCablingSvcConfig.py:11
TileGMConfig.TileGMCfg
def TileGMCfg(flags)
Definition: TileGMConfig.py:7
TileTBPulseMonitorAlgorithm.getPMT
def getPMT(partition, channel)
Definition: TileTBPulseMonitorAlgorithm.py:13