Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:17:31

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework include files
0015 #include <DD4hep/Printout.h>
0016 #include <DD4hep/Primitives.h>
0017 #include <DD4hep/InstanceCount.h>
0018 #include <DD4hep/Handle.h>
0019 #include <DDG4/Geant4RunAction.h>
0020 #include <DDG4/Geant4EventAction.h>
0021 #include <DDG4/Geant4SteppingAction.h>
0022 #include <DDG4/Geant4TrackingAction.h>
0023 #include <DDG4/Geant4StackingAction.h>
0024 #include <DDG4/Geant4GeneratorAction.h>
0025 #include <DDG4/Geant4UserInitialization.h>
0026 #include <DDG4/Geant4DetectorConstruction.h>
0027 #include <DDG4/Geant4PhysicsList.h>
0028 #include <DDG4/Geant4UIManager.h>
0029 #include <DDG4/Geant4Kernel.h>
0030 #include <DDG4/Geant4Random.h>
0031 
0032 // Geant4 include files
0033 #include <G4Version.hh>
0034 #include <G4UserRunAction.hh>
0035 #include <G4UserEventAction.hh>
0036 #include <G4UserTrackingAction.hh>
0037 #include <G4UserStackingAction.hh>
0038 #include <G4UserSteppingAction.hh>
0039 #include <G4VUserPhysicsList.hh>
0040 #include <G4VModularPhysicsList.hh>
0041 #include <G4VUserPrimaryGeneratorAction.hh>
0042 #include <G4VUserActionInitialization.hh>
0043 #include <G4VUserDetectorConstruction.hh>
0044 
0045 // C/C++ include files
0046 #include <memory>
0047 #include <stdexcept>
0048 
0049 namespace {
0050   G4Mutex action_mutex=G4MUTEX_INITIALIZER;
0051 }
0052 
0053 /// Namespace for the AIDA detector description toolkit
0054 namespace dd4hep {
0055 
0056   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0057   namespace sim {
0058 
0059     class Geant4DetectorConstructionSequence;
0060     
0061     /// Sequence handler implementing common actions to all sequences.
0062     /** @class SequenceHdl
0063      *
0064      * @author  M.Frank
0065      * @version 1.0
0066      */
0067     template <typename T> class SequenceHdl {
0068     public:
0069       typedef SequenceHdl<T> Base;
0070       T* m_sequence;
0071       mutable Geant4Context* m_activeContext;
0072       /// Default constructor
0073       SequenceHdl()
0074         : m_sequence(0), m_activeContext(0) {
0075       }
0076       /// Initializing constructor
0077       SequenceHdl(Geant4Context* ctxt, T* seq) : m_sequence(0), m_activeContext(ctxt)  {
0078         _aquire(seq);
0079       }
0080       /// Default destructor
0081       virtual ~SequenceHdl() {
0082         _release();
0083       }
0084       /// Aquire object reference
0085       void _aquire(T* s) {
0086         InstanceCount::increment(this);
0087         m_sequence = s;
0088         if ( m_sequence ) m_sequence->addRef();
0089       }
0090       /// Release object
0091       void _release() {
0092         detail::releasePtr(m_sequence);
0093         InstanceCount::decrement(this);
0094       }
0095       /// Update Geant4Context for current call
0096       void updateContext(Geant4Context* ctxt)   {
0097         m_activeContext = ctxt;
0098         if ( m_sequence )  {
0099           m_sequence->updateContext(ctxt);
0100         }
0101       }
0102       /// Access reference to the current active Geant4Context structure
0103       Geant4Context* context() const  {  
0104         return m_activeContext;
0105       }
0106       /// Access reference to the current active Geant4Kernel structure
0107       Geant4Kernel& kernel()  const  {
0108         return context()->kernel();
0109       }
0110       /// G4 callback in multi threaded mode to configure thread fiber
0111       void configureFiber(Geant4Context* ctxt)   {
0112         if ( m_sequence )  {
0113           m_sequence->configureFiber(ctxt);
0114         }
0115       }
0116       /// Create Geant4 run context
0117       void createClientContext(const G4Run* run)   {
0118         Geant4Run* r = new Geant4Run(run);
0119         m_activeContext->setRun(r);
0120       }
0121       /// Destroy Geant4 run context
0122       void destroyClientContext(const G4Run*)   {
0123         Geant4Run* r = m_activeContext->runPtr();
0124         if ( r )  {
0125           m_activeContext->setRun(0);
0126           detail::deletePtr(r);
0127         }
0128       }
0129       /// Create Geant4 event context
0130       void createClientContext(const G4Event* evt)   {
0131         Geant4Event* e = new Geant4Event(evt,Geant4Random::instance());
0132         m_activeContext->setEvent(e);
0133       }
0134       /// Destroy Geant4 event context
0135       void destroyClientContext(const G4Event*)   {
0136         Geant4Event* e = m_activeContext->eventPtr();
0137         if ( e )  {
0138           m_activeContext->setEvent(0);
0139           detail::deletePtr(e);
0140         }
0141       }
0142     };
0143 
0144     /// Forward declarations
0145     class Geant4UserRunAction;
0146     class Geant4UserEventAction;
0147 
0148     /// Concrete implementation of the Geant4 run action
0149     /** @class Geant4UserRunAction
0150      *
0151      * @author  M.Frank
0152      * @version 1.0
0153      */
0154     class Geant4UserRunAction :
0155       public G4UserRunAction,
0156       public SequenceHdl<Geant4RunActionSequence>
0157     {
0158     public:
0159       Geant4UserEventAction* eventAction;
0160       /// Standard constructor
0161       Geant4UserRunAction(Geant4Context* ctxt, Geant4RunActionSequence* seq)
0162         : Base(ctxt, seq), eventAction(0)  {
0163         updateContext(ctxt);
0164         configureFiber(ctxt);
0165       }
0166       /// Default destructor
0167       virtual ~Geant4UserRunAction() {
0168       }
0169       /// Begin-of-run callback
0170       virtual void BeginOfRunAction(const G4Run* run)  final;
0171       /// End-of-run callback
0172       virtual void EndOfRunAction(const G4Run* run)  final;
0173     };
0174 
0175     /// Concrete implementation of the Geant4 event action
0176     /** @class Geant4UserEventAction
0177      *
0178      * @author  M.Frank
0179      * @version 1.0
0180      */
0181     class Geant4UserEventAction :
0182       public G4UserEventAction, 
0183       public SequenceHdl<Geant4EventActionSequence>
0184     {
0185     public:
0186       Geant4UserRunAction* runAction;
0187       /// Standard constructor
0188       Geant4UserEventAction(Geant4Context* ctxt, Geant4EventActionSequence* seq)
0189         : Base(ctxt, seq), runAction(0)  {
0190         updateContext(ctxt);
0191         configureFiber(ctxt);
0192       }
0193       /// Default destructor
0194       virtual ~Geant4UserEventAction() {
0195       }
0196       /// Begin-of-event callback
0197       virtual void BeginOfEventAction(const G4Event* evt)  final;
0198       /// End-of-event callback
0199       virtual void EndOfEventAction(const G4Event* evt)  final;
0200     };
0201 
0202     /// Concrete implementation of the Geant4 tracking action
0203     /** @class Geant4UserTrackingAction
0204      *
0205      * @author  M.Frank
0206      * @version 1.0
0207      */
0208     class Geant4UserTrackingAction :
0209       public G4UserTrackingAction,
0210       public SequenceHdl<Geant4TrackingActionSequence>
0211     {
0212     public:
0213       /// Standard constructor
0214       Geant4UserTrackingAction(Geant4Context* ctxt, Geant4TrackingActionSequence* seq)
0215         : Base(ctxt, seq) {
0216         updateContext(ctxt);
0217         configureFiber(ctxt);
0218       }
0219       /// Default destructor
0220       virtual ~Geant4UserTrackingAction() {
0221       }
0222       /// Pre-track action callback
0223       virtual void PreUserTrackingAction(const G4Track* trk)  final  {
0224         m_sequence->context()->kernel().setTrackMgr(fpTrackingManager);
0225         m_sequence->begin(trk);
0226       }
0227       /// Post-track action callback
0228       virtual void PostUserTrackingAction(const G4Track* trk)   final  {
0229         m_sequence->end(trk);
0230         m_sequence->context()->kernel().setTrackMgr(0);
0231       }
0232     };
0233 
0234     /// Concrete implementation of the Geant4 stacking action sequence
0235     /** @class Geant4UserStackingAction
0236      *
0237      * @author  M.Frank
0238      * @version 1.0
0239      */
0240     class Geant4UserStackingAction :
0241       public G4UserStackingAction,
0242       public SequenceHdl<Geant4StackingActionSequence>
0243     {
0244     public:
0245       /// Standard constructor
0246       Geant4UserStackingAction(Geant4Context* ctxt, Geant4StackingActionSequence* seq)
0247         : Base(ctxt, seq) {
0248         updateContext(ctxt);
0249         configureFiber(ctxt);
0250       }
0251       /// Default destructor
0252       virtual ~Geant4UserStackingAction() {
0253       }
0254       /// New-stage callback
0255       virtual void NewStage()  override final  {
0256         m_sequence->newStage(stackManager);
0257       }
0258       /// Preparation callback
0259       virtual void PrepareNewEvent() override final  {
0260         m_sequence->prepare(stackManager);
0261       }
0262       virtual G4ClassificationOfNewTrack ClassifyNewTrack(const G4Track* track)  override final {
0263     auto ret = m_sequence->classifyNewTrack(stackManager, track);
0264     if ( ret.type != NoTrackClassification )
0265       return ret.value;
0266     return this->G4UserStackingAction::ClassifyNewTrack(track);
0267       }
0268     };
0269 
0270 
0271     /// Concrete implementation of the Geant4 generator action
0272     /** @class Geant4UserGeneratorAction
0273      *
0274      * @author  M.Frank
0275      * @version 1.0
0276      */
0277     class Geant4UserGeneratorAction : 
0278       public G4VUserPrimaryGeneratorAction,
0279       public SequenceHdl<Geant4GeneratorActionSequence> 
0280     {
0281     public:
0282       /// Standard constructor
0283       Geant4UserGeneratorAction(Geant4Context* ctxt, Geant4GeneratorActionSequence* seq)
0284         : G4VUserPrimaryGeneratorAction(), Base(ctxt, seq) {
0285         updateContext(ctxt);
0286         configureFiber(ctxt);
0287       }
0288       /// Default destructor
0289       virtual ~Geant4UserGeneratorAction() {
0290       }
0291       /// Generate primary particles
0292       virtual void GeneratePrimaries(G4Event* event)  final;
0293     };
0294 
0295     /// Concrete implementation of the Geant4 stepping action
0296     /** @class Geant4UserSteppingAction
0297      *
0298      * @author  M.Frank
0299      * @version 1.0
0300      */
0301     class Geant4UserSteppingAction :
0302       public G4UserSteppingAction,
0303       public SequenceHdl<Geant4SteppingActionSequence>
0304     {
0305     public:
0306       /// Standard constructor
0307       Geant4UserSteppingAction(Geant4Context* ctxt, Geant4SteppingActionSequence* seq)
0308         : Base(ctxt, seq) {
0309         updateContext(ctxt);
0310         configureFiber(ctxt);
0311       }
0312       /// Default destructor
0313       virtual ~Geant4UserSteppingAction() {
0314       }
0315       /// User stepping callback
0316       virtual void UserSteppingAction(const G4Step* s)   final  {
0317         (*m_sequence)(s, fpSteppingManager);
0318       }
0319     };
0320 
0321     /// Concrete implementation of the Geant4 user detector construction action sequence
0322     /** @class Geant4UserDetectorConstruction
0323      *
0324      * @author  M.Frank
0325      * @version 1.0
0326      */
0327     class Geant4UserDetectorConstruction : 
0328       public G4VUserDetectorConstruction, 
0329       public SequenceHdl<Geant4DetectorConstructionSequence>
0330     {
0331     protected:
0332       Geant4DetectorConstructionContext m_ctxt;
0333     public:
0334       /// Standard constructor
0335       Geant4UserDetectorConstruction(Geant4Context* ctxt, Geant4DetectorConstructionSequence* seq)
0336         : G4VUserDetectorConstruction(), Base(ctxt, seq), 
0337           m_ctxt(ctxt->kernel().detectorDescription(), this) 
0338       {
0339       }
0340       /// Default destructor
0341       virtual ~Geant4UserDetectorConstruction() {
0342       }
0343       /// Call the actions for the construction of the sensitive detectors and the field
0344       virtual void ConstructSDandField()  final;
0345       /// Call the actions to construct the detector geometry
0346       virtual G4VPhysicalVolume* Construct()  final;
0347     };
0348 
0349     /// Concrete implementation of the Geant4 user initialization action sequence
0350     /** @class Geant4UserActionInitialization
0351      *
0352      * @author  M.Frank
0353      * @version 1.0
0354      */
0355     class Geant4UserActionInitialization : 
0356       public G4VUserActionInitialization, 
0357       public SequenceHdl<Geant4UserInitializationSequence>
0358     {
0359     public:
0360       /// Standard constructor
0361       Geant4UserActionInitialization(Geant4Context* ctxt, Geant4UserInitializationSequence* seq)
0362         : G4VUserActionInitialization(), Base(ctxt, seq) {
0363       }
0364       /// Default destructor
0365       virtual ~Geant4UserActionInitialization()  {
0366       }
0367       /// Build the actions for the worker thread
0368       virtual void Build()  const  final;
0369       /// Build the action sequences for the master thread
0370       virtual void BuildForMaster()  const  final;
0371     };
0372 
0373     /// Begin-of-run callback
0374     void Geant4UserRunAction::BeginOfRunAction(const G4Run* run) {
0375       createClientContext(run);
0376       kernel().executePhase("begin-run",(const void**)&run);
0377       if ( m_sequence ) m_sequence->begin(run); // Action not mandatory
0378       kernel().applyInterruptHandlers();
0379     }
0380 
0381     /// End-of-run callback
0382     void Geant4UserRunAction::EndOfRunAction(const G4Run* run) {
0383       if ( m_sequence ) m_sequence->end(run); // Action not mandatory
0384       kernel().executePhase("end-run",(const void**)&run);
0385       destroyClientContext(run);
0386     }
0387 
0388     /// Begin-of-event callback
0389     void Geant4UserEventAction::BeginOfEventAction(const G4Event* evt) {
0390       kernel().executePhase("begin-event",(const void**)&evt);
0391       if ( m_sequence ) m_sequence->begin(evt); // Action not mandatory
0392     }
0393 
0394     /// End-of-event callback
0395     void Geant4UserEventAction::EndOfEventAction(const G4Event* evt) {
0396       if ( m_sequence ) m_sequence->end(evt); // Action not mandatory
0397       kernel().executePhase("end-event",(const void**)&evt);
0398       destroyClientContext(evt);
0399     }
0400 
0401     /// Generate primary particles
0402     void Geant4UserGeneratorAction::GeneratePrimaries(G4Event* event) {
0403       createClientContext(event);
0404       if ( m_sequence )  {
0405         (*m_sequence)(event);
0406         return;
0407       }
0408       throw std::runtime_error("GeneratePrimaries: Panic! No action sequencer defined. "
0409                                "No primary particles can be produced.");
0410     }
0411 
0412     /// Instantiate Geant4 sensitive detectors and electro-magnetic field
0413     void Geant4UserDetectorConstruction::ConstructSDandField()  {
0414       G4AutoLock protection_lock(&action_mutex);
0415       Geant4Context* ctx = m_sequence->context();
0416       Geant4Kernel&  krnl = kernel().worker(Geant4Kernel::thread_self(),true);
0417       updateContext(krnl.workerContext());
0418       m_sequence->constructField(&m_ctxt);
0419       m_sequence->constructSensitives(&m_ctxt);
0420       updateContext(ctx);
0421     }
0422 
0423     /// Construct electro magnetic field entity from the dd4hep field
0424     G4VPhysicalVolume* Geant4UserDetectorConstruction::Construct()    {
0425       /// The G4TransportationManager is thread-local. 
0426       /// Thus, regardless of whether the field class object is global or local 
0427       /// to a certain volume, a field object must be assigned to G4FieldManager.
0428       G4AutoLock protection_lock(&action_mutex);
0429       updateContext(m_sequence->context());
0430       m_sequence->constructGeo(&m_ctxt);
0431       if ( nullptr == m_ctxt.world )    {
0432         m_sequence->except("+++ Executing G4 detector construction did not result in a valid world volume!");
0433       }
0434       m_sequence->context()->kernel().setWorld(m_ctxt.world);
0435       return m_ctxt.world;
0436     }
0437 
0438     /// Build the actions for the worker thread
0439     void Geant4UserActionInitialization::Build()  const   {
0440       G4AutoLock protection_lock(&action_mutex);
0441       Geant4Kernel&  krnl = kernel().worker(Geant4Kernel::thread_self(),true);
0442       Geant4Context* ctx  = krnl.workerContext();
0443 
0444       if ( m_sequence )  {
0445         Geant4Context* old = m_sequence->context();
0446         m_sequence->info("+++ Executing Geant4UserActionInitialization::Build. "
0447                          "Context:%p Kernel:%p [%ld]", (void*)ctx, (void*)&krnl, krnl.id());
0448       
0449         m_sequence->updateContext(ctx);
0450         m_sequence->build();
0451         m_sequence->updateContext(old);
0452       }
0453       /// Set user generator action sequence. Not optional, since event context is defined inside
0454       Geant4UserGeneratorAction* gen_action = new Geant4UserGeneratorAction(ctx,krnl.generatorAction(false));
0455       SetUserAction(gen_action);
0456 
0457       /// Set the run action sequence. Not optional, since run context is defined/destroyed inside
0458       Geant4UserRunAction* run_action = new Geant4UserRunAction(ctx,krnl.runAction(false));
0459       SetUserAction(run_action);
0460 
0461       /// Set the event action sequence. Not optional, since event context is destroyed inside
0462       Geant4UserEventAction* evt_action = new Geant4UserEventAction(ctx,krnl.eventAction(false));
0463       run_action->eventAction = evt_action;
0464       evt_action->runAction = run_action;
0465       SetUserAction(evt_action);
0466 
0467       /// Set the tracking action sequence
0468       Geant4TrackingActionSequence* trk_action = krnl.trackingAction(false);
0469       if ( trk_action ) {
0470         Geant4UserTrackingAction* action = new Geant4UserTrackingAction(ctx, trk_action);
0471         SetUserAction(action);
0472       }
0473       /// Set the stepping action sequence
0474       Geant4SteppingActionSequence* stp_action = krnl.steppingAction(false);
0475       if ( stp_action ) {
0476         Geant4UserSteppingAction* action = new Geant4UserSteppingAction(ctx, stp_action);
0477         SetUserAction(action);
0478       }
0479       /// Set the stacking action sequence
0480       Geant4StackingActionSequence* stk_action = krnl.stackingAction(false);
0481       if ( stk_action ) {
0482         Geant4UserStackingAction* action = new Geant4UserStackingAction(ctx, stk_action);
0483         SetUserAction(action);
0484       }
0485       
0486     }
0487 
0488     /// Build the action sequences for the master thread
0489     void Geant4UserActionInitialization::BuildForMaster()  const  {
0490       if ( m_sequence )   {
0491         m_sequence->info("+++ Executing Geant4UserActionInitialization::BuildForMaster....");
0492         m_sequence->buildMaster();
0493       }
0494     }
0495     
0496     /// Compatibility actions for running Geant4 in single threaded mode
0497     /** @class Geant4Compatibility
0498      *
0499      * @author  M.Frank
0500      * @version 1.0
0501      */
0502     class Geant4Compatibility {
0503     public:
0504       /// Default constructor
0505       Geant4Compatibility() = default;
0506       /// Default destructor
0507       virtual ~Geant4Compatibility() = default;
0508       /// Detector construction invocation in compatibility mode
0509       Geant4DetectorConstructionSequence* buildDefaultDetectorConstruction(Geant4Kernel& kernel);
0510     };
0511 
0512   }
0513 }
0514 
0515 #include <DD4hep/Detector.h>
0516 #include <DD4hep/Plugins.h>
0517 #include <DDG4/Geant4DetectorConstruction.h>
0518 #include <DDG4/Geant4Kernel.h>
0519 
0520 using namespace dd4hep::sim;
0521 
0522 // Geant4 include files
0523 #include <G4RunManager.hh>
0524 #include <G4PhysListFactory.hh>
0525 
0526 /// Detector construction invocation in compatibility mode
0527 Geant4DetectorConstructionSequence* Geant4Compatibility::buildDefaultDetectorConstruction(Geant4Kernel& kernel)  {
0528   Geant4Action* cr;
0529   Geant4DetectorConstruction* det_cr;
0530   Geant4Context* ctx = kernel.workerContext();
0531   Geant4DetectorConstructionSequence* seq = kernel.detectorConstruction(true);
0532   printout(WARNING, "Geant4Exec", "+++ Building default Geant4DetectorConstruction for single threaded compatibility.");
0533 
0534   /// Attach first the geometry converter from dd4hep to Geant4
0535   cr = PluginService::Create<Geant4Action*>("Geant4DetectorGeometryConstruction",ctx,std::string("ConstructGeometry"));
0536   det_cr = dynamic_cast<Geant4DetectorConstruction*>(cr);
0537   if ( det_cr ) 
0538     seq->adopt(det_cr);
0539   else
0540     throw std::runtime_error("Panic! Failed to build Geant4DetectorGeometryConstruction.");
0541   /// Attach the sensitive detector manipulator:
0542   cr = PluginService::Create<Geant4Action*>("Geant4DetectorSensitivesConstruction",ctx,std::string("ConstructSensitives"));
0543   det_cr = dynamic_cast<Geant4DetectorConstruction*>(cr);
0544   if ( det_cr )
0545     seq->adopt(det_cr);
0546   else
0547     throw std::runtime_error("Panic! Failed to build Geant4DetectorSensitivesConstruction.");
0548   return seq;
0549 }
0550 
0551 /// Configure the simulation
0552 int Geant4Exec::configure(Geant4Kernel& kernel) {
0553   Detector& description = kernel.detectorDescription();
0554   Geant4Context* ctx = kernel.workerContext();
0555   Geant4Random* rndm = Geant4Random::instance(false);
0556   
0557   if ( !rndm )  {
0558     rndm = new Geant4Random(ctx, "Geant4Random");
0559     /// Initialize the engine etc.
0560     rndm->initialize();
0561   }
0562   Geant4Random::setMainInstance(rndm);
0563   kernel.executePhase("configure",0);
0564 
0565   /// Construct the default run manager
0566   G4RunManager& runManager = kernel.runManager();
0567 
0568   /// Check if the geometry was loaded
0569   if (description.sensitiveDetectors().size() <= 1) {
0570     printout(WARNING, "Geant4Exec", "+++ Only %d subdetectors present. "
0571              "You sure you loaded the geometry properly?",
0572              int(description.sensitiveDetectors().size()));
0573   }
0574 
0575   /// Get the detector constructed
0576   Geant4DetectorConstructionSequence* user_det = kernel.detectorConstruction(false);
0577   if ( nullptr == user_det && kernel.isMultiThreaded() )   {
0578     throw std::runtime_error("Panic! No valid detector construction sequencer present. [Mandatory MT]");
0579   }
0580   if ( nullptr == user_det && !kernel.isMultiThreaded() )   {
0581     user_det = Geant4Compatibility().buildDefaultDetectorConstruction(kernel);
0582   }
0583   Geant4UserDetectorConstruction* det_seq = new Geant4UserDetectorConstruction(ctx,user_det);
0584   runManager.SetUserInitialization(det_seq);
0585 
0586   /// Get the physics list constructed
0587   Geant4PhysicsListActionSequence* phys_seq = kernel.physicsList(false);
0588   if ( nullptr == phys_seq )   {
0589     std::string phys_model = "QGSP_BERT";
0590     phys_seq = kernel.physicsList(true);
0591     phys_seq->property("extends").set(phys_model);
0592   }
0593   G4VUserPhysicsList* physics = phys_seq->extensionList();
0594   if (nullptr == physics) {
0595     throw std::runtime_error("Panic! No valid user physics list present!");
0596   }
0597 #if 0
0598   /// Not here: Use seperate object to do this!
0599   printout(INFO, "Geant4Exec", "+++ PhysicsList RangeCut: %f", phys_seq->m_rangecut );
0600   physics->SetDefaultCutValue(phys_seq->m_rangecut);
0601   physics->SetCuts();
0602   if( DEBUG == printLevel() ) physics->DumpCutValuesTable();
0603 #endif
0604   phys_seq->enable(physics);
0605   runManager.SetUserInitialization(physics);
0606 
0607   /// Construct the remaining user initialization in multi-threaded mode
0608   Geant4UserInitializationSequence* user_init = kernel.userInitialization(false);
0609   if ( nullptr == user_init && kernel.isMultiThreaded() )   {
0610     throw std::runtime_error("Panic! No valid user initialization sequencer present. [Mandatory MT]");
0611   }
0612   else if ( nullptr == user_init && !kernel.isMultiThreaded() )  {
0613     /// Use default actions registered to the default kernel. Will do the right thing...
0614     user_init = kernel.userInitialization(true);
0615   }
0616   Geant4UserActionInitialization* init = new Geant4UserActionInitialization(ctx,user_init);
0617   runManager.SetUserInitialization(init);
0618   return 1;
0619 }
0620 
0621 /// Initialize the simulation
0622 int Geant4Exec::initialize(Geant4Kernel& kernel) {
0623   /// Construct the default run manager
0624   G4RunManager& runManager = kernel.runManager();
0625   ///
0626   /// Initialize G4 engine
0627   ///
0628   kernel.applyInterruptHandlers();
0629   kernel.executePhase("initialize",0);
0630   runManager.Initialize();
0631   return 1;
0632 }
0633 
0634 /// Run the simulation
0635 int Geant4Exec::run(Geant4Kernel& kernel) {
0636   Property& p = kernel.property("UI");
0637   std::string value = p.value<std::string>();
0638 
0639   kernel.executePhase("start",0);
0640   if ( !value.empty() )  {
0641     Geant4Action* ui = kernel.globalAction(value);
0642     if ( ui )  {
0643       Geant4Call* c = dynamic_cast<Geant4Call*>(ui);
0644       if ( c )  {
0645         (*c)(nullptr);
0646         kernel.executePhase("stop",0);
0647         return 1;
0648       }
0649       ui->except("++ Geant4Exec: Failed to start UI interface.");
0650     }
0651     throw std::runtime_error(format("Geant4Exec","++ Failed to locate UI interface %s.",value.c_str()));
0652   }
0653   long nevt = kernel.property("NumEvents").value<long>();
0654   kernel.applyInterruptHandlers();
0655   kernel.runManager().BeamOn(nevt);
0656   kernel.executePhase("stop",0);
0657   return 1;
0658 }
0659 
0660 /// Run the simulation
0661 int Geant4Exec::terminate(Geant4Kernel& kernel) {
0662   kernel.executePhase("terminate",0);
0663   return 1;
0664 }