From 1c2c7343b807a9d6822b0c6b1f7b579b732f848f Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Wed, 25 Nov 2015 19:31:48 +0000 Subject: [PATCH] Split functionality of Geant4Kernel object --- DDG4/include/DDG4/Geant4ActionContainer.h | 178 ++++++++++++++++++++++ DDG4/include/DDG4/Geant4Kernel.h | 175 +++------------------ DDG4/include/DDG4/Geant4SensDetAction.h | 2 +- DDG4/plugins/Geant4SensDet.cpp | 2 +- DDG4/plugins/Geant4TrackerWeightedSD.cpp | 6 +- DDG4/plugins/Geant4XMLSetup.cpp | 20 +-- DDG4/src/Geant4ActionContainer.cpp | 168 ++++++++++++++++++++ DDG4/src/Geant4Exec.cpp | 4 +- DDG4/src/Geant4Handle.cpp | 26 ++-- DDG4/src/Geant4Kernel.cpp | 157 ++----------------- DDG4/src/python/PyDDG4.cpp | 2 +- 11 files changed, 411 insertions(+), 329 deletions(-) create mode 100644 DDG4/include/DDG4/Geant4ActionContainer.h create mode 100644 DDG4/src/Geant4ActionContainer.cpp diff --git a/DDG4/include/DDG4/Geant4ActionContainer.h b/DDG4/include/DDG4/Geant4ActionContainer.h new file mode 100644 index 000000000..d18e80890 --- /dev/null +++ b/DDG4/include/DDG4/Geant4ActionContainer.h @@ -0,0 +1,178 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_DDG4_GEANT4ACTIONCONTAINER_H +#define DD4HEP_DDG4_GEANT4ACTIONCONTAINER_H + +// Framework include files +#include "DD4hep/Printout.h" +#include "DDG4/Geant4Primitives.h" +#include "DDG4/Geant4Action.h" + +// C/C++ include files +#include <map> +#include <string> +#include <typeinfo> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit + namespace Simulation { + + // Forward declarations + class Geant4Context; + class Geant4Action; + class Geant4RunAction; + class Geant4EventAction; + class Geant4SteppingAction; + class Geant4TrackingAction; + class Geant4StackingAction; + class Geant4GeneratorAction; + class Geant4PhysicsList; + class Geant4RunActionSequence; + class Geant4EventActionSequence; + class Geant4SteppingActionSequence; + class Geant4TrackingActionSequence; + class Geant4StackingActionSequence; + class Geant4GeneratorActionSequence; + class Geant4PhysicsListActionSequence; + class Geant4DetectorConstructionSequence; + class Geant4UserInitializationSequence; + class Geant4SensDetActionSequence; + class Geant4SensDetSequences; + + /// Class, which allows all Geant4Action to be stored + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_SIMULATION + */ + class Geant4ActionContainer { + protected: + + /// Geant4 worker context (thread specific) + Geant4Context* m_context; + + /// Reference to the Geant4 primary generator action + Geant4GeneratorActionSequence* m_generatorAction; + /// Reference to the Geant4 run action + Geant4RunActionSequence* m_runAction; + /// Reference to the Geant4 event action + Geant4EventActionSequence* m_eventAction; + /// Reference to the Geant4 track action + Geant4TrackingActionSequence* m_trackingAction; + /// Reference to the Geant4 step action + Geant4SteppingActionSequence* m_steppingAction; + /// Reference to the Geant4 stacking action + Geant4StackingActionSequence* m_stackingAction; + /// Reference to the Geant4 detector construction sequence + Geant4DetectorConstructionSequence* m_constructionAction; + + /// Reference to the Geant4 sensitive action sequences + Geant4SensDetSequences* m_sensDetActions; + /// Reference to the Geant4 physics list + Geant4PhysicsListActionSequence* m_physicsList; + /// Reference to the user initialization object + Geant4UserInitializationSequence* m_userInit; + + /// Helper to register an action sequence + template <typename C> bool registerSequence(C*& seq, const std::string& name); + + /// Standard constructor + Geant4ActionContainer(Geant4Context* ctxt=0); + + /// Default destructor + virtual ~Geant4ActionContainer(); + + /// Terminate all associated action instances + virtual int terminate(); + + /// Set the thread's context + void setContext(Geant4Context* ctxt); + + public: + /// Thread's Geant4 execution context + Geant4Context* workerContext(); + + /// Access generator action sequence + Geant4GeneratorActionSequence* generatorAction(bool create); + /// Access generator action sequence + Geant4GeneratorActionSequence& generatorAction() { + return *generatorAction(true); + } + + /// Access run action sequence + Geant4RunActionSequence* runAction(bool create); + /// Access run action sequence + Geant4RunActionSequence& runAction() { + return *runAction(true); + } + + /// Access run action sequence + Geant4EventActionSequence* eventAction(bool create); + /// Access run action sequence + Geant4EventActionSequence& eventAction() { + return *eventAction(true); + } + + /// Access stepping action sequence + Geant4SteppingActionSequence* steppingAction(bool create); + /// Access stepping action sequence + Geant4SteppingActionSequence& steppingAction() { + return *steppingAction(true); + } + + /// Access tracking action sequence + Geant4TrackingActionSequence* trackingAction(bool create); + /// Access tracking action sequence + Geant4TrackingActionSequence& trackingAction() { + return *trackingAction(true); + } + + /// Access stacking action sequence + Geant4StackingActionSequence* stackingAction(bool create); + /// Access stacking action sequence + Geant4StackingActionSequence& stackingAction() { + return *stackingAction(true); + } + + /// Access detector construcion action sequence (geometry+sensitives+field) + Geant4DetectorConstructionSequence* detectorConstruction(bool create); + /// Access detector construcion action sequence (geometry+sensitives+field) + Geant4DetectorConstructionSequence& detectorConstruction() { + return *detectorConstruction(true); + } + + /// Access to the sensitive detector sequences from the actioncontainer object + Geant4SensDetSequences& sensitiveActions() const; + /// Access to the sensitive detector action from the actioncontainer object + Geant4SensDetActionSequence* sensitiveAction(const std::string& name); + + /// Access to the physics list + Geant4PhysicsListActionSequence* physicsList(bool create); + /// Access to the physics list + Geant4PhysicsListActionSequence& physicsList() { + return *physicsList(true); + } + /// Access to the user initialization object + Geant4UserInitializationSequence* userInitialization(bool create); + /// Access to the user initialization object + Geant4UserInitializationSequence& userInitialization() { + return *userInitialization(true); + } + }; + + } // End namespace Simulation +} // End namespace DD4hep +#endif // DD4HEP_DDG4_GEANT4KERNEL_H diff --git a/DDG4/include/DDG4/Geant4Kernel.h b/DDG4/include/DDG4/Geant4Kernel.h index 819b4780b..a98d4cf83 100644 --- a/DDG4/include/DDG4/Geant4Kernel.h +++ b/DDG4/include/DDG4/Geant4Kernel.h @@ -15,16 +15,10 @@ #define DD4HEP_DDG4_GEANT4KERNEL_H // Framework include files -#include "DD4hep/Printout.h" -#include "DDG4/Geant4Primitives.h" -#include "DDG4/Geant4Action.h" - -// Geant4 headers -#include "G4Threading.hh" +#include "DDG4/Geant4ActionContainer.h" // C/C++ include files #include <map> -#include <string> #include <typeinfo> // Forward declarations @@ -39,26 +33,6 @@ namespace DD4hep { // Forward declarations class Geant4ActionPhase; - class Geant4Context; - class Geant4Action; - class Geant4RunAction; - class Geant4EventAction; - class Geant4SteppingAction; - class Geant4TrackingAction; - class Geant4StackingAction; - class Geant4GeneratorAction; - class Geant4PhysicsList; - class Geant4RunActionSequence; - class Geant4EventActionSequence; - class Geant4SteppingActionSequence; - class Geant4TrackingActionSequence; - class Geant4StackingActionSequence; - class Geant4GeneratorActionSequence; - class Geant4PhysicsListActionSequence; - class Geant4DetectorConstructionSequence; - class Geant4UserInitializationSequence; - class Geant4SensDetActionSequence; - class Geant4SensDetSequences; /// Class, which allows all Geant4Action derivatives to access the DDG4 kernel structures. /** @@ -66,12 +40,13 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_SIMULATION */ - class Geant4Kernel { + class Geant4Kernel : public Geant4ActionContainer { public: typedef DD4hep::Geometry::LCDD LCDD; typedef std::map<unsigned long, Geant4Kernel*> Workers; typedef std::map<std::string, Geant4ActionPhase*> Phases; typedef std::map<std::string, Geant4Action*> GlobalActions; + typedef std::map<std::string,int> ClientOutputLevels; protected: /// Reference to the run manager @@ -80,27 +55,6 @@ namespace DD4hep { G4UIdirectory* m_control; /// Property pool PropertyManager m_properties; - /// Reference to the Geant4 primary generator action - Geant4GeneratorActionSequence* m_generatorAction; - /// Reference to the Geant4 run action - Geant4RunActionSequence* m_runAction; - /// Reference to the Geant4 event action - Geant4EventActionSequence* m_eventAction; - /// Reference to the Geant4 track action - Geant4TrackingActionSequence* m_trackingAction; - /// Reference to the Geant4 step action - Geant4SteppingActionSequence* m_steppingAction; - /// Reference to the Geant4 stacking action - Geant4StackingActionSequence* m_stackingAction; - /// Reference to the Geant4 detector construction sequence - Geant4DetectorConstructionSequence* m_constructionAction; - - /// Reference to the Geant4 sensitive action sequences - Geant4SensDetSequences* m_sensDetActions; - /// Reference to the Geant4 physics list - Geant4PhysicsListActionSequence* m_physicsList; - /// Reference to the user initialization object - Geant4UserInitializationSequence* m_userInit; /// Reference to Geant4 track manager G4TrackingManager* m_trackMgr; @@ -124,7 +78,6 @@ namespace DD4hep { /// Property: Output level int m_outputLevel; /// Property: Client output levels - typedef std::map<std::string,int> ClientOutputLevels; ClientOutputLevels m_clientLevels; /// Property: Running in multi threaded context @@ -135,14 +88,12 @@ namespace DD4hep { unsigned long m_id, m_ident; /// Parent reference Geant4Kernel* m_master; + Geant4Kernel* m_shared; Geant4Context* m_threadContext; bool isMaster() const { return this == m_master; } bool isWorker() const { return this != m_master; } - /// Helper to register an action sequence - template <typename C> bool registerSequence(C*& seq, const std::string& name); - #ifndef __CINT__ /// Standard constructor for workers Geant4Kernel(LCDD& lcdd, Geant4Kernel* m, unsigned long identifier); @@ -152,12 +103,12 @@ namespace DD4hep { /// Standard constructor for the master instance Geant4Kernel(LCDD& lcdd); - /// Thread's master context - Geant4Context* workerContext(); - /// Thread's master context Geant4Kernel& master() const { return *m_master; } + /// Shared action context + Geant4Kernel& shared() const { return *m_shared; } + //bool isMultiThreaded() const { return m_multiThreaded; } bool isMultiThreaded() const { return m_numThreads > 0; } @@ -196,40 +147,28 @@ namespace DD4hep { /// Instance accessor static Geant4Kernel& instance(LCDD& lcdd); /// Accessof the Geant4Kernel object from the LCDD reference extension (if present and registered) - static Geant4Kernel& access(LCDD& lcdd); + //static Geant4Kernel& access(LCDD& lcdd); #endif - /// Access to the properties of the object - PropertyManager& properties() { - return m_properties; - } - /// Print the property values - void printProperties() const; /// Access phase phases - const Phases& phases() const { - return m_phases; - } + const Phases& phases() const { return m_phases; } /// Access to detector description - LCDD& lcdd() const { - return m_lcdd; - } + LCDD& lcdd() const { return m_lcdd; } /// Access the tracking manager - G4TrackingManager* trackMgr() const { - return m_trackMgr; - } + G4TrackingManager* trackMgr() const { return m_trackMgr; } /// Access the tracking manager - void setTrackMgr(G4TrackingManager* mgr) { - m_trackMgr = mgr; - } + void setTrackMgr(G4TrackingManager* mgr) { m_trackMgr = mgr; } /// Access the command directory - const std::string& directoryName() const { - return m_controlName; - } + const std::string& directoryName() const { return m_controlName; } /// Access worker identifier - unsigned long id() const { - return m_ident; - } + unsigned long id() const { return m_ident; } /// Access to the Geant4 run manager G4RunManager& runManager(); + + /** Property access */ + /// Access to the properties of the object + PropertyManager& properties() { return m_properties; } + /// Print the property values + void printProperties() const; /// Declare property template <typename T> Geant4Kernel& declareProperty(const std::string& nam, T& val); /// Declare property @@ -238,10 +177,10 @@ namespace DD4hep { bool hasProperty(const std::string& name) const; /// Access single property Property& property(const std::string& name); + + /** Output level settings */ /// Access the output level - PrintLevel outputLevel() const { - return (PrintLevel)m_outputLevel; - } + PrintLevel outputLevel() const { return (PrintLevel)m_outputLevel; } /// Set the global output level of the kernel object; returns previous value PrintLevel setOutputLevel(PrintLevel new_level); /// Fill cache with the global output level of a named object. Must be set before instantiation @@ -296,73 +235,6 @@ namespace DD4hep { /// Execute phase action if it exists virtual bool executePhase(const std::string& name, const void** args) const; - - /// Access generator action sequence - Geant4GeneratorActionSequence* generatorAction(bool create); - /// Access generator action sequence - Geant4GeneratorActionSequence& generatorAction() { - return *generatorAction(true); - } - - /// Access run action sequence - Geant4RunActionSequence* runAction(bool create); - /// Access run action sequence - Geant4RunActionSequence& runAction() { - return *runAction(true); - } - - /// Access run action sequence - Geant4EventActionSequence* eventAction(bool create); - /// Access run action sequence - Geant4EventActionSequence& eventAction() { - return *eventAction(true); - } - - /// Access stepping action sequence - Geant4SteppingActionSequence* steppingAction(bool create); - /// Access stepping action sequence - Geant4SteppingActionSequence& steppingAction() { - return *steppingAction(true); - } - - /// Access tracking action sequence - Geant4TrackingActionSequence* trackingAction(bool create); - /// Access tracking action sequence - Geant4TrackingActionSequence& trackingAction() { - return *trackingAction(true); - } - - /// Access stacking action sequence - Geant4StackingActionSequence* stackingAction(bool create); - /// Access stacking action sequence - Geant4StackingActionSequence& stackingAction() { - return *stackingAction(true); - } - - /// Access detector construcion action sequence (geometry+sensitives+field) - Geant4DetectorConstructionSequence* detectorConstruction(bool create); - /// Access detector construcion action sequence (geometry+sensitives+field) - Geant4DetectorConstructionSequence& detectorConstruction() { - return *detectorConstruction(true); - } - - /// Access to the sensitive detector sequences from the kernel object - Geant4SensDetSequences& sensitiveActions() const; - /// Access to the sensitive detector action from the kernel object - Geant4SensDetActionSequence* sensitiveAction(const std::string& name); - - /// Access to the physics list - Geant4PhysicsListActionSequence* physicsList(bool create); - /// Access to the physics list - Geant4PhysicsListActionSequence& physicsList() { - return *physicsList(true); - } - /// Access to the user initialization object - Geant4UserInitializationSequence* userInitialization(bool create); - /// Access to the user initialization object - Geant4UserInitializationSequence& userInitialization() { - return *userInitialization(true); - } /// Construct detector geometry using lcdd plugin void loadGeometry(const std::string& compact_file); @@ -414,5 +286,4 @@ namespace DD4hep { } // End namespace Simulation } // End namespace DD4hep - #endif // DD4HEP_DDG4_GEANT4KERNEL_H diff --git a/DDG4/include/DDG4/Geant4SensDetAction.h b/DDG4/include/DDG4/Geant4SensDetAction.h index c6bba4499..c1034b29a 100644 --- a/DDG4/include/DDG4/Geant4SensDetAction.h +++ b/DDG4/include/DDG4/Geant4SensDetAction.h @@ -409,7 +409,7 @@ namespace DD4hep { */ class Geant4SensDetSequences { public: - friend class Geant4Kernel; + friend class Geant4ActionContainer; friend class Geant4SensDetActionSequence; typedef std::map<std::string, Geant4SensDetActionSequence*> Members; private: diff --git a/DDG4/plugins/Geant4SensDet.cpp b/DDG4/plugins/Geant4SensDet.cpp index 3bc22c80a..36669acc4 100644 --- a/DDG4/plugins/Geant4SensDet.cpp +++ b/DDG4/plugins/Geant4SensDet.cpp @@ -80,7 +80,7 @@ namespace DD4hep { : G4VSensitiveDetector(nam), G4VSDFilter(nam), Geant4Action(0,nam), Geant4ActionSD(nam), Base() { - Geant4Kernel& master = Geant4Kernel::access(lcdd); + Geant4Kernel& master = Geant4Kernel::instance(lcdd); Geant4Kernel& kernel = master.worker(::pthread_self()); m_sensitive = lcdd.sensitiveDetector(nam); m_context = kernel.workerContext(); diff --git a/DDG4/plugins/Geant4TrackerWeightedSD.cpp b/DDG4/plugins/Geant4TrackerWeightedSD.cpp index ee51e48aa..5257ec52e 100644 --- a/DDG4/plugins/Geant4TrackerWeightedSD.cpp +++ b/DDG4/plugins/Geant4TrackerWeightedSD.cpp @@ -363,12 +363,12 @@ namespace DD4hep { } /// G4VSensitiveDetector interface: Method invoked at the begining of each event. - template <> void Geant4SensitiveAction<TrackerWeighted>::begin(G4HCofThisEvent* hce) { + template <> void Geant4SensitiveAction<TrackerWeighted>::begin(G4HCofThisEvent* /* hce */) { m_userData.startEvent(); } /// G4VSensitiveDetector interface: Method invoked at the end of each event. - template <> void Geant4SensitiveAction<TrackerWeighted>::end(G4HCofThisEvent* hce) { + template <> void Geant4SensitiveAction<TrackerWeighted>::end(G4HCofThisEvent* /* hce */) { m_userData.endEvent(); } @@ -378,7 +378,7 @@ namespace DD4hep { } /// Method for generating hit(s) using the information of G4Step object. - template <> void Geant4SensitiveAction<TrackerWeighted>::clear(G4HCofThisEvent*) { + template <> void Geant4SensitiveAction<TrackerWeighted>::clear(G4HCofThisEvent* /* hce */) { m_userData.clear(); } diff --git a/DDG4/plugins/Geant4XMLSetup.cpp b/DDG4/plugins/Geant4XMLSetup.cpp index 6f7a8b380..0e2796fb7 100644 --- a/DDG4/plugins/Geant4XMLSetup.cpp +++ b/DDG4/plugins/Geant4XMLSetup.cpp @@ -75,7 +75,7 @@ namespace DD4hep { /// Create/Configure Geant4 sensitive action object from XML static Action _convertSensitive(lcdd_t& lcdd, xml_h e, const string& detector) { xml_comp_t action(e); - Kernel& kernel = Kernel::access(lcdd); + Kernel& kernel = Kernel::instance(lcdd); TypeName tn = TypeName::split(action.attr<string>(_U(name))); // Create the object using the factory method Sensitive handle(kernel,action.attr<string>(_U(name)),detector); @@ -94,7 +94,7 @@ namespace DD4hep { /// Create/Configure Action object from XML static Action _convertAction(lcdd_t& lcdd, xml_h e) { xml_comp_t action(e); - Kernel& kernel = Kernel::access(lcdd); + Kernel& kernel = Kernel::instance(lcdd); TypeName tn = TypeName::split(action.attr<string>(_U(name))); // Create the object using the factory method Action handle(kernel,action.attr<string>(_U(name))); @@ -118,7 +118,7 @@ namespace DD4hep { Action _createAction(lcdd_t& lcdd, xml_h a, const string& seqType, int what) { string nam = a.attr<string>(_U(name)); TypeName typ = TypeName::split(nam); - Kernel& kernel = Kernel::access(lcdd); + Kernel& kernel = Kernel::instance(lcdd); Action action((what==FILTER) ? (Geant4Action*)kernel.globalFilter(typ.second,false) : (what==ACTION) ? kernel.globalAction(typ.second,false) /// : (what==FILTER) ? kernel.globalAction(typ.second,false) @@ -150,7 +150,7 @@ namespace DD4hep { */ template <> void Converter<Action>::operator()(xml_h e) const { Action a = _convertAction(lcdd, e); - Kernel::access(lcdd).registerGlobalAction(a); + Kernel::instance(lcdd).registerGlobalAction(a); } /// Convert Sensitive detector filters @@ -166,7 +166,7 @@ namespace DD4hep { */ template <> void Converter<Filter>::operator()(xml_h e) const { Action a = _convertAction(lcdd, e); - Kernel::access(lcdd).registerGlobalFilter(a); + Kernel::instance(lcdd).registerGlobalFilter(a); } /// Convert Geant4Phase objects @@ -181,7 +181,7 @@ namespace DD4hep { */ template <> void Converter<Phase>::operator()(xml_h e) const { xml_comp_t x_phase(e); - Kernel& kernel = Kernel::access(lcdd); + Kernel& kernel = Kernel::instance(lcdd); string nam = x_phase.attr<string>(_U(type)); typedef Geant4ActionPhase PH; Phase p; @@ -288,7 +288,7 @@ namespace DD4hep { string seqNam; TypeName seqType; int what = ACTION; - Kernel& kernel = Kernel::access(lcdd); + Kernel& kernel = Kernel::instance(lcdd); if ( seq.hasAttr(_U(sd)) ) { string sd_nam = seq.attr<string>(_U(sd)); @@ -440,7 +440,7 @@ namespace DD4hep { */ struct PhysicsListExtension; template <> void Converter<PhysicsListExtension>::operator()(xml_h e) const { - Kernel& kernel = Kernel::access(lcdd); + Kernel& kernel = Kernel::instance(lcdd); string ext = xml_comp_t(e).nameStr(); kernel.physicsList().properties()["extends"].str(ext); printout(INFO,"Geant4Setup","+++ PhysicsListExtension: Set predefined Geant4 physics list to '%s'",ext.c_str()); @@ -449,7 +449,7 @@ namespace DD4hep { /// Create/Configure PhysicsList objects: Predefined Geant4 Physics lists template <> void Converter<PhysicsList>::operator()(xml_h e) const { string name = e.attr<string>(_U(name)); - Kernel& kernel = Kernel::access(lcdd); + Kernel& kernel = Kernel::instance(lcdd); PhysicsList handle(kernel,name); _setAttributes(handle,e); xml_coll_t(e,_Unicode(particles)).for_each(_Unicode(construct),Converter<Geant4PhysicsList::ParticleConstructor>(lcdd,handle.get())); @@ -461,7 +461,7 @@ namespace DD4hep { /// Create/Configure Geant4Kernel objects template <> void Converter<Kernel>::operator()(xml_h e) const { - Kernel& kernel = Kernel::access(lcdd); + Kernel& kernel = Kernel::instance(lcdd); xml_comp_t k(e); if ( k.hasAttr(_Unicode(NumEvents)) ) kernel.property("NumEvents").str(k.attr<string>(_Unicode(NumEvents))); diff --git a/DDG4/src/Geant4ActionContainer.cpp b/DDG4/src/Geant4ActionContainer.cpp new file mode 100644 index 000000000..ef78984f9 --- /dev/null +++ b/DDG4/src/Geant4ActionContainer.cpp @@ -0,0 +1,168 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/Printout.h" +#include "DD4hep/Primitives.h" +#include "DD4hep/InstanceCount.h" + +#include "DDG4/Geant4ActionContainer.h" +#include "DDG4/Geant4RunAction.h" +#include "DDG4/Geant4PhysicsList.h" +#include "DDG4/Geant4EventAction.h" +#include "DDG4/Geant4SteppingAction.h" +#include "DDG4/Geant4TrackingAction.h" +#include "DDG4/Geant4StackingAction.h" +#include "DDG4/Geant4GeneratorAction.h" +#include "DDG4/Geant4DetectorConstruction.h" +#include "DDG4/Geant4UserInitialization.h" +#include "DDG4/Geant4SensDetAction.h" + +// C/C++ include files +#include <stdexcept> +#include <algorithm> + +using namespace std; +using namespace DD4hep::Simulation; + +/// Standard constructor +Geant4ActionContainer::Geant4ActionContainer(Geant4Context* ctxt) + : m_context(ctxt), + m_generatorAction(0), m_runAction(0), m_eventAction(0), m_trackingAction(0), + m_steppingAction(0), m_stackingAction(0), m_constructionAction(0), + m_sensDetActions(0), m_physicsList(0), m_userInit(0) +{ + m_sensDetActions = new Geant4SensDetSequences(); + InstanceCount::increment(this); +} + +/// Default destructor +Geant4ActionContainer::~Geant4ActionContainer() { + this->Geant4ActionContainer::terminate(); + InstanceCount::decrement(this); +} + +/// Terminate all associated action instances +int Geant4ActionContainer::terminate() { + releasePtr (m_physicsList); + releasePtr (m_constructionAction); + releasePtr (m_stackingAction); + releasePtr (m_steppingAction); + releasePtr (m_trackingAction); + releasePtr (m_eventAction); + releasePtr (m_generatorAction); + releasePtr (m_runAction); + deletePtr (m_sensDetActions); + deletePtr (m_context); + return 1; +} + +Geant4Context* Geant4ActionContainer::workerContext() { + if ( m_context ) return m_context; + throw runtime_error(format("Geant4Kernel", "DDG4: Master kernel object has no thread context! [Invalid Handle]")); +} + +/// Set the thread's context +void Geant4ActionContainer::setContext(Geant4Context* ctxt) { + m_context = ctxt; +} + +template <class C> bool Geant4ActionContainer::registerSequence(C*& seq, const std::string& name) { + if (!name.empty()) { + seq = new C(m_context, name); + seq->installMessengers(); + return true; + } + throw runtime_error(format("Geant4ActionContainer", "DDG4: The action '%s' not found. [Action-NotFound]", name.c_str())); +} + +/// Access generator action sequence +Geant4GeneratorActionSequence* Geant4ActionContainer::generatorAction(bool create) { + if (!m_generatorAction && create) + registerSequence(m_generatorAction, "GeneratorAction"); + return m_generatorAction; +} + +/// Access run action sequence +Geant4RunActionSequence* Geant4ActionContainer::runAction(bool create) { + if (!m_runAction && create) + registerSequence(m_runAction, "RunAction"); + return m_runAction; +} + +/// Access event action sequence +Geant4EventActionSequence* Geant4ActionContainer::eventAction(bool create) { + if (!m_eventAction && create) + registerSequence(m_eventAction, "EventAction"); + return m_eventAction; +} + +/// Access stepping action sequence +Geant4SteppingActionSequence* Geant4ActionContainer::steppingAction(bool create) { + if (!m_steppingAction && create) + registerSequence(m_steppingAction, "SteppingAction"); + return m_steppingAction; +} + +/// Access tracking action sequence +Geant4TrackingActionSequence* Geant4ActionContainer::trackingAction(bool create) { + if (!m_trackingAction && create) + registerSequence(m_trackingAction, "TrackingAction"); + return m_trackingAction; +} + +/// Access stacking action sequence +Geant4StackingActionSequence* Geant4ActionContainer::stackingAction(bool create) { + if (!m_stackingAction && create) + registerSequence(m_stackingAction, "StackingAction"); + return m_stackingAction; +} + +/// Access detector construcion action sequence (geometry+sensitives+field) +Geant4DetectorConstructionSequence* Geant4ActionContainer::detectorConstruction(bool create) { + if (!m_constructionAction && create) + registerSequence(m_constructionAction, "StackingAction"); + return m_constructionAction; +} + +/// Access to the sensitive detector sequences from the kernel object +Geant4SensDetSequences& Geant4ActionContainer::sensitiveActions() const { + return *m_sensDetActions; +} + +/// Access to the sensitive detector action from the kernel object +Geant4SensDetActionSequence* Geant4ActionContainer::sensitiveAction(const string& nam) { + Geant4SensDetActionSequence* ptr = m_sensDetActions->find(nam); + if (ptr) { + return ptr; + } + ptr = new Geant4SensDetActionSequence(workerContext(), nam); + m_sensDetActions->insert(nam, ptr); + return ptr; +} + +/// Access to the physics list +Geant4PhysicsListActionSequence* Geant4ActionContainer::physicsList(bool create) { + if (!m_physicsList && create) + registerSequence(m_physicsList, "PhysicsList"); + return m_physicsList; +} + +/// Access to the physics list +Geant4UserInitializationSequence* Geant4ActionContainer::userInitialization(bool create) { + if (!m_userInit && create) { + registerSequence(m_userInit, "UserInitialization"); + } + return m_userInit; +} diff --git a/DDG4/src/Geant4Exec.cpp b/DDG4/src/Geant4Exec.cpp index 17b68a774..e72b6f06b 100644 --- a/DDG4/src/Geant4Exec.cpp +++ b/DDG4/src/Geant4Exec.cpp @@ -387,7 +387,7 @@ namespace DD4hep { void Geant4UserDetectorConstruction::ConstructSDandField() { G4AutoLock protection_lock(&action_mutex); Geant4Context* ctx = m_sequence->context(); - Geant4Kernel& krnl = kernel().worker(Geant4Kernel::thread_self()); + Geant4Kernel& krnl = kernel().worker(Geant4Kernel::thread_self(),true); updateContext(krnl.workerContext()); m_sequence->constructField(&m_ctxt); m_sequence->constructSensitives(&m_ctxt); @@ -411,7 +411,7 @@ namespace DD4hep { /// Build the actions for the worker thread void Geant4UserActionInitialization::Build() const { G4AutoLock protection_lock(&action_mutex); - Geant4Kernel& krnl = kernel().worker(Geant4Kernel::thread_self()); + Geant4Kernel& krnl = kernel().worker(Geant4Kernel::thread_self(),true); Geant4Context* ctx = krnl.workerContext(); if ( m_sequence ) { diff --git a/DDG4/src/Geant4Handle.cpp b/DDG4/src/Geant4Handle.cpp index cfd80ab8e..bccb6663a 100644 --- a/DDG4/src/Geant4Handle.cpp +++ b/DDG4/src/Geant4Handle.cpp @@ -102,7 +102,7 @@ namespace DD4hep { template <typename TYPE, typename CONT> TYPE* _create_share(Geant4Kernel& kernel, - CONT& (Geant4Kernel::*pmf)(), + CONT& (Geant4ActionContainer::*pmf)(), const string& type_name, const string& shared_typ, bool shared, TYPE*) @@ -223,56 +223,56 @@ namespace DD4hep { template <> Geant4Handle<Geant4RunAction>::Geant4Handle(Geant4Kernel& kernel, const string& type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::runAction,type_name,"Geant4SharedRunAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::runAction,type_name,"Geant4SharedRunAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4RunAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::runAction,type_name,"Geant4SharedRunAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::runAction,type_name,"Geant4SharedRunAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4EventAction>::Geant4Handle(Geant4Kernel& kernel, const string& type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::eventAction,type_name,"Geant4SharedEventAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::eventAction,type_name,"Geant4SharedEventAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4EventAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::eventAction,type_name,"Geant4SharedEventAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::eventAction,type_name,"Geant4SharedEventAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4GeneratorAction>::Geant4Handle(Geant4Kernel& kernel, const string& type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::generatorAction,type_name,"Geant4SharedGeneratorAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::generatorAction,type_name,"Geant4SharedGeneratorAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4GeneratorAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::generatorAction,type_name,"Geant4SharedGeneratorAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::generatorAction,type_name,"Geant4SharedGeneratorAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4TrackingAction>::Geant4Handle(Geant4Kernel& kernel, const string& type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::trackingAction,type_name,"Geant4SharedTrackingAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::trackingAction,type_name,"Geant4SharedTrackingAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4TrackingAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::trackingAction,type_name,"Geant4SharedTrackingAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::trackingAction,type_name,"Geant4SharedTrackingAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4SteppingAction>::Geant4Handle(Geant4Kernel& kernel, const string& type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::steppingAction,type_name,"Geant4SharedSteppingAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::steppingAction,type_name,"Geant4SharedSteppingAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4SteppingAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::steppingAction,type_name,"Geant4SharedSteppingAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::steppingAction,type_name,"Geant4SharedSteppingAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4StackingAction>::Geant4Handle(Geant4Kernel& kernel, const string& type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::stackingAction,type_name,"Geant4SharedStackingAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::stackingAction,type_name,"Geant4SharedStackingAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4StackingAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) { - value = _create_share(kernel,&Geant4Kernel::stackingAction,type_name,"Geant4SharedStackingAction",shared,(handled_type*)0); + value = _create_share(kernel,&Geant4ActionContainer::stackingAction,type_name,"Geant4SharedStackingAction",shared,(handled_type*)0); } template <> Geant4Handle<Geant4Sensitive>::Geant4Handle(Geant4Kernel& kernel, const string& type_name, diff --git a/DDG4/src/Geant4Kernel.cpp b/DDG4/src/Geant4Kernel.cpp index ffa3a15fa..daed8a26e 100644 --- a/DDG4/src/Geant4Kernel.cpp +++ b/DDG4/src/Geant4Kernel.cpp @@ -22,17 +22,6 @@ #include "DDG4/Geant4Context.h" #include "DDG4/Geant4ActionPhase.h" -#include "DDG4/Geant4RunAction.h" -#include "DDG4/Geant4PhysicsList.h" -#include "DDG4/Geant4EventAction.h" -#include "DDG4/Geant4SteppingAction.h" -#include "DDG4/Geant4TrackingAction.h" -#include "DDG4/Geant4StackingAction.h" -#include "DDG4/Geant4GeneratorAction.h" -#include "DDG4/Geant4DetectorConstruction.h" -#include "DDG4/Geant4UserInitialization.h" -#include "DDG4/Geant4SensDetAction.h" - // Geant4 include files #ifdef G4MULTITHREADED #include "G4MTRunManager.hh" @@ -78,12 +67,9 @@ Geant4ActionPhase& Geant4Kernel::PhaseSelector::operator[](const std::string& na /// Standard constructor Geant4Kernel::Geant4Kernel(LCDD& lcdd_ref) - : m_runManager(0), m_generatorAction(0), m_runAction(0), m_eventAction(0), - m_trackingAction(0), m_steppingAction(0), m_stackingAction(0), m_constructionAction(0), - m_sensDetActions(0), m_physicsList(0), m_userInit(0), m_lcdd(lcdd_ref), - m_numThreads(0), m_id(Geant4Kernel::thread_self()), m_master(this), phase(this) + : Geant4ActionContainer(), m_runManager(0), m_lcdd(lcdd_ref), + m_numThreads(0), m_id(Geant4Kernel::thread_self()), m_master(this), m_shared(0), phase(this) { - m_sensDetActions = new Geant4SensDetSequences(); m_lcdd.addExtension < Geant4Kernel > (this); m_ident = -1; declareProperty("UI",m_uiName); @@ -91,26 +77,21 @@ Geant4Kernel::Geant4Kernel(LCDD& lcdd_ref) declareProperty("NumEvents", m_numEvent = 10); declareProperty("OutputLevels", m_clientLevels); declareProperty("NumberOfThreads",m_numThreads); - //declareProperty("MultiThreaded", m_multiThreaded=false); m_controlName = "/ddg4/"; m_control = new G4UIdirectory(m_controlName.c_str()); m_control->SetGuidance("Control for named Geant4 actions"); - m_threadContext = new Geant4Context(this); + setContext(new Geant4Context(this)); + //m_shared = new Geant4Kernel(lcdd_ref, this, -2); InstanceCount::increment(this); } /// Standard constructor Geant4Kernel::Geant4Kernel(LCDD& lcdd_ref, Geant4Kernel* m, unsigned long ident) - : m_runManager(0), m_generatorAction(0), m_runAction(0), m_eventAction(0), - m_trackingAction(0), m_steppingAction(0), m_stackingAction(0), m_constructionAction(0), - m_sensDetActions(0), m_physicsList(0), m_userInit(0), m_lcdd(lcdd_ref), m_id(ident), - m_master(m), phase(this) + : Geant4ActionContainer(), m_runManager(0), m_lcdd(lcdd_ref), + m_numThreads(1), m_id(ident), m_master(m), m_shared(0), phase(this) { char text[64]; - m_numThreads = 1; - //m_multiThreaded = m_master->m_multiThreaded; m_ident = m_master->m_workers.size(); - m_sensDetActions = new Geant4SensDetSequences(); declareProperty("UI",m_uiName = m_master->m_uiName); declareProperty("OutputLevel", m_outputLevel = m_master->m_outputLevel); declareProperty("OutputLevels",m_clientLevels = m_master->m_clientLevels); @@ -118,7 +99,7 @@ Geant4Kernel::Geant4Kernel(LCDD& lcdd_ref, Geant4Kernel* m, unsigned long ident) m_controlName = text; m_control = new G4UIdirectory(m_controlName.c_str()); m_control->SetGuidance("Control for thread specific Geant4 actions"); - m_threadContext = new Geant4Context(this); + setContext(new Geant4Context(this)); InstanceCount::increment(this); } @@ -131,17 +112,7 @@ Geant4Kernel::~Geant4Kernel() { } destroyPhases(); deletePtr (m_runManager); - releasePtr (m_physicsList); - releasePtr (m_constructionAction); - releasePtr (m_stackingAction); - releasePtr (m_steppingAction); - releasePtr (m_trackingAction); - releasePtr (m_eventAction); - releasePtr (m_generatorAction); - releasePtr (m_runAction); - releasePtr (m_userInit); - deletePtr (m_sensDetActions); - deletePtr (m_threadContext); + Geant4ActionContainer::terminate(); if ( isMaster() ) { m_lcdd.removeExtension < Geant4Kernel > (false); m_lcdd.destroyInstance(); @@ -155,6 +126,7 @@ Geant4Kernel& Geant4Kernel::instance(LCDD& lcdd) { return obj; } +#if 0 /// Accessof the Geant4Kernel object from the LCDD reference extension (if present and registered) Geant4Kernel& Geant4Kernel::access(LCDD& lcdd) { Geant4Kernel* kernel = lcdd.extension<Geant4Kernel>(); @@ -164,6 +136,7 @@ Geant4Kernel& Geant4Kernel::access(LCDD& lcdd) { } return *kernel; } +#endif /// Access thread identifier unsigned long int Geant4Kernel::thread_self() { @@ -171,11 +144,6 @@ unsigned long int Geant4Kernel::thread_self() { return thr_id; } -Geant4Context* Geant4Kernel::workerContext() { - if ( m_threadContext ) return m_threadContext; - throw runtime_error(format("Geant4Kernel", "DDG4: Master kernel object has no thread context! [Invalid Handle]")); -} - /// Create identified worker instance Geant4Kernel& Geant4Kernel::createWorker() { if ( isMaster() ) { @@ -323,28 +291,10 @@ int Geant4Kernel::terminate() { for_each(m_globalFilters.begin(), m_globalFilters.end(), releaseObjects(m_globalFilters)); for_each(m_globalActions.begin(), m_globalActions.end(), releaseObjects(m_globalActions)); deletePtr (m_runManager); - releasePtr (m_physicsList); - releasePtr (m_constructionAction); - releasePtr (m_stackingAction); - releasePtr (m_steppingAction); - releasePtr (m_trackingAction); - releasePtr (m_eventAction); - releasePtr (m_generatorAction); - releasePtr (m_runAction); - deletePtr (m_sensDetActions); - //return *this; + Geant4ActionContainer::terminate(); return 1; } -template <class C> bool Geant4Kernel::registerSequence(C*& seq, const std::string& name) { - if (!name.empty()) { - seq = new C(workerContext(), name); - seq->installMessengers(); - return true; - } - throw runtime_error(format("Geant4Kernel", "DDG4: The action '%s' not found. [Action-NotFound]", name.c_str())); -} - /// Register action by name to be retrieved when setting up and connecting action objects /** Note: registered actions MUST be unique. * However, not all actions need to registered.... @@ -471,88 +421,3 @@ bool Geant4Kernel::removePhase(const std::string& nam) { void Geant4Kernel::destroyPhases() { for_each(m_phases.begin(), m_phases.end(), destroyObjects(m_phases)); } - -/// Access generator action sequence -Geant4GeneratorActionSequence* Geant4Kernel::generatorAction(bool create) { - if (!m_generatorAction && create) - registerSequence(m_generatorAction, "GeneratorAction"); - return m_generatorAction; -} - -/// Access run action sequence -Geant4RunActionSequence* Geant4Kernel::runAction(bool create) { - if (!m_runAction && create) - registerSequence(m_runAction, "RunAction"); - return m_runAction; -} - -/// Access event action sequence -Geant4EventActionSequence* Geant4Kernel::eventAction(bool create) { - if (!m_eventAction && create) - registerSequence(m_eventAction, "EventAction"); - return m_eventAction; -} - -/// Access stepping action sequence -Geant4SteppingActionSequence* Geant4Kernel::steppingAction(bool create) { - if (!m_steppingAction && create) - registerSequence(m_steppingAction, "SteppingAction"); - return m_steppingAction; -} - -/// Access tracking action sequence -Geant4TrackingActionSequence* Geant4Kernel::trackingAction(bool create) { - if (!m_trackingAction && create) - registerSequence(m_trackingAction, "TrackingAction"); - return m_trackingAction; -} - -/// Access stacking action sequence -Geant4StackingActionSequence* Geant4Kernel::stackingAction(bool create) { - if (!m_stackingAction && create) - registerSequence(m_stackingAction, "StackingAction"); - return m_stackingAction; -} - -/// Access detector construcion action sequence (geometry+sensitives+field) -Geant4DetectorConstructionSequence* Geant4Kernel::detectorConstruction(bool create) { - if (!m_constructionAction && create) - registerSequence(m_constructionAction, "StackingAction"); - return m_constructionAction; -} - -/// Access to the sensitive detector sequences from the kernel object -Geant4SensDetSequences& Geant4Kernel::sensitiveActions() const { - return *m_sensDetActions; -} - -/// Access to the sensitive detector action from the kernel object -Geant4SensDetActionSequence* Geant4Kernel::sensitiveAction(const string& nam) { - Geant4SensDetActionSequence* ptr = m_sensDetActions->find(nam); - if (ptr) { - return ptr; - } - ptr = new Geant4SensDetActionSequence(workerContext(), nam); - m_sensDetActions->insert(nam, ptr); - return ptr; -} - -/// Access to the physics list -Geant4PhysicsListActionSequence* Geant4Kernel::physicsList(bool create) { - if (!m_physicsList && create) - registerSequence(m_physicsList, "PhysicsList"); - return m_physicsList; -} - -/// Access to the physics list -Geant4UserInitializationSequence* Geant4Kernel::userInitialization(bool create) { - if ( !m_userInit && create ) { - if ( isMaster() ) - registerSequence(m_userInit, "UserInitialization"); - else - throw runtime_error(format("Geant4Kernel", - "DDG4: Only the master thread may initialize " - "a user initialization object!")); - } - return m_userInit; -} diff --git a/DDG4/src/python/PyDDG4.cpp b/DDG4/src/python/PyDDG4.cpp index 0c3e50942..0068882e5 100644 --- a/DDG4/src/python/PyDDG4.cpp +++ b/DDG4/src/python/PyDDG4.cpp @@ -30,7 +30,7 @@ int PyDDG4::run(Kernel& kernel) { } int PyDDG4::execute() { - Kernel& k = Kernel::access(DD4hep::Geometry::LCDD::getInstance()); + Kernel& k = Kernel::instance(DD4hep::Geometry::LCDD::getInstance()); return run(k); } -- GitLab