DrawTrajectory ignored in EndOfEventAction

My drawing command, ‘trj->DrawTrajectory();’, where trj is G4Trajectory, in my EventAction::EndOfEventAction seems to be ignored. It seems to be taken over by ‘/vis/scene/endOfEventAction accumulate N’, in my vis.mac.

If I remove trj->DrawTrajectory(), it still draws.

I would like to accumulate, but only what I draw.

It seems that I have been successful with this in the past, but for some reason, my approach is currently unsuccessful. I imagine that the fix is something rather silly.


Hi Micah

It’s a while since we put this functionality in place, so I may be mis-remembering, but here is what I think should happen.

/vis/scene/endOfEventAction accumulate N does/should not affect what is drawn. It affects only whether the trajectories are cleared (refresh) or not (accumulate) at the end of event.

/vis/scene/add/trajectories on the other hand asks the vis manager to draw trajectories. So if you /vis/scene/add/trajectories, putting trj->DrawTrajectory() in your event action should have no effect. If you do not request that, then your trj->DrawTrajectory() should be effective, and if this is subject to some selection criterion (some interesting events perhaps) then you should only see those events, accumulated or not depending on /vis/scene/endOfEventAction. That’s what I think should happen, but if you find different, we will dig into it further.

There are other ways of drawing selected events. In your event action you can keep selected events:

if (some criterion) {
G4EventManager* evMan = G4EventManager::GetEventManager();

and review them at end of run, but you can also


Hope this helps

Thanks John,
I think we’re on the same page, but I probably misspoke when I hung the issue on /vis/scene/endOfEventAction. I should have put it on the /vis/scene/add/trajectories, as you correctly did.

Here is my situation (as simplified as I can make it, using my cpp code and vis.mac):


void myEventAction::EndOfEventAction(const G4Event* evt)
G4TrajectoryContainer* trajectoryContainer = evt->GetTrajectoryContainer();
G4int n_trajectories = trajectoryContainer->entries();
if (G4VVisManager::GetConcreteInstance()){
for (i=0; i<n_trajectories; i++){
G4Trajectory* trj = (G4Trajectory*) ((*(evt->GetTrajectoryContainer()))[i]);
// if(conditions)
G4cout << “Drawing” << G4endl;


/vis/viewer/set/viewpointVector -1 0 0
/vis/open OGL 600x600-0+0
/tracking/storeTrajectory 1
/vis/scene/endOfEventAction accumulate 100
/run/beamOn 10

If I remove trj->DrawTrajectory() in *.cc; and keep /vis/scene/add/trajectories in *.mac, I get all 10 events.
However, if I keep trj->DrawTrajectory() in *.cc; and remove /vis/scene/add/trajectories in *.mac, I get no events displayed.
In both cases, my debug statement “Drawing” in *.cc is printed.

I would have expected that the latter would have given me the trajectories that I requested (based on my chosen conditions). I believe that my understanding is consistent with your comments.

There’s not an invisibility thing going on, is there? Just to reiterate, this did work in the past (prior to my current version of 10.07).


Hi Micah

I need to see if I can replicate this. I’ll get back to you.

I can’t recall any changes in 10.7 that might have caused this. I will have a look in the latest version 11.0 first.


Hi Micah

I have it! My guess is you are running in multithreaded mode. We abandoned “user drawing” in multithreaded mode because of the complication of separating drawing from different events that are being processed in parallel.

All should work in sequential mode. Or use the event keeping facilities I mentioned above.

Let me know how you get on.

Thanks John,
Unfortunately, I am not running in MT mode. If you don’t have any other suggestions, I will switch over to the new approach, as you suggest. However, I would like to know what and why, so that I don’t stumble with using trajectories in the future.


PS: I am on a MacBook Pro

Hello John,
I believe I am getting to the neighborhood of where the problem is at. I’m still trying to drill down on the culprit, but maybe you can see what I am looking at and see if something jogs your memory.

I’m in G4VisManager.cc::DispatchToModel(…). If I look at on old G4 version, i.e. 4.8, when I believe that my trj->DrawTrajectory() in EndOfEventAction(…) was working, the DispatchToModel(…) was:
void G4VisManager::DispatchToModel(const G4VTrajectory& trajectory, G4int i_mode)
assert (0 != fpTrajectoryModelMgr);

const G4VTrajectoryModel* model = fpTrajectoryModelMgr->Current();

if (0 == model) {
// No model was registered with the trajectory model manager.
// Use G4TrajectoryDrawByCharge as a default.
fpTrajectoryModelMgr->Register(new G4TrajectoryDrawByCharge());

if (fVerbosity >= warnings) {
  G4cout<<"G4VisManager: Using G4TrajectoryDrawByCharge as default trajectory model."<<G4endl;
  G4cout<<"See commands in /vis/modeling/trajectories/ for other options."<<G4endl;


model = fpTrajectoryModelMgr->Current();
assert (0 != model); // Should definitely exist now

model->Draw(trajectory, i_mode);

However, my current version, 10.7 is:
void G4VisManager::DispatchToModel(const G4VTrajectory& trajectory)
G4bool visible(true);

// See if trajectory passes filter
G4bool passed = FilterTrajectory(trajectory);

if (!passed) {
// Draw invisible trajectory if trajectory failed filter and
// are filtering in soft mode
if (fpTrajFilterMgr->GetMode() == FilterMode::Soft) visible = false;
else {return;}

// Go on to draw trajectory
assert (0 != fpTrajDrawModelMgr);

const G4VTrajectoryModel* trajectoryModel = CurrentTrajDrawModel();

assert (0 != trajectoryModel); // Should exist

if (IsValidView()) {
trajectoryModel->Draw(trajectory, visible);

One thing that jumps out at me is that in the new version there is a comment suggesting that if the filter fails, invisible trajectories are drawn. Does this mean something to you?

I’m going to continue to hunt down this potential issue, but hopefully, you will see something and let me know.


OK, Micah. Please continue digging. I am taking a few days away, so might not be able to follow this up. Or at least, only sporadically.

Note that

if (fpTrajFilterMgr->GetMode() == FilterMode::Soft) visible = false;

The default is, I believe “hard mode” (i.e., not “soft”). Soft is only intended to be used for passing trajectories that do not pass the filtering to a driver that can “resurrect” them after end of run on user request. I think only HepRepFile and its browser HepRApp can do this. (Personally, I cannot think of a reasonable use case for this.) Normally, in hard mode, trajectories that do not pass are simply discarded.

Just checking…When you say you are not running in MT mode, are you sure? Sequential is not the same (as far as this is concerned) as MT mode with a single thread. 10.7 has to be built separately for sequential mode.

I will watch this thread when I can and think about what might be the problem,


Hi John,
I hope your respite was helpful to you. I believe that the issue may be in G4VisManager::EndOfRun(). The current version of G4VisManager::EndOfRun() is a lot more complex than the previous versions, and I keep getting twisted.

As per MT mode, this is what I mean, in my main.cc:
G4cout << “MT run manager” << G4endl;
G4MTRunManager * runManager = new G4MTRunManager;
G4cout << “NonMT run manager” << G4endl;
G4RunManager * runManager = new G4RunManager;

where the output is “NonMT run manager”.

I tried using the ‘kept events’ approach, and amazingly, it does the same thing. Here is my eventAction and runAction user class files:

myEventAction.cc ******************************

void myEventAction::EndOfEventAction(const G4Event* evt)

// get number of stored trajectories
G4TrajectoryContainer* trajectoryContainer = evt->GetTrajectoryContainer();
G4int i, n_trajectories = 0;
if (trajectoryContainer) n_trajectories = trajectoryContainer->entries();
G4String particleName;

G4EventManager* eventManager = G4EventManager::GetEventManager();
G4int event_id = = evt->GetEventID();
if(event_id<100 || event_id%100 == 0) G4cout << "End event number: " << event_id << G4endl;
// Testing
G4cout << "Keeping event " << event_id << G4endl;
return; // testing

// extract the trajectories and draw them
if (G4VVisManager::GetConcreteInstance()){
for (i=0; i<n_trajectories; i++)
{ G4Trajectory* trj = (G4Trajectory*)
particleName = trj->GetParticleName();
if(event_id<2){ //particleName==“gamma”){
G4cout << “Drawing or Keeping event " << event_id << G4endl;
return; // this is only for testing; remove the return for below
// Declare end of visualization

myRunAction.cc ******************************

void myRunAction::EndOfRunAction(const G4Run* aRun)
G4int run_id = aRun->GetRunID();
G4cout << “### Run " << run_id << " end.” << G4endl;


// Testing:

G4VisManager* visManager( static_cast< G4VisManager * >(G4VVisManager::GetConcreteInstance() ) );
G4Scene* curScene( visManager->GetCurrentScene() );
G4bool isValid = true;
if ( ! curScene ) isValid = false;

G4VViewer* curViewer( visManager->GetCurrentViewer() );
G4bool isViewer = true;
if ( ! curViewer ) isViewer = false;

if (isValid && isViewer){
G4cout << "Initialised visManager at EndOfRunAction with refresher: " << curScene->GetRefreshAtEndOfRun()
<< " and using auto-refresh: " << curViewer->GetViewParameters().IsAutoRefresh() << G4endl;
else if (isValid){
G4cout << "Initialised visManager at EndOfRunAction with refresher: " << curScene->GetRefreshAtEndOfRun() << G4endl;
G4cout << “No visManager at EndOfRunAction” << G4endl;

So, you can see from myEventAction::EndOfEventAction(…),
it should keep 2 of my 10 events (i.e. /run/beamOn 10). As before with attempting my original trj->DrawTrajectory(), I should have only had 2 events worth of trajectories. In both approaches, I had all 10 events drawn, but only if I used /vis/scene/add/trajectories in my vis.mac. If I did not include /vis/scene/add/trajectories, nothing was drawn (or was invisible).

If you look at my myRunAction::EndOfRunAction(…) you can see that I did some diagnostics of G4VisManager, specifically in EndOfRun(), namely this section:

G4VisManager::EndOfRun() *************************

if (GetConcreteInstance() && valid) {
if (fpScene->GetRefreshAtEndOfRun()) {
if (fpViewer->GetViewParameters().IsAutoRefresh()) {
else { stuff}

You left a lot of comments in this section, and there are references to refreshing, and I was curious whether or not my drawings were being ‘refreshed’ out of the scene.

So, I am stuck… my approach for trj->DrawTrajectory() doesn’t work, nor does my G4EventManager->KeepTheCurrentEvent().

I put my /vis/verbose level to 6 and here is some of the output:

G4VisManager::GeometryHasChanged() called.
/vis/scene/notifyHandlers scene-0
G4VisManager::SetCurrentViewer: viewer now viewer-0 (OpenGLStoredQt)
G4VisManager::SetCurrentSceneHandler: scene handler now “scene-handler-0”
Viewer “viewer-0 (OpenGLStoredQt)” of scene handler “scene-handler-0”
refreshed at request of scene “scene-0”.
G4VisManager::SetCurrentViewer: viewer now viewer-0 (OpenGLStoredQt)
G4VisManager::SetCurrentSceneHandler: scene handler now “scene-handler-0”

Run 0 starts.

Run: 0; Seed: 1; start.

Initialised visManager at BeginOfRunAction with refresher: 1 and using auto-refresh: 1
Begin event number: 0 (0)
End event number: 0
Keeping event 0
Begin event number: 1 (1)
End event number: 1
Keeping event 1
Begin event number: 2 (2)
End event number: 2
Begin event number: 3 (3)
End event number: 3
Begin event number: 4 (4)
End event number: 4
Begin event number: 5 (5)
End event number: 5
Begin event number: 6 (6)
End event number: 6
Begin event number: 7 (7)
End event number: 7
Begin event number: 8 (8)
End event number: 8
Begin event number: 9 (9)
End event number: 9
Run terminated.
Run Summary
Number of events processed : 10
User=0.020000s Real=0.031626s Sys=0.010000s

Run 0 end.

10 events have been kept for refreshing and/or reviewing.
“/vis/reviewKeptEvents” to review them one by one.
“/vis/enable”, then “/vis/viewer/flush” or “/vis/viewer/rebuild” to see them accumulated.
/vis/viewer/refresh viewer-0
Refreshing viewer “viewer-0 (OpenGLStoredQt)”…
Viewer “viewer-0 (OpenGLStoredQt)” refreshed.
(You might also need “/vis/viewer/update”.)
/vis/viewer/update viewer-0
Viewer “viewer-0 (OpenGLStoredQt)” post-processing triggered.
Viewer “viewer-0 (OpenGLStoredQt)” flushed.
Viewer “viewer-0 (OpenGLStoredQt)” post-processing triggered.
Traversing scene data…
Refreshing events in run…
Traversing scene data…
Refreshing events in run…

Graphics systems deleted.
Visualization Manager deleting…
G4 kernel has come to Quit state.
================== Deleting memory pools ===================
Number of memory pools allocated: 18; of which, static: 4
Dynamic pools deleted: 14 / Total memory freed: 0.46 MB

RunManagerKernel is deleted. Good bye :slight_smile:

Again, I am using 10.07


I got it to work. I’m not sure what I did to make it work, but I will look at the new commands I have implemented and figure it out later. I am on vacation and I am being asked to grill up some burgers. I will post what I did later once the festivities end.


Good to hear, Micah. I look forward to hearing your story, for it’s still a puzzle to me. Hopefully this will lead to a bug fix.