From 7189694a3a5330f5f82c26d4c5d8b02126c165b7 Mon Sep 17 00:00:00 2001
From: Andre Sailer <andre.philippe.sailer@cern.ch>
Date: Mon, 23 Aug 2021 14:05:33 +0200
Subject: [PATCH] DDSim: add possibility for users to inject their own output
 plugins

---
 DDG4/python/DDSim/DD4hepSimulation.py    |  6 ++-
 DDG4/python/DDSim/Helper/OutputConfig.py | 52 ++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 1 deletion(-)
 create mode 100644 DDG4/python/DDSim/Helper/OutputConfig.py

diff --git a/DDG4/python/DDSim/DD4hepSimulation.py b/DDG4/python/DDSim/DD4hepSimulation.py
index 81b064ad4..d9b529d63 100644
--- a/DDG4/python/DDSim/DD4hepSimulation.py
+++ b/DDG4/python/DDSim/DD4hepSimulation.py
@@ -18,6 +18,7 @@ from DDSim.Helper.Physics import Physics
 from DDSim.Helper.Filter import Filter
 from DDSim.Helper.Random import Random
 from DDSim.Helper.Action import Action
+from DDSim.Helper.OutputConfig import OutputConfig
 from DDSim.Helper.ConfigHelper import ConfigHelper
 from DDSim.Helper.MagneticField import MagneticField
 from DDSim.Helper.ParticleHandler import ParticleHandler
@@ -93,6 +94,7 @@ class DD4hepSimulation(object):
     self.part = ParticleHandler()
     self.field = MagneticField()
     self.action = Action()
+    self.outputConfig = OutputConfig()
     self.guineapig = GuineaPig()
     self.lcio = LCIO()
     self.hepmc3 = HepMC3()
@@ -342,7 +344,9 @@ class DD4hepSimulation(object):
     self.random.initialize(DDG4, kernel, self.output.random)
 
     # Configure I/O
-    if self.outputFile.endswith(".slcio"):
+    if callable(self.outputConfig._userPlugin):
+      self.outputConfig._userPlugin(self)
+    elif self.outputFile.endswith(".slcio"):
       lcOut = simple.setupLCIOOutput('LcioOutput', self.outputFile)
       lcOut.RunHeader = self.meta.addParametersToRunHeader(self)
       eventPars = self.meta.parseEventParameters()
diff --git a/DDG4/python/DDSim/Helper/OutputConfig.py b/DDG4/python/DDSim/Helper/OutputConfig.py
new file mode 100644
index 000000000..2dcb822b5
--- /dev/null
+++ b/DDG4/python/DDSim/Helper/OutputConfig.py
@@ -0,0 +1,52 @@
+"""Class for output file configuration"""
+
+from __future__ import absolute_import, unicode_literals
+from DDSim.Helper.ConfigHelper import ConfigHelper
+
+
+class OutputConfig(ConfigHelper):
+  """Configuration for Output Files."""
+
+  def __init__(self):
+    super(OutputConfig, self).__init__()
+    self._userPlugin = None
+
+  @property
+  def userOutputPlugin(self):
+    """Set a function to configure the outputFile.
+
+    The function must take a ``DD4hepSimulation`` object as its only argument and return ``None``.
+
+    For example one can add this to the ddsim steering file:
+
+      def exampleUserPlugin(dd4hepSimulation):
+        '''Example code for user created plugin.
+
+        :param DD4hepSimulation dd4hepSimulation: The DD4hepSimulation instance, so all parameters can be accessed
+        :return: None
+        '''
+        from DDG4 import EventAction, Kernel
+        dd = dd4hepSimulation  # just shorter variable name
+        evt_root = EventAction(Kernel(), 'Geant4Output2ROOT/' + dd.outputFile, True)
+        evt_root.HandleMCTruth = True or False
+        evt_root.Control = True
+        if not dd.outputFile.endswith(dd.outputConfig.myExtension):
+          output = dd.outputFile + dd.outputConfig.myExtension
+        evt_root.Output = output
+        evt_root.enableUI()
+        Kernel().eventAction().add(evt_root)
+        return None
+
+      SIM.outputConfig.userOutputPlugin = exampleUserPlugin
+      # arbitrary options can be created and set via the steering file or command line
+      SIM.outputConfig.myExtension = '.csv'
+    """
+    return self._userPlugin
+
+  @userOutputPlugin.setter
+  def userOutputPlugin(self, userOutputPluginConfig):
+    if userOutputPluginConfig is None:
+      return
+    if not callable(userOutputPluginConfig):
+      raise RuntimeError("The provided userPlugin is not a callable function.")
+    self._userPlugin = userOutputPluginConfig
-- 
GitLab