Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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