Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4EventManager.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4EventManager class implementation
27//
28// Author: M.Asai, SLAC
29// Adding sub-event parallelism: M.Asai, JLAB
30// --------------------------------------------------------------------
31
32#include "G4EventManager.hh"
33#include "G4ios.hh"
34#include "G4EvManMessenger.hh"
35#include "G4Event.hh"
37#include "G4VTrackingManager.hh"
38#include "G4UserEventAction.hh"
40#include "G4SDManager.hh"
41#include "G4StateManager.hh"
42#include "G4ApplicationState.hh"
44#include "G4Navigator.hh"
45#include "Randomize.hh"
46#include "G4Profiler.hh"
47#include "G4TiMemory.hh"
49#include "G4AutoLock.hh"
50
51namespace {
52 G4Mutex EventMgrMutex = G4MUTEX_INITIALIZER;
53}
54
55#include <unordered_set>
56
57G4ThreadLocal G4EventManager* G4EventManager::fpEventManager = nullptr;
58
60{
61 return fpEventManager;
62}
63
65{
66 if(fpEventManager != nullptr)
67 {
68 G4Exception("G4EventManager::G4EventManager", "Event0001", FatalException,
69 "G4EventManager::G4EventManager() has already been made.");
70 }
71 else
72 {
73 trackManager = new G4TrackingManager;
74 transformer = new G4PrimaryTransformer;
75 trackContainer = new G4StackManager;
76 theMessenger = new G4EvManMessenger(this);
78 stateManager = G4StateManager::GetStateManager();
79 fpEventManager = this;
80 }
81}
82
84{
85 delete trackContainer;
86 delete transformer;
87 delete trackManager;
88 delete theMessenger;
89 delete userEventAction;
90 fpEventManager = nullptr;
91}
92
93void G4EventManager::DoProcessing(G4Event* anEvent)
94{
95 abortRequested = false;
96 G4ApplicationState currentState = stateManager->GetCurrentState();
97 if(currentState != G4State_GeomClosed)
98 {
99 G4Exception("G4EventManager::ProcessOneEvent", "Event0002", JustWarning,
100 "IllegalState -- Geometry not closed: cannot process an event.");
101 return;
102 }
103 currentEvent = anEvent;
104 stateManager->SetNewState(G4State_EventProc);
105 if(storetRandomNumberStatusToG4Event > 1)
106 {
107 std::ostringstream oss;
109 randomNumberStatusToG4Event = oss.str();
110 currentEvent->SetRandomNumberStatusForProcessing(randomNumberStatusToG4Event);
111 }
112
113 // Resetting Navigator has been moved to G4EventManager,
114 // so that resetting is now done for every event.
115 G4ThreeVector center(0,0,0);
118 navigator->LocateGlobalPointAndSetup(center,nullptr,false);
119
120 G4Track* track = nullptr;
121 G4TrackStatus istop = fAlive;
122
123#ifdef G4VERBOSE
124 if ( verboseLevel > 0 )
125 {
126 G4cout << "=====================================" << G4endl;
127 G4cout << " G4EventManager::ProcessOneEvent() " << G4endl;
128 G4cout << "=====================================" << G4endl;
129 }
130#endif
131
132 trackContainer->PrepareNewEvent(currentEvent);
133
134#ifdef G4_STORE_TRAJECTORY
135 trajectoryContainer = nullptr;
136#endif
137
139 if(sdManager != nullptr)
140 { currentEvent->SetHCofThisEvent(sdManager->PrepareNewEvent()); }
141
142 if(userEventAction != nullptr) userEventAction->BeginOfEventAction(currentEvent);
143
144#if defined(GEANT4_USE_TIMEMORY)
145 eventProfiler.reset(new ProfilerConfig(currentEvent));
146#endif
147
148#ifdef G4VERBOSE
149 if ( verboseLevel > 1 )
150 {
151 G4cout << currentEvent->GetNumberOfPrimaryVertex()
152 << " vertices passed from G4Event." << G4endl;
153 }
154#endif
155
156 if(!abortRequested)
157 {
158 StackTracks(transformer->GimmePrimaries(currentEvent,trackIDCounter), true);
159 }
160
161#ifdef G4VERBOSE
162 if ( verboseLevel > 0 )
163 {
164 G4cout << trackContainer->GetNTotalTrack() << " primaries "
165 << "are passed from G4EventTransformer." << G4endl;
166 G4cout << "!!!!!!! Now start processing an event !!!!!!!" << G4endl;
167 }
168#endif
169
170 std::unordered_set<G4VTrackingManager *> trackingManagersToFlush;
171
172 do
173 {
174 G4VTrajectory* previousTrajectory;
175 while( (track=trackContainer->PopNextTrack(&previousTrajectory)) != nullptr )
176 { // Loop checking 12.28.2015 M.Asai
177
178 const G4ParticleDefinition* partDef = track->GetParticleDefinition();
179 G4VTrackingManager* particleTrackingManager = partDef->GetTrackingManager();
180
181 if (particleTrackingManager != nullptr)
182 {
183#ifdef G4VERBOSE
184 if ( verboseLevel > 1 )
185 {
186 G4cout << "Track " << track << " (trackID " << track->GetTrackID()
187 << ", parentID " << track->GetParentID()
188 << ") is handed over to custom TrackingManager." << G4endl;
189 }
190#endif
191
192 particleTrackingManager->HandOverOneTrack(track);
193 // The particle's tracking manager may either track immediately or
194 // defer processing until FlushEvent is called. Thus, we must neither
195 // check the track's status nor stack secondaries.
196
197 // Remember this tracking manager to later call FlushEvent.
198 trackingManagersToFlush.insert(particleTrackingManager);
199
200 } else {
201#ifdef G4VERBOSE
202 if ( verboseLevel > 1 )
203 {
204 G4cout << "Track " << track << " (trackID " << track->GetTrackID()
205 << ", parentID " << track->GetParentID()
206 << ") is passed to G4TrackingManager." << G4endl;
207 }
208#endif
209
210 tracking = true;
211 trackManager->ProcessOneTrack( track );
212 istop = track->GetTrackStatus();
213 tracking = false;
214
215#ifdef G4VERBOSE
216 if ( verboseLevel > 0 )
217 {
218 G4cout << "Track (trackID " << track->GetTrackID()
219 << ", parentID " << track->GetParentID()
220 << ") is processed with stopping code " << istop << G4endl;
221 }
222#endif
223
224 G4VTrajectory* aTrajectory = nullptr;
225#ifdef G4_STORE_TRAJECTORY
226 aTrajectory = trackManager->GimmeTrajectory();
227
228 if(previousTrajectory != nullptr)
229 {
230 previousTrajectory->MergeTrajectory(aTrajectory);
231 delete aTrajectory;
232 aTrajectory = previousTrajectory;
233 }
234 if((aTrajectory != nullptr)&&(istop!=fStopButAlive)
235 &&(istop!=fSuspend)&&(istop!=fSuspendAndWait))
236 {
237 if(trajectoryContainer == nullptr)
238 {
239 trajectoryContainer = new G4TrajectoryContainer;
240 currentEvent->SetTrajectoryContainer(trajectoryContainer);
241 }
242 trajectoryContainer->insert(aTrajectory);
243 }
244#endif
245
246 G4TrackVector* secondaries = trackManager->GimmeSecondaries();
247 switch (istop)
248 {
249 case fStopButAlive:
250 case fSuspend:
251 case fSuspendAndWait:
252 trackContainer->PushOneTrack( track, aTrajectory );
253 StackTracks( secondaries );
254 break;
255
257 trackContainer->PushOneTrack( track );
258 StackTracks( secondaries );
259 break;
260
261 case fStopAndKill:
262 StackTracks( secondaries );
263 delete track;
264 break;
265
266 case fAlive:
267 G4Exception("G4EventManager::DoProcessing", "Event004", JustWarning,
268 "Illegal track status returned from G4TrackingManager."\
269 " Continue with simulation.");
270 break;
271
273 if( secondaries != nullptr )
274 {
275 for(auto & secondarie : *secondaries)
276 { delete secondarie; }
277 secondaries->clear();
278 }
279 delete track;
280 break;
281 }
282 }
283 }
284
285 // Flush all tracking managers, which may have deferred processing until now.
286 for (G4VTrackingManager *tm : trackingManagersToFlush)
287 {
288 tm->FlushEvent();
289 }
290 trackingManagersToFlush.clear();
291
292 // flush any fast simulation models
294
295 // Check if flushing one of the tracking managers or a fast simulation model
296 // stacked new secondaries.
297 } while (trackContainer->GetNUrgentTrack() > 0);
298
299#ifdef G4VERBOSE
300 if ( verboseLevel > 0 )
301 {
302 G4cout << "NULL returned from G4StackManager." << G4endl;
303 G4cout << "Terminate current event processing." << G4endl;
304 }
305#endif
306
307 if(sdManager != nullptr)
308 {
309 sdManager->TerminateCurrentEvent(currentEvent->GetHCofThisEvent());
310 }
311
312#if defined(GEANT4_USE_TIMEMORY)
313 eventProfiler.reset();
314#endif
315
316// In case of sub-event parallelism, an event may not be completed at
317// this point but results of sus-events may be merged later. Thus
318// userEventAction->EndOfEventAction() is invoked by G4RunManager
319// immediately prior to deleting the event.
320 if(!subEventPara && (userEventAction != nullptr))
321 {
322 userEventAction->EndOfEventAction(currentEvent);
323 }
324
325 // Store remaining sub-events to the current event
326 auto nses = trackContainer->GetNSubEventTypes();
327 if(nses>0)
328 {
329#ifdef G4VERBOSE
330 if ( verboseLevel > 2 )
331 {
332 G4cout<<"## End of processing an event --- "
333 <<nses<<" sub-event types registered."<<G4endl;
334 }
335#endif
336 for(std::size_t i=0;i<nses;i++)
337 {
338 auto ty = trackContainer->GetSubEventType(i);
339 trackContainer->ReleaseSubEvent(ty);
340 }
341 }
342
343 stateManager->SetNewState(G4State_GeomClosed);
344 currentEvent = nullptr;
345 abortRequested = false;
346}
347
349{
350 G4AutoLock lock(&EventMgrMutex);
351 if(currentEvent==nullptr) return nullptr;
352 return currentEvent->PopSubEvent(ty);
353}
354
356{
357 G4AutoLock lock(&EventMgrMutex);
358 auto ev = se->GetEvent();
359 ev->MergeSubEventResults(evt);
360 userEventAction->MergeSubEvent(ev,evt);
361#ifdef G4VERBOSE
362 // Capture this here because termination will delete subevent...
363 G4int seType = se->GetSubEventType();
364#endif
365 ev->TerminateSubEvent(const_cast<G4SubEvent*>(se));
366#ifdef G4VERBOSE
367 if ( verboseLevel > 1 )
368 {
369 G4cout << "A sub-event of type " << seType
370 << " is merged to the event " << ev->GetEventID() << G4endl;
371 if(ev->GetNumberOfRemainingSubEvents()>0)
372 {
373 G4cout << " ---- This event still has " << ev->GetNumberOfRemainingSubEvents()
374 << " sub-events to be processed." << G4endl;
375 }
376 else
377 { G4cout << " ---- This event has no more sub-event remaining." << G4endl; }
378 }
379#endif
380}
381
383 G4bool IDhasAlreadySet)
384{
385 if( trackVector != nullptr )
386 {
387 if( trackVector->empty() ) return;
388 for( auto newTrack : *trackVector )
389 {
390 ++trackIDCounter;
391 if(!IDhasAlreadySet)
392 {
393 newTrack->SetTrackID( trackIDCounter );
394 if(newTrack->GetDynamicParticle()->GetPrimaryParticle() != nullptr)
395 {
396 auto* pp
397 = (G4PrimaryParticle*)(newTrack->GetDynamicParticle()->GetPrimaryParticle());
398 pp->SetTrackID(trackIDCounter);
399 }
400 }
401 newTrack->SetOriginTouchableHandle(newTrack->GetTouchableHandle());
402 trackContainer->PushOneTrack( newTrack );
403#ifdef G4VERBOSE
404 if ( verboseLevel > 1 )
405 {
406 G4cout << "A new track " << newTrack
407 << " (trackID " << newTrack->GetTrackID()
408 << ", parentID " << newTrack->GetParentID()
409 << ") is passed to G4StackManager." << G4endl;
410 }
411#endif
412 }
413 trackVector->clear();
414 }
415}
416
418{
419 userEventAction = userAction;
420 if(userEventAction != nullptr)
421 {
422 userEventAction->SetEventManager(this);
423 }
424}
425
427{
428 userStackingAction = userAction;
429 trackContainer->SetUserStackingAction(userAction);
430}
431
433{
434 userTrackingAction = userAction;
435 trackManager->SetUserAction(userAction);
436}
437
439{
440 userSteppingAction = userAction;
441 trackManager->SetUserAction(userAction);
442}
443
445{
446 trackIDCounter = 0;
447 DoProcessing(anEvent);
448}
449
451 G4Event* anEvent)
452{
453 static G4ThreadLocal G4String* randStat = nullptr;
454 if (randStat == nullptr) randStat = new G4String;
455 trackIDCounter = 0;
456 G4bool tempEvent = false;
457 if(anEvent == nullptr)
458 {
459 anEvent = new G4Event();
460 tempEvent = true;
461 }
462 if (storetRandomNumberStatusToG4Event==1
463 || storetRandomNumberStatusToG4Event==3)
464 {
465 std::ostringstream oss;
467 (*randStat) = oss.str();
468 anEvent->SetRandomNumberStatus(*randStat);
469 }
470 StackTracks(trackVector,false);
471 DoProcessing(anEvent);
472 if(tempEvent) { delete anEvent; }
473}
474
476{
477 G4ApplicationState currentState = stateManager->GetCurrentState();
478 if(currentState != G4State_EventProc || currentEvent == nullptr)
479 {
480 G4Exception("G4EventManager::SetUserInformation",
481 "Event0003", JustWarning,
482 "G4VUserEventInformation cannot be set because of absence "\
483 "of G4Event.");
484 return;
485 }
486
487 currentEvent->SetUserInformation(anInfo);
488}
489
491{
492 G4ApplicationState currentState = stateManager->GetCurrentState();
493 if(currentState != G4State_EventProc || currentEvent == nullptr)
494 {
495 return nullptr;
496 }
497
498 return currentEvent->GetUserInformation();
499}
500
502{
503 if(currentEvent != nullptr) { currentEvent->KeepTheEvent(); }
504}
505
507{
508 abortRequested = true;
509 trackContainer->clear();
510 if(tracking) trackManager->EventAborted();
511}
G4ApplicationState
@ G4State_EventProc
@ G4State_GeomClosed
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
G4TrackStatus
@ fKillTrackAndSecondaries
@ fSuspend
@ fAlive
@ fSuspendAndWait
@ fStopAndKill
@ fStopButAlive
@ fPostponeToNextEvent
std::vector< G4Track * > G4TrackVector
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
static std::ostream & saveFullState(std::ostream &os)
Definition Random.cc:288
void SetUserAction(G4UserEventAction *userAction)
void SetUserInformation(G4VUserEventInformation *anInfo)
G4ProfilerConfig< G4ProfileType::Event > ProfilerConfig
static G4EventManager * GetEventManager()
void StackTracks(G4TrackVector *trackVector, G4bool IDhasAlreadySet=false)
G4SubEvent * PopSubEvent(G4int ty)
void ProcessOneEvent(G4Event *anEvent)
G4VUserEventInformation * GetUserInformation()
void TerminateSubEvent(const G4SubEvent *se, const G4Event *evt)
G4int GetNumberOfPrimaryVertex() const
Definition G4Event.hh:138
void SetRandomNumberStatus(G4String &st)
Definition G4Event.hh:95
void KeepTheEvent(G4bool vl=true)
Definition G4Event.hh:105
G4HCofThisEvent * GetHCofThisEvent() const
Definition G4Event.hh:161
void MergeSubEventResults(const G4Event *se)
Definition G4Event.cc:204
void SetRandomNumberStatusForProcessing(G4String &st)
Definition G4Event.hh:100
void SetHCofThisEvent(G4HCofThisEvent *value)
Definition G4Event.hh:87
void SetUserInformation(G4VUserEventInformation *anInfo)
Definition G4Event.hh:176
G4SubEvent * PopSubEvent(G4int)
Definition G4Event.cc:173
G4VUserEventInformation * GetUserInformation() const
Definition G4Event.hh:178
void SetTrajectoryContainer(G4TrajectoryContainer *value)
Definition G4Event.hh:91
static G4GlobalFastSimulationManager * GetGlobalFastSimulationManager()
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
G4VTrackingManager * GetTrackingManager() const
G4TrackVector * GimmePrimaries(G4Event *anEvent, G4int trackIDCounter=0)
void TerminateCurrentEvent(G4HCofThisEvent *HCE)
G4HCofThisEvent * PrepareNewEvent()
static G4SDManager * GetSDMpointerIfExist()
G4int GetNTotalTrack() const
G4int GetNUrgentTrack() const
G4int GetSubEventType(std::size_t i)
G4Track * PopNextTrack(G4VTrajectory **newTrajectory)
G4int PrepareNewEvent(G4Event *currentEvent)
std::size_t GetNSubEventTypes()
G4int PushOneTrack(G4Track *newTrack, G4VTrajectory *newTrajectory=nullptr)
void SetUserStackingAction(G4UserStackingAction *value)
void ReleaseSubEvent(G4int ty)
const G4ApplicationState & GetCurrentState() const
static G4StateManager * GetStateManager()
G4bool SetNewState(const G4ApplicationState &requestedState)
G4int GetSubEventType() const
Definition G4SubEvent.hh:61
G4Event * GetEvent() const
Definition G4SubEvent.hh:69
G4TrackStatus GetTrackStatus() const
G4int GetTrackID() const
const G4ParticleDefinition * GetParticleDefinition() const
G4int GetParentID() const
void SetUserAction(G4UserTrackingAction *apAction)
G4TrackVector * GimmeSecondaries() const
void ProcessOneTrack(G4Track *apValueG4Track)
G4VTrajectory * GimmeTrajectory() const
G4bool insert(G4VTrajectory *p)
static G4TransportationManager * GetTransportationManager()
G4Navigator * GetNavigatorForTracking() const
virtual void SetEventManager(G4EventManager *value)
virtual void MergeSubEvent(G4Event *masterEvent, const G4Event *subEvent)
virtual void BeginOfEventAction(const G4Event *anEvent)
virtual void EndOfEventAction(const G4Event *anEvent)
virtual void HandOverOneTrack(G4Track *aTrack)=0
virtual void MergeTrajectory(G4VTrajectory *secondTrajectory)=0
#define G4ThreadLocal
Definition tls.hh:77