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  kwargs.setdefault("OnDemandMB", True)
95  if kind == PUBkgKind.LOWPT:
96  acc.merge(LowPtMinBiasEventSelectorCfg(flags))
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("SkippedHSEvents", skip)
116  kwargs.setdefault("AvgMBPerBunch", flags.Digitization.PU.NumberOfHighPtMinBias)
117  kwargs.setdefault(
118  "BkgEventSelector", acc.getService("HighPtMinBiasEventSelector")
119  )
120  elif kind == PUBkgKind.CAVERN:
121  acc.merge(CavernEventSelectorCfg(flags))
122  kwargs.setdefault("SkippedHSEvents", skip)
123  kwargs.setdefault("AvgMBPerBunch", flags.Digitization.PU.NumberOfCavern)
124  kwargs.setdefault("UsePoisson", False)
125  kwargs.setdefault("UseBeamInt", False)
126  kwargs.setdefault("UseBeamLumi", False)
127  kwargs.setdefault("BkgEventSelector", acc.getService("CavernEventSelector"))
128  elif kind == PUBkgKind.BEAMGAS:
129  acc.merge(BeamGasEventSelectorCfg(flags))
130  kwargs.setdefault("SkippedHSEvents", skip)
131  kwargs.setdefault("AvgMBPerBunch", flags.Digitization.PU.NumberOfBeamGas)
132  kwargs.setdefault("UseBeamInt", True)
133  kwargs.setdefault("UseBeamLumi", False)
134  kwargs.setdefault("BkgEventSelector", acc.getService("BeamGasEventSelector"))
135  elif kind == PUBkgKind.BEAMHALO:
136  acc.merge(BeamHaloEventSelectorCfg(flags))
137  kwargs.setdefault("SkippedHSEvents", skip)
138  kwargs.setdefault("AvgMBPerBunch", flags.Digitization.PU.NumberOfBeamHalo)
139  kwargs.setdefault("UseBeamInt", True)
140  kwargs.setdefault("UseBeamLumi", False)
141  kwargs.setdefault("BkgEventSelector", acc.getService("BeamHaloEventSelector"))
142 
143  if kind == PUBkgKind.LOWPT:
144  acc.addService(CompFactory.BatchedMinbiasSvc(name, **kwargs), primary=True)
145  else:
146  acc.addService(CompFactory.OnDemandMinbiasSvc(name, **kwargs), primary=True)
147  return acc
148 
149 
150 def PileUpMTAlgCfg(flags, **kwargs):
151  from BeamSpotConditions.BeamSpotConditionsConfig import BeamSpotCondAlgCfg
152  acc = ComponentAccumulator()
153  acc.addService(CompFactory.SkipEventIdxSvc("SkipEventIdxSvc"))
154  kwargs.setdefault("Cardinality", flags.Concurrency.NumThreads)
155 
156  assert (
157  not flags.Digitization.DoXingByXingPileUp
158  ), "PileUpMTAlg does not support XingByXing pile-up!"
159  acc.merge(BeamSpotCondAlgCfg(flags))
160 
161  # Set a number of kwargs early so they can be passed to the minbias services
162  # Bunch Structure
163  if flags.Digitization.PU.BeamIntensityPattern:
164  if flags.Digitization.PU.SignalPatternForSteppingCache:
165  # Simulate Bunch Structure with events sliding backwards on a conveyor belt
166  acc.merge(StepArrayBMCfg(flags))
167  kwargs.setdefault("BeamIntSvc", acc.getService("StepArrayBM"))
168  elif flags.Digitization.PU.FixedT0BunchCrossing:
169  # Simulate Bunch Structure using a fixed point for the central bunch crossing
170  acc.merge(FixedArrayBMCfg(flags))
171  kwargs.setdefault("BeamIntSvc", acc.getService("FixedArrayBM"))
172  else:
173  # Simulate Bunch Structure and allow the central bunch crossing to vary
174  acc.merge(ArrayBMCfg(flags))
175  kwargs.setdefault("BeamIntSvc", acc.getService("ArrayBM"))
176 
177  kwargs.setdefault("SkippedHSEvents", flags.Exec.SkipEvents)
178  kwargs.setdefault("BCSpacing", flags.Digitization.PU.BunchSpacing)
179  kwargs.setdefault("EarliestDeltaBC", flags.Digitization.PU.InitialBunchCrossing)
180  kwargs.setdefault("LatestDeltaBC", flags.Digitization.PU.FinalBunchCrossing)
181  if flags.Input.RunAndLumiOverrideList:
182  acc.merge(LumiProfileSvcCfg(flags))
183  kwargs.setdefault("BeamLumiSvc", acc.getService("LumiProfileSvc"))
184  kwargs.setdefault("AverageMu", maxNevtsPerXing(flags))
185  else:
186  acc.merge(NoProfileSvcCfg(flags))
187  kwargs.setdefault("BeamLumiSvc", acc.getService("NoProfileSvc"))
188  kwargs.setdefault("AverageMu", flags.Digitization.PU.NumberOfCollisions)
189 
190  # define inputs
191  assert not flags.Input.SecondaryFiles, (
192  "Found ConfigFlags.Input.SecondaryFiles = %r; "
193  "double event selection is not supported "
194  "by PileUpMTAlg" % (not flags.Input.SecondaryFiles)
195  )
196  acc.merge(HSInputRenameCfg())
197  acc.merge(PoolReadCfg(flags))
198  # add minbias service(s)
199  mbKwargs = {
200  k: kwargs[k]
201  for k in (
202  "SkippedHSEvents",
203  "EarliestDeltaBC",
204  "LatestDeltaBC",
205  "BeamIntSvc",
206  "BeamLumiSvc",
207  )
208  }
209  if flags.Digitization.PU.LowPtMinBiasInputCols:
210  svc = acc.getPrimaryAndMerge(
212  flags, name="LowPtMinBiasSvc", kind=PUBkgKind.LOWPT, **mbKwargs
213  )
214  )
215  kwargs.setdefault("LowPtMinbiasSvc", svc)
216  kwargs.setdefault(
217  "FracLowPt",
218  flags.Digitization.PU.NumberOfLowPtMinBias
219  / flags.Digitization.PU.NumberOfCollisions,
220  )
221  if flags.Digitization.PU.HighPtMinBiasInputCols:
222  svc = acc.getPrimaryAndMerge(
224  flags, name="HighPtMinBiasSvc", kind=PUBkgKind.HIGHPT, **mbKwargs
225  )
226  )
227  kwargs.setdefault("HighPtMinbiasSvc", svc)
228  kwargs.setdefault(
229  "FracHighPt",
230  flags.Digitization.PU.NumberOfHighPtMinBias
231  / flags.Digitization.PU.NumberOfCollisions,
232  )
233  if flags.Digitization.PU.CavernInputCols:
234  svc = acc.getPrimaryAndMerge(
236  flags, name="CavernMinBiasSvc", kind=PUBkgKind.CAVERN, **mbKwargs
237  )
238  )
239  kwargs.setdefault("CavernMinbiasSvc", svc)
240  kwargs.setdefault("NumCavern", flags.Digitization.PU.NumberOfCavern)
241  if flags.Digitization.PU.BeamGasInputCols:
242  svc = acc.getPrimaryAndMerge(
244  flags, name="BeamGasMinBiasSvc", kind=PUBkgKind.BEAMGAS, **mbKwargs
245  )
246  )
247  kwargs.setdefault("BeamGasMinbiasSvc", svc)
248  kwargs.setdefault("NumBeamGas", flags.Digitization.PU.NumberOfBeamGas)
249  if flags.Digitization.PU.BeamHaloInputCols:
250  svc = acc.getPrimaryAndMerge(
252  flags, name="BeamHaloMinBiasSvc", kind=PUBkgKind.BEAMHALO, **mbKwargs
253  )
254  )
255  kwargs.setdefault("BeamHaloMinbiasSvc", svc)
256  kwargs.setdefault("NumBeamHalo", flags.Digitization.PU.NumberOfBeamHalo)
257  presampling = flags.Common.ProductionStep == ProductionStep.PileUpPresampling
258  if presampling:
259  kwargs.setdefault("EventInfoKey", flags.Overlay.BkgPrefix + "EventInfo")
260  else:
261  kwargs.setdefault("EventInfoKey", "EventInfo")
262 
263  acc.addEventAlgo(
264  CompFactory.PileUpMTAlg(flags.Digitization.DigiSteeringConf, **kwargs)
265  )
266 
267  # write PileUpEventInfo
268  if flags.Output.doWriteRDO:
269  from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
270 
271  acc.merge(
273  flags,
274  "RDO",
275  ItemList=[
276  "xAOD::EventInfoContainer#PileUpEventInfo",
277  "xAOD::EventInfoAuxContainer#PileUpEventInfo*",
278  ],
279  )
280  )
281 
282  return acc
python.PileUpMTConfig.PUBkgKind
Definition: PileUpMTConfig.py:62
python.OutputStreamConfig.OutputStreamCfg
def OutputStreamCfg(flags, streamName, ItemList=None, MetadataItemList=None, disableEventTag=False, trigNavThinningSvc=None, takeItemsFromInput=False, extendProvenanceRecord=True, keepProvenanceTagsRegEx=None, AcceptAlgs=None, HelperTools=None)
Definition: OutputStreamConfig.py:13
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
python.PileUpMTConfig.BatchedMinbiasSvcCfg
def BatchedMinbiasSvcCfg(flags, name="LowPtMinbiasSvc", kind=PUBkgKind.LOWPT, **kwargs)
Definition: PileUpMTConfig.py:88
python.BeamSpotConditionsConfig.BeamSpotCondAlgCfg
def BeamSpotCondAlgCfg(flags, name="BeamSpotCondAlg", **kwargs)
Definition: BeamSpotConditionsConfig.py:7
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:150
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.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
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:71
AddressRemappingConfig.InputRenameCfg
def InputRenameCfg(type, from_name, to_name)
Definition: AddressRemappingConfig.py:28