From 3d6c2f5a2aada61725394632b22e00a902a79645 Mon Sep 17 00:00:00 2001
From: John Chapman <jchapman@cern.ch>
Date: Mon, 8 Aug 2022 14:39:36 +0200
Subject: [PATCH 1/4] Clean-up CA-based AFP_Digitization configuration

---
 .../python/AFP_DigitizationConfig.py          | 135 ++++++++++++++++++
 .../python/AFP_DigitizationConfigNew.py       |  93 ------------
 ...test.py => AFP_DigitizationConfig_test.py} |   6 +-
 .../python/DigitizationSteering.py            |   4 +-
 4 files changed, 140 insertions(+), 98 deletions(-)
 create mode 100644 ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfig.py
 delete mode 100644 ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfigNew.py
 rename ForwardDetectors/AFP/AFP_Digitization/python/{AFP_DigitizationConfigNew_test.py => AFP_DigitizationConfig_test.py} (92%)

diff --git a/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfig.py b/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfig.py
new file mode 100644
index 000000000000..14d834df9913
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfig.py
@@ -0,0 +1,135 @@
+# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+
+#==============================================================
+# Job options file for the AFP_Digitization package
+#==============================================================
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+from AthenaConfiguration.Enums import ProductionStep
+from Digitization.PileUpMergeSvcConfigNew import PileUpMergeSvcCfg, PileUpXingFolderCfg
+
+
+# The earliest bunch crossing time for which interactions will be sent to the AFP Digitization code.
+def AFP_FirstXing():
+    return 0 #Assume AFP is only sensitive to the current bunch crossing, for the moment
+
+
+# The latest bunch crossing time for which interactions will be sent to the AFP Digitization code.
+def AFP_LastXing():
+    return 0 #Assume AFP is only sensitive to the current bunch crossing, for the moment
+
+
+def AFP_SIDPUXinfFolderCfg(flags, name="AFP_SIDXinfFolder", **kwargs):
+    """Return a PileUpXingFoldertool for AFP SID"""
+    # bunch crossing range in ns
+    kwargs.setdefault("FirstXing", AFP_FirstXing())
+    kwargs.setdefault("LastXing", AFP_LastXing())
+    kwargs.setdefault("ItemList", ["AFP_SIDSimHitCollection#AFP_SIDSimHitCollection"])
+    return PileUpXingFolderCfg(flags, name, **kwargs)
+
+
+def AFP_TDPUXinfFolderCfg(flags, name="AFP_TDXinfFolder", **kwargs):
+    """Return a PileUpXingFoldertool for AFP TD"""
+    # bunch crossing range in ns
+    kwargs.setdefault("FirstXing", AFP_FirstXing())
+    kwargs.setdefault("LastXing", AFP_LastXing())
+    kwargs.setdefault("ItemList", ["AFP_TDSimHitCollection#AFP_TDSimHitCollection"])
+    return PileUpXingFolderCfg(flags, name, **kwargs)
+
+
+def AFP_DigitizationToolCfg(flags, **kwargs):
+    """Return ComponentAccumulator with AFP digitization tool."""
+    acc = ComponentAccumulator()
+
+    if flags.Digitization.PileUp:
+        intervals = []
+        if flags.Digitization.DoXingByXingPileUp:
+            kwargs.setdefault("FirstXing", AFP_FirstXing())
+            kwargs.setdefault("LastXing", AFP_LastXing())
+        else:
+            intervals += [acc.popToolsAndMerge(AFP_SIDPUXinfFolderCfg(flags))]
+            intervals += [acc.popToolsAndMerge(AFP_TDPUXinfFolderCfg(flags))]
+        kwargs.setdefault("mergeSvc", acc.getPrimaryAndMerge(PileUpMergeSvcCfg(flags, Intervals=intervals)).name)
+        kwargs.setdefault("OnlyUseContainerName", True)
+    else:
+        kwargs.setdefault("mergeSvc", '')
+        kwargs.setdefault("OnlyUseContainerName", False)
+
+    from RngComps.RandomServices import AthRNGSvcCfg
+    kwargs.setdefault("RndmSvc", acc.getPrimaryAndMerge(AthRNGSvcCfg(flags)).name)
+
+    acc.setPrivateTools(CompFactory.AFP_PileUpTool("AFP_PileUpTool", **kwargs))
+    return acc
+
+
+def AFP_OverlayDigitizationToolCfg(flags, name="AFP_OverlayDigitizationTool", **kwargs):
+    """Return ComponentAccumulator with AFP_DigitizationTool for Overlay"""
+    acc = ComponentAccumulator()
+    kwargs.setdefault("mergeSvc", '')
+    kwargs.setdefault("OnlyUseContainerName", False)
+    tool = acc.popToolsAndMerge(AFP_DigitizationToolCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
+
+
+def AFP_DigitizationOutputCfg(flags):
+    """Return ComponentAccumulator with Output for AFP. Not standalone."""
+    acc = ComponentAccumulator()
+    if flags.Output.doWriteRDO:
+        ItemList = ["AFP_TDDigiCollection#AFP_TDDigiCollection",
+                                               "AFP_SiDigiCollection#AFP_SiDigiCollection",
+                                               "xAOD::AFPSiHitContainer#AFPSiHitContainer", "xAOD::AFPSiHitAuxContainer#AFPSiHitContainerAux.",
+                                               "xAOD::AFPToFHitContainer#AFPToFHitContainer", "xAOD::AFPToFHitAuxContainer#AFPToFHitContainerAux."]
+        from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+        acc.merge(OutputStreamCfg(flags,"RDO", ItemList))
+    return acc
+
+
+def AFP_DigitizationBasicCfg(flags, **kwargs):
+    """Return ComponentAccumulator for AFP digitization"""
+    acc = ComponentAccumulator()
+    if "PileUpTools" not in kwargs:
+        PileUpTools = acc.popToolsAndMerge(AFP_DigitizationToolCfg(flags))
+        kwargs["PileUpTools"] = PileUpTools
+    from Digitization.PileUpToolsConfig import PileUpToolsCfg
+    acc.merge(PileUpToolsCfg(flags, **kwargs))
+    return acc
+
+
+def AFP_OverlayDigitizationBasicCfg(flags, **kwargs):
+    """Return ComponentAccumulator with AFP_DigiTop."""
+    acc = ComponentAccumulator()
+    if flags.Common.ProductionStep != ProductionStep.FastChain:
+        from SGComps.SGInputLoaderConfig import SGInputLoaderCfg
+        acc.merge(SGInputLoaderCfg(flags,Load=[('AFP_TDSimHitCollection','StoreGateSvc+AFP_TDSimHitCollection'),
+                                               ('AFP_SIDSimHitCollection','StoreGateSvc+AFP_SIDSimHitCollection')] ) )
+    if "DigitizationTool" not in kwargs:
+        kwargs.setdefault("DigitizationTool", acc.popToolsAndMerge(AFP_OverlayDigitizationToolCfg(flags)))
+
+    if flags.Concurrency.NumThreads > 0:
+        kwargs.setdefault("Cardinality", flags.Concurrency.NumThreads)
+
+    # Set common overlay extra inputs
+    kwargs.setdefault("ExtraInputs", flags.Overlay.ExtraInputs)
+
+    acc.addEventAlgo(CompFactory.AFP_DigiTop("AFP_DigiTop", **kwargs))
+    return acc
+
+
+def AFP_DigitizationCfg(flags, **kwargs):
+    """Return ComponentAccumulator for AFP digitization and Output"""
+    acc = ComponentAccumulator()
+    acc.merge(AFP_DigitizationBasicCfg(flags, **kwargs))
+    acc.merge(AFP_DigitizationOutputCfg(flags))
+
+    return acc
+
+
+def AFP_DigitizationOverlayCfg(flags, **kwargs):
+    """Return ComponentAccumulator for AFP digitization and Output"""
+    acc = ComponentAccumulator()
+    acc.merge(AFP_OverlayDigitizationBasicCfg(flags, **kwargs))
+    acc.merge(AFP_DigitizationOutputCfg(flags))
+
+    return acc
diff --git a/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfigNew.py b/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfigNew.py
deleted file mode 100644
index a39b50d18a15..000000000000
--- a/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfigNew.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
-
-#==============================================================
-# Job options file for the AFP_Digitization package
-#==============================================================
-
-from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-from AthenaConfiguration.ComponentFactory import CompFactory
-from Digitization.PileUpMergeSvcConfigNew import PileUpMergeSvcCfg
-from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
-from SGComps.SGInputLoaderConfig import SGInputLoaderCfg
-
-
-# The earliest bunch crossing time for which interactions will be sent to the AFP Digitization code.
-def AFP_FirstXing(flags):
-    return 0 #Assume AFP is only sensitive to the current bunch crossing, for the moment
-
-
-# The latest bunch crossing time for which interactions will be sent to the AFP Digitization code.
-def AFP_LastXing(flags):
-    return 0 #Assume AFP is only sensitive to the current bunch crossing, for the moment
-
-
-def AFP_SIDPUXinfFolder(flags, name="AFP_SIDXinfFolder", **kwargs):
-    """Return a PileUpXingFoldertool for AFP SID"""
-    # bunch crossing range in ns
-    kwargs.setdefault("FirstXing", AFP_FirstXing(flags))
-    kwargs.setdefault("LastXing", AFP_LastXing(flags))
-    kwargs.setdefault("ItemList", ["AFP_SIDSimHitCollection#AFP_SIDSimHitCollection"])
-    PileUpXingFolder = CompFactory.PileUpXingFolder
-    return PileUpXingFolder(name, **kwargs)
-
-
-def AFP_TDPUXinfFolder(flags, name="AFP_TDXinfFolder", **kwargs):
-    """Return a PileUpXingFoldertool for AFP TD"""
-    # bunch crossing range in ns
-    kwargs.setdefault("FirstXing", AFP_FirstXing(flags))
-    kwargs.setdefault("LastXing", AFP_LastXing(flags))
-    kwargs.setdefault("ItemList", ["AFP_TDSimHitCollection#AFP_TDSimHitCollection"])
-    PileUpXingFolder = CompFactory.PileUpXingFolder
-    return PileUpXingFolder(name, **kwargs)
-
-
-def AFP_DigitizationToolCfg(flags, **kwargs):
-    """Return ComponentAccumulator with AFP digitization tool."""
-    acc = ComponentAccumulator()
-    
-    if flags.Digitization.PileUp:
-        intervals = []
-        if flags.Digitization.DoXingByXingPileUp:
-            kwargs.setdefault("FirstXing", AFP_FirstXing(flags))
-            kwargs.setdefault("LastXing", AFP_LastXing(flags))
-        else:
-            intervals += [acc.popToolsAndMerge(AFP_SIDPUXinfFolder(flags))]
-            intervals += [acc.popToolsAndMerge(AFP_TDPUXinfFolder(flags))]
-        kwargs.setdefault("mergeSvc", acc.getPrimaryAndMerge(PileUpMergeSvcCfg(flags, Intervals=intervals)).name)
-        kwargs.setdefault("OnlyUseContainerName", True)
-    else:
-        kwargs.setdefault("mergeSvc", '')
-        kwargs.setdefault("OnlyUseContainerName", False)
-    
-    from RngComps.RandomServices import AthRNGSvcCfg
-    kwargs.setdefault("RndmSvc", acc.getPrimaryAndMerge(AthRNGSvcCfg(flags)).name)
-    
-    AFP_PileUpTool = CompFactory.AFP_PileUpTool("AFP_PileUpTool", **kwargs)
-    AFP_DigiTop = CompFactory.AFP_DigiTop("AFP_DigiTop",DigitizationTool=AFP_PileUpTool)
-    acc.addEventAlgo(AFP_DigiTop)
-    
-    return acc
-
-
-def AFP_DigitizationOutputCfg(flags):
-    """Return ComponentAccumulator with Output for AFP. Not standalone."""
-    acc = ComponentAccumulator()
-    if flags.Output.doWriteRDO:
-        acc.merge(OutputStreamCfg(flags,"RDO",["AFP_TDDigiCollection#AFP_TDDigiCollection", 
-                                               "AFP_SiDigiCollection#AFP_SiDigiCollection", 
-                                               "xAOD::AFPSiHitContainer#AFPSiHitContainer", "xAOD::AFPSiHitAuxContainer#AFPSiHitContainerAux.",
-                                               "xAOD::AFPToFHitContainer#AFPToFHitContainer", "xAOD::AFPToFHitAuxContainer#AFPToFHitContainerAux."]))
-    
-    acc.merge(SGInputLoaderCfg(flags,Load=[('AFP_TDSimHitCollection','StoreGateSvc+AFP_TDSimHitCollection'), 
-                                           ('AFP_SIDSimHitCollection','StoreGateSvc+AFP_SIDSimHitCollection')] ) )
-    
-    return acc
-
-
-def AFP_DigitizationCfg(flags, **kwargs):
-    """Return ComponentAccumulator for AFP digitization and Output"""
-    acc = AFP_DigitizationToolCfg(flags, **kwargs)
-    acc.merge(AFP_DigitizationOutputCfg(flags))
-    
-    return acc
-
diff --git a/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfigNew_test.py b/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfig_test.py
similarity index 92%
rename from ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfigNew_test.py
rename to ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfig_test.py
index a6983f65835c..ebec8a128831 100755
--- a/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfigNew_test.py
+++ b/ForwardDetectors/AFP/AFP_Digitization/python/AFP_DigitizationConfig_test.py
@@ -2,16 +2,16 @@
 
 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 
-# file   AFP_DigitizationConfigNew_test.py
+# file   AFP_DigitizationConfig_test.py
 # author Petr Balek <petr.balek@cern.ch>
 # date   2022-05-25
 
 # brief  A script to test AFP_Digitization package. Mostly inspired by Digitization/DigitizationConfigNew_test.py, but includes switching AFP digitization on (it's off by default). To test it:
 #           0. setup athena enviroment
 #           1a. run this script:
-#              $ python AFP_DigitizationConfigNew_test.py
+#              $ python AFP_DigitizationConfig_test.py
 #           1b. it's also possible to add some arguments:
-#              $ python AFP_DigitizationConfigNew_test.py Detector.EnableAFP=True
+#              $ python AFP_DigitizationConfig_test.py Detector.EnableAFP=True
 #           2. you may want to continue with reconstruction:
 #              $ RecoSteeringTest.py --filesInput=myRDO.pool.root --RDO Reco.EnableAFP=True
 
diff --git a/Simulation/Digitization/python/DigitizationSteering.py b/Simulation/Digitization/python/DigitizationSteering.py
index 0aac5fd47c2e..3d0bb2120133 100644
--- a/Simulation/Digitization/python/DigitizationSteering.py
+++ b/Simulation/Digitization/python/DigitizationSteering.py
@@ -27,7 +27,7 @@ from StripDigitization.StripDigitizationConfig import ITkStripDigitizationCfg
 from HGTD_Digitization.HGTD_DigitizationConfig import HGTD_DigitizationCfg
 from TileSimAlgs.TileDigitizationConfig import TileDigitizationCfg, TileTriggerDigitizationCfg
 from TRT_Digitization.TRT_DigitizationConfig import TRT_DigitizationCfg
-from AFP_Digitization.AFP_DigitizationConfigNew import AFP_DigitizationCfg
+from AFP_Digitization.AFP_DigitizationConfig import AFP_DigitizationCfg
 from RunDependentSimComps.PileUpUtils import pileupInputCollections
 
 from AthenaCommon.Logging import logging
@@ -156,7 +156,7 @@ def DigitizationMainContentCfg(flags):
     # AFP
     if flags.Detector.EnableAFP:
         acc.merge(AFP_DigitizationCfg(flags))
-    
+
     # Add MT-safe PerfMon
     if flags.PerfMon.doFastMonMT or flags.PerfMon.doFullMonMT:
         from PerfMonComps.PerfMonCompsConfig import PerfMonMTSvcCfg
-- 
GitLab


From a850d98540f5b88319a7037a14a58b98c6c76aa9 Mon Sep 17 00:00:00 2001
From: John Chapman <jchapman@cern.ch>
Date: Mon, 8 Aug 2022 14:42:58 +0200
Subject: [PATCH 2/4] Initial implementation of CA-based ALFA digitization
 configuration

---
 .../python/ALFA_DigitizationConfig.py         | 125 ++++++++++++++++++
 .../python/DigitizationSteering.py            |   5 +
 2 files changed, 130 insertions(+)
 create mode 100644 ForwardDetectors/ALFA/ALFA_Digitization/python/ALFA_DigitizationConfig.py

diff --git a/ForwardDetectors/ALFA/ALFA_Digitization/python/ALFA_DigitizationConfig.py b/ForwardDetectors/ALFA/ALFA_Digitization/python/ALFA_DigitizationConfig.py
new file mode 100644
index 000000000000..62ddbe1e5ebf
--- /dev/null
+++ b/ForwardDetectors/ALFA/ALFA_Digitization/python/ALFA_DigitizationConfig.py
@@ -0,0 +1,125 @@
+# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+from AthenaConfiguration.Enums import ProductionStep
+from Digitization.PileUpMergeSvcConfigNew import PileUpMergeSvcCfg, PileUpXingFolderCfg
+
+# The earliest bunch crossing time for which interactions will be sent
+# to the ALFA Digitization code.
+def ALFA_FirstXing():
+    return 0 #Assume ALFA is only sensitive to the current bunch crossing, for the moment
+
+######################################################################################
+
+# The latest bunch crossing time for which interactions will be sent
+# to the ALFA Digitization code.
+def ALFA_LastXing():
+    return 0 #Assume ALFA is only sensitive to the current bunch crossing, for the moment
+
+######################################################################################
+
+def ALFARangeCfg(flags, name="ALFARange", **kwargs):
+    #this is the time of the xing in ns
+    kwargs.setdefault('FirstXing', ALFA_FirstXing() )
+    kwargs.setdefault('LastXing',  ALFA_LastXing() )
+    kwargs.setdefault('CacheRefreshFrequency', 1.0 ) #default 0 no dataproxy reset
+    kwargs.setdefault('ItemList', ["ALFA_HitCollection#ALFA_HitCollection",
+                                   "ALFA_ODHitCollection#ALFA_ODHitCollection"] )
+    return PileUpXingFolderCfg(flags, name, **kwargs)
+
+######################################################################################
+
+def ALFA_PileUpToolCfg(flags, name="ALFA_PileUpTool", **kwargs):
+    """Return ComponentAccumulator with ALFA digitization tool."""
+    acc = ComponentAccumulator()
+
+    # Configure bunch-crossing envelope
+    if flags.Digitization.PileUp:
+        intervals = []
+        if flags.Digitization.DoXingByXingPileUp:
+            kwargs.setdefault("FirstXing", ALFA_FirstXing() )
+            kwargs.setdefault("LastXing", ALFA_LastXing() )
+        else:
+            intervals += [acc.popToolsAndMerge(ALFARangeCfg(flags))]
+        kwargs.setdefault("mergeSvc", acc.getPrimaryAndMerge(PileUpMergeSvcCfg(flags, Intervals=intervals)).name)
+        #kwargs.setdefault("OnlyUseContainerName", True) # TODO in future MR
+    else:
+        kwargs.setdefault("mergeSvc", '')
+        #kwargs.setdefault("OnlyUseContainerName", False) #TODO in future MR
+
+    from RngComps.RandomServices import AthRNGSvcCfg
+    kwargs.setdefault("RndmSvc", acc.getPrimaryAndMerge(AthRNGSvcCfg(flags)).name)
+
+    acc.setPrivateTools(CompFactory.ALFA_PileUpTool(name, **kwargs))
+    return acc
+
+
+def ALFA_OverlayPileUpToolCfg(flags, name="ALFA_OverlayPileUpTool", **kwargs):
+    """Return ComponentAccumulator with ALFA_PileUpTool for Overlay"""
+    acc = ComponentAccumulator()
+    kwargs.setdefault("mergeSvc", '')
+    #kwargs.setdefault("OnlyUseContainerName", False) #TODO in future MR
+    tool = acc.popToolsAndMerge(ALFA_PileUpToolCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
+
+
+def ALFA_DigitizationOutputCfg(flags):
+    """Return ComponentAccumulator with Output for ALFA. Not standalone."""
+    acc = ComponentAccumulator()
+    if flags.Output.doWriteRDO:
+        ItemList = ["ALFA_DigitCollection#ALFA_DigitCollection",
+                    "ALFA_ODDigitCollection#ALFA_ODDigitCollection"]
+        from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+        acc.merge(OutputStreamCfg(flags,"RDO", ItemList))
+    return acc
+
+
+def ALFA_DigitizationBasicCfg(flags, **kwargs):
+    """Return ComponentAccumulator for ALFA digitization"""
+    acc = ComponentAccumulator()
+    if "PileUpTools" not in kwargs:
+        PileUpTools = acc.popToolsAndMerge(ALFA_PileUpToolCfg(flags))
+        kwargs["PileUpTools"] = PileUpTools
+    from Digitization.PileUpToolsConfig import PileUpToolsCfg
+    acc.merge(PileUpToolsCfg(flags, **kwargs))
+    return acc
+
+
+def ALFA_OverlayDigitizationBasicCfg(flags, **kwargs):
+    """Return ComponentAccumulator with ALFA_DigiAlg."""
+    acc = ComponentAccumulator()
+    if flags.Common.ProductionStep != ProductionStep.FastChain:
+        from SGComps.SGInputLoaderConfig import SGInputLoaderCfg
+        acc.merge(SGInputLoaderCfg(flags,Load=[('ALFA_HitCollection','ALFA_HitCollection'),
+                                               ('ALFA_ODHitCollection','ALFA_ODHitCollection')] ) )
+    if "DigitizationTool" not in kwargs:
+        kwargs.setdefault("DigitizationTool", acc.popToolsAndMerge(ALFA_OverlayPileUpToolCfg(flags)))
+
+    if flags.Concurrency.NumThreads > 0:
+        kwargs.setdefault("Cardinality", flags.Concurrency.NumThreads)
+
+    # Set common overlay extra inputs
+    kwargs.setdefault("ExtraInputs", flags.Overlay.ExtraInputs)
+
+    acc.addEventAlgo(CompFactory.ALFA_DigiAlg("ALFA_DigiAlg", **kwargs))
+    return acc
+
+
+def ALFA_DigitizationCfg(flags, **kwargs):
+    """Return ComponentAccumulator for ALFA digitization and Output"""
+    acc = ComponentAccumulator()
+    acc.merge(ALFA_DigitizationBasicCfg(flags, **kwargs))
+    acc.merge(ALFA_DigitizationOutputCfg(flags))
+
+    return acc
+
+
+def ALFA_DigitizationOverlayCfg(flags, **kwargs):
+    """Return ComponentAccumulator for ALFA digitization and Output"""
+    acc = ComponentAccumulator()
+    acc.merge(ALFA_OverlayDigitizationBasicCfg(flags, **kwargs))
+    acc.merge(ALFA_DigitizationOutputCfg(flags))
+
+    return acc
diff --git a/Simulation/Digitization/python/DigitizationSteering.py b/Simulation/Digitization/python/DigitizationSteering.py
index 3d0bb2120133..4b95e65751ec 100644
--- a/Simulation/Digitization/python/DigitizationSteering.py
+++ b/Simulation/Digitization/python/DigitizationSteering.py
@@ -27,6 +27,7 @@ from StripDigitization.StripDigitizationConfig import ITkStripDigitizationCfg
 from HGTD_Digitization.HGTD_DigitizationConfig import HGTD_DigitizationCfg
 from TileSimAlgs.TileDigitizationConfig import TileDigitizationCfg, TileTriggerDigitizationCfg
 from TRT_Digitization.TRT_DigitizationConfig import TRT_DigitizationCfg
+from ALFA_Digitization.ALFA_DigitizationConfig import ALFA_DigitizationCfg
 from AFP_Digitization.AFP_DigitizationConfig import AFP_DigitizationCfg
 from RunDependentSimComps.PileUpUtils import pileupInputCollections
 
@@ -157,6 +158,10 @@ def DigitizationMainContentCfg(flags):
     if flags.Detector.EnableAFP:
         acc.merge(AFP_DigitizationCfg(flags))
 
+    # ALFA
+    if flags.Detector.EnableALFA:
+        acc.merge(ALFA_DigitizationCfg(flags))
+
     # Add MT-safe PerfMon
     if flags.PerfMon.doFastMonMT or flags.PerfMon.doFullMonMT:
         from PerfMonComps.PerfMonCompsConfig import PerfMonMTSvcCfg
-- 
GitLab


From d86e7b424142293740cf61d9942c6bf7c3d23c44 Mon Sep 17 00:00:00 2001
From: John Chapman <jchapman@cern.ch>
Date: Mon, 8 Aug 2022 15:18:56 +0200
Subject: [PATCH 3/4] Initial commit of CA-based configuration of LUCID
 digitization

---
 .../python/LUCID_DigitizationConfig.py        | 128 ++++++++++++++++++
 .../python/DigitizationSteering.py            |   5 +
 2 files changed, 133 insertions(+)
 create mode 100644 ForwardDetectors/LUCID/LUCID_Digitization/python/LUCID_DigitizationConfig.py

diff --git a/ForwardDetectors/LUCID/LUCID_Digitization/python/LUCID_DigitizationConfig.py b/ForwardDetectors/LUCID/LUCID_Digitization/python/LUCID_DigitizationConfig.py
new file mode 100644
index 000000000000..aafb75cd8e4a
--- /dev/null
+++ b/ForwardDetectors/LUCID/LUCID_Digitization/python/LUCID_DigitizationConfig.py
@@ -0,0 +1,128 @@
+# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+from AthenaConfiguration.Enums import ProductionStep
+from Digitization.PileUpMergeSvcConfigNew import PileUpMergeSvcCfg, PileUpXingFolderCfg
+
+# The earliest bunch crossing time for which interactions will be sent
+# to the LUCID Digitization code.
+def LUCID_FirstXing():
+    return 0
+
+
+# The latest bunch crossing time for which interactions will be sent
+# to the LUCID Digitization code.
+def LUCID_LastXing():
+    return 0
+
+######################################################################################
+
+def LucidRangeCfg(flags, name="LucidRange" , **kwargs):
+    #this is the time of the xing in ns
+    kwargs.setdefault('FirstXing', LUCID_FirstXing() ) #LUCID is only sensitive to the current bunch crossing.
+    kwargs.setdefault('LastXing', LUCID_LastXing() ) #LUCID is only sensitive to the current bunch crossing.
+    kwargs.setdefault('CacheRefreshFrequency', 1.0 ) #default 0 no dataproxy reset
+    kwargs.setdefault('ItemList', ["LUCID_SimHitCollection#LucidSimHitsVector"] )
+    return PileUpXingFolderCfg(flags, name, **kwargs)
+
+######################################################################################
+
+def LUCID_PileUpToolCfg(flags, name="LUCID_PileUpTool",**kwargs):
+    acc = ComponentAccumulator()
+
+    if flags.Digitization.PileUp:
+        intervals = []
+        if flags.Digitization.DoXingByXingPileUp:
+            kwargs.setdefault("FirstXing", LUCID_FirstXing() )
+            kwargs.setdefault("LastXing", LUCID_LastXing() )
+        else:
+            intervals += [acc.popToolsAndMerge(LucidRangeCfg(flags))]
+        kwargs.setdefault("mergeSvc", acc.getPrimaryAndMerge(PileUpMergeSvcCfg(flags, Intervals=intervals)).name)
+        #kwargs.setdefault("OnlyUseContainerName", True) # FIXME in future MR
+    else:
+        kwargs.setdefault("mergeSvc", '')
+        #kwargs.setdefault("OnlyUseContainerName", False) # FIXME in future MR
+
+    from RngComps.RandomServices import AthRNGSvcCfg
+    kwargs.setdefault("RndmSvc", acc.getPrimaryAndMerge(AthRNGSvcCfg(flags)).name)
+
+    kwargs.setdefault('pmtSmearing', [0.317, 0.000, 0.292, 0.316, 0.208, 0.178, 0.204, 0.281, 0.233, 0.261, 0.223, 0.250, 0.254, 0.239, 0.202, 0.224,  1,  1,  1,  1,
+                          0.268, 0.277, 0.297, 0.310, 0.203, 0.347, 0.269, 0.241, 0.234, 0.234, 0.277, 0.297, 0.225, 0.297, 0.238, 0.000,  1,  1,  1,  1] )
+    kwargs.setdefault('pmtScaling', [1.010, 0.000, 0.991, 0.948, 1.152, 1.221, 1.160, 0.988, 1.092, 1.063, 1.143, 1.091, 1.109, 1.117, 1.185, 1.142,  1,  1,  1,  1,
+                          1.023, 1.127, 1.043, 0.986, 1.148, 0.899, 0.898, 1.098, 1.115, 1.109, 1.127, 1.043, 1.085, 1.043, 1.063, 0.000,  1,  1,  1,  1] )
+    kwargs.setdefault('gasScaling', [1.176, 0.000, 1.217, 1.101, 1.143, 1.105, 1.103, 1.144, 1.075, 1.069, 1.100, 1.208, 1.212, 1.125, 1.026, 1.037,  1,  1,  1,  1,
+                          1.064, 0.956, 0.975, 0.938, 1.205, 1.095, 1.137, 1.222, 1.262, 1.160, 0.923, 0.969, 1.132, 0.969, 1.174, 0.000,  1,  1,  1,  1] )
+    kwargs.setdefault('npeThreshold', [   17,    15,    16,    16,    18,    16,    16,    18,    17,    16,    16,    17,    19,    16,    16,    17, 15, 15, 15, 15,
+                             17,    16,    16,    17,    17,    15,    16,    16,    17,    16,    15,    17,    17,    15,    16,    15, 15, 15, 15, 15] )
+
+    acc.setPrivateTools(CompFactory.LUCID_PileUpTool(name,**kwargs))
+    return acc
+
+
+def LUCID_OverlayPileUpToolCfg(flags, name="LUCID_OverlayPileUpTool", **kwargs):
+    """Return ComponentAccumulator with LUCID_PileUpTool for Overlay"""
+    acc = ComponentAccumulator()
+    kwargs.setdefault("mergeSvc", '')
+    #kwargs.setdefault("OnlyUseContainerName", False) #TODO in future MR
+    tool = acc.popToolsAndMerge(LUCID_PileUpToolCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
+
+
+def LUCID_DigitizationOutputCfg(flags):
+    """Return ComponentAccumulator with Output for LUCID. Not standalone."""
+    acc = ComponentAccumulator()
+    if flags.Output.doWriteRDO:
+        ItemList = ["LUCID_DigitContainer#LucidDigitsCnt"]
+        from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+        acc.merge(OutputStreamCfg(flags,"RDO", ItemList))
+    return acc
+
+
+def LUCID_DigitizationBasicCfg(flags, **kwargs):
+    """Return ComponentAccumulator for LUCID digitization"""
+    acc = ComponentAccumulator()
+    if "PileUpTools" not in kwargs:
+        PileUpTools = acc.popToolsAndMerge(LUCID_PileUpToolCfg(flags))
+        kwargs["PileUpTools"] = PileUpTools
+    from Digitization.PileUpToolsConfig import PileUpToolsCfg
+    acc.merge(PileUpToolsCfg(flags, **kwargs))
+    return acc
+
+
+def LUCID_OverlayDigitizationBasicCfg(flags, **kwargs):
+    """Return ComponentAccumulator with LUCID_DigiTop."""
+    acc = ComponentAccumulator()
+    if flags.Common.ProductionStep != ProductionStep.FastChain:
+        from SGComps.SGInputLoaderConfig import SGInputLoaderCfg
+        acc.merge(SGInputLoaderCfg(flags,Load=[('LUCID_SimHitCollection','LucidSimHitsVector')] ) )
+    if "DigitizationTool" not in kwargs:
+        kwargs.setdefault("DigitizationTool", acc.popToolsAndMerge(LUCID_OverlayPileUpToolCfg(flags)))
+
+    if flags.Concurrency.NumThreads > 0:
+        kwargs.setdefault("Cardinality", flags.Concurrency.NumThreads)
+
+    # Set common overlay extra inputs
+    kwargs.setdefault("ExtraInputs", flags.Overlay.ExtraInputs)
+
+    acc.addEventAlgo(CompFactory.LUCID_DigiTop("LUCID_DigiTop", **kwargs))
+    return acc
+
+
+def LUCID_DigitizationCfg(flags, **kwargs):
+    """Return ComponentAccumulator for LUCID digitization and Output"""
+    acc = ComponentAccumulator()
+    acc.merge(LUCID_DigitizationBasicCfg(flags, **kwargs))
+    acc.merge(LUCID_DigitizationOutputCfg(flags))
+
+    return acc
+
+
+def LUCID_DigitizationOverlayCfg(flags, **kwargs):
+    """Return ComponentAccumulator for LUCID digitization and Output"""
+    acc = ComponentAccumulator()
+    acc.merge(LUCID_OverlayDigitizationBasicCfg(flags, **kwargs))
+    acc.merge(LUCID_DigitizationOutputCfg(flags))
+
+    return acc
diff --git a/Simulation/Digitization/python/DigitizationSteering.py b/Simulation/Digitization/python/DigitizationSteering.py
index 4b95e65751ec..85296447d4aa 100644
--- a/Simulation/Digitization/python/DigitizationSteering.py
+++ b/Simulation/Digitization/python/DigitizationSteering.py
@@ -29,6 +29,7 @@ from TileSimAlgs.TileDigitizationConfig import TileDigitizationCfg, TileTriggerD
 from TRT_Digitization.TRT_DigitizationConfig import TRT_DigitizationCfg
 from ALFA_Digitization.ALFA_DigitizationConfig import ALFA_DigitizationCfg
 from AFP_Digitization.AFP_DigitizationConfig import AFP_DigitizationCfg
+from LUCID_Digitization.LUCID_DigitizationConfig import LUCID_DigitizationCfg
 from RunDependentSimComps.PileUpUtils import pileupInputCollections
 
 from AthenaCommon.Logging import logging
@@ -154,6 +155,10 @@ def DigitizationMainContentCfg(flags):
     if flags.Detector.EnableMM:
         acc.merge(MM_DigitizationDigitToRDOCfg(flags))
 
+    # LUCID
+    if flags.Detector.EnableLucid:
+        acc.merge(LUCID_DigitizationCfg(flags))
+
     # AFP
     if flags.Detector.EnableAFP:
         acc.merge(AFP_DigitizationCfg(flags))
-- 
GitLab


From fc5f26e2b1bcbe305a5dd4a2975c9020423b59b7 Mon Sep 17 00:00:00 2001
From: John Chapman <jchapman@cern.ch>
Date: Mon, 8 Aug 2022 15:40:58 +0200
Subject: [PATCH 4/4] Initial Commit of CA-based ZDC digitization configuration

---
 .../python/ZDC_SimuDigitizationConfig.py      | 126 ++++++++++++++++++
 .../python/DigitizationSteering.py            |   5 +
 2 files changed, 131 insertions(+)
 create mode 100644 ForwardDetectors/ZDC/ZDC_SimuDigitization/python/ZDC_SimuDigitizationConfig.py

diff --git a/ForwardDetectors/ZDC/ZDC_SimuDigitization/python/ZDC_SimuDigitizationConfig.py b/ForwardDetectors/ZDC/ZDC_SimuDigitization/python/ZDC_SimuDigitizationConfig.py
new file mode 100644
index 000000000000..1fadd2ace510
--- /dev/null
+++ b/ForwardDetectors/ZDC/ZDC_SimuDigitization/python/ZDC_SimuDigitizationConfig.py
@@ -0,0 +1,126 @@
+# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+from AthenaConfiguration.Enums import ProductionStep
+from Digitization.PileUpMergeSvcConfigNew import PileUpMergeSvcCfg, PileUpXingFolderCfg
+
+# The earliest bunch crossing time for which interactions will be sent
+# to the ZDC Digitization code.
+def ZDC_FirstXing():
+    return 0 #Assume ZDC is only sensitive to the current bunch crossing, for the moment
+
+######################################################################################
+
+# The latest bunch crossing time for which interactions will be sent
+# to the ZDC Digitization code.
+def ZDC_LastXing():
+    return 0 #Assume ZDC is only sensitive to the current bunch crossing, for the moment
+
+######################################################################################
+
+def ZDC_RangeCfg(flags, name="ZdcRange" , **kwargs):
+    #this is the time of the xing in ns
+    kwargs.setdefault('FirstXing', ZDC_FirstXing() )
+    kwargs.setdefault('LastXing',  ZDC_LastXing() )
+    kwargs.setdefault('CacheRefreshFrequency', 1.0 ) #default 0 no dataproxy reset
+    kwargs.setdefault('ItemList', ["ZDC_SimStripHit_Collection#ZDC_SimStripHit_Collection",
+                                   "ZDC_SimPixelHit_Collection#ZDC_SimPixelHit_Collection"] )
+    return PileUpXingFolderCfg(flags, name, **kwargs)
+
+######################################################################################
+
+def ZDC_PileUpToolCfg(flags, name="ZDC_PileUpTool",**kwargs):
+    """Return ComponentAccumulator with ZDC digitization tool."""
+    acc = ComponentAccumulator()
+
+    # Configure bunch-crossing envelope
+    if flags.Digitization.PileUp:
+        intervals = []
+        if flags.Digitization.DoXingByXingPileUp:
+            kwargs.setdefault("FirstXing", ZDC_FirstXing() )
+            kwargs.setdefault("LastXing", ZDC_LastXing() )
+        else:
+            intervals += [acc.popToolsAndMerge(ZDC_RangeCfg(flags))]
+        kwargs.setdefault("mergeSvc", acc.getPrimaryAndMerge(PileUpMergeSvcCfg(flags, Intervals=intervals)).name)
+        #kwargs.setdefault("OnlyUseContainerName", True) # TODO in future MR
+    else:
+        kwargs.setdefault("mergeSvc", '')
+        #kwargs.setdefault("OnlyUseContainerName", False) #TODO in future MR
+
+    from RngComps.RandomServices import AthRNGSvcCfg
+    kwargs.setdefault("RndmSvc", acc.getPrimaryAndMerge(AthRNGSvcCfg(flags)).name)
+
+    acc.setPrivateTools(CompFactory.ZDC_PileUpTool(name, **kwargs))
+    return acc
+
+
+def ZDC_OverlayPileUpToolCfg(flags, name="ZDC_OverlayPileUpTool", **kwargs):
+    """Return ComponentAccumulator with ZDC_PileUpTool for Overlay"""
+    acc = ComponentAccumulator()
+    kwargs.setdefault("mergeSvc", '')
+    #kwargs.setdefault("OnlyUseContainerName", False) #TODO in future MR
+    tool = acc.popToolsAndMerge(ZDC_PileUpToolCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
+
+
+def ZDC_DigitizationOutputCfg(flags):
+    """Return ComponentAccumulator with Output for ZDC. Not standalone."""
+    acc = ComponentAccumulator()
+    if flags.Output.doWriteRDO:
+        ItemList = ["ZdcDigitsCollection#ZdcDigitsCollection"]
+        from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+        acc.merge(OutputStreamCfg(flags,"RDO", ItemList))
+    return acc
+
+
+def ZDC_DigitizationBasicCfg(flags, **kwargs):
+    """Return ComponentAccumulator for ZDC digitization"""
+    acc = ComponentAccumulator()
+    if "PileUpTools" not in kwargs:
+        PileUpTools = acc.popToolsAndMerge(ZDC_PileUpToolCfg(flags))
+        kwargs["PileUpTools"] = PileUpTools
+    from Digitization.PileUpToolsConfig import PileUpToolsCfg
+    acc.merge(PileUpToolsCfg(flags, **kwargs))
+    return acc
+
+
+def ZDC_OverlayDigitizationBasicCfg(flags, **kwargs):
+    """Return ComponentAccumulator with ZDC_DigiAlg."""
+    acc = ComponentAccumulator()
+    if flags.Common.ProductionStep != ProductionStep.FastChain:
+        from SGComps.SGInputLoaderConfig import SGInputLoaderCfg
+        acc.merge(SGInputLoaderCfg(flags,Load=[
+            ('ZDC_SimStripHit_Collection','ZDC_SimStripHit_Collection'),
+            ('ZDC_SimPixelHit_Collection','ZDC_SimPixelHit_Collection')
+        ] ) )
+    if "DigitizationTool" not in kwargs:
+        kwargs.setdefault("DigitizationTool", acc.popToolsAndMerge(ZDC_OverlayPileUpToolCfg(flags)))
+
+    if flags.Concurrency.NumThreads > 0:
+        kwargs.setdefault("Cardinality", flags.Concurrency.NumThreads)
+
+    # Set common overlay extra inputs
+    kwargs.setdefault("ExtraInputs", flags.Overlay.ExtraInputs)
+
+    acc.addEventAlgo(CompFactory.ZDC_DigiAlg("ZDC_DigiAlg", **kwargs))
+    return acc
+
+
+def ZDC_DigitizationCfg(flags, **kwargs):
+    """Return ComponentAccumulator for ZDC digitization and Output"""
+    acc = ComponentAccumulator()
+    acc.merge(ZDC_DigitizationBasicCfg(flags, **kwargs))
+    acc.merge(ZDC_DigitizationOutputCfg(flags))
+
+    return acc
+
+
+def ZDC_DigitizationOverlayCfg(flags, **kwargs):
+    """Return ComponentAccumulator for ZDC digitization and Output"""
+    acc = ComponentAccumulator()
+    acc.merge(ZDC_OverlayDigitizationBasicCfg(flags, **kwargs))
+    acc.merge(ZDC_DigitizationOutputCfg(flags))
+
+    return acc
diff --git a/Simulation/Digitization/python/DigitizationSteering.py b/Simulation/Digitization/python/DigitizationSteering.py
index 85296447d4aa..c9e40abadafe 100644
--- a/Simulation/Digitization/python/DigitizationSteering.py
+++ b/Simulation/Digitization/python/DigitizationSteering.py
@@ -30,6 +30,7 @@ from TRT_Digitization.TRT_DigitizationConfig import TRT_DigitizationCfg
 from ALFA_Digitization.ALFA_DigitizationConfig import ALFA_DigitizationCfg
 from AFP_Digitization.AFP_DigitizationConfig import AFP_DigitizationCfg
 from LUCID_Digitization.LUCID_DigitizationConfig import LUCID_DigitizationCfg
+from ZDC_SimuDigitization.ZDC_SimuDigitizationConfig import ZDC_DigitizationCfg
 from RunDependentSimComps.PileUpUtils import pileupInputCollections
 
 from AthenaCommon.Logging import logging
@@ -167,6 +168,10 @@ def DigitizationMainContentCfg(flags):
     if flags.Detector.EnableALFA:
         acc.merge(ALFA_DigitizationCfg(flags))
 
+    # ZDC
+    if flags.Detector.EnableZDC:
+        acc.merge(ZDC_DigitizationCfg(flags))
+
     # Add MT-safe PerfMon
     if flags.PerfMon.doFastMonMT or flags.PerfMon.doFullMonMT:
         from PerfMonComps.PerfMonCompsConfig import PerfMonMTSvcCfg
-- 
GitLab