From 19f96ce5924ea251996130fd1c18e5a7aac346f3 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Mon, 30 Jun 2014 18:03:04 +0000 Subject: [PATCH] Please see release notes --- DDCore/include/DD4hep/ObjectExtensions.h | 4 + DDCore/src/DetectorInterna.cpp | 23 +-- DDCore/src/VolumeManager.cpp | 4 +- DDG4/examples/CLICSidSimu.py | 9 +- DDG4/include/DDG4/Geant4Action.h | 63 ++++++-- DDG4/include/DDG4/Geant4Context.h | 139 ++++++++++++++++-- DDG4/include/DDG4/Geant4EventAction.h | 1 + DDG4/include/DDG4/Geant4Handle.h | 6 +- DDG4/include/DDG4/Geant4Kernel.h | 15 +- .../DDG4/Geant4MonteCarloRecordManager.h | 4 +- DDG4/include/DDG4/Geant4TestActions.h | 48 +++++- DDG4/include/DDG4/Geant4TrackPersistency.h | 11 +- DDG4/include/DDG4/Geant4TrackingAction.h | 2 +- DDG4/plugins/Geant4Factories.cpp | 2 +- DDG4/plugins/Geant4SensDet.cpp | 29 +++- DDG4/plugins/Geant4SensDetFilters.cpp | 12 +- DDG4/python/DD4hep.py | 2 + DDG4/src/Geant4Action.cpp | 93 +++++++++--- DDG4/src/Geant4Context.cpp | 64 ++++++-- DDG4/src/Geant4DetectorConstruction.cpp | 2 + DDG4/src/Geant4EventAction.cpp | 9 +- DDG4/src/Geant4Exec.cpp | 125 ++++++++++++---- DDG4/src/Geant4GeneratorAction.cpp | 2 + DDG4/src/Geant4Handle.cpp | 28 ++-- DDG4/src/Geant4Kernel.cpp | 19 +-- DDG4/src/Geant4MonteCarloRecordManager.cpp | 8 +- DDG4/src/Geant4OutputAction.cpp | 3 +- DDG4/src/Geant4RunAction.cpp | 2 + DDG4/src/Geant4SensDetAction.cpp | 6 +- DDG4/src/Geant4StackingAction.cpp | 2 + DDG4/src/Geant4SteppingAction.cpp | 2 + DDG4/src/Geant4TestActions.cpp | 103 +++++++++---- DDG4/src/Geant4TrackPersistency.cpp | 19 ++- DDG4/src/Geant4TrackingAction.cpp | 6 +- DDG4/src/Geant4TrackingPostAction.cpp | 2 +- DDG4/src/Geant4TrackingPreAction.cpp | 2 +- DDG4/src/Geant4VolumeManager.cpp | 6 +- doc/release.notes | 17 +++ 38 files changed, 688 insertions(+), 206 deletions(-) diff --git a/DDCore/include/DD4hep/ObjectExtensions.h b/DDCore/include/DD4hep/ObjectExtensions.h index e528033ff..959bfb0cc 100644 --- a/DDCore/include/DD4hep/ObjectExtensions.h +++ b/DDCore/include/DD4hep/ObjectExtensions.h @@ -47,6 +47,10 @@ namespace DD4hep { /// Pointer to the extension map ExtensionMap* extensionMap; //! + /// Function to be passed as dtor if object should NOT be deleted! + static void _noDelete(void*) {} + /// If the object SHOULD be deleted, use DD4hep::deletePtr<TYPE>! + public: /// Default constructor ObjectExtensions(const std::type_info& parent_type); diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp index 553270c27..b03cdba16 100644 --- a/DDCore/src/DetectorInterna.cpp +++ b/DDCore/src/DetectorInterna.cpp @@ -29,16 +29,18 @@ DD4HEP_INSTANTIATE_HANDLE_NAMED(SensitiveDetectorObject); /// Default constructor SensitiveDetectorObject::SensitiveDetectorObject() - : NamedObject(), ObjectExtensions(typeid(SensitiveDetectorObject)), magic(magic_word()), verbose(0), combineHits(0), ecut(0.0), readout(), region(), limits(), hitsCollection() { - printout(DEBUG,"SensitiveDetectorObject","+++ Created new anonymous SensitiveDetectorObject()"); + : NamedObject(), ObjectExtensions(typeid(SensitiveDetectorObject)), magic(magic_word()), + verbose(0), combineHits(0), ecut(0.0), readout(), region(), limits(), hitsCollection() { + printout(VERBOSE,"SensitiveDetectorObject","+++ Created new anonymous SensitiveDetectorObject()"); InstanceCount::increment(this); } /// Initializing constructor SensitiveDetectorObject::SensitiveDetectorObject(const std::string& nam) - : NamedObject(), ObjectExtensions(typeid(SensitiveDetectorObject)), magic(magic_word()), verbose(0), combineHits(0), ecut(0.0), readout(), region(), limits(), hitsCollection() { + : NamedObject(), ObjectExtensions(typeid(SensitiveDetectorObject)), magic(magic_word()), + verbose(0), combineHits(0), ecut(0.0), readout(), region(), limits(), hitsCollection() { SetName(nam.c_str()); - printout(DEBUG,"SensitiveDetectorObject","+++ Created new SensitiveDetectorObject('%s')",nam.c_str()); + printout(VERBOSE,"SensitiveDetectorObject","+++ Created new SensitiveDetectorObject('%s')",nam.c_str()); InstanceCount::increment(this); } @@ -53,22 +55,24 @@ SensitiveDetectorObject::~SensitiveDetectorObject() { /// Default constructor DetElementObject::DetElementObject() - : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()), flag(0), id(0), combineHits(0), path(), placementPath(), + : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()), + flag(0), id(0), combineHits(0), path(), placementPath(), idealPlace(), placement(), volumeID(0), parent(), reference(), children(), alignment(), volume_alignments(), conditions(), worldTrafo(), parentTrafo(), referenceTrafo(0) { - printout(DEBUG,"DetElementObject","+++ Created new anonymous DetElementObject()"); + printout(VERBOSE,"DetElementObject","+++ Created new anonymous DetElementObject()"); InstanceCount::increment(this); } /// Initializing constructor DetElementObject::DetElementObject(const std::string& nam, int ident) - : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()), flag(0), id(ident), combineHits(0), path(), placementPath(), + : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()), + flag(0), id(ident), combineHits(0), path(), placementPath(), idealPlace(), placement(), volumeID(0), parent(), reference(), children(), alignment(), volume_alignments(), conditions(), worldTrafo(), parentTrafo(), referenceTrafo(0) { SetName(nam.c_str()); - printout(DEBUG,"DetElementObject","+++ Created new DetElementObject('%s', %d)",nam.c_str(),id); + printout(VERBOSE,"DetElementObject","+++ Created new DetElementObject('%s', %d)",nam.c_str(),id); InstanceCount::increment(this); } @@ -114,7 +118,8 @@ DetElementObject* DetElementObject::clone(int new_id, int flag) const { child._data().parent = obj; } else { - throw runtime_error("DD4hep: DetElement::copy: Element " + string(child.name()) + " is already present [Double-Insert]"); + throw runtime_error("DD4hep: DetElement::copy: Element " + string(child.name()) + + " is already present [Double-Insert]"); } } return obj; diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp index 81213ba7f..f2e76519a 100644 --- a/DDCore/src/VolumeManager.cpp +++ b/DDCore/src/VolumeManager.cpp @@ -128,7 +128,7 @@ namespace { if (ro.isValid()) { IDDescriptor iddesc = ro.idSpec(); pair<VolumeID, VolumeID> det_encoding = encoding(iddesc,ids); - printout(DEBUG,"VolumeManager","++++ %-11s SD:%s VolID=%p Mask=%p",e.path().c_str(), + printout(VERBOSE,"VolumeManager","++++ %-11s SD:%s VolID=%p Mask=%p",e.path().c_str(), got_readout ? "RECUPERATED" : "REGULAR", sd.name(), (void*)det_encoding.first, (void*)det_encoding.second); e.object<DetElement::Object>().volumeID = det_encoding.first; @@ -334,7 +334,7 @@ bool VolumeManager::adoptPlacement(VolumeID /* sys_id */, Context* context) { o.detMask |= context->mask; err << "Inserted new volume:" << setw(6) << left << o.volumes.size() << " Ptr:" << (void*) pv.ptr() << " [" << pv.name() << "]" << " ID:" << (void*) context->identifier << " Mask:" << (void*) context->mask; - printout(DEBUG, "VolumeManager", err.str().c_str()); + printout(VERBOSE, "VolumeManager", err.str().c_str()); return true; } err << "+++ Attempt to register duplicate volID " << (void*) context->identifier diff --git a/DDG4/examples/CLICSidSimu.py b/DDG4/examples/CLICSidSimu.py index aa9301b80..8e86f1587 100644 --- a/DDG4/examples/CLICSidSimu.py +++ b/DDG4/examples/CLICSidSimu.py @@ -16,6 +16,7 @@ from SystemOfUnits import * def run(): install_dir = os.environ['DD4hepINSTALL'] example_dir = install_dir+'/examples/DDG4/examples'; + DDG4.setPrintLevel(Output.DEBUG) kernel = DDG4.Kernel() kernel.UI = "UI" kernel.loadGeometry("file:"+install_dir+"/examples/CLICSiD/compact/compact.xml") @@ -65,10 +66,10 @@ def run(): kernel.eventAction().add(evt2) """ trk = DDG4.Action(kernel,"Geant4TrackPersistency/MonteCarloTruthHandler") - mc = DDG4.Action(kernel,"Geant4MonteCarloRecordManager/MonteCarloRecordManager") kernel.registerGlobalAction(trk) - kernel.registerGlobalAction(mc) trk.release() + mc = DDG4.Action(kernel,"Geant4MonteCarloRecordManager/MonteCarloRecordManager") + kernel.registerGlobalAction(mc) mc.release() """ # Configure I/O @@ -83,6 +84,9 @@ def run(): #evt_lcio.enableUI() #kernel.eventAction().add(evt_lcio) + gen = DDG4.GeneratorAction(kernel,"Geant4TestGeneratorAction/Generate") + kernel.generatorAction().add(gen) + # Setup particle gun gun = DDG4.GeneratorAction(kernel,"Geant4ParticleGun/Gun") gun.energy = 100*GeV @@ -206,6 +210,7 @@ def run(): kernel.configure() kernel.initialize() + kernel.run() kernel.terminate() diff --git a/DDG4/include/DDG4/Geant4Action.h b/DDG4/include/DDG4/Geant4Action.h index e5b7fbe75..f3b74efc5 100644 --- a/DDG4/include/DDG4/Geant4Action.h +++ b/DDG4/include/DDG4/Geant4Action.h @@ -118,17 +118,15 @@ namespace DD4hep { }; #endif - /** @class Invoke Geant4Action.h DDG4/Geant4Action.h - * - * Default base class for all geant 4 actions and derivates thereof. - * + /// Default base class for all geant 4 actions and derivates thereof. + /** * @author M.Frank * @version 1.0 */ class Geant4Action { protected: /// Reference to the Geant4 context - Geant4Context* m_context; + Geant4Context m_context; /// Control directory of this action Geant4UIMessenger* m_control; @@ -143,8 +141,28 @@ namespace DD4hep { /// Reference count. Initial value: 1 long m_refCount; + /// Functor to update the context of a Geant4Action object + /** + * @author M.Frank + * @version 1.0 + */ + class ContextUpdate { + public: + /// reference to the context; + const Geant4Context* context; + /// Constructor + ContextUpdate(const Geant4Context* c=0) : context(c) {} + /// Callback + void operator()(Geant4Action* action) const; + }; + friend class ContextUpdate; + /// Actor class to manipulate action groups + /** + * @author M.Frank + * @version 1.0 + */ template <typename T> struct Actors { - typedef std::vector<T*> _V; + typedef typename std::vector<T*> _V; _V m_v; Actors() { } @@ -168,6 +186,17 @@ namespace DD4hep { _V* operator->() { return &m_v; } + typename _V::iterator begin() { return m_v.begin(); } + typename _V::iterator end() { return m_v.end(); } + typename _V::const_iterator begin() const { return m_v.begin(); } + typename _V::const_iterator end() const { return m_v.end(); } + /// Context updates + void operator()(const ContextUpdate& context) { + if (m_v.empty()) + return; + for (typename _V::iterator i = m_v.begin(); i != m_v.end(); ++i) + context(*i); + } /// NON-CONST actions template <typename R, typename Q> void operator()(R (Q::*pmf)()) { if (m_v.empty()) @@ -244,11 +273,9 @@ namespace DD4hep { long addRef(); /// Decrease reference count. Implicit destruction long release(); - /// Set the context pointer - void setContext(Geant4Context* context); /// Access the context - Geant4Context* context() const { - return m_context; + const Geant4Context* context() const { + return &m_context; } /// Access name of the action const std::string& name() const { @@ -301,18 +328,30 @@ namespace DD4hep { /// Support of debug messages. void debug(const std::string& fmt, ...) const; + /// Support of warning messages. + void debug(const std::string& tag, const std::string& fmt, ...) const; /// Support of info messages. void info(const std::string& fmt, ...) const; /// Support of warning messages. + void info(const std::string& tag, const std::string& fmt, ...) const; + /// Support of warning messages. void warning(const std::string& fmt, ...) const; + /// Support of warning messages. + void warning(const std::string& tag, const std::string& fmt, ...) const; /// Support of error messages. void error(const std::string& fmt, ...) const; + /// Support of error messages. + void error(const std::string& tag, const std::string& fmt, ...) const; /// Action to support error messages. bool error(bool return_value, const std::string& fmt, ...) const; /// Support of fatal messages. Throws exception void fatal(const std::string& fmt, ...) const; + /// Support of warning messages. + void fatal(const std::string& tag, const std::string& fmt, ...) const; /// Support of exceptions: Print fatal message and throw runtime_error. void except(const std::string& fmt, ...) const; + /// Support of warning messages. + void except(const std::string& tag, const std::string& fmt, ...) const; /// Abort Geant4 Run by throwing a G4Exception with type RunMustBeAborted void abortRun(const std::string& exception, const std::string& fmt, ...) const; @@ -329,10 +368,6 @@ namespace DD4hep { Geant4StackingActionSequence& stackingAction() const; /// Access to the main generator action sequence from the kernel object Geant4GeneratorActionSequence& generatorAction() const; - /// Access to the Track Persistency Manager from the kernel object - Geant4MonteCarloTruth* mcTruthMgr(bool throw_exception=true) const; - /// Access to the MC record manager from the kernel object - Geant4MonteCarloRecordManager* mcRecordMgr(bool throw_exception=true) const; }; /// Declare property diff --git a/DDG4/include/DDG4/Geant4Context.h b/DDG4/include/DDG4/Geant4Context.h index 320e587b5..9139baf49 100644 --- a/DDG4/include/DDG4/Geant4Context.h +++ b/DDG4/include/DDG4/Geant4Context.h @@ -9,8 +9,14 @@ #ifndef DD4HEP_DDG4_GEANT4CONTEXT_H #define DD4HEP_DDG4_GEANT4CONTEXT_H +// Framework incloude files +#include "DD4hep/Primitives.h" +#include "DD4hep/ObjectExtensions.h" + // Forward declarations +class G4Run; class G4Track; +class G4Event; class G4VTrajectory; class G4TrackingManager; @@ -30,7 +36,10 @@ namespace DD4hep { */ namespace Simulation { + class Geant4Run; + class Geant4Event; class Geant4Kernel; + class ContextUpdate; class Geant4RunActionSequence; class Geant4EventActionSequence; class Geant4SteppingActionSequence; @@ -41,25 +50,135 @@ namespace DD4hep { class Geant4MonteCarloTruth; class Geant4MonteCarloRecordManager; - /** @class Geant4Context Geant4Context.h DDG4/Geant4Context.h + + /// User run context for DDG4 + /** + * The context is accessible from the Geant4Context pointer, + * which is present in every Geant4Action. + * The run context is only valid however, if there is actually + * an run being procesed ie. only during the lifetime of the + * corresponding G4Run objects. + * + * Please note: + * Extensions are only valid within the hosting run and are INVALID + * across different runs. + * Hence: They are only useful to extend data of an run. + * + * @author M.Frank + * @version 1.0 + */ + class Geant4Run : public ObjectExtensions { + /// Reference to the original Geant4 run object + const G4Run* m_run; + public: + /// Intializing constructor + Geant4Run(const G4Run* run); + /// Default destructor + virtual ~Geant4Run(); + /// Access the G4Run directly + operator const G4Run&() const { return *m_run; } + const G4Run& run() const { return *m_run; } + /// Add an extension object to the detector element + /** Note: + * To add an extension, which should NOT be deleted, + * set 'dtor' to ObjectExtensions::_noDelete or 0. + */ + void* addExtension(void* ptr, const std::type_info& info, destruct_t dtor) { + return ObjectExtensions::addExtension(ptr,info,dtor); + } + /// Add user extension object. Ownership is transferred! + template <typename T> T* addExtension(T* ptr) { + return (T*)ObjectExtensions::addExtension(ptr,typeid(T),deletePtr<T>); + } + /// Access to type safe extension object. Exception is thrown if the object is invalid + template <typename T> T* extension(bool alert=true) { + return (T*)ObjectExtensions::extension(typeid(T),alert); + } + }; + + /// User event context for DDG4 + /** + * The context is accessible from the Geant4Context pointer, + * which is present in every Geant4Action. + * The event context is only valid however, if there is actually + * an event being procesed ie. only during the lifetime of the + * corresponding G4Event objects. + * + * Please note: + * Extensions are only valid within the hosting event and are INVALID + * across different events. + * Hence: They are only useful to extend data of an event. + * + * @author M.Frank + * @version 1.0 + */ + class Geant4Event : public ObjectExtensions { + /// Reference to the original Geant4 event object + const G4Event* m_event; + public: + /// Intializing constructor + Geant4Event(const G4Event* run); + /// Default destructor + virtual ~Geant4Event(); + /// Access the G4Event directly + operator const G4Event&() const { return *m_event; } + const G4Event& event() const { return *m_event; } + /// Add an extension object to the detector element + /** Note: + * To add an extension, which should NOT be deleted, + * set 'dtor' to ObjectExtensions::_noDelete or 0. + */ + void* addExtension(void* ptr, const std::type_info& info, destruct_t dtor) { + return ObjectExtensions::addExtension(ptr,info,dtor); + } + /// Add user extension object. Ownership is transferred and object deleted at the end of the event. + template <typename T> T* addExtension(T* ptr) { + return (T*)ObjectExtensions::addExtension(ptr,typeid(T),deletePtr<T>); + } + /// Access to type safe extension object. Exception is thrown if the object is invalid + template <typename T> T* extension(bool alert=true) { + return (T*)ObjectExtensions::extension(typeid(T),alert); + } + }; + + /// Generic context to extend user, run and event information + /** * * @author M.Frank * @version 1.0 */ - struct Geant4Context { + class Geant4Context { + public: +#ifdef R__DICTIONARY_FILENAME + /// ROOT does not know how to process the nested ns otherwise + public: typedef Geometry::LCDD LCDD; - +#endif + protected: Geant4Kernel* m_kernel; + Geant4Run* m_run; + Geant4Event* m_event; + public: /// Default constructor Geant4Context(Geant4Kernel* kernel); /// Default destructor virtual ~Geant4Context(); + /// Set the geant4 run reference + void setRun(Geant4Run* new_run); + /// Access the geant4 run -- valid only between BeginRun() and EndRun()! + Geant4Run& run() const; + /// Access the geant4 run by ptr. Must be checked by clients! + Geant4Run* runPtr() const { return m_run; } + /// Set the geant4 event reference + void setEvent(Geant4Event* new_event); + /// Access the geant4 event -- valid only between BeginEvent() and EndEvent()! + Geant4Event& event() const; + /// Access the geant4 event by ptr. Must be checked by clients! + Geant4Event* eventPtr() const { return m_event; } /// Access to the kernel object - Geant4Kernel& kernel() { - return *m_kernel; - } + Geant4Kernel& kernel() const { return *m_kernel; } /// Access to detector description - LCDD& lcdd() const; + Geometry::LCDD& lcdd() const; /// Access the tracking manager G4TrackingManager* trackMgr() const; /// Create a user trajectory @@ -78,12 +197,6 @@ namespace DD4hep { Geant4GeneratorActionSequence& generatorAction() const; /// Access to the sensitive detector sequences from the kernel object Geant4SensDetSequences& sensitiveActions() const; - - /// Access to the Track Manager from the kernel object - Geant4MonteCarloTruth& mcTruthMgr() const; - /// Access to the MC record manager from the kernel object (if instantiated!) - Geant4MonteCarloRecordManager& mcRecordMgr() const; - }; } // End namespace Simulation diff --git a/DDG4/include/DDG4/Geant4EventAction.h b/DDG4/include/DDG4/Geant4EventAction.h index 80544246f..b8a788089 100644 --- a/DDG4/include/DDG4/Geant4EventAction.h +++ b/DDG4/include/DDG4/Geant4EventAction.h @@ -11,6 +11,7 @@ // Framework include files #include "DDG4/Geant4Action.h" + // Forward declarations class G4Event; diff --git a/DDG4/include/DDG4/Geant4Handle.h b/DDG4/include/DDG4/Geant4Handle.h index 0b51905d4..5cd67783a 100644 --- a/DDG4/include/DDG4/Geant4Handle.h +++ b/DDG4/include/DDG4/Geant4Handle.h @@ -51,10 +51,10 @@ namespace DD4hep { checked_assign(dynamic_cast<handled_type*>(typ)); } Geant4Handle(const Geant4Handle& handle); - Geant4Handle(const Geant4Kernel&, const char* type_name); - Geant4Handle(const Geant4Kernel&, const std::string& type_name); + Geant4Handle(Geant4Kernel&, const char* type_name); + Geant4Handle(Geant4Kernel&, const std::string& type_name); /// Constructor only implemented for sensitive objects - Geant4Handle(const Geant4Kernel& ctxt, const std::string& type_name, const std::string& detector); + Geant4Handle(Geant4Kernel& ctxt, const std::string& type_name, const std::string& detector); ~Geant4Handle(); Property& operator[](const std::string& property_name) const; Geant4Handle& operator=(const Geant4Handle& handle); diff --git a/DDG4/include/DDG4/Geant4Kernel.h b/DDG4/include/DDG4/Geant4Kernel.h index ce56eeec2..7831c71f2 100644 --- a/DDG4/include/DDG4/Geant4Kernel.h +++ b/DDG4/include/DDG4/Geant4Kernel.h @@ -70,8 +70,6 @@ namespace DD4hep { typedef std::map<std::string, Geant4Action*> GlobalActions; protected: - /// Reference to execution context - Geant4Context* m_context; /// Reference to the run manager G4RunManager* m_runManager; /// Top level control directory @@ -158,14 +156,6 @@ namespace DD4hep { /// Accessof the Geant4Kernel object from the LCDD reference extension (if present and registered) static Geant4Kernel& access(LCDD& lcdd); #endif - /// Access the context - Geant4Context* context() const { - return m_context; - } - /// Automatic conversion to the context - operator Geant4Context*() const { - return m_context; - } /// Access to the properties of the object PropertyManager& properties() { return m_properties; @@ -299,7 +289,7 @@ namespace DD4hep { /// 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) const; + Geant4SensDetActionSequence* sensitiveAction(const std::string& name); /// Access to the physics list Geant4PhysicsListActionSequence* physicsList(bool create); @@ -307,11 +297,12 @@ namespace DD4hep { Geant4PhysicsListActionSequence& physicsList() { return *physicsList(true); } +#if 0 /// Access to the Track Manager from the kernel object Geant4MonteCarloTruth* mcTruthMgr(bool throw_exception=true); /// Access to the MC record manager from the kernel object (if instantiated!) Geant4MonteCarloRecordManager* mcRecordMgr(bool throw_exception=true); - +#endif /// Construct detector geometry using lcdd plugin void loadGeometry(const std::string& compact_file); /// Run the simulation diff --git a/DDG4/include/DDG4/Geant4MonteCarloRecordManager.h b/DDG4/include/DDG4/Geant4MonteCarloRecordManager.h index b328e9b49..39e939788 100644 --- a/DDG4/include/DDG4/Geant4MonteCarloRecordManager.h +++ b/DDG4/include/DDG4/Geant4MonteCarloRecordManager.h @@ -32,7 +32,7 @@ namespace DD4hep { * @author M.Frank * @version 1.0 */ - class Geant4MonteCarloRecordManager : public Geant4Action { + class Geant4MonteCarloRecordManager : public Geant4GeneratorAction { public: /// Flag to indicate if the track information should be collected bool m_collectInfo; @@ -41,6 +41,8 @@ namespace DD4hep { Geant4MonteCarloRecordManager(Geant4Context* context, const std::string& nam); /// Default destructor virtual ~Geant4MonteCarloRecordManager(); + /// Event generation action callback + virtual void operator()(G4Event* event); /// Save G4Track data virtual void save(const Geant4TrackPersistency::TrackInfo& track); }; diff --git a/DDG4/include/DDG4/Geant4TestActions.h b/DDG4/include/DDG4/Geant4TestActions.h index fa4dd6849..2de9dce08 100644 --- a/DDG4/include/DDG4/Geant4TestActions.h +++ b/DDG4/include/DDG4/Geant4TestActions.h @@ -32,7 +32,9 @@ namespace DD4hep { namespace Simulation { namespace Test { - /** @class Geant4TestRunAction + + /// Common base class for test action + /** * * @author M.Frank * @version 1.0 @@ -49,6 +51,26 @@ namespace DD4hep { /// Default destructor virtual ~Geant4TestBase(); }; + + /// Example generator action doing nothing, but print + /** + * @author M.Frank + * @version 1.0 + */ + struct Geant4TestGeneratorAction: public Geant4GeneratorAction, public Geant4TestBase { + /// Standard constructor with initializing arguments + Geant4TestGeneratorAction(Geant4Context* c, const std::string& n); + /// Default destructor + virtual ~Geant4TestGeneratorAction(); + /// Callback to generate primary particles + virtual void operator()(G4Event*); + }; + + /// Example run action doing nothing, but print + /** + * @author M.Frank + * @version 1.0 + */ struct Geant4TestRunAction: public Geant4RunAction, public Geant4TestBase { /// Standard constructor with initializing arguments Geant4TestRunAction(Geant4Context* c, const std::string& n); @@ -63,6 +85,12 @@ namespace DD4hep { /// End-of-event callback void endEvent(const G4Event*); }; + + /// Example event action doing nothing, but print + /** + * @author M.Frank + * @version 1.0 + */ struct Geant4TestEventAction: public Geant4EventAction, public Geant4TestBase { /// Standard constructor with initializing arguments Geant4TestEventAction(Geant4Context* c, const std::string& n); @@ -77,6 +105,12 @@ namespace DD4hep { /// End-of-run callback void endRun(const G4Run*); }; + + /// Example tracking action doing nothing, but print + /** + * @author M.Frank + * @version 1.0 + */ struct Geant4TestTrackAction: public Geant4TrackingAction, public Geant4TestBase { /// Standard constructor with initializing arguments Geant4TestTrackAction(Geant4Context* c, const std::string& n); @@ -87,6 +121,12 @@ namespace DD4hep { /// End-of-tracking callback virtual void end(const G4Track*); }; + + /// Example stepping action doing nothing, but print + /** + * @author M.Frank + * @version 1.0 + */ struct Geant4TestStepAction: public Geant4SteppingAction, public Geant4TestBase { /// Standard constructor with initializing arguments Geant4TestStepAction(Geant4Context* c, const std::string& n); @@ -95,6 +135,12 @@ namespace DD4hep { /// User stepping callback void operator()(const G4Step*, G4SteppingManager*); }; + + /// Example sensitve detector action doing nothing, but print + /** + * @author M.Frank + * @version 1.0 + */ struct Geant4TestSensitive: public Geant4Sensitive, public Geant4TestBase { size_t m_collectionID; /// Standard constructor with initializing arguments diff --git a/DDG4/include/DDG4/Geant4TrackPersistency.h b/DDG4/include/DDG4/Geant4TrackPersistency.h index c097905b3..2aed25b6e 100644 --- a/DDG4/include/DDG4/Geant4TrackPersistency.h +++ b/DDG4/include/DDG4/Geant4TrackPersistency.h @@ -11,6 +11,8 @@ // Framework include files #include "DDG4/Geant4Action.h" +#include "DDG4/Geant4EventAction.h" +#include "DDG4/Geant4GeneratorAction.h" #include "DDG4/Geant4MonteCarloTruth.h" #include "Math/PxPyPzE4D.h" #include "G4VUserTrackInformation.hh" @@ -45,7 +47,10 @@ namespace DD4hep { * @author M.Frank * @version 1.0 */ - class Geant4TrackPersistency : public Geant4Action, public Geant4MonteCarloTruth { + class Geant4TrackPersistency + : public Geant4GeneratorAction, + public Geant4MonteCarloTruth + { public: typedef ROOT::Math::PxPyPzE4D<double> FourMomentum; typedef std::map<int,void*> TrackMap; @@ -99,7 +104,9 @@ namespace DD4hep { /// Default destructor virtual ~Geant4TrackPersistency(); /// Access the Geant4 tracking manager. Only use between tracking pre- and post action - G4TrackingManager* trackMgr() const { return m_context->trackMgr(); } + G4TrackingManager* trackMgr() const { return m_context.trackMgr(); } + /// Event generation action callback + virtual void operator()(G4Event* event); /// User stepping callback virtual void step(const G4Step* step, G4SteppingManager* mgr); /// Pre-event action callback diff --git a/DDG4/include/DDG4/Geant4TrackingAction.h b/DDG4/include/DDG4/Geant4TrackingAction.h index e8cc401ff..84a1502b2 100644 --- a/DDG4/include/DDG4/Geant4TrackingAction.h +++ b/DDG4/include/DDG4/Geant4TrackingAction.h @@ -44,7 +44,7 @@ namespace DD4hep { virtual ~Geant4TrackingAction(); /// Access the Geant4 tracking manager. Only use between tracking pre- and post action G4TrackingManager* trackMgr() const { - return m_context->trackMgr(); + return m_context.trackMgr(); } /// Mark the track to be kept for MC truth propagation void mark(const G4Track* track) const; diff --git a/DDG4/plugins/Geant4Factories.cpp b/DDG4/plugins/Geant4Factories.cpp index f64104bfd..ae990432c 100644 --- a/DDG4/plugins/Geant4Factories.cpp +++ b/DDG4/plugins/Geant4Factories.cpp @@ -81,7 +81,7 @@ DECLARE_GEANT4ACTION(Geant4TestEventAction) DECLARE_GEANT4ACTION(Geant4TestStepAction) DECLARE_GEANT4ACTION(Geant4TestTrackAction) //DECLARE_GEANT4ACTION(Geant4TestStackingAction) -//DECLARE_GEANT4ACTION(Geant4TestGeneratorAction) +DECLARE_GEANT4ACTION(Geant4TestGeneratorAction) DECLARE_GEANT4SENSITIVE(Geant4TestSensitive) DECLARE_GEANT4SENSITIVE(Geant4TestSensitiveTracker) DECLARE_GEANT4SENSITIVE(Geant4TestSensitiveCalorimeter) diff --git a/DDG4/plugins/Geant4SensDet.cpp b/DDG4/plugins/Geant4SensDet.cpp index 0c5878f38..63fb17fbb 100644 --- a/DDG4/plugins/Geant4SensDet.cpp +++ b/DDG4/plugins/Geant4SensDet.cpp @@ -11,9 +11,12 @@ #include "DD4hep/InstanceCount.h" #include "DDG4/Geant4Kernel.h" +#include "DDG4/Geant4Context.h" #include "DDG4/Geant4HitCollection.h" #include "DDG4/Geant4SensDetAction.h" #include "G4VSensitiveDetector.hh" +#include "G4Event.hh" +#include "G4Run.hh" /* * DD4hep namespace declaration @@ -25,6 +28,8 @@ namespace DD4hep { */ namespace Simulation { + Geant4Context* ddg4_globalContext(); + template <typename T> struct RefCountedSequence { typedef RefCountedSequence<T> Base; T* m_sequence; @@ -53,7 +58,7 @@ namespace DD4hep { Geant4Action(0,nam), Geant4ActionSD(nam), Base() { Geant4Kernel& kernel = Geant4Kernel::access(lcdd); - setContext(kernel.context()); + m_context = Geant4Context(&kernel); m_outputLevel = kernel.getOutputLevel(nam); _aquire(kernel.sensitiveAction(nam)); m_sequence->defineCollections(this); @@ -84,11 +89,25 @@ namespace DD4hep { virtual G4bool Accept(const G4Step* step) const { return m_sequence->accept(step); } /// Method invoked at the begining of each event. - virtual void Initialize(G4HCofThisEvent* hce) - { m_sequence->begin(hce); } + virtual void Initialize(G4HCofThisEvent* hce) { + m_context.setRun(&ddg4_globalContext()->run()); + m_context.setEvent(&ddg4_globalContext()->event()); + (Geant4Action::ContextUpdate(&m_context))(m_sequence); + m_sequence->begin(hce); +#if 0 + const G4Event& evt = context()->event(); + error(name(), "%s> calling Initialize(event_id=%d Context: run=%p (%d) evt=%p (%d))", + GetName().c_str(), evt.GetEventID(), + &context()->run(), context()->run().run().GetRunID(), + &context()->event(), context()->event().event().GetEventID()); +#endif + } /// Method invoked at the end of each event. - virtual void EndOfEvent(G4HCofThisEvent* hce) - { m_sequence->end(hce); } + virtual void EndOfEvent(G4HCofThisEvent* hce) { + m_sequence->end(hce); + m_context.setEvent(0); + (Geant4Action::ContextUpdate(&m_context))(m_sequence); + } /// Method for generating hit(s) using the information of G4Step object. virtual G4bool ProcessHits(G4Step* step,G4TouchableHistory* hist) { return m_sequence->process(step,hist); } diff --git a/DDG4/plugins/Geant4SensDetFilters.cpp b/DDG4/plugins/Geant4SensDetFilters.cpp index 2fa2a4d96..9e85dd469 100644 --- a/DDG4/plugins/Geant4SensDetFilters.cpp +++ b/DDG4/plugins/Geant4SensDetFilters.cpp @@ -181,7 +181,8 @@ bool ParticleFilter::isGeantino(const G4Track* track) const { } /// Constructor. -GeantinoRejectFilter::GeantinoRejectFilter(Geant4Context* c, const std::string& n): ParticleFilter(c,n) { +GeantinoRejectFilter::GeantinoRejectFilter(Geant4Context* c, const std::string& n) +: ParticleFilter(c,n) { InstanceCount::increment(this); } @@ -196,7 +197,8 @@ bool GeantinoRejectFilter::operator()(const G4Step* step) const { } /// Constructor. -ParticleRejectFilter::ParticleRejectFilter(Geant4Context* c, const std::string& n): ParticleFilter(c,n) { +ParticleRejectFilter::ParticleRejectFilter(Geant4Context* c, const std::string& n) +: ParticleFilter(c,n) { InstanceCount::increment(this); } @@ -211,7 +213,8 @@ bool ParticleRejectFilter::operator()(const G4Step* step) const { } /// Constructor. -ParticleSelectFilter::ParticleSelectFilter(Geant4Context* c, const std::string& n) : ParticleFilter(c,n) { +ParticleSelectFilter::ParticleSelectFilter(Geant4Context* c, const std::string& n) + : ParticleFilter(c,n) { InstanceCount::increment(this); } @@ -226,7 +229,8 @@ bool ParticleSelectFilter::operator()(const G4Step* step) const { } /// Constructor. -EnergyDepositMinimumCut::EnergyDepositMinimumCut(Geant4Context* c, const std::string& n) : Geant4Filter(c,n) { +EnergyDepositMinimumCut::EnergyDepositMinimumCut(Geant4Context* c, const std::string& n) + : Geant4Filter(c,n) { InstanceCount::increment(this); declareProperty("Cut",m_energyCut=0.0); } diff --git a/DDG4/python/DD4hep.py b/DDG4/python/DD4hep.py index b270acacb..b586739e5 100644 --- a/DDG4/python/DD4hep.py +++ b/DDG4/python/DD4hep.py @@ -78,6 +78,8 @@ import_class('Core','NamedObject') import_class('Core','run_interpreter') def import_geometry(): + import_class('Core','setPrintLevel') + import_class('Core','printLevel') import_class('Geo','LCDD') import_class('Geo','VolumeManager') import_class('Geo','OverlayedField') diff --git a/DDG4/src/Geant4Action.cpp b/DDG4/src/Geant4Action.cpp index a8837abbf..5897c58fb 100644 --- a/DDG4/src/Geant4Action.cpp +++ b/DDG4/src/Geant4Action.cpp @@ -35,10 +35,25 @@ TypeName TypeName::split(const string& type_name) { return split(type_name,"/"); } +void Geant4Action::ContextUpdate::operator()(Geant4Action* action) const { + if ( context ) { + action->m_context.setRun(context->runPtr()); + action->m_context.setEvent(context->eventPtr()); + } +#if 0 + else { + action->m_context.setRun(0); + action->m_context.setEvent(0); + } +#endif +} + /// Standard constructor Geant4Action::Geant4Action(Geant4Context* context, const string& nam) - : m_context(context), m_control(0), m_outputLevel(INFO), m_needsControl(false), m_name(nam), m_refCount(1) { + : m_context(0), + m_control(0), m_outputLevel(INFO), m_needsControl(false), m_name(nam), m_refCount(1) { InstanceCount::increment(this); + if ( context ) m_context = *context; m_outputLevel = context ? context->kernel().getOutputLevel(nam) : (printLevel()-1); declareProperty("Name", m_name); declareProperty("name", m_name); @@ -69,11 +84,6 @@ long Geant4Action::release() { return count; } -/// Set the context pointer -void Geant4Action::setContext(Geant4Context* context) { - m_context = context; -} - /// Set the output level; returns previous value PrintLevel Geant4Action::setOutputLevel(PrintLevel new_level) { int old = m_outputLevel; @@ -161,6 +171,14 @@ void Geant4Action::debug(const string& fmt, ...) const { va_end(args); } +/// Support for messages with variable output level using output level +void Geant4Action::debug(const std::string& tag, const std::string& fmt, ...) const { + va_list args; + va_start(args, fmt); + DD4hep::printout(DD4hep::DEBUG, tag, fmt, args); + va_end(args); +} + /// Support of info messages. void Geant4Action::info(const string& fmt, ...) const { va_list args; @@ -169,6 +187,14 @@ void Geant4Action::info(const string& fmt, ...) const { va_end(args); } +/// Support for messages with variable output level using output level +void Geant4Action::info(const std::string& tag, const std::string& fmt, ...) const { + va_list args; + va_start(args, fmt); + DD4hep::printout(DD4hep::INFO, tag, fmt, args); + va_end(args); +} + /// Support of warning messages. void Geant4Action::warning(const string& fmt, ...) const { va_list args; @@ -177,6 +203,14 @@ void Geant4Action::warning(const string& fmt, ...) const { va_end(args); } +/// Support for messages with variable output level using output level +void Geant4Action::warning(const std::string& tag, const std::string& fmt, ...) const { + va_list args; + va_start(args, fmt); + DD4hep::printout(DD4hep::WARNING, tag, fmt, args); + va_end(args); +} + /// Action to support error messages. void Geant4Action::error(const string& fmt, ...) const { va_list args; @@ -185,6 +219,14 @@ void Geant4Action::error(const string& fmt, ...) const { va_end(args); } +/// Support for messages with variable output level using output level +void Geant4Action::error(const std::string& tag, const std::string& fmt, ...) const { + va_list args; + va_start(args, fmt); + DD4hep::printout(DD4hep::ERROR, tag, fmt, args); + va_end(args); +} + /// Action to support error messages. bool Geant4Action::error(bool return_value, const string& fmt, ...) const { va_list args; @@ -203,6 +245,14 @@ void Geant4Action::fatal(const string& fmt, ...) const { va_end(args); } +/// Support for messages with variable output level using output level +void Geant4Action::fatal(const std::string& tag, const std::string& fmt, ...) const { + va_list args; + va_start(args, fmt); + DD4hep::printout(DD4hep::FATAL, tag, fmt, args); + va_end(args); +} + /// Support of exceptions: Print fatal message and throw runtime_error. void Geant4Action::except(const string& fmt, ...) const { string err; @@ -214,6 +264,14 @@ void Geant4Action::except(const string& fmt, ...) const { throw runtime_error(err); } +/// Support for messages with variable output level using output level +void Geant4Action::except(const std::string& tag, const std::string& fmt, ...) const { + va_list args; + va_start(args, fmt); + DD4hep::printout(DD4hep::FATAL, tag, fmt, args); + va_end(args); +} + /// Abort Geant4 Run by throwing a G4Exception with type RunMustBeAborted void Geant4Action::abortRun(const string& exception, const string& fmt, ...) const { string desc, typ = typeName(typeid(*this)); @@ -228,41 +286,30 @@ void Geant4Action::abortRun(const string& exception, const string& fmt, ...) con /// Access to the main run action sequence from the kernel object Geant4RunActionSequence& Geant4Action::runAction() const { - return m_context->kernel().runAction(); + return m_context.kernel().runAction(); } /// Access to the main event action sequence from the kernel object Geant4EventActionSequence& Geant4Action::eventAction() const { - return m_context->kernel().eventAction(); + return m_context.kernel().eventAction(); } /// Access to the main stepping action sequence from the kernel object Geant4SteppingActionSequence& Geant4Action::steppingAction() const { - return m_context->kernel().steppingAction(); + return m_context.kernel().steppingAction(); } /// Access to the main tracking action sequence from the kernel object Geant4TrackingActionSequence& Geant4Action::trackingAction() const { - return m_context->kernel().trackingAction(); + return m_context.kernel().trackingAction(); } /// Access to the main stacking action sequence from the kernel object Geant4StackingActionSequence& Geant4Action::stackingAction() const { - return m_context->kernel().stackingAction(); + return m_context.kernel().stackingAction(); } /// Access to the main generator action sequence from the kernel object Geant4GeneratorActionSequence& Geant4Action::generatorAction() const { - return m_context->kernel().generatorAction(); + return m_context.kernel().generatorAction(); } - -/// Access to the Track Manager from the kernel object -Geant4MonteCarloTruth* Geant4Action::mcTruthMgr(bool throw_exception) const { - return m_context->kernel().mcTruthMgr(throw_exception); -} - -/// Access to the MC record manager from the kernel object -Geant4MonteCarloRecordManager* Geant4Action::mcRecordMgr(bool throw_exception) const { - return m_context->kernel().mcRecordMgr(throw_exception); -} - diff --git a/DDG4/src/Geant4Context.cpp b/DDG4/src/Geant4Context.cpp index f91f76433..a31d4b3ab 100644 --- a/DDG4/src/Geant4Context.cpp +++ b/DDG4/src/Geant4Context.cpp @@ -16,13 +16,64 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::Simulation; +/// Intializing constructor +Geant4Run::Geant4Run(const G4Run* run) +: ObjectExtensions(typeid(Geant4Run)), m_run(run) +{ + InstanceCount::increment(this); +} + +/// Default destructor +Geant4Run::~Geant4Run() { + InstanceCount::decrement(this); +} + +/// Intializing constructor +Geant4Event::Geant4Event(const G4Event* evt) +: ObjectExtensions(typeid(Geant4Event)), m_event(evt) +{ + InstanceCount::increment(this); +} + +/// Default destructor +Geant4Event::~Geant4Event() { + InstanceCount::decrement(this); +} + /// Default constructor Geant4Context::Geant4Context(Geant4Kernel* kernel) - : m_kernel(kernel) { + : m_kernel(kernel), m_run(0), m_event(0) { + InstanceCount::increment(this); } /// Default destructor Geant4Context::~Geant4Context() { + // Do not delete run and event structures here. This is done outside in the framework + InstanceCount::decrement(this); +} + +/// Set the geant4 run reference +void Geant4Context::setRun(Geant4Run* new_run) { + m_run = new_run; +} + +/// Access the geant4 run -- valid only between BeginRun() and EndRun()! +Geant4Run& Geant4Context::run() const { + if ( m_run ) return *m_run; + invalidHandleError<Geant4Run>(); + return *m_run; +} + +/// Set the geant4 event reference +void Geant4Context::setEvent(Geant4Event* new_event) { + m_event = new_event; +} + +/// Access the geant4 event -- valid only between BeginEvent() and EndEvent()! +Geant4Event& Geant4Context::event() const { + if ( m_event ) return *m_event; + invalidHandleError<Geant4Event>(); + return *m_event; } /// Access to detector description @@ -76,14 +127,3 @@ Geant4GeneratorActionSequence& Geant4Context::generatorAction() const { Geant4SensDetSequences& Geant4Context::sensitiveActions() const { return m_kernel->sensitiveActions(); } - -/// Access to the Track Manager from the kernel object -Geant4MonteCarloTruth& Geant4Context::mcTruthMgr() const { - return *m_kernel->mcTruthMgr(true); -} - -/// Access to the MC record manager from the kernel object -Geant4MonteCarloRecordManager& Geant4Context::mcRecordMgr() const { - return *m_kernel->mcRecordMgr(true); -} - diff --git a/DDG4/src/Geant4DetectorConstruction.cpp b/DDG4/src/Geant4DetectorConstruction.cpp index 4a7ae76ea..80d847ea6 100644 --- a/DDG4/src/Geant4DetectorConstruction.cpp +++ b/DDG4/src/Geant4DetectorConstruction.cpp @@ -45,6 +45,8 @@ G4VPhysicalVolume* DD4hep::Simulation::Geant4DetectorConstruction::Construct() { g4map.attach(info); m_world = info->world(); m_lcdd.apply("DD4hepVolumeManager", 0, 0); + // Create Geant4 volume manager + g4map.volumeManager(); //Geant4HierarchyDump dmp(m_lcdd); //dmp.dump("",m_world); #ifdef GEANT4_HAS_GDML diff --git a/DDG4/src/Geant4EventAction.cpp b/DDG4/src/Geant4EventAction.cpp index 006b9655b..bc9a7ce1d 100644 --- a/DDG4/src/Geant4EventAction.cpp +++ b/DDG4/src/Geant4EventAction.cpp @@ -13,10 +13,11 @@ // C/C++ include files #include <stdexcept> +using namespace std; using namespace DD4hep::Simulation; /// Standard constructor -Geant4EventAction::Geant4EventAction(Geant4Context* context, const std::string& nam) +Geant4EventAction::Geant4EventAction(Geant4Context* context, const string& nam) : Geant4Action(context, nam) { InstanceCount::increment(this); } @@ -35,7 +36,7 @@ void Geant4EventAction::end(const G4Event*) { } /// Standard constructor -Geant4EventActionSequence::Geant4EventActionSequence(Geant4Context* context, const std::string& name) +Geant4EventActionSequence::Geant4EventActionSequence(Geant4Context* context, const string& name) : Geant4Action(context, name) { m_needsControl = true; InstanceCount::increment(this); @@ -58,11 +59,12 @@ void Geant4EventActionSequence::adopt(Geant4EventAction* action) { m_actors.add(action); return; } - throw std::runtime_error("Geant4EventActionSequence: Attempt to add invalid actor!"); + throw runtime_error("Geant4EventActionSequence: Attempt to add invalid actor!"); } /// Pre-track action callback void Geant4EventActionSequence::begin(const G4Event* event) { + m_actors(ContextUpdate(context())); m_actors(&Geant4EventAction::begin, event); m_begin(event); } @@ -72,4 +74,5 @@ void Geant4EventActionSequence::end(const G4Event* event) { m_end(event); m_actors(&Geant4EventAction::end, event); m_final(event); + m_actors(ContextUpdate()); } diff --git a/DDG4/src/Geant4Exec.cpp b/DDG4/src/Geant4Exec.cpp index ecae73f3c..045c3d126 100644 --- a/DDG4/src/Geant4Exec.cpp +++ b/DDG4/src/Geant4Exec.cpp @@ -43,13 +43,24 @@ namespace DD4hep { * Simulation namespace declaration */ namespace Simulation { + + namespace { + Geant4Context* s_globalContext = 0; + } + + Geant4Context* ddg4_globalContext() { + return s_globalContext; + } + + template <typename T> struct SequenceHdl { typedef SequenceHdl<T> Base; T* m_sequence; + Geant4Context* m_activeContext; SequenceHdl() - : m_sequence(0) { + : m_sequence(0), m_activeContext(0) { } - SequenceHdl(T* seq) { + SequenceHdl(Geant4Context* context, T* seq) : m_sequence(0), m_activeContext(context) { _aquire(seq); } virtual ~SequenceHdl() { @@ -64,6 +75,41 @@ namespace DD4hep { releasePtr(m_sequence); InstanceCount::decrement(this); } + void setContextToClients() { + (Geant4Action::ContextUpdate(m_activeContext))(m_sequence); + } + void releaseContextFromClients() { + Geant4Action::ContextUpdate(0)(m_sequence); + } + void releaseContextFromClients2() { + Geant4Action::ContextUpdate(0)(m_sequence); + } + void createClientContext(const G4Run* run) { + Geant4Run* r = new Geant4Run(run); + m_activeContext->setRun(r); + setContextToClients(); + } + void destroyClientContext(const G4Run*) { + Geant4Run* r = m_activeContext->runPtr(); + releaseContextFromClients(); + if ( r ) { + m_activeContext->setRun(0); + deletePtr(r); + } + } + void createClientContext(const G4Event* evt) { + Geant4Event* e = new Geant4Event(evt); + m_activeContext->setEvent(e); + setContextToClients(); + } + void destroyClientContext(const G4Event*) { + Geant4Event* e = m_activeContext->eventPtr(); + releaseContextFromClients(); + if ( e ) { + m_activeContext->setEvent(0); + deletePtr(e); + } + } }; /** @class Geant4UserRunAction @@ -75,19 +121,21 @@ namespace DD4hep { */ struct Geant4UserRunAction : public G4UserRunAction, public SequenceHdl<Geant4RunActionSequence> { /// Standard constructor - Geant4UserRunAction(Geant4RunActionSequence* seq) - : Base(seq) { + Geant4UserRunAction(Geant4Context* context, Geant4RunActionSequence* seq) + : Base(context, seq) { } /// Default destructor virtual ~Geant4UserRunAction() { } /// begin-of-run callback virtual void BeginOfRunAction(const G4Run* run) { + createClientContext(run); m_sequence->begin(run); } /// End-of-run callback virtual void EndOfRunAction(const G4Run* run) { m_sequence->end(run); + destroyClientContext(run); } }; @@ -100,19 +148,21 @@ namespace DD4hep { */ struct Geant4UserEventAction : public G4UserEventAction, public SequenceHdl<Geant4EventActionSequence> { /// Standard constructor - Geant4UserEventAction(Geant4EventActionSequence* seq) - : Base(seq) { + Geant4UserEventAction(Geant4Context* context, Geant4EventActionSequence* seq) + : Base(context, seq) { } /// Default destructor virtual ~Geant4UserEventAction() { } /// begin-of-event callback virtual void BeginOfEventAction(const G4Event* evt) { + setContextToClients(); m_sequence->begin(evt); } /// End-of-event callback virtual void EndOfEventAction(const G4Event* evt) { m_sequence->end(evt); + destroyClientContext(evt); } }; @@ -125,14 +175,15 @@ namespace DD4hep { */ struct Geant4UserTrackingAction : public G4UserTrackingAction, public SequenceHdl<Geant4TrackingActionSequence> { /// Standard constructor - Geant4UserTrackingAction(Geant4TrackingActionSequence* seq) - : Base(seq) { + Geant4UserTrackingAction(Geant4Context* context, Geant4TrackingActionSequence* seq) + : Base(context, seq) { } /// Default destructor virtual ~Geant4UserTrackingAction() { } /// Pre-track action callback virtual void PreUserTrackingAction(const G4Track* trk) { + setContextToClients(); m_sequence->context()->kernel().setTrackMgr(fpTrackingManager); m_sequence->begin(trk); } @@ -140,6 +191,7 @@ namespace DD4hep { virtual void PostUserTrackingAction(const G4Track* trk) { m_sequence->end(trk); m_sequence->context()->kernel().setTrackMgr(0); + releaseContextFromClients2(); //Let's leave this out for now...Frank has dirty tricks. } }; @@ -152,19 +204,23 @@ namespace DD4hep { */ struct Geant4UserStackingAction : public G4UserStackingAction, public SequenceHdl<Geant4StackingActionSequence> { /// Standard constructor - Geant4UserStackingAction(Geant4StackingActionSequence* seq) - : Base(seq) { + Geant4UserStackingAction(Geant4Context* context, Geant4StackingActionSequence* seq) + : Base(context, seq) { } /// Default destructor virtual ~Geant4UserStackingAction() { } /// New-stage callback virtual void NewStage() { + setContextToClients(); m_sequence->newStage(); + releaseContextFromClients2(); //Let's leave this out for now...Frank has dirty tricks. } /// Preparation callback virtual void PrepareNewEvent() { + setContextToClients(); m_sequence->prepare(); + releaseContextFromClients2(); //Let's leave this out for now...Frank has dirty tricks. } }; @@ -177,15 +233,17 @@ namespace DD4hep { */ struct Geant4UserGeneratorAction : public G4VUserPrimaryGeneratorAction, public SequenceHdl<Geant4GeneratorActionSequence> { /// Standard constructor - Geant4UserGeneratorAction(Geant4GeneratorActionSequence* seq) - : G4VUserPrimaryGeneratorAction(), Base(seq) { + Geant4UserGeneratorAction(Geant4Context* context, Geant4GeneratorActionSequence* seq) + : G4VUserPrimaryGeneratorAction(), Base(context, seq) { } /// Default destructor virtual ~Geant4UserGeneratorAction() { } /// Generate primary particles virtual void GeneratePrimaries(G4Event* event) { + createClientContext(event); (*m_sequence)(event); + releaseContextFromClients2(); //Let's leave this out for now...Frank has dirty tricks. } }; @@ -198,15 +256,17 @@ namespace DD4hep { */ struct Geant4UserSteppingAction : public G4UserSteppingAction, public SequenceHdl<Geant4SteppingActionSequence> { /// Standard constructor - Geant4UserSteppingAction(Geant4SteppingActionSequence* seq) - : Base(seq) { + Geant4UserSteppingAction(Geant4Context* context, Geant4SteppingActionSequence* seq) + : Base(context, seq) { } /// Default destructor virtual ~Geant4UserSteppingAction() { } /// User stepping callback virtual void UserSteppingAction(const G4Step* s) { + setContextToClients(); (*m_sequence)(s, fpSteppingManager); + releaseContextFromClients2(); //Let's leave this out for now...Frank has dirty tricks. } }; @@ -230,6 +290,7 @@ using namespace DD4hep::Simulation; int Geant4Exec::configure(Geant4Kernel& kernel) { CLHEP::HepRandom::setTheEngine(new CLHEP::RanecuEngine); Geometry::LCDD& lcdd = kernel.lcdd(); + Geant4Context* ctx = s_globalContext = new Geant4Context(&kernel); // Construct the default run manager G4RunManager& runManager = kernel.runManager(); @@ -259,35 +320,34 @@ int Geant4Exec::configure(Geant4Kernel& kernel) { throw runtime_error("Panic! No valid user physics list present!"); } runManager.SetUserInitialization(physics); + // Set user generator action sequence. Not optional, since event context is defined inside + Geant4UserGeneratorAction* gen_action = + new Geant4UserGeneratorAction(ctx,kernel.generatorAction(false)); + runManager.SetUserAction(gen_action); + + // Set the run action sequence. Not optional, since run context is defined/destroyed inside + Geant4UserRunAction* run_action = + new Geant4UserRunAction(ctx,kernel.runAction(false)); + runManager.SetUserAction(run_action); + + // Set the event action sequence. Not optional, since event context is destroyed inside + Geant4UserEventAction* evt_action = + new Geant4UserEventAction(ctx,kernel.eventAction(false)); + runManager.SetUserAction(evt_action); - // Set user generator action sequence - if (kernel.generatorAction(false)) { - Geant4UserGeneratorAction* action = new Geant4UserGeneratorAction(kernel.generatorAction(false)); - runManager.SetUserAction(action); - } - // Set the run action sequence - if (kernel.runAction(false)) { - Geant4UserRunAction* action = new Geant4UserRunAction(kernel.runAction(false)); - runManager.SetUserAction(action); - } - // Set the event action sequence - if (kernel.eventAction(false)) { - Geant4UserEventAction* action = new Geant4UserEventAction(kernel.eventAction(false)); - runManager.SetUserAction(action); - } // Set the tracking action sequence if (kernel.trackingAction(false)) { - Geant4UserTrackingAction* action = new Geant4UserTrackingAction(kernel.trackingAction(false)); + Geant4UserTrackingAction* action = new Geant4UserTrackingAction(ctx,kernel.trackingAction(false)); runManager.SetUserAction(action); } // Set the stepping action sequence if (kernel.steppingAction(false)) { - Geant4UserSteppingAction* action = new Geant4UserSteppingAction(kernel.steppingAction(false)); + Geant4UserSteppingAction* action = new Geant4UserSteppingAction(ctx,kernel.steppingAction(false)); runManager.SetUserAction(action); } // Set the stacking action sequence if (kernel.stackingAction(false)) { - Geant4UserStackingAction* action = new Geant4UserStackingAction(kernel.stackingAction(false)); + Geant4UserStackingAction* action = new Geant4UserStackingAction(ctx,kernel.stackingAction(false)); runManager.SetUserAction(action); } return 1; @@ -327,5 +387,6 @@ int Geant4Exec::run(Geant4Kernel& kernel) { /// Run the simulation int Geant4Exec::terminate(Geant4Kernel&) { + deletePtr(s_globalContext); return 1; } diff --git a/DDG4/src/Geant4GeneratorAction.cpp b/DDG4/src/Geant4GeneratorAction.cpp index 6394dfbf2..e7bf85344 100644 --- a/DDG4/src/Geant4GeneratorAction.cpp +++ b/DDG4/src/Geant4GeneratorAction.cpp @@ -53,6 +53,8 @@ void Geant4GeneratorActionSequence::adopt(Geant4GeneratorAction* action) { /// Generator callback void Geant4GeneratorActionSequence::operator()(G4Event* event) { + m_actors(ContextUpdate(context())); m_actors(&Geant4GeneratorAction::operator(), event); m_calls(event); + m_actors(ContextUpdate(0)); } diff --git a/DDG4/src/Geant4Handle.cpp b/DDG4/src/Geant4Handle.cpp index a4baccf78..771e55a80 100644 --- a/DDG4/src/Geant4Handle.cpp +++ b/DDG4/src/Geant4Handle.cpp @@ -56,22 +56,22 @@ template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(const Geant4Handle<TYP value->addRef(); } -template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(const Geant4Kernel& kernel, const string& type_name) +template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(Geant4Kernel& kernel, const string& type_name) : value(0) { TypeName typ = TypeName::split(type_name); - Geant4Context* ctxt = kernel.context(); - Geant4Action* object = PluginService::Create<Geant4Action*>(typ.first, ctxt, typ.second); + Geant4Context ctxt(&kernel); + Geant4Action* object = PluginService::Create<Geant4Action*>(typ.first, &ctxt, typ.second); if (!object && typ.first == typ.second) { typ.first = typeName(typeid(TYPE)); printout(DEBUG, "Geant4Handle<Geant4Sensitive>", "Object factory for %s not found. Try out %s", typ.second.c_str(), - typ.first.c_str()); - object = PluginService::Create<Geant4Action*>(typ.first, ctxt, typ.second); + typ.first.c_str()); + object = PluginService::Create<Geant4Action*>(typ.first, &ctxt, typ.second); if (!object) { size_t idx = typ.first.rfind(':'); if (idx != string::npos) typ.first = string(typ.first.substr(idx + 1)); printout(DEBUG, "Geant4Handle<Geant4Sensitive>", "Try out object factory for %s", typ.first.c_str()); - object = PluginService::Create<Geant4Action*>(typ.first, ctxt, typ.second); + object = PluginService::Create<Geant4Action*>(typ.first, &ctxt, typ.second); } } if (object) { @@ -87,23 +87,23 @@ template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(const Geant4Kernel& ke throw runtime_error(format("Geant4Handle", "Failed to create object of type %s!", type_name.c_str())); } -template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(const Geant4Kernel& kernel, const char* type_name_char) +template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(Geant4Kernel& kernel, const char* type_name_char) : value(0) { string type_name = type_name_char; TypeName typ = TypeName::split(type_name); - Geant4Context* ctxt = kernel.context(); - Geant4Action* object = PluginService::Create<Geant4Action*>(typ.first, ctxt, typ.second); + Geant4Context ctxt(&kernel); + Geant4Action* object = PluginService::Create<Geant4Action*>(typ.first, &ctxt, typ.second); if (!object && typ.first == typ.second) { typ.first = typeName(typeid(TYPE)); printout(DEBUG, "Geant4Handle<Geant4Sensitive>", "Object factory for %s not found. Try out %s", typ.second.c_str(), typ.first.c_str()); - object = PluginService::Create<Geant4Action*>(typ.first, ctxt, typ.second); + object = PluginService::Create<Geant4Action*>(typ.first, &ctxt, typ.second); if (!object) { size_t idx = typ.first.rfind(':'); if (idx != string::npos) typ.first = string(typ.first.substr(idx + 1)); printout(DEBUG, "Geant4Handle<Geant4Sensitive>", "Try out object factory for %s", typ.first.c_str()); - object = PluginService::Create<Geant4Action*>(typ.first, ctxt, typ.second); + object = PluginService::Create<Geant4Action*>(typ.first, &ctxt, typ.second); } } if (object) { @@ -193,14 +193,14 @@ namespace DD4hep { value = 0; } - template <> Geant4Handle<Geant4Sensitive>::Geant4Handle(const Geant4Kernel& kernel, const string& type_name, + template <> Geant4Handle<Geant4Sensitive>::Geant4Handle(Geant4Kernel& kernel, const string& type_name, const string& detector) { try { - Geant4Context* ctxt = kernel.context(); + Geant4Context ctxt(&kernel); TypeName typ = TypeName::split(type_name); Geometry::LCDD& lcdd = kernel.lcdd(); Geometry::DetElement det = lcdd.detector(detector); - Geant4Sensitive* object = PluginService::Create<Geant4Sensitive*>(typ.first, ctxt, typ.second, &det, &lcdd); + Geant4Sensitive* object = PluginService::Create<Geant4Sensitive*>(typ.first, &ctxt, typ.second, &det, &lcdd); if (object) { value = object; return; diff --git a/DDG4/src/Geant4Kernel.cpp b/DDG4/src/Geant4Kernel.cpp index 5cf0bb546..28335656f 100644 --- a/DDG4/src/Geant4Kernel.cpp +++ b/DDG4/src/Geant4Kernel.cpp @@ -67,7 +67,7 @@ Geant4ActionPhase& Geant4Kernel::PhaseSelector::operator[](const std::string& na /// Standard constructor Geant4Kernel::Geant4Kernel(LCDD& lcdd) - : m_context(0), m_runManager(0), m_generatorAction(0), m_runAction(0), m_eventAction(0), + : m_runManager(0), m_generatorAction(0), m_runAction(0), m_eventAction(0), m_trackingAction(0), m_steppingAction(0), m_stackingAction(0), m_sensDetActions(0), m_physicsList(0), m_mcTruthMgr(0), m_mcRecordMgr(0), m_lcdd(lcdd), phase(this) { @@ -80,7 +80,6 @@ Geant4Kernel::Geant4Kernel(LCDD& lcdd) registerSequence(m_generatorAction,"GeneratorAction"); #endif m_sensDetActions = new Geant4SensDetSequences(); - m_context = new Geant4Context(this); m_lcdd.addExtension < Geant4Kernel > (this); declareProperty("UI",m_uiName); declareProperty("OutputLevel",m_outputLevel = DEBUG); @@ -110,7 +109,6 @@ Geant4Kernel::~Geant4Kernel() { releasePtr (m_generatorAction); releasePtr (m_runAction); deletePtr (m_sensDetActions); - deletePtr (m_context); m_lcdd.removeExtension < Geant4Kernel > (false); m_lcdd.destroyInstance(); InstanceCount::decrement(this); @@ -224,13 +222,13 @@ void Geant4Kernel::terminate() { releasePtr (m_generatorAction); releasePtr (m_runAction); deletePtr (m_sensDetActions); - deletePtr (m_context); //return *this; } template <class C> bool Geant4Kernel::registerSequence(C*& seq, const std::string& name) { if (!name.empty()) { - seq = new C(m_context, name); + Geant4Context ctxt(this); + seq = new C(&ctxt, name); seq->installMessengers(); return true; } @@ -322,7 +320,8 @@ Geant4ActionPhase* Geant4Kernel::addPhase(const std::string& nam, const type_inf const type_info& arg2, bool throw_on_exist) { Phases::const_iterator i = m_phases.find(nam); if (i == m_phases.end()) { - Geant4ActionPhase* p = new Geant4ActionPhase(m_context, nam, arg0, arg1, arg2); + Geant4Context ctxt(this); + Geant4ActionPhase* p = new Geant4ActionPhase(&ctxt, nam, arg0, arg1, arg2); m_phases.insert(make_pair(nam, p)); return p; } @@ -397,11 +396,12 @@ Geant4SensDetSequences& Geant4Kernel::sensitiveActions() const { } /// Access to the sensitive detector action from the kernel object -Geant4SensDetActionSequence* Geant4Kernel::sensitiveAction(const string& nam) const { +Geant4SensDetActionSequence* Geant4Kernel::sensitiveAction(const string& nam) { Geant4SensDetActionSequence* ptr = m_sensDetActions->find(nam); if (ptr) return ptr; - ptr = new Geant4SensDetActionSequence(context(), nam); + Geant4Context ctxt(this); + ptr = new Geant4SensDetActionSequence(&ctxt, nam); m_sensDetActions->insert(nam, ptr); return ptr; } @@ -413,6 +413,7 @@ Geant4PhysicsListActionSequence* Geant4Kernel::physicsList(bool create) { return m_physicsList; } +#if 0 /// Access to the Track Manager from the kernel object Geant4MonteCarloTruth* Geant4Kernel::mcTruthMgr(bool throw_exception) { if ( m_mcTruthMgr ) return m_mcTruthMgr; @@ -442,4 +443,4 @@ Geant4MonteCarloRecordManager* Geant4Kernel::mcRecordMgr(bool throw_exception) throw runtime_error(format("Geant4Kernel", "DDG4: No MonteCarloRecordManager defined. " "Geant4 tracks cannot be saved!")); } - +#endif diff --git a/DDG4/src/Geant4MonteCarloRecordManager.cpp b/DDG4/src/Geant4MonteCarloRecordManager.cpp index a98a613e4..8ddb6023d 100644 --- a/DDG4/src/Geant4MonteCarloRecordManager.cpp +++ b/DDG4/src/Geant4MonteCarloRecordManager.cpp @@ -21,7 +21,7 @@ using namespace DD4hep::Simulation; /// Standard constructor Geant4MonteCarloRecordManager::Geant4MonteCarloRecordManager(Geant4Context* context, const std::string& nam) - : Geant4Action(context,nam) + : Geant4GeneratorAction(context,nam) { declareProperty("Collect",m_collectInfo=true); } @@ -30,6 +30,12 @@ Geant4MonteCarloRecordManager::Geant4MonteCarloRecordManager(Geant4Context* cont Geant4MonteCarloRecordManager::~Geant4MonteCarloRecordManager() { } +/// Event generation action callback +void Geant4MonteCarloRecordManager::operator()(G4Event* ) { + printout(INFO,name(),"+++ Add EVENT extension of type Geant4MonteCarloRecordManager....."); + context()->event().addExtension(this, typeid(*this),0); +} + /// Save G4Track data void Geant4MonteCarloRecordManager::save(const Geant4TrackPersistency::TrackInfo& trk) { if ( m_collectInfo ) { diff --git a/DDG4/src/Geant4OutputAction.cpp b/DDG4/src/Geant4OutputAction.cpp index fbba4ea29..e0c2d1acc 100644 --- a/DDG4/src/Geant4OutputAction.cpp +++ b/DDG4/src/Geant4OutputAction.cpp @@ -23,7 +23,8 @@ using namespace std; /// Standard constructor Geant4OutputAction::Geant4OutputAction(Geant4Context* ctxt, const string& nam) - : Geant4EventAction(ctxt, nam) { + : Geant4EventAction(ctxt, nam) +{ InstanceCount::increment(this); declareProperty("Output", m_output); context()->runAction().callAtBegin(this, &Geant4OutputAction::beginRun); diff --git a/DDG4/src/Geant4RunAction.cpp b/DDG4/src/Geant4RunAction.cpp index 638869a1d..304ad9791 100644 --- a/DDG4/src/Geant4RunAction.cpp +++ b/DDG4/src/Geant4RunAction.cpp @@ -62,6 +62,7 @@ void Geant4RunActionSequence::adopt(Geant4RunAction* action) { /// Pre-track action callback void Geant4RunActionSequence::begin(const G4Run* run) { + m_actors(ContextUpdate(context())); m_actors(&Geant4RunAction::begin, run); m_begin(run); } @@ -70,4 +71,5 @@ void Geant4RunActionSequence::begin(const G4Run* run) { void Geant4RunActionSequence::end(const G4Run* run) { m_end(run); m_actors(&Geant4RunAction::end, run); + m_actors(ContextUpdate()); } diff --git a/DDG4/src/Geant4SensDetAction.cpp b/DDG4/src/Geant4SensDetAction.cpp index 9a98f9a31..f314f8a36 100644 --- a/DDG4/src/Geant4SensDetAction.cpp +++ b/DDG4/src/Geant4SensDetAction.cpp @@ -172,13 +172,13 @@ void Geant4Sensitive::clear(G4HCofThisEvent* /* HCE */) { /// Mark the track to be kept for MC truth propagation during hit processing void Geant4Sensitive::mark(const G4Track* track) const { - Geant4MonteCarloTruth* truth = mcTruthMgr(false); + Geant4MonteCarloTruth* truth = context()->event().extension<Geant4MonteCarloTruth>(false); if ( truth ) truth->mark(track,true); } /// Mark the track of this step to be kept for MC truth propagation during hit processing void Geant4Sensitive::mark(const G4Step* step) const { - Geant4MonteCarloTruth* truth = mcTruthMgr(false); + Geant4MonteCarloTruth* truth = context()->event().extension<Geant4MonteCarloTruth>(false); if ( truth ) truth->mark(step); } @@ -310,6 +310,7 @@ bool Geant4SensDetActionSequence::process(G4Step* step, G4TouchableHistory* hist */ void Geant4SensDetActionSequence::begin(G4HCofThisEvent* hce) { m_hce = hce; + m_actors(ContextUpdate(context())); for (size_t count = 0; count < m_collections.size(); ++count) { const std::pair<string, create_t>& cr = m_collections[count]; G4VHitsCollection* c = (*cr.second)(name(), cr.first); @@ -324,6 +325,7 @@ void Geant4SensDetActionSequence::begin(G4HCofThisEvent* hce) { void Geant4SensDetActionSequence::end(G4HCofThisEvent* hce) { m_end(hce); m_actors(&Geant4Sensitive::end, hce); + m_actors(ContextUpdate()); m_hce = 0; } diff --git a/DDG4/src/Geant4StackingAction.cpp b/DDG4/src/Geant4StackingAction.cpp index 1fec7d5eb..a4a840747 100644 --- a/DDG4/src/Geant4StackingAction.cpp +++ b/DDG4/src/Geant4StackingAction.cpp @@ -55,6 +55,7 @@ void Geant4StackingActionSequence::adopt(Geant4StackingAction* action) { /// Pre-track action callback void Geant4StackingActionSequence::newStage() { + m_actors(ContextUpdate(context())); m_actors(&Geant4StackingAction::newStage); m_newStage(); } @@ -63,4 +64,5 @@ void Geant4StackingActionSequence::newStage() { void Geant4StackingActionSequence::prepare() { m_actors(&Geant4StackingAction::prepare); m_prepare(); + m_actors(ContextUpdate()); } diff --git a/DDG4/src/Geant4SteppingAction.cpp b/DDG4/src/Geant4SteppingAction.cpp index edda14117..3fa5128b0 100644 --- a/DDG4/src/Geant4SteppingAction.cpp +++ b/DDG4/src/Geant4SteppingAction.cpp @@ -44,8 +44,10 @@ Geant4SteppingActionSequence::~Geant4SteppingActionSequence() { /// Pre-track action callback void Geant4SteppingActionSequence::operator()(const G4Step* step, G4SteppingManager* mgr) { + m_actors(ContextUpdate(context())); m_actors(&Geant4SteppingAction::operator(), step, mgr); m_calls(step, mgr); + m_actors(ContextUpdate()); } /// Add an actor responding to all callbacks. Sequence takes ownership. diff --git a/DDG4/src/Geant4TestActions.cpp b/DDG4/src/Geant4TestActions.cpp index c1853e4b5..87dd0200c 100644 --- a/DDG4/src/Geant4TestActions.cpp +++ b/DDG4/src/Geant4TestActions.cpp @@ -32,6 +32,9 @@ namespace { }; } +#define PRINT info + + /// Standard constructor Geant4TestBase::Geant4TestBase(Geant4Action* a, const std::string& typ) : m_type(typ) { @@ -45,102 +48,148 @@ Geant4TestBase::~Geant4TestBase() { InstanceCount::decrement(this); } +/// Standard constructor with initializing arguments +Geant4TestGeneratorAction::Geant4TestGeneratorAction(Geant4Context* c, const std::string& n) + : Geant4GeneratorAction(c, n), Geant4TestBase(this, "Geant4TestGeneratorAction") { + InstanceCount::increment(this); +} + +/// Default destructor +Geant4TestGeneratorAction::~Geant4TestGeneratorAction() { + InstanceCount::decrement(this); +} + +/// Callback to generate primary particles +void Geant4TestGeneratorAction::operator()(G4Event* evt) { + PRINT(name(), "%s> calling Geant4TestGeneratorAction(event_id=%d Context: run=%p evt=%p)", + m_type.c_str(), evt->GetEventID(), &context()->run(), &context()->event()); +} + +/// Standard constructor with initializing arguments Geant4TestRunAction::Geant4TestRunAction(Geant4Context* c, const std::string& n) - : Geant4RunAction(c, n), Geant4TestBase(this, "Geant4TestRunAction") { + : Geant4RunAction(c, n), Geant4TestBase(this, "Geant4TestRunAction") { InstanceCount::increment(this); } + +/// Default destructor Geant4TestRunAction::~Geant4TestRunAction() { InstanceCount::decrement(this); } + /// begin-of-run callback void Geant4TestRunAction::begin(const G4Run* run) { - print(name(), "%s> calling begin(run_id=%d,num_event=%d)", m_type.c_str(), run->GetRunID(), - run->GetNumberOfEventToBeProcessed()); + PRINT(name(), "%s> calling begin(run_id=%d,num_event=%d Context:%p)", m_type.c_str(), run->GetRunID(), + run->GetNumberOfEventToBeProcessed(), &context()->run()); } + /// End-of-run callback void Geant4TestRunAction::end(const G4Run* run) { - print(name(), "%s> calling end(run_id=%d, num_event=%d)", - m_type.c_str(), run->GetRunID(), run->GetNumberOfEvent()); + PRINT(name(), "%s> calling end(run_id=%d, num_event=%d Context:%p)", + m_type.c_str(), run->GetRunID(), run->GetNumberOfEvent(), &context()->run()); } + /// begin-of-event callback void Geant4TestRunAction::beginEvent(const G4Event* evt) { - print(name(), "%s> calling beginEvent(event_id=%d)", m_type.c_str(), evt->GetEventID()); + PRINT(name(), "%s> calling beginEvent(event_id=%d Context: run=%p evt=%p)", + m_type.c_str(), evt->GetEventID(), &context()->run(), &context()->event()); } + /// End-of-event callback void Geant4TestRunAction::endEvent(const G4Event* evt) { - print(name(), "%s> calling endEvent(event_id=%d)", m_type.c_str(), evt->GetEventID()); + PRINT(name(), "%s> calling endEvent(event_id=%d Context: run=%p evt=%p)", + m_type.c_str(), evt->GetEventID(), &context()->run(), &context()->event()); } +/// Standard constructor with initializing arguments Geant4TestEventAction::Geant4TestEventAction(Geant4Context* c, const std::string& n) : Geant4EventAction(c, n), Geant4TestBase(this, "Geant4TestEventAction") { InstanceCount::increment(this); } + +/// Default destructor Geant4TestEventAction::~Geant4TestEventAction() { InstanceCount::decrement(this); } /// begin-of-event callback void Geant4TestEventAction::begin(const G4Event* evt) { - print(name(), "%s> calling begin(event_id=%d)", m_type.c_str(), evt->GetEventID()); + PRINT(name(), "%s> calling begin(event_id=%d Context: run=%p (%d) evt=%p (%d))", + m_type.c_str(), evt->GetEventID(), + &context()->run(), context()->run().run().GetRunID(), + &context()->event(), context()->event().event().GetEventID()); } /// End-of-event callback void Geant4TestEventAction::end(const G4Event* evt) { - print(name(), "%s> calling end(event_id=%d)", m_type.c_str(), evt->GetEventID()); + PRINT(name(), "%s> calling end(event_id=%d Context: run=%p (%d) evt=%p (%d))", + m_type.c_str(), evt->GetEventID(), &context()->run(), &context()->event(), + &context()->run(), context()->run().run().GetRunID(), + &context()->event(), context()->event().event().GetEventID()); } /// begin-of-run callback void Geant4TestEventAction::beginRun(const G4Run* run) { - print(name(), "%s> calling beginRun(run_id=%d,num_event=%d)", + PRINT(name(), "%s> calling beginRun(run_id=%d,num_event=%d Context:%p)", m_type.c_str(), run->GetRunID(), - run->GetNumberOfEventToBeProcessed()); + run->GetNumberOfEventToBeProcessed(), &context()->run()); } /// End-of-run callback void Geant4TestEventAction::endRun(const G4Run* run) { - print(name(), "%s> calling endRun(run_id=%d, num_event=%d)", + PRINT(name(), "%s> calling endRun(run_id=%d, num_event=%d Context:%p)", m_type.c_str(), run->GetRunID(), - run->GetNumberOfEvent()); + run->GetNumberOfEvent(), &context()->run()); } +/// Standard constructor with initializing arguments Geant4TestTrackAction::Geant4TestTrackAction(Geant4Context* c, const std::string& n) : Geant4TrackingAction(c, n), Geant4TestBase(this, "Geant4TestTrackAction") { InstanceCount::increment(this); } + +/// Default destructor Geant4TestTrackAction::~Geant4TestTrackAction() { InstanceCount::decrement(this); } /// Begin-of-tracking callback void Geant4TestTrackAction::begin(const G4Track* trk) { - print(name(), "%s> calling begin(track=%d, parent=%d, position=(%f,%f,%f))", - m_type.c_str(), trk->GetTrackID(), - trk->GetParentID(), trk->GetPosition().x(), trk->GetPosition().y(), trk->GetPosition().z()); + PRINT(name(), "%s> calling begin(track=%d, parent=%d, position=(%f,%f,%f) Context: run=%p evt=%p)", + m_type.c_str(), trk->GetTrackID(), + trk->GetParentID(), trk->GetPosition().x(), trk->GetPosition().y(), trk->GetPosition().z(), + &context()->run(), &context()->event()); } /// End-of-tracking callback void Geant4TestTrackAction::end(const G4Track* trk) { - print(name(), "%s> calling end(track=%d, parent=%d, position=(%f,%f,%f))", - m_type.c_str(), trk->GetTrackID(), - trk->GetParentID(), trk->GetPosition().x(), trk->GetPosition().y(), trk->GetPosition().z()); + PRINT(name(), "%s> calling end(track=%d, parent=%d, position=(%f,%f,%f) Context: run=%p evt=%p)", + m_type.c_str(), trk->GetTrackID(), + trk->GetParentID(), trk->GetPosition().x(), trk->GetPosition().y(), trk->GetPosition().z(), + &context()->run(), &context()->event()); } +/// Standard constructor with initializing arguments Geant4TestStepAction::Geant4TestStepAction(Geant4Context* c, const std::string& n) : Geant4SteppingAction(c, n), Geant4TestBase(this, "Geant4TestStepAction") { InstanceCount::increment(this); } + +/// Default destructor Geant4TestStepAction::~Geant4TestStepAction() { InstanceCount::decrement(this); } /// User stepping callback void Geant4TestStepAction::operator()(const G4Step*, G4SteppingManager*) { - print(name(), "%s> calling operator()", m_type.c_str()); + PRINT(name(), "%s> calling operator()", m_type.c_str()); } +/// Standard constructor with initializing arguments Geant4TestSensitive::Geant4TestSensitive(Geant4Context* c, const std::string& n, DetElement det, LCDD& lcdd) : Geant4Sensitive(c, n, det, lcdd), Geant4TestBase(this, "Geant4TestSensitive") { InstanceCount::increment(this); m_collectionID = defineCollection < TestHit > (n); - print(name(), "%s> Collection ID is %d", m_type.c_str(), int(m_collectionID)); + PRINT(name(), "%s> Collection ID is %d", m_type.c_str(), int(m_collectionID)); } + +/// Default destructor Geant4TestSensitive::~Geant4TestSensitive() { InstanceCount::decrement(this); } @@ -148,27 +197,27 @@ Geant4TestSensitive::~Geant4TestSensitive() { /// Begin-of-tracking callback void Geant4TestSensitive::begin(G4HCofThisEvent* hce) { Geant4HitCollection* c = collectionByID(m_collectionID); - print(name(), "%s> calling begin(num_coll=%d, coll=%s)", + PRINT(name(), "%s> calling begin(num_coll=%d, coll=%s Context: run=%p evt=%p)", m_type.c_str(), hce->GetNumberOfCollections(), - c ? c->GetName().c_str() : "None"); + c ? c->GetName().c_str() : "None", &context()->run(), &context()->event()); } /// End-of-tracking callback void Geant4TestSensitive::end(G4HCofThisEvent* hce) { Geant4HitCollection* c = collection(m_collectionID); - print(name(), "%s> calling end(num_coll=%d, coll=%s)", + PRINT(name(), "%s> calling end(num_coll=%d, coll=%s Context: run=%p evt=%p)", m_type.c_str(), hce->GetNumberOfCollections(), - c ? c->GetName().c_str() : "None"); + c ? c->GetName().c_str() : "None", &context()->run(), &context()->event()); } /// Method for generating hit(s) using the information of G4Step object. bool Geant4TestSensitive::process(G4Step* step, G4TouchableHistory*) { Geant4HitCollection* c = collection(m_collectionID); - print(name(), "%s> calling process(track=%d, dE=%f, dT=%f len=%f, First,last in Vol=(%c,%c), coll=%s)", + PRINT(name(), "%s> calling process(track=%d, dE=%f, dT=%f len=%f, First,last in Vol=(%c,%c), coll=%s Context: run=%p evt=%p)", m_type.c_str(), step->GetTrack()->GetTrackID(), step->GetTotalEnergyDeposit(), step->GetDeltaTime(), step->GetStepLength(), step->IsFirstStepInVolume() ? 'Y' : 'N', step->IsLastStepInVolume() ? 'Y' : 'N', - c ? c->GetName().c_str() : "None"); + c ? c->GetName().c_str() : "None", &context()->run(), &context()->event()); return true; } diff --git a/DDG4/src/Geant4TrackPersistency.cpp b/DDG4/src/Geant4TrackPersistency.cpp index e5adf0256..01692ab8b 100644 --- a/DDG4/src/Geant4TrackPersistency.cpp +++ b/DDG4/src/Geant4TrackPersistency.cpp @@ -329,9 +329,10 @@ void Geant4TrackPersistency::TrackInfo::set(const G4Track* trk, void* inf) { /// Standard constructor Geant4TrackPersistency::Geant4TrackPersistency(Geant4Context* context, const std::string& nam) - : Geant4Action(context,nam), Geant4MonteCarloTruth(), m_current() + : Geant4GeneratorAction(context,nam), Geant4MonteCarloTruth(), m_current() { m_current.manager = this; + generatorAction().adopt(this); eventAction().callAtBegin(this,&Geant4TrackPersistency::beginEvent); eventAction().callAtFinal(this,&Geant4TrackPersistency::endEvent); trackingAction().callAtFinal(this,&Geant4TrackPersistency::end,CallbackSequence::FRONT); @@ -393,9 +394,16 @@ void Geant4TrackPersistency::mark(const G4Track* track) { track,m_current.track); } +/// Event generation action callback +void Geant4TrackPersistency::operator()(G4Event* ) { + typedef Geant4MonteCarloTruth _MC; + m_trackMap.clear(); + printout(INFO,name(),"+++ Add EVENT extension of type Geant4TrackPersistency....."); + context()->event().addExtension((_MC*)this, typeid(_MC), 0); +} + /// Pre-event action callback void Geant4TrackPersistency::beginEvent(const G4Event* ) { - m_trackMap.clear(); } /// Pre-event action callback @@ -519,7 +527,7 @@ void Geant4TrackPersistency::end(const G4Track* track) { Geant4TrackHandler t(track); std::string proc = t.creatorName(); G4ThreeVector pos = t.position(); - + this->info("END Track %p ID=%4d Parent:%4d E:%7.2f MeV " "%-6s %-8s L:%7.2f Pos:(%8.2f %8.2f %8.2f) Ref:%d Keep:%s Tracked:%s Hit:%s", track,t.id(), t.parent(), t.energy(), @@ -530,8 +538,9 @@ void Geant4TrackPersistency::end(const G4Track* track) { } /// If required save Track record... if ( m_current.store ) { - Geant4MonteCarloRecordManager* mgr = mcRecordMgr(true); - mgr->save(m_current); + Geant4MonteCarloRecordManager* mgr = + context()->event().extension<Geant4MonteCarloRecordManager>(false); + if ( mgr ) mgr->save(m_current); } m_current.set(0,0); trackMgr()->SetUserTrackInformation(0); diff --git a/DDG4/src/Geant4TrackingAction.cpp b/DDG4/src/Geant4TrackingAction.cpp index 54942ca39..7baa98527 100644 --- a/DDG4/src/Geant4TrackingAction.cpp +++ b/DDG4/src/Geant4TrackingAction.cpp @@ -57,6 +57,7 @@ void Geant4TrackingActionSequence::adopt(Geant4TrackingAction* action) { /// Pre-track action callback void Geant4TrackingActionSequence::begin(const G4Track* track) { + m_actors(ContextUpdate(context())); m_front(track); m_actors(&Geant4TrackingAction::begin, track); m_begin(track); @@ -67,6 +68,7 @@ void Geant4TrackingActionSequence::end(const G4Track* track) { m_end(track); m_actors(&Geant4TrackingAction::end, track); m_final(track); + m_actors(ContextUpdate(0)); } /// Standard constructor @@ -90,7 +92,7 @@ void Geant4TrackingAction::end(const G4Track*) { /// Mark the track to be kept for MC truth propagation void Geant4TrackingAction::mark(const G4Track* track) const { - Geant4MonteCarloTruth* truth = mcTruthMgr(false); + Geant4MonteCarloTruth* truth = context()->event().extension<Geant4MonteCarloTruth>(false); if ( truth ) truth->mark(track,true); } @@ -99,7 +101,7 @@ Geant4TrackInformation* Geant4TrackingAction::trackInfo(G4Track* track) const { if (track) { Geant4TrackInformation* gau = 0; G4VUserTrackInformation* g4 = track->GetUserInformation(); - if (0 == g4) { + if (0 == g4) { gau = new Geant4TrackInformation(); track->SetUserInformation(gau); return gau; // RETURN diff --git a/DDG4/src/Geant4TrackingPostAction.cpp b/DDG4/src/Geant4TrackingPostAction.cpp index 21288755a..47f8eb7f4 100644 --- a/DDG4/src/Geant4TrackingPostAction.cpp +++ b/DDG4/src/Geant4TrackingPostAction.cpp @@ -57,7 +57,7 @@ void Geant4TrackingPostAction::begin(const G4Track* track) { return; trackMgr()->SetStoreTrajectory(true); // create GaussTrajectory and inform Tracking Manager - G4VTrajectory* tr = m_context->createTrajectory(track); + G4VTrajectory* tr = context()->createTrajectory(track); trackMgr()->SetTrajectory(tr); } diff --git a/DDG4/src/Geant4TrackingPreAction.cpp b/DDG4/src/Geant4TrackingPreAction.cpp index 6c8db1aaf..799b4cba4 100644 --- a/DDG4/src/Geant4TrackingPreAction.cpp +++ b/DDG4/src/Geant4TrackingPreAction.cpp @@ -34,7 +34,7 @@ void Geant4TrackingPreAction::begin(const G4Track* track) { return; trackMgr()->SetStoreTrajectory(true); // create GaussTrajectory and inform Tracking Manager - G4VTrajectory* tr = m_context->createTrajectory(track); + G4VTrajectory* tr = context()->createTrajectory(track); trackMgr()->SetTrajectory(tr); } diff --git a/DDG4/src/Geant4VolumeManager.cpp b/DDG4/src/Geant4VolumeManager.cpp index f5a350e49..942f01914 100644 --- a/DDG4/src/Geant4VolumeManager.cpp +++ b/DDG4/src/Geant4VolumeManager.cpp @@ -109,9 +109,9 @@ namespace { IDDescriptor iddesc = ro.idSpec(); VolumeID code = iddesc.encode(ids); Registries::const_iterator i = m_entries.find(code); - PrintLevel print_action = DEBUG; - PrintLevel print_chain = DEBUG; - PrintLevel print_res = DEBUG; + PrintLevel print_action = VERBOSE; + PrintLevel print_chain = VERBOSE; + PrintLevel print_res = VERBOSE; printout(print_action,"Geant4VolumeManager","+++ Add path:%s vid:%016X", DetectorTools::placementPath(nodes,false).c_str(),code); diff --git a/doc/release.notes b/doc/release.notes index 9983a0360..6d4133a02 100644 --- a/doc/release.notes +++ b/doc/release.notes @@ -1,6 +1,23 @@ DD4hep ---- Release Notes ================================= +2014/06/30 Markus Frank +----------------------- + - DDG4: Support user (context-) extensions for Geant4. + User contexts are availible for events and runs. The contexts + are accessible from the Geant4Context meber of each Geant4Action, + the base class for all processing entities. + -- Adding a context: + context()->event().addExtension(pointer_to_object, typeid(TYPE), 0); + or + context()->event().addExtension<TYPE>(pointer_to_object); + In the first case the object is NOT DELETED at the end of the event. + In the second case the object is deleted. + -- Accessing the context: + TYPE* ctx = context()->event().extension<TYPE>(false); + The boolean argument indicates if an exception should be thrown + if the extension is not present ie. here no exception. + - DDCore: adjust a few print statements. 2014/06/27 Markus Frank ----------------------- -- GitLab