ATLAS Offline Software
Loading...
Searching...
No Matches
RunTilePulseSim.py
Go to the documentation of this file.
1#!/usr/bin/env python
2#
3# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4#
5'''@file RunTilePulseSim.py
6@brief Script to run Tile pulse simulator
7'''
8
9from AthenaConfiguration.ComponentFactory import CompFactory
10from TileConfiguration.TileConfigFlags import TileRunType
11
12
13def TileDigitsFromPulseCfg(flags, **kwargs):
14 """Return component accumulator with configured Tile digits from pulse algorithm
15
16 Arguments:
17 flags -- Athena configuration flags
18 Keyword arguments:
19 OutputDigitsContainer -- Name of container with TileDigits to write
20 ImperfectionMean -- Mean value of pulse shape broadening
21 ImperfectionRMS -- RMS of pulse shape broadening
22 InTimeAmp -- Amplitude of in-time pulse
23 OutOfTimeAmp -- Amplitude of out-of-time pulse
24 InTimeOffset -- In-time pulse offset from nominal time
25 OutOfTimeOffset -- Out-of-time pulse offset from nominal time
26 UseGaussNoise -- Set to TRUE in order to create noise from double gaussian
27 GaussNoiseAmpOne -- Amplitude of first gaussian of double gaussian noise
28 GaussNoiseSigmaOne -- Standard deviation of first gaussian of double gaussian noise
29 GaussNoiseAmpTwo -- Amplitude of second gaussian of double gaussian noise
30 GaussNoiseSigmaTwo -- Standard deviation of second gaussian of double gaussian noise
31 UseInTimeAmpDist -- Set to TRUE in order to use a distribution for the in-time amplitude instead of a const.
32 UseOutOfTimeAmpDist -- Set to TRUE in order to use a distribution for the out-of-time amplitude instead of a const
33 InTimeAmpDistFileName -- Filename of file to use for amplitude distribution of in-time pulses
34 InTimeAmpDistHistogramName -- Name of the histogram to use for in-time amplitude distribution
35 InTimeAmpPulseProb -- Probability to add an in-time pulse
36 OutOfTimeAmpDistFileName -- Filename of file to use for amplitude distribution of out-of-time pulses
37 InTimeAmpPulseProb -- Probability to add an in-time pulse
38 PileUpFraction -- Probability that an out-of-time component will be added
39 GaussianC2CPhaseVariation -- RMS for the in-time pulse offset (channel-to-channel phase variation)
40 ChannelSpecificPedestal -- Set to TRUE in order to use a channel specific value for the pedestal
41 ChannelSpecificNoise -- Set to TRUE in order to add channel specific noise
42 OutOfTimeOffsetHistogramFile -- Filename of file containing histogram of pile-up timing distribution
43 OutOfTimeOffsetHistogramName -- Name of the histogram to use for pile-up timing distribution
44 AmpDistLowerLimit -- Set all bins lower than this to zero. Default = 135
45 PedestalValueHG -- Pedestal in HG if not taken from database
46 PedestalValueLG -- Pedestal in LG if not taken from database
47 SimulatePileUpWithPoiss -- Simulate pile-up overlaying signals from distribution
48 AvgMuForPileUpSimulation -- Average number of pp collisions for pile-up simulation with SimulatePileUpWithPoiss
49 PileUpAmpDistFileName -- Distribution to simulate pile-up with SimulatePileUpWithPoiss
50 RandomSeed -- Random seed for random number generator
51 SimulatePulseChain -- Simulate continuous output from readout cosidering HL-LHC paradigm
52 Bigain -- Save two gains in ntuple
53 NPulses -- The number of neighboring bunch crossings (before and after the in-time crossing) whose signals are accounted for when simulating the total contribution to a given bunch crossing
54 """
55
56 kwargs.setdefault('InTimeAmp', 1000)
57 kwargs.setdefault('InTimeAmpPulseProb', 1)
58 kwargs.setdefault('ImperfectionMean', 1)
59 kwargs.setdefault('ImperfectionRms', 0)
60 kwargs.setdefault('TilePhaseII', False)
61 kwargs.setdefault('NSamples', 7)
62 kwargs.setdefault('Bigain', False)
63 kwargs.setdefault('SimulatePulseChain', False)
64
65 PhaseII = kwargs['TilePhaseII']
66 PulseChain = kwargs['SimulatePulseChain']
67
68 # PhaseII parameters
69 if PhaseII:
70 kwargs.setdefault('PedestalValueHG', 100)
71 kwargs.setdefault('PedestalValueLG', 100)
72 kwargs.setdefault('ChannelSpecificPedestal', False)
73 kwargs.setdefault('UseGaussNoise', True)
74 else:
75 kwargs.setdefault('ChannelSpecificPedestal', True)
76 kwargs.setdefault('ChannelSpecificNoise', True)
77
78 kwargs.setdefault('PileUpFraction', 0)
79 kwargs.setdefault('AmpDistLowerLimit', 0)
80 kwargs.setdefault('SimulatePileUpWithPoiss', False)
81 kwargs.setdefault('AvgMuForPileUpSimulation', 80)
82
83 from TileGeoModel.TileGMConfig import TileGMCfg
84 acc = TileGMCfg(flags)
85
86 from TileConditions.TileCablingSvcConfig import TileCablingSvcCfg
87 acc.merge(TileCablingSvcCfg(flags))
88
89 from TileConditions.TileSampleNoiseConfig import TileSampleNoiseCondAlgCfg
90 acc.merge( TileSampleNoiseCondAlgCfg(flags) )
91
92 from RngComps.RngCompsConfig import AthRNGSvcCfg
93 kwargs['RndmSvc'] = acc.getPrimaryAndMerge( AthRNGSvcCfg(flags) )
94
95 # Configure TileInfoLoader to set up number of samples
96 nSamples = kwargs['NSamples'] if not PulseChain else 1
97 ADCmax = 4095 if PhaseII else 1023
98 ADCmaskValue = 4800 if PhaseII else 2047
99 from TileConditions.TileInfoLoaderConfig import TileInfoLoaderCfg
100 acc.merge( TileInfoLoaderCfg(flags,
101 NSamples=nSamples, TrigSample=((nSamples-1)//2),
102 ADCmax=ADCmax, ADCmaskValue=ADCmaskValue) )
103
104 TileDigitsFromPulse = CompFactory.TileDigitsFromPulse
105 acc.addEventAlgo(TileDigitsFromPulse(**kwargs), primary=True)
106
107 return acc
108
109
110if __name__ == '__main__':
111 import sys
112
113 # Setup logs
114 from AthenaCommon.Logging import log
115 from AthenaCommon import Constants
116 log.setLevel(Constants.INFO)
117
118 from AthenaConfiguration.AllConfigFlags import initConfigFlags
119 flags = initConfigFlags()
120
121 parser = flags.getArgumentParser(description='Run Tile pulse simulator. \
122 One can use it without input file and default conditions will be used. \
123 Or one can use --run to specify run number from which conditions should be used \
124 (probably conditions and geometries tags should be changed also in this case). \
125 Or one can use --filesInput to specify input file with HITS to take conditions from. \
126 Example: athena --CA RunTilePulseSim.py --evtMax 10')
127
128 parser.add_argument('--preExec', help='Code to execute before locking configs')
129 parser.add_argument('--postExec', help='Code to execute after setup')
130 parser.add_argument('--printDetailedConfig', action='store_true', help='Print detailed Athena configuration')
131 parser.add_argument('--outputDirectory', default='.', help='Output directory for produced files')
132 parser.add_argument('--outputVersion', type=str, default='0', help='Version to be used in output file for ntuple')
133 parser.add_argument('--nsamples', type=int, default=7, help='Number of samples')
134 parser.add_argument('--phaseII', type=bool, default=False, help='Use parameters of TilePhaseII')
135 parser.add_argument('--run', type=int, default=410000, help='Run number')
136 parser.add_argument('--save-true-amplitude', action='store_true', help='Save true Tile raw channel amplitude into h2000')
137 parser.add_argument('--pulseChain', type=bool, default=False, help='Simulate continuous output of readout across bunch crossings')
138 parser.add_argument('--acr-db', action='store_true', help='Use auto correlation matrix from DB')
139
140 args, _ = parser.parse_known_args()
141
142 flags.Tile.RunType = TileRunType.PHY
143
144 # Set up Tile reconstuction methods
145 if(args.pulseChain): # no reconstruction ran for continuous readout simulation
146 flags.Tile.doOpt2 = False
147 flags.Tile.doOptATLAS = False
148 flags.Tile.OfcFromCOOL = False
149 else:
150 flags.Tile.doOpt2 = True
151 flags.Tile.doOptATLAS = True
152 if args.nsamples != 7:
153 flags.Tile.OfcFromCOOL = False
154
155 flags.Input.isMC = True
156 flags.Input.Files = []
157 flags.Exec.MaxEvents = 3
158
159 # Override default configuration flags from command line arguments
160 flags.fillFromArgs(parser=parser)
161
162 if not flags.Input.Files:
163 flags.Input.RunNumbers = [args.run]
164 flags.Input.ConditionsRunNumber = args.run
165 flags.Input.OverrideRunNumber = True
166
167 from AthenaConfiguration.TestDefaults import defaultConditionsTags, defaultGeometryTags
168 flags.GeoModel.AtlasVersion = defaultGeometryTags.RUN3
169 flags.IOVDb.GlobalTag = defaultConditionsTags.RUN3_MC
170
171 if args.preExec:
172 log.info('Executing preExec: %s', args.preExec)
173 exec(args.preExec)
174
175 flags.lock()
176 flags.dump()
177
178 runNumber = flags.Input.RunNumbers[0]
179
180 from AthenaConfiguration.MainServicesConfig import MainServicesCfg
181 cfg = MainServicesCfg(flags)
182
183 if flags.Input.Files:
184 from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
185 cfg.merge(PoolReadCfg(flags))
186
187 # =======>>> Configure Tile digits from pulse algorithm
188 cfg.merge( TileDigitsFromPulseCfg(flags, NSamples=args.nsamples, TilePhaseII=args.phaseII, SimulatePulseChain=args.pulseChain) )
189
190 # =======>>> Configure Tile raw channel maker
191 from TileRecUtils.TileRawChannelMakerConfig import TileRawChannelMakerCfg
192 cfg.merge( TileRawChannelMakerCfg(flags) )
193 if not flags.Tile.OfcFromCOOL:
194 rawChannelBuilders = cfg.getEventAlgo('TileRChMaker').TileRawChannelBuilder
195 for rawChannelBuilder in rawChannelBuilders:
196 if hasattr(rawChannelBuilder, 'TileCondToolOfc'):
197 rawChannelBuilder.TileCondToolOfc.nSamples = args.nsamples
198 # True - unity matrix, False - use matrix from DB
199 rawChannelBuilder.TileCondToolOfc.OptFilterDeltaCorrelation = not args.acr_db
200
201 # =======>>> Configure Tile h2000 ntuple production
202 ntupleFile = f'{args.outputDirectory}/tile_{runNumber}_{args.outputVersion}.aan.root'
203 from TileRec.TileAANtupleConfig import TileAANtupleCfg
204
205 cfg.merge( TileAANtupleCfg(flags,
206 saveTMDB=False,
207 TileL2Cnt='',
208 TileDigitsContainerFlt='',
209 TileDigitsContainer='TileDigitsCnt',
210 CalibrateEnergy=False,
211 OfflineUnits=0,
212 CalibMode=True,
213 outputFile=ntupleFile) )
214
215 if args.pulseChain:
216 cfg.getEventAlgo('TileNtuple').NSamples = 1
217 cfg.getEventAlgo('TileNtuple').TileRawChannelContainer = 'TrueAmp'
218 else:
219 cfg.getEventAlgo('TileNtuple').NSamples = args.nsamples
220 cfg.getEventAlgo('TileNtuple').TileRawChannelContainer='TileRawChannelCnt'
221 cfg.getEventAlgo('TileNtuple').TileRawChannelContainerOpt='TileRawChannelOpt2'
222
223 if args.save_true_amplitude:
224 cfg.getEventAlgo('TileNtuple').TileRawChannelContainerFit = 'TrueAmp'
225
226 # =======>>> Any last things to do?
227 if args.postExec:
228 log.info('Executing postExec: %s', args.postExec)
229 exec(args.postExec)
230
231 cfg.printConfig(withDetails=args.printDetailedConfig,
232 summariseProps=args.printDetailedConfig,
233 printDefaults=args.printDetailedConfig)
234
235 if not args.config_only:
236 sc = cfg.run()
237 sys.exit(0 if sc.isSuccess() else 1)
if(febId1==febId2)
This algorithm creates TileDigits from pulses provided by pulse simulator.
TileDigitsFromPulseCfg(flags, **kwargs)