ATLAS Offline Software
PileUpMTConfig.py
Go to the documentation of this file.
1 """ComponentAccumulator configuration for MT pileup digitization
2 
3 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
4 """
5 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
6 from AthenaConfiguration.ComponentFactory import CompFactory
7 from AthenaConfiguration.Enums import ProductionStep
8 from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
9 from SGComps.AddressRemappingConfig import InputRenameCfg
10 from DigitizationConfig.RunDependentConfig import (
11  maxNevtsPerXing,
12  LumiProfileSvcCfg,
13  NoProfileSvcCfg,
14 )
15 from DigitizationConfig.PileUpConfig import (
16  LowPtMinBiasEventSelectorCfg,
17  HighPtMinBiasEventSelectorCfg,
18  CavernEventSelectorCfg,
19  BeamGasEventSelectorCfg,
20  BeamHaloEventSelectorCfg,
21  StepArrayBMCfg,
22  FixedArrayBMCfg,
23  ArrayBMCfg,
24 )
25 
26 from enum import Enum
27 from math import ceil
28 from hashlib import blake2b
29 
30 def numBkgToLoad(nPerBC):
31  "Given number of bkg needed (on average) per BC, returns number to load per batch"
32  import numpy as np
33  # We don't have scipy in the release so we have a lookup table
34  # Lookup table computed using scipy.stats.poisson.isf to determine how many events need
35  # to be loaded to have a probability of running out of events < 10^-6.
36  boundaries = np.array([1.74752840e-03, 4.03701726e-03, 7.74263683e-03, 1.23284674e-02,
37  1.78864953e-02, 2.36448941e-02, 3.12571585e-02, 3.76493581e-02,
38  4.53487851e-02, 5.46227722e-02, 6.57933225e-02, 7.92482898e-02,
39  8.69749003e-02, 9.54548457e-02, 1.04761575e-01, 1.14975700e-01,
40  1.26185688e-01, 1.38488637e-01, 1.51991108e-01, 1.66810054e-01,
41  1.83073828e-01, 2.00923300e-01, 2.20513074e-01, 2.42012826e-01,
42  2.65608778e-01, 2.91505306e-01, 3.19926714e-01, 3.51119173e-01,
43  3.85352859e-01, 4.22924287e-01, 4.64158883e-01, 5.09413801e-01,
44  5.59081018e-01, 6.13590727e-01, 6.73415066e-01, 7.39072203e-01,
45  8.11130831e-01, 8.90215085e-01, 9.77009957e-01, 1.07226722e+00,
46  1.17681195e+00, 1.29154967e+00, 1.41747416e+00, 1.55567614e+00,
47  1.70735265e+00, 1.87381742e+00, 2.05651231e+00, 2.25701972e+00,
48  2.47707636e+00, 2.71858824e+00, 2.98364724e+00, 3.27454916e+00,
49  3.59381366e+00, 3.94420606e+00, 4.32876128e+00, 4.75081016e+00,
50  5.21400829e+00, 5.72236766e+00, 6.28029144e+00, 6.89261210e+00,
51  7.56463328e+00, 8.30217568e+00, 9.11162756e+00, 1.00000000e+01])
52  n_to_load = np.array([ 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13.,
53  14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24.,
54  26., 27., 29., 31., 33., 35., 37., 39., 42., 44., 47.,
55  51., 54., 58., 62., 66., 71., 76., 81., 88., 94., 101.,
56  109., 117., 126., 136., 147., 158., 171., 185., 200., 216., 234.,
57  253., 275., 298., 323., 350., 380., 413., 448., 487.])
58  if nPerBC > 10:
59  return int(ceil(1.224 * nPerBC * 39)) # Table only goes up to 10 per bunch crossing
60  return int(n_to_load[np.searchsorted(boundaries, nPerBC, side='right')])
61 
62 class PUBkgKind(Enum):
63  LOWPT = 1
64  HIGHPT = 2
65  CAVERN = 3
66  BEAMGAS = 4
67  BEAMHALO = 5
68 
69 
71  acc = ComponentAccumulator()
72  acc.merge(InputRenameCfg("xAOD::EventInfo", "EventInfo", "HSEventInfo"))
73  acc.merge(InputRenameCfg("xAOD::EventAuxInfo", "EventInfoAux.", "HSEventInfoAux."))
74  acc.merge(InputRenameCfg("EventInfo", "EventInfo", "HSEventInfo"))
75  acc.merge(InputRenameCfg("McEventCollection", "TruthEvent", "HSTruthEvent"))
76  acc.merge(InputRenameCfg("TrackRecordCollection", "MuonEntryLayer", "HSMuonEntryLayer"))
77  return acc
78 
79 
80 def MinbiasSvcSeed(flags, name, kwargs):
81  # That is *correctly* not **kwargs. This functions updates the kwargs in another.
82  kwargs["Seed"] = (
83  int.from_bytes(blake2b(name.encode(), digest_size=8).digest(), 'big')
84  + flags.Digitization.RandomSeedOffset
85  )
86 
87 
88 def BatchedMinbiasSvcCfg(flags, name="LowPtMinbiasSvc", kind=PUBkgKind.LOWPT, **kwargs):
89  acc = ComponentAccumulator()
90  n_evt = flags.Exec.MaxEvents
91  skip = flags.Exec.SkipEvents
92 
93  MinbiasSvcSeed(flags, name, kwargs)
94  if kind == PUBkgKind.LOWPT:
95  acc.merge(LowPtMinBiasEventSelectorCfg(flags))
96  kwargs.setdefault("OnDemandMB", True)
97  kwargs.setdefault("SkippedHSEvents", skip)
98  kwargs.setdefault("MBBatchSize", 10000)
99  kwargs.setdefault("NSimultaneousBatches", 1)
100  kwargs.setdefault("HSBatchSize", 128)
101  kwargs.setdefault("AvgMBPerBunch", flags.Digitization.PU.NumberOfLowPtMinBias)
102  evt_per_batch = kwargs["HSBatchSize"]
103  actualNHSEventsPerBatch = (
104  (skip // evt_per_batch) * [0]
105  + (skip % evt_per_batch != 0) * [evt_per_batch - (skip % evt_per_batch)]
106  + (n_evt // evt_per_batch) * [evt_per_batch]
107  + (n_evt % evt_per_batch != 0) * [n_evt % evt_per_batch]
108  )
109  kwargs["actualNHSEventsPerBatch"] = actualNHSEventsPerBatch
110  kwargs.setdefault(
111  "BkgEventSelector", acc.getService("LowPtMinBiasEventSelector")
112  )
113  elif kind == PUBkgKind.HIGHPT:
114  acc.merge(HighPtMinBiasEventSelectorCfg(flags))
115  kwargs.setdefault("OnDemandMB", False)
116  kwargs.setdefault("SkippedHSEvents", skip)
117  kwargs.setdefault("AvgMBPerBunch", flags.Digitization.PU.NumberOfHighPtMinBias)
118  kwargs.setdefault(
119  "BkgEventSelector", acc.getService("HighPtMinBiasEventSelector")
120  )
121  elif kind == PUBkgKind.CAVERN:
122  acc.merge(CavernEventSelectorCfg(flags))
123  kwargs.setdefault("OnDemandMB", False)
124  kwargs.setdefault("SkippedHSEvents", skip)
125  kwargs.setdefault("AvgMBPerBunch", flags.Digitization.PU.NumberOfCavern)
126  kwargs.setdefault("UsePoisson", False)
127  kwargs.setdefault("UseBeamInt", False)
128  kwargs.setdefault("UseBeamLumi", False)
129  kwargs.setdefault("BkgEventSelector", acc.getService("CavernEventSelector"))
130  elif kind == PUBkgKind.BEAMGAS:
131  acc.merge(BeamGasEventSelectorCfg(flags))
132  kwargs.setdefault("OnDemandMB", False)
133  kwargs.setdefault("SkippedHSEvents", skip)
134  kwargs.setdefault("AvgMBPerBunch", flags.Digitization.PU.NumberOfBeamGas)
135  kwargs.setdefault("UseBeamInt", True)
136  kwargs.setdefault("UseBeamLumi", False)
137  kwargs.setdefault("BkgEventSelector", acc.getService("BeamGasEventSelector"))
138  elif kind == PUBkgKind.BEAMHALO:
139  acc.merge(BeamHaloEventSelectorCfg(flags))
140  kwargs.setdefault("OnDemandMB", False)
141  kwargs.setdefault("SkippedHSEvents", skip)
142  kwargs.setdefault("AvgMBPerBunch", flags.Digitization.PU.NumberOfBeamHalo)
143  kwargs.setdefault("UseBeamInt", True)
144  kwargs.setdefault("UseBeamLumi", False)
145  kwargs.setdefault("BkgEventSelector", acc.getService("BeamHaloEventSelector"))
146 
147  if kind == PUBkgKind.LOWPT:
148  acc.addService(CompFactory.BatchedMinbiasSvc(name, **kwargs), primary=True)
149  else:
150  acc.addService(CompFactory.OnDemandMinbiasSvc(name, **kwargs), primary=True)
151  return acc
152 
153 
154 def PileUpMTAlgCfg(flags, **kwargs):
155  acc = ComponentAccumulator()
156  acc.addService(CompFactory.SkipEventIdxSvc("SkipEventIdxSvc"))
157  kwargs.setdefault("Cardinality", flags.Concurrency.NumThreads)
158  # acc = BeamSpotFixerAlgCfg(flags) # Needed currently for running on 21.0 HITS
159 
160  assert (
161  not flags.Digitization.DoXingByXingPileUp
162  ), "PileUpMTAlg does not support XingByXing pile-up!"
163  # Set a number of kwargs early so they can be passed to the minbias services
164  # Bunch Structure
165  if flags.Digitization.PU.BeamIntensityPattern:
166  if flags.Digitization.PU.SignalPatternForSteppingCache:
167  # Simulate Bunch Structure with events sliding backwards on a conveyor belt
168  acc.merge(StepArrayBMCfg(flags))
169  kwargs.setdefault("BeamIntSvc", acc.getService("StepArrayBM"))
170  elif flags.Digitization.PU.FixedT0BunchCrossing:
171  # Simulate Bunch Structure using a fixed point for the central bunch crossing
172  acc.merge(FixedArrayBMCfg(flags))
173  kwargs.setdefault("BeamIntSvc", acc.getService("FixedArrayBM"))
174  else:
175  # Simulate Bunch Structure and allow the central bunch crossing to vary
176  acc.merge(ArrayBMCfg(flags))
177  kwargs.setdefault("BeamIntSvc", acc.getService("ArrayBM"))
178 
179  kwargs.setdefault("SkippedHSEvents", flags.Exec.SkipEvents)
180  kwargs.setdefault("BCSpacing", flags.Digitization.PU.BunchSpacing)
181  kwargs.setdefault("EarliestDeltaBC", flags.Digitization.PU.InitialBunchCrossing)
182  kwargs.setdefault("LatestDeltaBC", flags.Digitization.PU.FinalBunchCrossing)
183  if flags.Input.RunAndLumiOverrideList:
184  acc.merge(LumiProfileSvcCfg(flags))
185  kwargs.setdefault("BeamLumiSvc", acc.getService("LumiProfileSvc"))
186  kwargs.setdefault("AverageMu", maxNevtsPerXing(flags))
187  else:
188  acc.merge(NoProfileSvcCfg(flags))
189  kwargs.setdefault("BeamLumiSvc", acc.getService("NoProfileSvc"))
190  kwargs.setdefault("AverageMu", flags.Digitization.PU.NumberOfCollisions)
191 
192  # define inputs
193  assert not flags.Input.SecondaryFiles, (
194  "Found ConfigFlags.Input.SecondaryFiles = %r; "
195  "double event selection is not supported "
196  "by PileUpMTAlg" % (not flags.Input.SecondaryFiles)
197  )
198  acc.merge(HSInputRenameCfg())
199  acc.merge(PoolReadCfg(flags))
200  # add minbias service(s)
201  mbKwargs = {
202  k: kwargs[k]
203  for k in (
204  "SkippedHSEvents",
205  "EarliestDeltaBC",
206  "LatestDeltaBC",
207  "BeamIntSvc",
208  "BeamLumiSvc",
209  )
210  }
211  if flags.Digitization.PU.LowPtMinBiasInputCols:
212  svc = acc.getPrimaryAndMerge(
214  flags, name="LowPtMinBiasSvc", kind=PUBkgKind.LOWPT, **mbKwargs
215  )
216  )
217  kwargs.setdefault("LowPtMinbiasSvc", svc)
218  kwargs.setdefault(
219  "FracLowPt",
220  flags.Digitization.PU.NumberOfLowPtMinBias
221  / flags.Digitization.PU.NumberOfCollisions,
222  )
223  if flags.Digitization.PU.HighPtMinBiasInputCols:
224  svc = acc.getPrimaryAndMerge(
226  flags, name="HighPtMinBiasSvc", kind=PUBkgKind.HIGHPT, **mbKwargs
227  )
228  )
229  kwargs.setdefault("HighPtMinbiasSvc", svc)
230  kwargs.setdefault(
231  "FracHighPt",
232  flags.Digitization.PU.NumberOfHighPtMinBias
233  / flags.Digitization.PU.NumberOfCollisions,
234  )
235  if flags.Digitization.PU.CavernInputCols:
236  svc = acc.getPrimaryAndMerge(
238  flags, name="CavernMinBiasSvc", kind=PUBkgKind.CAVERN, **mbKwargs
239  )
240  )
241  kwargs.setdefault("CavernMinbiasSvc", svc)
242  kwargs.setdefault("NumCavern", flags.Digitization.PU.NumberOfCavern)
243  if flags.Digitization.PU.BeamGasInputCols:
244  svc = acc.getPrimaryAndMerge(
246  flags, name="BeamGasMinBiasSvc", kind=PUBkgKind.BEAMGAS, **mbKwargs
247  )
248  )
249  kwargs.setdefault("BeamGasMinbiasSvc", svc)
250  kwargs.setdefault("NumBeamGas", flags.Digitization.PU.NumberOfBeamGas)
251  if flags.Digitization.PU.BeamHaloInputCols:
252  svc = acc.getPrimaryAndMerge(
254  flags, name="BeamHaloMinBiasSvc", kind=PUBkgKind.BEAMHALO, **mbKwargs
255  )
256  )
257  kwargs.setdefault("BeamHaloMinbiasSvc", svc)
258  kwargs.setdefault("NumBeamHalo", flags.Digitization.PU.NumberOfBeamHalo)
259  presampling = flags.Common.ProductionStep == ProductionStep.PileUpPresampling
260  if presampling:
261  kwargs.setdefault("EventInfoKey", flags.Overlay.BkgPrefix + "EventInfo")
262  else:
263  kwargs.setdefault("EventInfoKey", "EventInfo")
264 
265  acc.addEventAlgo(
266  CompFactory.PileUpMTAlg(flags.Digitization.DigiSteeringConf, **kwargs)
267  )
268 
269  # write PileUpEventInfo
270  if flags.Output.doWriteRDO:
271  from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
272 
273  acc.merge(
275  flags,
276  "RDO",
277  ItemList=[
278  "xAOD::EventInfoContainer#PileUpEventInfo",
279  "xAOD::EventInfoAuxContainer#PileUpEventInfo*",
280  ],
281  )
282  )
283 
284  return acc
python.PileUpMTConfig.PUBkgKind
Definition: PileUpMTConfig.py:62
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
python.OutputStreamConfig.OutputStreamCfg
def OutputStreamCfg(flags, streamName, ItemList=[], MetadataItemList=[], disableEventTag=False, trigNavThinningSvc=None, takeItemsFromInput=False, extendProvenanceRecord=True, AcceptAlgs=[], HelperTools=[])
Definition: OutputStreamConfig.py:12
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.PileUpMTConfig.BatchedMinbiasSvcCfg
def BatchedMinbiasSvcCfg(flags, name="LowPtMinbiasSvc", kind=PUBkgKind.LOWPT, **kwargs)
Definition: PileUpMTConfig.py:88
python.PileUpConfig.LowPtMinBiasEventSelectorCfg
def LowPtMinBiasEventSelectorCfg(flags, name="LowPtMinBiasEventSelector", **kwargs)
Definition: PileUpConfig.py:59
python.RunDependentConfig.maxNevtsPerXing
def maxNevtsPerXing(flags)
Definition: RunDependentConfig.py:9
python.PileUpConfig.CavernEventSelectorCfg
def CavernEventSelectorCfg(flags, name="cavernEventSelector", **kwargs)
Definition: PileUpConfig.py:70
python.PileUpMTConfig.HSInputRenameCfg
def HSInputRenameCfg()
Definition: PileUpMTConfig.py:70
python.PileUpConfig.HighPtMinBiasEventSelectorCfg
def HighPtMinBiasEventSelectorCfg(flags, name="HighPtMinBiasEventSelector", **kwargs)
Definition: PileUpConfig.py:64
python.PileUpConfig.StepArrayBMCfg
def StepArrayBMCfg(flags, name="StepArrayBM", **kwargs)
Definition: PileUpConfig.py:27
python.PileUpMTConfig.PileUpMTAlgCfg
def PileUpMTAlgCfg(flags, **kwargs)
Definition: PileUpMTConfig.py:154
python.PileUpConfig.BeamGasEventSelectorCfg
def BeamGasEventSelectorCfg(flags, name="BeamGasEventSelector", **kwargs)
Definition: PileUpConfig.py:75
python.PileUpConfig.ArrayBMCfg
def ArrayBMCfg(flags, name="ArrayBM", **kwargs)
Definition: PileUpConfig.py:43
python.PileUpConfig.FixedArrayBMCfg
def FixedArrayBMCfg(flags, name="FixedArrayBM", **kwargs)
Definition: PileUpConfig.py:35
python.PileUpMTConfig.MinbiasSvcSeed
def MinbiasSvcSeed(flags, name, kwargs)
Definition: PileUpMTConfig.py:80
python.RunDependentConfig.NoProfileSvcCfg
def NoProfileSvcCfg(flags, name="NoProfileSvc", **kwargs)
Definition: RunDependentConfig.py:46
python.PileUpConfig.BeamHaloEventSelectorCfg
def BeamHaloEventSelectorCfg(flags, name="BeamHaloEventSelector", **kwargs)
Definition: PileUpConfig.py:80
python.PileUpMTConfig.numBkgToLoad
def numBkgToLoad(nPerBC)
Definition: PileUpMTConfig.py:30
python.RunDependentConfig.LumiProfileSvcCfg
def LumiProfileSvcCfg(flags, name="LumiProfileSvc", **kwargs)
Definition: RunDependentConfig.py:36
python.PoolReadConfig.PoolReadCfg
def PoolReadCfg(flags)
Definition: PoolReadConfig.py:69
AddressRemappingConfig.InputRenameCfg
def InputRenameCfg(type, from_name, to_name)
Definition: AddressRemappingConfig.py:28