Geant4 VMC Version 6.6
Loading...
Searching...
No Matches
TG4RunManager.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2007 - 2015 Ivana Hrivnacova
4// All rights reserved.
5//
6// For the licensing terms see geant4_vmc/LICENSE.
7// Contact: root-vmc@cern.ch
8//-------------------------------------------------
9
14
15#include "TG4RunManager.h"
17#include "TG4DetConstruction.h"
18#include "TG4EventAction.h"
19#include "TG4G3PhysicsManager.h"
20#include "TG4GeometryManager.h"
21#include "TG4GeometryServices.h"
22#include "TG4Globals.h"
23#include "TG4PhysicsManager.h"
25#include "TG4RegionsManager.h"
26#include "TG4RegionsManager2.h"
27#include "TG4RunConfiguration.h"
28#include "TG4SDConstruction.h"
29#include "TG4SDManager.h"
30#include "TG4SDServices.h"
32#include "TG4StackPopper.h"
33#include "TG4StateManager.h"
34#include "TG4StepManager.h"
35#include "TG4SteppingAction.h"
36#include "TG4TrackManager.h"
37#include "TG4TrackingAction.h"
39
40#include <G4Threading.hh>
41#include <G4Types.hh>
42#ifdef G4MULTITHREADED
43#include <G4MTRunManager.hh>
44#else
45#include <G4RunManager.hh>
46#endif
47
48#include <G4UIExecutive.hh>
49#include <G4UImanager.hh>
50#include <G4UIsession.hh>
51#include <G4Version.hh>
52#include <Randomize.hh>
53
54#ifdef USE_G4ROOT
55#include <TG4RootNavMgr.h>
56#endif
57
58#include <TGeoManager.h>
59#include <TInterpreter.h>
60#include <TMCManager.h>
61#include <TMCManagerStack.h>
62#include <TROOT.h>
63#include <TRandom.h>
64#include <TRint.h>
65#include <TVirtualMC.h>
66#include <TVirtualMCApplication.h>
67
68namespace
69{
70
71TG4EventAction* GetEventAction()
72{
73 return dynamic_cast<TG4EventAction*>(const_cast<G4UserEventAction*>(
74 G4RunManager::GetRunManager()->GetUserEventAction()));
75}
76
77} // namespace
78
79//_____________________________________________________________________________
82
83//_____________________________________________________________________________
85 TG4RunConfiguration* runConfiguration, int argc, char** argv)
86 : TG4Verbose("runManager"),
87 fRunManager(0),
88 fMessenger(this),
89 fRunConfiguration(runConfiguration),
90 fRegionsManager(0),
91 fGeantUISession(0),
92 fRootUISession(0),
93 fRootUIOwner(false),
94 fARGC(argc),
95 fARGV(argv),
96 fUseRootRandom(true),
97 fIsMCStackCached(false),
98 fHasEventByEventInitialization(false),
99 fNEventsProcessed(0),
100 fInProcessRun(false)
101{
103
104 if (VerboseLevel() > 1) {
105 G4cout << "TG4RunManager::TG4RunManager " << this << G4endl;
106 }
107
108 if (fgInstance) {
109 TG4Globals::Exception("TG4RunManager", "TG4RunManager",
110 "Cannot create two instances of singleton.");
111 }
112
113 if (!fRunConfiguration) {
114 TG4Globals::Exception("TG4RunManager", "TG4RunManager",
115 "Cannot create instance without runConfiguration.");
116 }
117
118 fgInstance = this;
119
120 // Define fARGV, fARGC if not provided
121 if (fARGC == 0) {
122 fARGC = 1;
123 fARGV = (char**)new char*[fARGC];
124 fARGV[0] = StrDup("undefined");
125 }
126
127 G4bool isMaster = !G4Threading::IsWorkerThread();
128
129 if (isMaster) {
130 fgMasterInstance = this;
131
132 // create and configure G4 run manager
134 }
135 else {
136 // Get G4 worker run manager
137 fRunManager = G4RunManager::GetRunManager();
138
139 // Clone G4Root navigator if needed
141
145 }
146
147 if (VerboseLevel() > 1) {
148 G4cout << "TG4RunManager has been created." << this << G4endl;
149 }
150}
151
152//_____________________________________________________________________________
154{
156
157 G4bool isMaster = !G4Threading::IsWorkerThread();
158
159 if (isMaster) {
160 delete fRunConfiguration;
161 delete fRegionsManager;
162 delete fGeantUISession;
163 delete fRunManager;
164 if (fRootUIOwner) delete fRootUISession;
166 }
167 fgInstance = 0;
168}
169
170//
171// private methods
172//
173
174//_____________________________________________________________________________
176{
179
180 // Geometry construction and navigator
181 //
182 if (VerboseLevel() > 1)
183 G4cout << "TG4RunManager::ConfigureRunManager " << this << G4endl;
184
185 TString userGeometry = fRunConfiguration->GetUserGeometry();
186
189
192
193 // Root navigator
194#ifdef USE_G4ROOT
195 TG4RootNavMgr* rootNavMgr = 0;
196 if (userGeometry == "VMCtoRoot" || userGeometry == "Root") {
197 if (!TMCManager::Instance()) {
198
199#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 22, 8)
200 // Set Root default units to TGeo
201 TGeoManager::LockDefaultUnits(false);
202 TGeoManager::SetDefaultUnits(TGeoManager::kRootUnits);
203 TGeoManager::LockDefaultUnits(true);
204#endif
205
206 // Construct geometry via VMC application
208 G4cout << "Running TVirtualMCApplication::ConstructGeometry"
209 << std::endl;
210
212 TVirtualMCApplication::Instance()->ConstructGeometry();
214
215 // Set top volume and close Root geometry if not yet done
216 if (!gGeoManager->IsClosed()) {
217 TGeoVolume* top = (TGeoVolume*)gGeoManager->GetListOfVolumes()->First();
218 gGeoManager->SetTopVolume(top);
219 gGeoManager->CloseGeometry();
220 }
221
222 // Now that we have the ideal geometry, call application misalignment code
224 TVirtualMCApplication::Instance()->MisalignGeometry();
226 }
227 // Pass geometry to G4Root navigator
228 rootNavMgr = TG4RootNavMgr::GetInstance(gGeoManager);
229 }
230#endif
231
232 // G4 run manager
233#ifdef G4MULTITHREADED
235 fRunManager = new G4MTRunManager();
236 fRunManager->SetUserInitialization(new TG4WorkerInitialization());
237 }
238 else {
239 fRunManager = new G4RunManager();
240 }
241#else
242 fRunManager = new G4RunManager();
243#endif
244 if (VerboseLevel() > 1) {
245 G4cout << "G4RunManager has been created." << G4endl;
246 }
247
248 if (userGeometry != "VMCtoRoot" && userGeometry != "Root") {
249 fRunManager->SetUserInitialization(
251 if (VerboseLevel() > 1)
252 G4cout << "CreateDetectorConstruction done." << G4endl;
253 }
254 else {
255#ifdef USE_G4ROOT
256 G4int nthreads = 1;
257#ifdef G4MULTITHREADED
259 nthreads = G4MTRunManager::GetMasterRunManager()->GetNumberOfThreads();
260 }
261#endif
262 rootNavMgr->Initialize(new TG4PostDetConstruction(), nthreads);
263 rootNavMgr->ConnectToG4();
264#else
265 TG4Globals::Exception("TG4RunManager", "ConfigureRunManager",
266 "geomVMCtoRoot and geomRoot options require Geant4 VMC built with "
267 "G4Root.");
268#endif
269 }
270
271 // Other mandatory classes
272 //
273 fRunManager->SetUserInitialization(fRunConfiguration->CreatePhysicsList());
274 if (VerboseLevel() > 1) G4cout << "CreatePhysicsList done." << G4endl;
275
276 // User fast simulation
277 TG4VUserFastSimulation* userFastSimulation =
279 if (userFastSimulation) {
282 userFastSimulation);
283 }
284 else {
285 TG4Globals::Warning("TG4RunManager", "ConfigureRunManager",
286 "TG4SpecialPhysicsList must be instantiated to use fast simulation");
287 }
288 }
289
290 fRunManager->SetUserInitialization(
292 if (VerboseLevel() > 1)
293 G4cout << "Create ActionInitialization done." << G4endl;
294
295 // Regions manager
296 //
300 }
301 else {
303 }
304 }
305
306 if (VerboseLevel() > 1)
307 G4cout << "TG4RunManager::ConfigureRunManager done " << this << G4endl;
308}
309
310//_____________________________________________________________________________
312{
313 // Clone Root navigator for worker thread
314 //
315#ifdef USE_G4ROOT
316 TString userGeometry = fRunConfiguration->GetUserGeometry();
317 if (userGeometry != "VMCtoRoot" && userGeometry != "Root") return;
318
319 if (VerboseLevel() > 1)
320 G4cout << "TG4RunManager::CloneRootNavigatorForWorker " << this << G4endl;
321
322 // Master Root navigator
323 TG4RootNavMgr* masterRootNavMgr = TG4RootNavMgr::GetMasterInstance();
324
325 // Create G4Root navigator on worker
326 TG4RootNavMgr* rootNavMgr = TG4RootNavMgr::GetInstance(*masterRootNavMgr);
327 if (VerboseLevel() > 1)
328 G4cout << "TG4RootNavMgr has been created." << rootNavMgr << G4endl;
329
330 // rootNavMgr->Initialize(new TG4PostDetConstruction());
331 rootNavMgr->ConnectToG4();
332
333 if (VerboseLevel() > 1)
334 G4cout << "TG4RunManager::CloneRootNavigatorForWorker done " << this
335 << G4endl;
336#endif
337}
338
339//_____________________________________________________________________________
341{
343
344 // get Root UI session if it exists
345 fRootUISession = gROOT->GetApplication();
346 if (fRootUISession) {
347 fARGC = fRootUISession->Argc();
348 delete[] fARGV;
349 fARGV = fRootUISession->Argv();
350 }
351
352 // filter out "-splash" from argument list
353 FilterARGV("-splash");
354
355 // create root UI if it does not exist
356 if (!fRootUISession) {
357 // copy only first command line argument (name of program)
358 // (use the same way as in TApplication.cxx)
359 char** argv = 0;
360 if (fARGC > 0) {
361 argv = (char**)new char*[fARGC];
362 }
363
364 // copy command line arguments, can be later accessed via Argc() and Argv()
365 for (int i = 0; i < fARGC; i++) {
366 argv[i] = StrDup(fARGV[i]);
367 }
368
369 fRootUISession = new TRint("rootSession", &fARGC, argv, 0, 0);
370 fRootUIOwner = true;
371 }
372}
373
374//_____________________________________________________________________________
375void TG4RunManager::FilterARGV(const G4String& arg)
376{
379
380 if (fARGC <= 1) return;
381
382 G4bool isArg = false;
383 for (G4int i = 0; i < fARGC; i++) {
384 if (G4String(fARGV[i]) == arg) isArg = true;
385 if (isArg && i + 1 < fARGC) fARGV[i] = fARGV[i + 1];
386 }
387
388 if (isArg) fARGC--;
389}
390
391//_____________________________________________________________________________
393{
396
397 long seeds[10];
398 seeds[0] = gRandom->GetSeed();
399 seeds[1] = gRandom->GetSeed();
400 seeds[2] = 0;
401 CLHEP::HepRandom::setTheSeeds(seeds);
402}
403
404// public methods
405
406//_____________________________________________________________________________
408{
410
411 if (VerboseLevel() > 1)
412 G4cout << "TG4RunManager::Initialize " << this << G4endl;
413
414 // create G4RunManager
415 // ConfigureRunManager();
416
417#if G4VERSION_NUMBER == 1100
418 // Temporary work-around for bug in Cerenkov in Geant4 11.0
419 TG4PhysicsManager::Instance()->StoreCerenkovMaxBetaChangeValue();
420#endif
421
422 // initialize Geant4
423 fRunManager->Initialize();
424
425 // finish geometry
427
428 // initialize SD manager
429 // TG4SDManager::Instance()->Initialize();
430
431 if (VerboseLevel() > 1)
432 G4cout << "TG4RunManager::Initialize done " << this << G4endl;
433}
434
435//_____________________________________________________________________________
437{
440
441 if (VerboseLevel() > 1)
442 G4cout << "TG4RunManager::LateInitialize " << this << G4endl;
443
444 G4bool isMaster = !G4Threading::IsWorkerThread();
445
446 // define particles
448
449 // set user limits
450 if (isMaster) {
452 *TG4G3PhysicsManager::Instance()->GetCutVector(),
453 *TG4G3PhysicsManager::Instance()->GetControlVector());
454
455 // pass info if cut on e+e- pair is activated to stepping action
456 // TO DO LATER - Stepping Action NOT AVAILABLE
457 //((TG4SteppingAction*)fRunManager->GetUserSteppingAction())
458 // ->SetIsPairCut((*TG4G3PhysicsManager::Instance()->GetIsCutVector())[kEplus]);
459
460 // convert tracking cuts in range cuts per regions
464 }
465 }
466
467 // activate/inactivate physics processes
470
471 // late initialize step manager
473
474 // late initialize action classes
475 if (GetEventAction()) {
476 GetEventAction()->LateInitialize();
479 }
480
481 // print statistics
484
485 if (VerboseLevel() > 2) {
487 }
488
489 // set the random number seed
491
492 if (VerboseLevel() > 1)
493 G4cout << "TG4RunManager::LateInitialize done " << this << G4endl;
494}
495
496//_____________________________________________________________________________
498{
500
501 // Do only once
502 if (fIsMCStackCached) return;
503
504 // The VMC stack must be set to MC at this stage !!
505 TVirtualMCStack* mcStack = gMC->GetStack();
506 if (!mcStack) {
508 "TG4RunManager", "CacheMCStack", "VMC stack is not set");
509 return;
510 }
511
512 TMCManagerStack* mcManagerStack = gMC->GetManagerStack();
513 // Set stack to the event actions if they exists
514 // (on worker only if in MT mode)
515 if (GetEventAction()) {
516 GetEventAction()->SetMCStack(mcStack);
520
523 }
524 }
525
526 fIsMCStackCached = true;
527}
528
529//_____________________________________________________________________________
536
537//_____________________________________________________________________________
538void TG4RunManager::ProcessEvent(G4int eventId, G4bool isInterruptible)
539{
541
542 // First, replay what is done in G4RunManager::BeamOn(...) explicitly
544 G4bool cond = fRunManager->ConfirmBeamOnCondition();
545 if (!cond) {
546 TG4Globals::Warning("TG4RunManager", "ProcessEvent",
547 "Bad beam condition in G4RunManager. No event processed.");
548 return;
549 }
550 fRunManager->ConstructScoringWorlds();
551 fRunManager->RunInitialization();
553 }
554 GetEventAction()->SetIsInterruptibleEvent(isInterruptible);
555
556 // Explicitly call the following 2 methods which are otherwise called from
557 // G4RunManager::BeamOn(...)
558 fRunManager->ProcessOneEvent(eventId);
559 fRunManager->TerminateOneEvent();
560}
561
562//_____________________________________________________________________________
563Bool_t TG4RunManager::ProcessRun(G4int nofEvents)
564{
566
567 // Runinit for per-event processing ==> Don't allow for process run.
569 TG4Globals::Warning("TG4RunManager", "ProcessRun",
570 "Current run is terminated first, then the requested run is processed");
571 FinishRun();
572 }
573 fInProcessRun = true;
574 fRunManager->BeamOn(nofEvents);
575 fInProcessRun = false;
576 fNEventsProcessed = nofEvents;
577 return FinishRun();
578}
579
580//_____________________________________________________________________________
582{
584 if (fInProcessRun) {
585 TG4Globals::Warning("TG4RunManager", "FinishRun",
586 "You are processing a run. To stop it, call StopRun()");
587 return false;
588 }
589 else {
591 }
592 }
593 else {
594 fRunManager->RunTermination();
597 }
598 // Pring field statistics
600
601 G4bool result = !TG4SDServices::Instance()->GetIsStopRun();
603
604 return result;
605}
606
607//_____________________________________________________________________________
609{
611
612 if (fGeantUISession) return;
613
614 // create session if it does not exist
615 fGeantUISession = new G4UIExecutive(fARGC, fARGV);
616}
617
618//_____________________________________________________________________________
620{
622
624
625 if (fGeantUISession) {
626 // interactive session
627 G4cout << "Welcome (back) in Geant4" << G4endl;
628 fGeantUISession->GetSession()->SessionStart();
629 G4cout << "Welcome (back) in Root" << G4endl;
630 }
631 else {
632 G4cout << "Geant4 UI not available." << G4endl;
633 }
634}
635
636//_____________________________________________________________________________
638{
640
642 if (fRootUISession) {
643 G4cout << "Welcome (back) in Root" << G4endl;
644 fRootUISession->Run(kTRUE);
645 G4cout << "Welcome (back) in Geant4" << G4endl;
646 }
647}
648
649//_____________________________________________________________________________
650void TG4RunManager::ProcessGeantMacro(G4String macroName)
651{
653
654 G4String command = "/control/execute " + macroName;
655 ProcessGeantCommand(command);
656}
657
658//_____________________________________________________________________________
659void TG4RunManager::ProcessRootMacro(G4String macroName)
660{
662
663 // load macro file
664 G4String macroFile = macroName;
665 macroFile.append(".C");
666 gROOT->LoadMacro(macroFile);
667
668 // execute macro function
669 G4String macroFunction = macroName;
670 macroFunction.append("()");
671 gInterpreter->ProcessLine(macroFunction);
672}
673
674//_____________________________________________________________________________
676{
678
679 G4UImanager* pUI = G4UImanager::GetUIpointer();
680 G4int result = pUI->ApplyCommand(command);
681
682 // From G4UIbatch::ExecCommand():
683 switch (result) {
684 case fCommandSucceeded:
685 break;
686 case fCommandNotFound:
687 G4cerr << "***** COMMAND NOT FOUND <" << command << "> *****" << G4endl;
688 break;
689 case fIllegalApplicationState:
690 G4cerr << "***** Illegal application state <" << command << "> *****"
691 << G4endl;
692 break;
693 default:
694 G4int pn = result % 100;
695 G4cerr << "***** Illegal parameter (" << pn << ") <" << command
696 << "> *****" << G4endl;
697 }
698}
699
700//_____________________________________________________________________________
702{
704
705 gInterpreter->ProcessLine(command);
706}
707
708//_____________________________________________________________________________
716
717//_____________________________________________________________________________
719{
721
722 G4int eventID = fRunManager->GetCurrentEvent()->GetEventID();
723 return eventID;
724}
725
726//_____________________________________________________________________________
728{
731
732 return false;
733}
Definition of the TG4ActionInitialization class.
Definition of the TG4DetConstruction class.
Definition of the TG4EventAction class.
Definition of the TG4G3PhysicsManager class.
Definition of the TG4GeometryManager class.
Definition of the TG4GeometryServices class.
Definition of the TG4Globals class and basic container types.
Definition of the TG4PhysicsManager class.
Definition of the TG4PostDetConstruction class.
Definition of the TG4RegionsManager2 class.
Definition of the TG4RegionsManager class.
Definition of the TG4RunConfiguration class.
Definition of the TG4RunManager.h class.
Definition of the TG4SDConstruction class.
Definition of the TG4SDManager class.
Definition of the TG4SDServices class.
Definition of the TG4SpecialPhysicsList class.
Definition of the TG4StackPopper class.
Definition of the TG4StateManager class.
Definition of the TG4StepManager class.
Definition of the TG4SteppingAction class.
Definition of the TG4TrackManager class.
Definition of the TG4TrackingAction class.
Definition of the TG4WorkerInitialization class.
Action Initialization class (required for MT mode)
Actions at the beginning and the end of event.
static TG4G3PhysicsManager * Instance()
void SetUserPostDetConstruction(TG4VUserPostDetConstruction *userPostDetConstruction)
void SetUserRegionConstruction(TG4VUserRegionConstruction *userRegionConstruction)
static TG4GeometryManager * Instance()
void SetUserLimits(const TG4G3CutVector &cuts, const TG4G3ControlVector &controls) const
void PrintStatistics(G4bool open, G4bool close) const
static TG4GeometryServices * Instance()
static void Warning(const TString &className, const TString &methodName, const TString &text)
static void Exception(const TString &className, const TString &methodName, const TString &text)
static TG4PhysicsManager * Instance()
Manager class for setting VMC cuts in energy in G4 regions.
Manager class for converting VMC cuts in energy in G4 regions.
Takes care of creating Geant4 user action classes using VMC.
virtual G4VUserPhysicsList * CreatePhysicsList()
virtual TG4VUserFastSimulation * CreateUserFastSimulation()
virtual G4VUserDetectorConstruction * CreateDetectorConstruction()
virtual TG4VUserRegionConstruction * CreateUserRegionConstruction()
TString GetUserGeometry() const
virtual TG4VUserPostDetConstruction * CreateUserPostDetConstruction()
Geant4 implementation of the TVirtualMC interface methods for access to Geant4 at run level.
void ProcessGeantCommand(G4String command)
void ConfigureRunManager()
G4bool fIsMCStackCached
the flag to cache MC stack only once
G4bool fHasEventByEventInitialization
Flag event-by-event processing.
G4int fNEventsProcessed
Number of events processed in event-by-event mode.
void SetRandomSeed()
picks up random seed from ROOT gRandom and propagates to Geant4
char ** fARGV
argv
Bool_t SecondariesAreOrdered() const
TG4VRegionsManager * fRegionsManager
regions manager
static TG4RunManager * fgMasterInstance
master instance
TApplication * fRootUISession
Root UI.
Int_t CurrentEvent() const
void ProcessRootCommand(G4String command)
static G4ThreadLocal TG4RunManager * fgInstance
thread local instance
G4bool fRootUIOwner
ownership of Root UI
G4RunManager * fRunManager
G4RunManager.
TG4RunManager()
Not implemented.
G4UIExecutive * fGeantUISession
G4 UI.
G4bool fUseRootRandom
the option to use Root random number seed
G4int fARGC
argc
void CloneRootNavigatorForWorker()
TG4RunConfiguration * fRunConfiguration
TG4RunConfiguration.
void ProcessRootMacro(G4String macroName)
void ProcessGeantMacro(G4String macroName)
Bool_t ProcessRun(G4int nofEvents)
void FilterARGV(const G4String &option)
G4bool fInProcessRun
flag while being in BeamOn
virtual ~TG4RunManager()
void SetIsStopRun(G4bool stopRun)
void PrintStatistics(G4bool open, G4bool close) const
G4bool GetIsStopRun() const
static TG4SDServices * Instance()
void SetUserFastSimulation(TG4VUserFastSimulation *fastSimulation)
static TG4SpecialPhysicsList * Instance()
static TG4StackPopper * Instance()
void SetMCStack(TVirtualMCStack *mcStack)
void SetNewState(TG4ApplicationState state)
static TG4StateManager * Instance()
static TG4StepManager * Instance()
static TG4SteppingAction * Instance()
void SetMCStack(TVirtualMCStack *mcStack)
static TG4TrackManager * Instance()
void SetMCManagerStack(TMCManagerStack *mcManagerStack)
void SetMCStack(TVirtualMCStack *mcStack)
static TG4TrackingAction * Instance()
virtual void DefineRegions()=0
virtual void UpdateProductionCutsTable()=0
The abstract base class which is used to build fast simulation models.
Base class for defining the verbose level and a common messenger.
Definition TG4Verbose.h:36
virtual G4int VerboseLevel() const
Definition TG4Verbose.h:78
Actions at start and end of run on a worker (call in MT mode only)
@ kMisalignGeometry
in MisalignGeometry
@ kConstructGeometry
in ConstructGeometry
@ kNotInApplication
not in VMC application