From db641dbd63950c3832743e03604652dec21f6c29 Mon Sep 17 00:00:00 2001
From: Elmar Ritsch <Elmar.Ritsch@cern.ch>
Date: Tue, 16 Aug 2016 11:15:44 +0200
Subject: [PATCH] Refactor ISF input processing for AthenaMT. ATLASSIM-2928
 (merge changes from ISF_Algorithms-00-02-00->ISF_Algorithms-00-02-00-02 into
 trunk) (ISF_Algorithms-00-04-00)

	* Refactor ISF input processing for AthenaMT. ATLASSIM-2928
	(merge changes from ISF_Algorithms-00-02-00->ISF_Algorithms-00-02-00-02
	into trunk)
	* tag as ISF_Algorithms-00-04-00
---
 .../ISF_Core/ISF_Algorithms/CMakeLists.txt    |  5 +-
 .../ISF_Core/ISF_Algorithms/cmt/requirements  |  2 +
 .../ISF_Core/ISF_Algorithms/src/SimKernel.cxx | 63 +++++++++++++++++--
 .../ISF_Core/ISF_Algorithms/src/SimKernel.h   | 23 ++++++-
 4 files changed, 87 insertions(+), 6 deletions(-)

diff --git a/Simulation/ISF/ISF_Core/ISF_Algorithms/CMakeLists.txt b/Simulation/ISF/ISF_Core/ISF_Algorithms/CMakeLists.txt
index 61d50d9dfb5..40085d649aa 100644
--- a/Simulation/ISF/ISF_Core/ISF_Algorithms/CMakeLists.txt
+++ b/Simulation/ISF/ISF_Core/ISF_Algorithms/CMakeLists.txt
@@ -10,11 +10,14 @@ atlas_depends_on_subdirs( PUBLIC
                           GaudiKernel
                           PRIVATE
                           Control/AthenaBaseComps
+                          Control/StoreGate
+                          Control/CxxUtils
                           DetectorDescription/AtlasDetDescr
                           InnerDetector/InDetSimEvent
                           LArCalorimeter/LArSimEvent
                           TileCalorimeter/TileSimEvent
                           MuonSpectrometer/MuonSimEvent
+                          Generators/GeneratorObjects
                           Simulation/ISF/ISF_Core/ISF_Event
                           Simulation/ISF/ISF_Core/ISF_Interfaces
                           Tools/PmbCxxUtils
@@ -31,7 +34,7 @@ atlas_add_component( ISF_Algorithms
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${Boost_LIBRARIES} ${ROOT_LIBRARIES} GaudiKernel AthenaBaseComps AtlasDetDescr ISF_Event ISF_Interfaces PmbCxxUtils InDetSimEvent LArSimEvent TileSimEvent MuonSimEvent )
+                     LINK_LIBRARIES ${Boost_LIBRARIES} ${ROOT_LIBRARIES} GaudiKernel AthenaBaseComps StoreGate CxxUtils AtlasDetDescr GeneratorObjects ISF_Event ISF_Interfaces PmbCxxUtils InDetSimEvent LArSimEvent TileSimEvent MuonSimEvent )
 
 atlas_add_test( CollectionMerger_test
                 SOURCES test/CollectionMerger_test.cxx src/*.cxx
diff --git a/Simulation/ISF/ISF_Core/ISF_Algorithms/cmt/requirements b/Simulation/ISF/ISF_Core/ISF_Algorithms/cmt/requirements
index 336c6571024..9f45496f99b 100644
--- a/Simulation/ISF/ISF_Core/ISF_Algorithms/cmt/requirements
+++ b/Simulation/ISF/ISF_Core/ISF_Algorithms/cmt/requirements
@@ -19,6 +19,7 @@ use AtlasDetDescr        AtlasDetDescr-*         DetectorDescription
 use AtlasROOT            AtlasROOT-*             External
 use ISF_Event            ISF_Event-*             Simulation/ISF/ISF_Core
 use ISF_Interfaces       ISF_Interfaces-*        Simulation/ISF/ISF_Core
+use CxxUtils             CxxUtils-*              Control
 use PmbCxxUtils          PmbCxxUtils-*           Tools
 use InDetSimEvent        InDetSimEvent-*         InnerDetector
 use LArSimEvent          LArSimEvent-*           LArCalorimeter
@@ -27,6 +28,7 @@ use MuonSimEvent         MuonSimEvent-*          MuonSpectrometer
 use CxxUtils             CxxUtils-*              Control
 use StoreGate            StoreGate-*             Control
 use AtlasGoogleTest      AtlasGoogleTest-*       External
+use GeneratorObjects     GeneratorObjects-*      Generators
 
 public
 library ISF_Algorithms *.cxx components/*.cxx
diff --git a/Simulation/ISF/ISF_Core/ISF_Algorithms/src/SimKernel.cxx b/Simulation/ISF/ISF_Core/ISF_Algorithms/src/SimKernel.cxx
index 3d870098789..d5f3640cb63 100644
--- a/Simulation/ISF/ISF_Core/ISF_Algorithms/src/SimKernel.cxx
+++ b/Simulation/ISF/ISF_Core/ISF_Algorithms/src/SimKernel.cxx
@@ -21,14 +21,15 @@
 #include "GaudiKernel/Property.h"
 // Boost
 #include <boost/lexical_cast.hpp>
-// Benchmarking
+// ATLAS cxx utils
+#include "CxxUtils/make_unique.h"
 #include "PmbCxxUtils/CustomBenchmark.h"
 // ROOT includes
 #include "TTree.h"
 // DetectorDescription
 #include "AtlasDetDescr/AtlasRegionHelper.h"
-
-#include <pthread.h>
+// McEventCollection
+#include "GeneratorObjects/McEventCollection.h"
 
 ///////////////////////////////////////////////////////////////////
 // Public methods:
@@ -38,6 +39,11 @@
 ////////////////
 ISF::SimKernel::SimKernel( const std::string& name, ISvcLocator* pSvcLocator ) :
   ::AthAlgorithm( name, pSvcLocator ),
+  m_inputHardScatterEvgen(),
+  m_inputPileupEvgen(),
+  m_outputHardScatterTruth(),
+  m_outputPileupTruth(),
+  m_inputConverter("",name),
   m_particleBroker("ISF_ParticleBroker", name),
   m_truthRecordSvc("ISF_TruthRecordSvc", name),
   m_simHitSvc("ISF_SimHitSvc", name),
@@ -55,6 +61,22 @@ ISF::SimKernel::SimKernel( const std::string& name, ISvcLocator* pSvcLocator ) :
   m_numParticles(0),
   m_maxParticleVectorSize(10240)
 {
+    declareProperty("InputHardScatterCollection",
+                    m_inputHardScatterEvgen,
+                    "Input Hard Scatter EVGEN collection.");
+    declareProperty("InputPileupCollection",
+                     m_inputPileupEvgen,
+                    "Input Pileup EVGEN collection.");
+    declareProperty("OutputHardScatterTruthCollection",
+                    m_outputHardScatterTruth,
+                    "Output Hard Scatter Truth collection.");
+    declareProperty("OutputPileupTruthCollection",
+                     m_outputPileupTruth,
+                    "Output Pileup Truth collection.");
+    declareProperty("InputConverter",
+                    m_inputConverter,
+                    "Input McEventCollection->ISFParticleContainer conversion service.");
+
     // the general services and tools needed
     declareProperty("ParticleBroker"             , m_particleBroker                  );
     declareProperty("TruthRecordService"         , m_truthRecordSvc                  );
@@ -100,6 +122,7 @@ StatusCode ISF::SimKernel::initialize()
     m_memMon->recordCurrent("at beginning of SimKernel initialize()");
   }
 
+
   // setup CPU Benchmarks
   if (m_doCPUMon) {
     //if (!m_benchPDGCode)
@@ -325,9 +348,20 @@ StatusCode ISF::SimKernel::execute()
     m_memMon->recordCurrent("before 1st event");
   }
 
+  // read and convert input
+  //  a. hard-scatter
+  ISFParticleContainer simParticles{}; // particles for ISF simulation
+  ATH_CHECK( prepareInput(m_inputHardScatterEvgen, m_outputHardScatterTruth, simParticles) );
+  //  b. pileup
+  if (!m_inputPileupEvgen.key().empty()) {
+    bool isPileup = true;
+    ATH_CHECK( prepareInput(m_inputPileupEvgen, m_outputPileupTruth, simParticles, isPileup) );
+  }
+
   // -----------------------------------------------------------------------------------------------
   // Step 1: Initialize the particle stack and the TruthManager, ABORT if failure
-  if ( (m_particleBroker->initializeEvent()).isFailure() ){
+  StatusCode sc = m_particleBroker->initializeEvent( std::move(simParticles) );
+  if ( sc.isFailure() ){
       ATH_MSG_FATAL( "Failed to initialize Particle Broker. Abort." );
       return StatusCode::FAILURE;
   }
@@ -481,3 +515,24 @@ StatusCode ISF::SimKernel::execute()
 
   return StatusCode::SUCCESS;
 }
+
+
+/** Convert input generator particles to ISFParticles and copy input
+    generator truth collection into output simulation truth collection */
+StatusCode ISF::SimKernel::prepareInput(SG::ReadHandle<McEventCollection>& inputTruth,
+                                        SG::WriteHandle<McEventCollection>& outputTruth,
+                                        ISFParticleContainer& simParticles,
+                                        bool isPileup) const {
+
+  if (!inputTruth.isValid()) {
+    ATH_MSG_FATAL("Unable to read input GenEvent collection '" << inputTruth.key() << "'");
+    return StatusCode::FAILURE;
+  }
+
+  // create copy
+  outputTruth = CxxUtils::make_unique<McEventCollection>(*inputTruth);
+
+  ATH_CHECK( m_inputConverter->convert(*outputTruth, simParticles, isPileup) );
+
+  return StatusCode::SUCCESS;
+}
diff --git a/Simulation/ISF/ISF_Core/ISF_Algorithms/src/SimKernel.h b/Simulation/ISF/ISF_Core/ISF_Algorithms/src/SimKernel.h
index 61542150b71..985b497936b 100644
--- a/Simulation/ISF/ISF_Core/ISF_Algorithms/src/SimKernel.h
+++ b/Simulation/ISF/ISF_Core/ISF_Algorithms/src/SimKernel.h
@@ -13,6 +13,8 @@
 #include <string>
 
 // FrameWork includes
+#include "StoreGate/ReadHandle.h"
+#include "StoreGate/WriteHandle.h"
 #include "GaudiKernel/ToolHandle.h"
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ITHistSvc.h"
@@ -21,10 +23,14 @@
 // ISF includes
 #include "ISF_Event/SimSvcID.h"
 #include "ISF_Interfaces/ISimulationSelector.h"
+#include "ISF_Interfaces/IInputConverter.h"
 
 // DetectorDescription
 #include "AtlasDetDescr/AtlasRegion.h"
 
+// McEventCollection
+#include "GeneratorObjects/McEventCollection.h"
+
 // forward declarations
 namespace PMonUtils {
   class CustomBenchmark;
@@ -70,7 +76,7 @@ namespace ISF {
   class SimKernel : public AthAlgorithm {
 
   public:
-    //** Constructor with parameters */
+    /** Constructor with parameters */
     SimKernel( const std::string& name, ISvcLocator* pSvcLocator );
 
     /** Destructor */
@@ -86,6 +92,21 @@ namespace ISF {
   private:
     StatusCode initSimSvcs( SimSelectorToolArray &simSelectorTools);
 
+    /** Convert input generator particles to ISFParticles and copy input
+        generator truth collection into output simulation truth collection */
+    StatusCode prepareInput(SG::ReadHandle<McEventCollection>& inputTruth,
+                            SG::WriteHandle<McEventCollection>& outputTruth,
+                            ISFParticleContainer& simParticles,
+                            bool isPileup=false) const;
+
+
+    /** Input/output truth collections and input conversion */
+    SG::ReadHandle<McEventCollection>    m_inputHardScatterEvgen; //!< input hard scatter collection
+    SG::ReadHandle<McEventCollection>    m_inputPileupEvgen;      //!< input pileup collection
+    SG::WriteHandle<McEventCollection>   m_outputHardScatterTruth;//!< output hard scatter truth collection
+    SG::WriteHandle<McEventCollection>   m_outputPileupTruth;     //!< output pileup truth collection
+    ServiceHandle<IInputConverter>       m_inputConverter;        //!< input->ISFParticle converter
+
     /** Central particle broker service */
     ServiceHandle<IParticleBroker>       m_particleBroker;
     /** Central truth service */
-- 
GitLab