Import Geant4 11.3.0 source tree

This commit is contained in:
Gabriele Cosmo
2024-12-06 11:11:40 +01:00
parent e58e650b32
commit 32390e802b
1984 changed files with 98713 additions and 83996 deletions
+134
View File
@@ -6,6 +6,140 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-10-27 John Allison (visman-V11-02-28)
- G4VisExecutive.icc:
- Remove #include <QtGlobal> - no longer needed.
- Was included to resolve some Qt5/6 issues in 11.2.
## 2024-10-16 John Allison (visman-V11-02-27)
- G4VSceneHandler.cc:
- Move some printing outside the loop over models - more hygenic
- Improve indentation.
## 2024-10-03 John Allison (visman-V11-02-26)
- Introduce TOOLS_USE_FREETYPE flag in vis management for /vis/plot command
- sources.cmake:
- Add geant4_module_compile_definitions.
- Set cpp flag TOOLS_USE_FREETYPE if built with GEANT4_USE_FREETYPE.
- G4VisCommandsCompound.cc:
- If TOOLS_USE_FREETYPE, augment /vis/plot command to take "style" argument.
- Candidates are: "none ROOT_default hippodraw".
- Default is: "ROOT_default".
## 2024-10-02 John Allison (visman-V11-02-25)
- G4VisManager.cc:
- Protect KeepForPostProcessing() with an mtVisSubThreadMutex lock.
- KeepForPostProcessing() is called on a worker thread, PostProcessingFinished()
is called on the vis sub-thread, so should be protected.
- Not sure about sub-event parallelism, because KeepForPostProcessing() is still
called on a worker thread, but PostProcessingFinished() is called from the
G4SubEvtRunManager. But having a short piece of code locked does no harm, so
let's do this.
- G4VisManager.cc, G4VisCommandsSceneAdd.cc:
- Tidied redundant comments and corrected some.
## 2024-09-30 Makoto Asai (visman-V11-02-24)
- G4VisManager.cc, G4VisCommandsSceneAdd.cc:
- Optimize the timing of G4Event::KeepForPostProcessing() and
G4Event::PostProcessingFinished() so that event object that are not
requested to be kept are cleanly deleted at the end of each run.
Kept events are deleted at the beginning of the next run or when the
program terminates.
- Use G4Run::GetNumberOfKeptEvent() to properly display the number of kept
events.
- Co-working with run-V11-02-18
## 2024-09-12 John Allison (visman-V11-02-23)
- G4ViewParameters.cc: Minor improvements to messages in output operator<<.
- G4VisCommandsSceneAdd.cc:
- G4VisCommandSceneAddLogo::SetNewValue (/vis/scene/add/logo):
- Ensure the logo respects the current requested number of sides per circle.
- G4VisCommandsViewer.cc:
- G4VisCommandViewerCreate::SetNewValue (/vis/viewer/create):
- Simplify the use of view parameters of a pre-existing viewer.
- Use the parameters of the most recent viewer whatever its type.
- Exclude GlobalMarkerScale from parameters copied from pre-existing viewer.
- Thus each viewer is allowed to specify its own GlobalMarkerScale.
- Mostly viewers use the default value of 1, but ToolsSG sets it to 2
to handle special displays such as Apple's Retina.
## 2024-08-31 John Allison (visman-V11-02-22)
- Coverity fixes.
- Some checks, which gave Coverity concern, are no longer needed, because
Begin/EndOfRun/Event are protected by flag set once and for all in
BeginOfRun.
## 2024-08-26 John Allison (visman-V11-02-21)
- G4VisManager.cc:
- Protect Begin/EndOfRun against invalid view (includes check on
existence of a scene).
- A dead-lock in MT mode if there is a view but no scene with OGL.
- Seems viewer has trouble changing threads.
- Some tidying and streamlining.
- Introduced local booleans isValidViewForRun and isFakeRun.
## 2024-08-18 John Allison (visman-V11-02-20)
- Improve messaging around /vis/verbose and /vis/list.
- G4VisManager:
- Introduce PrintAvailableVerbosity().
- GetVerbosityValue: Print verbosity options on unknown or empty argument
- G4VisCommands.cc:
- /vis/list: Add printing of verbosity options.
- /vis/verbose: Change default value to empty string (triggers printing
of verbosity options in G4VisManager::GetVerbosityValue().
## 2024-08-04 John Allison (visman-V11-02-19)
- Fix "accumulate" bug in Serial mode, and other small improvements.
- G4VisManager.cc:
- Bug fix: In Serial mode, "accumulate" fails (behaves like "refresh").
- This relates to end-of-event action, e.g., trajectory drawing.
- Bug was introduced in visman-V11-02-18.
- Fix and rationalise by moving the following to EndOfEventCleanup():
if (pScene->GetRefreshAtEndOfEvent()) {
pViewer->ShowView();
pSceneHandler->SetMarkForClearingTransientStore(true);
}
- Improve printing of colours in PrintAvailableColours and advise on use.
- Used in /vis/list.
- Tidy further:
- Remove some commented-out debug printing to make code cleaner to read.
- Fix some errant indentations.
- G4VisCommandsSceneAdd.cc:
- Move date model (/vis/scene/add/date) from run-duration to end-of-event list.
- Thus date and time are updated for every event displayed.
## 2024-07-21 John Allison (visman-V11-02-18)
- G4VisManager: Further rationalising and tidying after visman-V11-02-12.
- Replace method `G4bool Relinquishable` (used only if false) by its logical
opposite, `G4bool RequiredToBeKeptForVis` - clearer.
- Move `void EventReadyForVis` (invoked by G4SubEvtRunManager) to improve
readability of code.
- Improve some messaging.
## 2024-07-21 John Allison (visman-V11-02-17)
- G4VisExecutive.icc:
- Remove duplicate instantiation of TOOLSSG_OFFSCREEN
## 2024-07-17 John Allison (visman-V11-02-16)
- With gMocren-V11-02-00, modeling-V11-02-02
- Coverity fixes
## 2024-07-12 Guy Barrand (visman-V11-02-15)
- G4VViewer.hh: add virtual ReadyToDraw(). It helps avoiding a crash on macOS
if doing /run/beamOn in vis.mac at startup.
- G4VSceneHandler.cc: DrawEvent(), DrawEndOfRunModels(): check if viewer is
ReadyToDraw() at begin of method.
## 2024-07-06 John Allison (visman-V11-02-14)
- G4VisManager:
- Call PostProcessingFinished for _every_ event in EndOfEventCleanup.
- Write lengthy comment about different end-of-event scenarios.
- Tidy up previous tag visman-V11-02-12.
## 2024-06-21 Ben Morgan (visman-V11-02-13)
- Remove use of G4MULTITHREADED symbol where not required, using runtime checks
as far as possible.
## 2024-06-04 John Allison (visman-V11-02-12)
- G4VisManager:
- Implement EventReadyForVis, used by G4SubEvtRunManager.
@@ -105,9 +105,10 @@ public: // With description
// It is not yet the end of all drawing; that is signalled by
// ShowView ().)
virtual G4bool ReadyToDraw() {return true;}
std::vector<G4ThreeVector> ComputeFlyThrough(G4Vector3D*);
#ifdef G4MULTITHREADED
// Note: the order of calling of MovingToVisSubThread and SwitchToVisSubThread
// is undefined, so you may need to implement mutexes to ensure your preferred
// order - see, e.g., G4OpenGLQtViewer. To summarise, the order of calling is
@@ -120,23 +121,22 @@ public: // With description
// SwitchToMasterThread
// Called on the master thread before starting the vis sub-thread.
virtual void DoneWithMasterThread ();
virtual void DoneWithMasterThread () {}
// Called on the master thread after starting the vis sub-thread.
virtual void MovingToVisSubThread ();
virtual void MovingToVisSubThread () {}
// Called on the vis sub-thread at start of vis sub-thread.
virtual void SwitchToVisSubThread ();
virtual void SwitchToVisSubThread () {}
// Called on the vis sub-thread when all events have been processed.
virtual void DoneWithVisSubThread ();
virtual void DoneWithVisSubThread () {}
// Called on the vis sub-thread when all events have been processed.
virtual void MovingToMasterThread ();
virtual void MovingToMasterThread () {}
// Called on the master thread after the vis sub-thread has terminated.
virtual void SwitchToMasterThread ();
#endif
virtual void SwitchToMasterThread () {}
//////////////////////////////////////////////////////////////
// Stuff for scene tree.
@@ -70,10 +70,10 @@ protected:
void InterpolateViews
(G4VViewer* currentViewer,
std::vector<G4ViewParameters> viewVector,
const std::vector<G4ViewParameters>& viewVector,
const G4int nInterpolationPoints = 50,
const G4int waitTimePerPointmilliseconds = 20,
const G4String exportString = "");
const G4String& exportString = "");
void InterpolateToNewView
(G4VViewer* currentViewer,
@@ -81,7 +81,7 @@ protected:
const G4ViewParameters& newVP,
const G4int nInterpolationPoints = 50,
const G4int waitTimePerPointmilliseconds = 20,
const G4String exportString = "");
const G4String& exportString = "");
void Twinkle
// Twinkles the touchables in paths
@@ -186,7 +186,7 @@ private:
class G4VVisCommandGeometrySet: public G4VVisCommandGeometry {
protected:
void Set(G4String logVolName, const G4VVisCommandGeometrySetFunction&,
void Set(const G4String& logVolName, const G4VVisCommandGeometrySetFunction&,
G4int requestedDepth);
void SetLVVisAtts(G4LogicalVolume*, const G4VVisCommandGeometrySetFunction&,
G4int depth, G4int requestedDepth);
@@ -27,8 +27,6 @@
// /vis/multithreading commands - John Allison 29th September 2015
#ifdef G4MULTITHREADED
#ifndef G4VISCOMMANDSMULTITHREADING_HH
#define G4VISCOMMANDSMULTITHREADING_HH
@@ -66,5 +64,3 @@ private:
};
#endif
#endif
@@ -138,10 +138,6 @@
#include "G4VtkQt.hh" // no_geant4_module_check
#endif
#if defined (G4VIS_USE_OPENGLQT) || (G4VIS_USE_TOOLSSG_QT_GLES)
#include <QtGlobal>
#endif
#include "G4UImanager.hh"
#include "G4UIsession.hh"
#include "G4UIbatch.hh"
@@ -346,7 +342,6 @@ void G4VisExecutive::RegisterGraphicsSystems () {
RegisterGraphicsSystem (new G4RayTracer);
RegisterGraphicsSystem (new G4VRML2File);
RegisterGraphicsSystem (new G4GMocrenFile);
RegisterGraphicsSystem (new G4ToolsSGOffscreen);
G4VGraphicsSystem* tsg_offscreen = new G4ToolsSGOffscreen;
RegisterGraphicsSystem(tsg_offscreen);
tsg_offscreen->AddNickname("TSG_FILE");
@@ -333,8 +333,6 @@ public: // With description
G4bool FilterHit(const G4VHit&);
G4bool FilterDigi(const G4VDigi&);
#ifdef G4MULTITHREADED
virtual void SetUpForAThread();
// This method is invoked by G4WorkerRunManager
@@ -345,7 +343,6 @@ public: // With description
static G4ThreadFunReturnType G4VisSubThread(G4ThreadFunArgType);
// Vis sub-thread function.
#endif
////////////////////////////////////////////////////////////////////////
// Administration routines.
@@ -363,14 +360,10 @@ private:
void BeginOfEvent ();
void EndOfEvent ();
// This is called on change of state (G4ApplicationState). It is
// used to draw hits, digis and trajectories if included in the
// current scene at the end of event, as required.
G4bool Relinquishable (G4int eventID, G4int nKeptEvents, G4int nRequests);
void EndOfEventKernel (const G4Event* event);
void EndOfEventCleanup
(const G4Event* currentEvent,
G4int eventID); // See EndOfEventKernel: can be == -2?
void EndOfEventKernel (const G4Event* currentEvent);
void EndOfEventCleanup (const G4Event* currentEvent);
G4bool RequiredToBeKeptForVis (G4int eventID);
// Cluster of methods to handle end of event.
void EndOfRun ();
@@ -419,10 +412,8 @@ public: // With description
G4bool GetReviewingPlots () const;
G4bool GetAbortReviewPlots () const;
const G4ViewParameters& GetDefaultViewParameters () const;
#ifdef G4MULTITHREADED
G4int GetMaxEventQueueSize () const;
G4bool GetWaitOnEventQueueFull () const;
#endif
virtual const G4String& GetDefaultGraphicsSystemName();
// The above has to be virtual so that the derived class, G4VisExecutive,
// can override and non-const because on first pass it may/should
@@ -452,10 +443,8 @@ public: // With description
void SetReviewingPlots (G4bool);
void SetAbortReviewPlots (G4bool);
void SetDefaultViewParameters (const G4ViewParameters&);
#ifdef G4MULTITHREADED
void SetMaxEventQueueSize (G4int);
void SetWaitOnEventQueueFull (G4bool);
#endif
void SetDefaultGraphicsSystemName(const G4String&);
void SetDefaultXGeometryString (const G4String&);
void SetDefaultGraphicsSystemBasis(const G4String&);
@@ -485,6 +474,8 @@ public: // With description
static std::vector<G4String> VerbosityGuidanceStrings;
// Guidance on the use of visualization verbosity.
static void PrintAvailableVerbosity (std::ostream& os);
void PrintAvailableGraphicsSystems (Verbosity, std::ostream& = G4cout) const;
protected:
@@ -564,10 +555,8 @@ private:
G4bool fIsDrawGroup;
G4int fDrawGroupNestingDepth;
G4bool fIgnoreStateChanges;
#ifdef G4MULTITHREADED
G4int fMaxEventQueueSize;
G4bool fWaitOnEventQueueFull;
#endif
// Trajectory draw model manager
G4VisModelManager<G4VTrajectoryModel>* fpTrajDrawModelMgr;
@@ -126,8 +126,6 @@ inline const G4ViewParameters& G4VisManager::GetDefaultViewParameters() const {
return fDefaultViewParameters;
}
#ifdef G4MULTITHREADED
inline G4int G4VisManager::GetMaxEventQueueSize() const {
return fMaxEventQueueSize;
}
@@ -136,8 +134,6 @@ inline G4bool G4VisManager::GetWaitOnEventQueueFull () const {
return fWaitOnEventQueueFull;
}
#endif
inline const G4String& G4VisManager::GetDefaultGraphicsSystemName () {
return fDefaultGraphicsSystemName;
}
@@ -212,8 +208,6 @@ inline void G4VisManager::SetDefaultViewParameters
fDefaultViewParameters = vp;
}
#ifdef G4MULTITHREADED
inline void G4VisManager::SetMaxEventQueueSize (G4int size) {
fMaxEventQueueSize = size;
}
@@ -222,8 +216,6 @@ inline void G4VisManager::SetWaitOnEventQueueFull (G4bool wait) {
fWaitOnEventQueueFull = wait;
}
#endif
inline void G4VisManager::SetDefaultGraphicsSystemName (const G4String& name) {
fDefaultGraphicsSystemName = name;
}
@@ -102,3 +102,7 @@ geant4_module_link_libraries(G4vis_management
if(GEANT4_BUILD_MULTITHREADED)
geant4_module_link_libraries(G4vis_management PRIVATE G4volumes)
endif()
if(GEANT4_USE_FREETYPE)
geant4_module_compile_definitions(G4vis_management PRIVATE TOOLS_USE_FREETYPE)
endif()
@@ -754,39 +754,39 @@ void G4VSceneHandler::ProcessScene()
}
}
// Some printing
if(verbosity >= G4VisManager::confirmations) {
for (const auto& model: runDurationModelList) {
if (model.fActive) {
auto pvModel = dynamic_cast<G4PhysicalVolumeModel*>(model.fpModel);
if (pvModel) {
G4int nTouchables = 0;
G4cout << "Numbers of touchables by depth in model \""
<< pvModel->GetGlobalDescription() << "\":";
for (const auto& dn : pvModel->GetNumberOfTouchables()) {
G4cout << "\n Depth " << dn.first << ": " << dn.second;
nTouchables += dn.second;
}
G4cout << "\n Total number of touchables: " << nTouchables << G4endl;
}
}
}
if (fProblematicVolumes.size() > 0) {
G4cout << "Problematic volumes:";
for (const auto& prob: fProblematicVolumes) {
G4cout << "\n " << prob.first->GetName() << " (" << prob.second << ')';
}
G4cout << G4endl;
}
}
fpModel = 0;
delete pMP;
EndModeling();
}
// Some printing
if(verbosity >= G4VisManager::confirmations) {
for (const auto& model: runDurationModelList) {
if (model.fActive) {
auto pvModel = dynamic_cast<G4PhysicalVolumeModel*>(model.fpModel);
if (pvModel) {
G4int nTouchables = 0;
G4cout << "Numbers of touchables by depth in model \""
<< pvModel->GetGlobalDescription() << "\":";
for (const auto& dn : pvModel->GetNumberOfTouchables()) {
G4cout << "\n Depth " << dn.first << ": " << dn.second;
nTouchables += dn.second;
}
G4cout << "\n Total number of touchables: " << nTouchables << G4endl;
}
}
}
if (fProblematicVolumes.size() > 0) {
G4cout << "Problematic volumes:";
for (const auto& prob: fProblematicVolumes) {
G4cout << "\n " << prob.first->GetName() << " (" << prob.second << ')';
}
G4cout << G4endl;
}
}
fReadyForTransients = true;
// Refresh event from end-of-event model list.
@@ -869,6 +869,7 @@ void G4VSceneHandler::ProcessScene()
void G4VSceneHandler::DrawEvent(const G4Event* event)
{
if(!fpViewer->ReadyToDraw()) return;
const std::vector<G4Scene::Model>& EOEModelList =
fpScene -> GetEndOfEventModelList ();
std::size_t nModels = EOEModelList.size();
@@ -887,7 +888,7 @@ void G4VSceneHandler::DrawEvent(const G4Event* event)
fpViewer->InsertModelInSceneTree(fpModel);
// Reset modeling parameters pointer
fpModel -> SetModelingParameters(0);
fpModel -> SetModelingParameters(0);
}
}
fpModel = 0;
@@ -897,6 +898,7 @@ void G4VSceneHandler::DrawEvent(const G4Event* event)
void G4VSceneHandler::DrawEndOfRunModels()
{
if(!fpViewer->ReadyToDraw()) return;
const std::vector<G4Scene::Model>& EORModelList =
fpScene -> GetEndOfRunModelList ();
std::size_t nModels = EORModelList.size();
@@ -909,7 +911,7 @@ void G4VSceneHandler::DrawEndOfRunModels()
fpModel -> SetModelingParameters(pMP);
// Describe to the current scene handler
fpModel -> DescribeYourselfTo (*this);
fpModel -> DescribeYourselfTo (*this);
// Enter models in the scene tree
fpViewer->InsertModelInSceneTree(fpModel);
@@ -234,8 +234,8 @@ void G4VViewer::UpdateGUISceneTree()
void G4VViewer::InsertModelInSceneTree(G4VModel* model)
{
auto modelType = model->GetType();
auto modelDescription = model->GetGlobalDescription();
const auto& modelType = model->GetType();
const auto& modelDescription = model->GetGlobalDescription();
auto type = G4SceneTreeItem::model;
auto pvModel = dynamic_cast<G4PhysicalVolumeModel*>(model);
@@ -443,40 +443,6 @@ std::list<G4SceneTreeItem>::iterator G4VViewer::SceneTreeScene::FindOrInsertTouc
}
// clang-format on
#ifdef G4MULTITHREADED
void G4VViewer::DoneWithMasterThread()
{
// G4cout << "G4VViewer::DoneWithMasterThread" << G4endl;
}
void G4VViewer::MovingToMasterThread()
{
// G4cout << "G4VViewer::MovingToMasterThread" << G4endl;
}
void G4VViewer::SwitchToVisSubThread()
{
// G4cout << "G4VViewer::SwitchToVisSubThread" << G4endl;
}
void G4VViewer::DoneWithVisSubThread()
{
// G4cout << "G4VViewer::DoneWithVisSubThread" << G4endl;
}
void G4VViewer::MovingToVisSubThread()
{
// G4cout << "G4VViewer::MovingToVisSubThread" << G4endl;
}
void G4VViewer::SwitchToMasterThread()
{
// G4cout << "G4VViewer::SwitchToMasterThread" << G4endl;
}
#endif
std::ostream& operator<<(std::ostream& os, const G4VViewer& v)
{
os << "View " << v.fName << ":\n";
@@ -293,10 +293,10 @@ void G4VVisCommand::RefreshIfRequired(G4VViewer* viewer) {
void G4VVisCommand::InterpolateViews
(G4VViewer* currentViewer,
std::vector<G4ViewParameters> viewVector,
const std::vector<G4ViewParameters>& viewVector,
const G4int nInterpolationPoints,
const G4int waitTimePerPointmilliseconds,
const G4String exportString)
const G4String& exportString)
{
const G4int safety = (G4int)viewVector.size()*nInterpolationPoints;
G4int safetyCount = 0;
@@ -322,7 +322,7 @@ void G4VVisCommand::InterpolateToNewView
const G4ViewParameters& newVP,
const G4int nInterpolationPoints,
const G4int waitTimePerPointmilliseconds,
const G4String exportString)
const G4String& exportString)
{
std::vector<G4ViewParameters> viewVector;
viewVector.push_back(oldVP);
@@ -1011,7 +1011,7 @@ std::ostream& operator << (std::ostream& os, const G4ViewParameters& v) {
os << "\n Default TextVisAttributes:\n " << v.fDefaultTextVisAttributes;
os << "\n Default marker: " << v.fDefaultMarker;
os << "\n Default marker:\n " << v.fDefaultMarker;
os << "\n Global marker scale: " << v.fGlobalMarkerScale;
@@ -1048,7 +1048,7 @@ std::ostream& operator << (std::ostream& os, const G4ViewParameters& v) {
default: os << "unrecognised"; break;
}
os << "\n Vis attributes modifiers: ";
os << "\nVis attributes modifiers: ";
const std::vector<G4ModelingParameters::VisAttributesModifier>& vams =
v.fVisAttributesModifiers;
if (vams.empty()) {
@@ -1057,7 +1057,7 @@ std::ostream& operator << (std::ostream& os, const G4ViewParameters& v) {
os << vams;
}
os << "\n Time window parameters:"
os << "\nTime window parameters:"
<< "\n Start time: " << v.fStartTime/ns << " ns"
<< "\n End time: " << v.fEndTime/ns << " ns"
<< "\n Fade factor: " << v.fFadeFactor;
@@ -1083,7 +1083,7 @@ std::ostream& operator << (std::ostream& os, const G4ViewParameters& v) {
<< ' ' << v.fDisplayLightFrontGreen << ' ' << v.fDisplayLightFrontBlue;
}
os << "\n Special Mesh Rendering";
os << "\nSpecial Mesh Rendering";
if (v.fSpecialMeshRendering) {
os << " requested with option \"" << v.fSpecialMeshRenderingOption;
os << "\" for ";
@@ -214,10 +214,10 @@ G4String G4VisCommandList::GetCurrentValue (G4UIcommand*)
void G4VisCommandList::SetNewValue (G4UIcommand*, G4String newValue)
{
G4String& verbosityString = newValue;
G4VisManager::Verbosity verbosity =
fpVisManager->GetVerbosityValue(verbosityString);
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosityValue(newValue);
G4VisManager::PrintAvailableVerbosity(G4cout);
G4cout << G4endl;
fpVisManager->PrintAvailableGraphicsSystems(verbosity);
G4cout << G4endl;
fpVisManager->PrintAvailableModels(verbosity);
@@ -228,6 +228,7 @@ void G4VisCommandList::SetNewValue (G4UIcommand*, G4String newValue)
G4cout << G4endl;
G4UImanager* UImanager = G4UImanager::GetUIpointer();
UImanager->ApplyCommand("/vis/scene/list ! " + newValue);
G4cout << G4endl;
UImanager->ApplyCommand("/vis/viewer/list ! " + newValue);
G4cout <<
@@ -563,7 +564,7 @@ G4VisCommandVerbose::G4VisCommandVerbose () {
fpCommand -> SetGuidance(G4VisManager::VerbosityGuidanceStrings[i]);
}
fpCommand -> SetParameterName("verbosity", omitable=true);
fpCommand -> SetDefaultValue("warnings");
fpCommand -> SetDefaultValue("");
}
G4VisCommandVerbose::~G4VisCommandVerbose () {
@@ -580,6 +581,6 @@ void G4VisCommandVerbose::SetNewValue (G4UIcommand*,
fpVisManager->GetVerbosityValue(newValue);
fpVisManager->SetVerboseLevel(verbosity);
// Always prints whatever the verbosity...
G4cout << "Visualization verbosity changed to "
G4cout << "Visualization verbosity is now "
<< G4VisManager::VerbosityString(verbosity) << G4endl;
}
@@ -414,6 +414,12 @@ G4VisCommandPlot::G4VisCommandPlot ()
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("id", 'i', omitable = false);
fpCommand -> SetParameter (parameter);
#ifdef TOOLS_USE_FREETYPE
parameter = new G4UIparameter ("style", 's', omitable = true);
parameter -> SetParameterCandidates("none ROOT_default hippodraw");
parameter -> SetDefaultValue("ROOT_default");
fpCommand -> SetParameter (parameter);
#endif
}
G4VisCommandPlot::~G4VisCommandPlot ()
@@ -437,9 +443,13 @@ void G4VisCommandPlot::SetNewValue (G4UIcommand*, G4String newValue)
return;
}
G4String type, id;
std::istringstream is (newValue);
G4String type, id;
is >> type >> id;
#ifdef TOOLS_USE_FREETYPE
G4String style;
is >> style;
#endif
auto keepEnable = fpVisManager->IsEnabled();
@@ -455,6 +465,11 @@ void G4VisCommandPlot::SetNewValue (G4UIcommand*, G4String newValue)
ui->ApplyCommand("/vis/plotter/create " + plotterName);
ui->ApplyCommand("/vis/scene/add/plotter " + plotterName);
ui->ApplyCommand("/vis/plotter/add/" + type + ' ' + id + ' ' + plotterName);
#ifdef TOOLS_USE_FREETYPE
if (style != "none") {
ui->ApplyCommand("/vis/plotter/addStyle " + plotterName + ' ' + style);
}
#endif
ui->ApplyCommand("/vis/sceneHandler/attach");
if (!keepEnable) {
@@ -39,7 +39,7 @@
#define G4warn G4cout
void G4VVisCommandGeometrySet::Set
(G4String requestedName,
(const G4String& requestedName,
const G4VVisCommandGeometrySetFunction& setFunction,
G4int requestedDepth)
{
@@ -27,15 +27,16 @@
// /vis/multithreading commands - John Allison 29th September 2015
#include "G4Types.hh"
#ifdef G4MULTITHREADED
#include "G4VisCommandsMultithreading.hh"
#include "G4Threading.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithAString.hh"
#include "G4VisManager.hh"
// For future use with additional G4ios logging streams
#define G4warn G4cout
////////////// /vis/multithreading/actionOnEventQueueFull ///////////////////////////////////////
G4VisCommandMultithreadingActionOnEventQueueFull::G4VisCommandMultithreadingActionOnEventQueueFull()
@@ -64,6 +65,14 @@ void G4VisCommandMultithreadingActionOnEventQueueFull::SetNewValue(G4UIcommand*,
{
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
// Only relevant in a MT application
if(!G4Threading::IsMultithreadedApplication()) {
if (verbosity >= G4VisManager::warnings) {
G4warn << "command /vis/multithreading/actionOnEventQueueFull ignored in sequential mode" << G4endl;
}
return;
}
if (newValue == "wait") {
fpVisManager->SetWaitOnEventQueueFull(true);
} else {
@@ -116,6 +125,14 @@ void G4VisCommandMultithreadingMaxEventQueueSize::SetNewValue(G4UIcommand*, G4St
{
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
// Only relevant in a MT application
if(!G4Threading::IsMultithreadedApplication()) {
if (verbosity >= G4VisManager::warnings) {
G4warn << "command /vis/multithreading/maxEventQueueSize ignored in sequential mode" << G4endl;
}
return;
}
G4int maxEventQueueSize = fpCommand->GetNewIntValue(newValue);
fpVisManager->SetMaxEventQueueSize(maxEventQueueSize);
@@ -126,5 +143,3 @@ void G4VisCommandMultithreadingMaxEventQueueSize::SetNewValue(G4UIcommand*, G4St
<< G4endl;
}
}
#endif
@@ -448,7 +448,7 @@ void G4VisCommandSceneAddDate::SetNewValue (G4UIcommand*, G4String newValue)
model->SetGlobalTag("Date");
model->SetGlobalDescription("Date: " + newValue);
const G4String& currentSceneName = pScene -> GetName ();
G4bool successful = pScene -> AddRunDurationModel (model, warn);
G4bool successful = pScene -> AddEndOfEventModel(model, warn);
if (successful) {
if (verbosity >= G4VisManager::confirmations) {
G4cout << "Date has been added to scene \""
@@ -745,8 +745,7 @@ void G4VisCommandSceneAddEventID::EventID::operator()
// Only use if NOT reviewing kept events
if (fpVisManager->GetReviewingKeptEvents()) return;
const G4int nEvents = currentRun->GetNumberOfEventToBeProcessed();
const auto* events = currentRun->GetEventVector();
size_t nKeptEvents = events? events->size(): 0;
size_t nKeptEvents = (size_t)(currentRun->GetNumberOfKeptEvents());
oss << "Run " << currentRunID << " (" << nEvents << " event";
if (nEvents != 1) oss << 's';
oss << ", " << nKeptEvents << " kept)";
@@ -1883,7 +1882,11 @@ G4VisCommandSceneAddLogo::G4Logo::G4Logo
G4Tubs tG("tG",ri,ro,d2,0.15*pi,1.85*pi);
G4Box bG("bG",w2,ro2,d2);
G4UnionSolid logoG("logoG",&tG,&bG,G4Translate3D(ri+w2,-ro2,0.));
// Create with these vis atts (force solid) and current no of sides per circle.
G4Polyhedron::SetNumberOfRotationSteps
(fpVisManager->GetCurrentViewer()->GetViewParameters().GetNoOfSides());
fpG = logoG.CreatePolyhedron();
G4Polyhedron::ResetNumberOfRotationSteps ();
fpG->SetVisAttributes(visAtts);
fpG->Transform(G4Translate3D(-0.55*h,0.,0.));
fpG->Transform(transform);
@@ -38,7 +38,9 @@
#include "G4TouchablePropertiesScene.hh"
#include "G4TransportationManager.hh"
#include "G4BoundingExtentScene.hh"
#include <sstream>
#include <utility>
#define G4warn G4cout
@@ -440,7 +442,7 @@ void G4VisCommandSetTouchable::SetNewValue (G4UIcommand*, G4String newValue)
if (iEnd == G4String::npos) {
iEnd = newValue.length();
}
G4String name(newValue.substr(iBegin,iEnd-iBegin));
const G4String& name(newValue.substr(iBegin,iEnd-iBegin));
iBegin = newValue.find_first_not_of(' ',iEnd);
if (iBegin == G4String::npos) {
if (verbosity >= G4VisManager::warnings) {
@@ -1073,16 +1073,6 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand* command, G4String newVa
}
}
if (fThereWasAViewer) {
// ...and if it's still current...
auto existingViewer = fpVisManager->GetCurrentViewer();
if (existingViewer) {
// ...bring view parameters up to date...
fExistingVP = existingViewer->GetViewParameters();
fExistingSceneTree = existingViewer->GetSceneTree();
}
}
if (fThereWasAViewer && windowSizeHintString == "none") {
// The user did not specify a window size hint - get from existing VPs
windowSizeHintString = fExistingVP.GetXGeometryString();
@@ -1099,6 +1089,7 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand* command, G4String newVa
// Copy view parameters from existing viewer, except for...
fExistingVP.SetAutoRefresh(vp.IsAutoRefresh());
fExistingVP.SetBackgroundColour(vp.GetBackgroundColour());
fExistingVP.SetGlobalMarkerScale(vp.GetGlobalMarkerScale());
// ...including window hint paramaters that have been set already above...
fExistingVP.SetXGeometryString(vp.GetXGeometryString());
vp = fExistingVP;
@@ -43,6 +43,7 @@
#include <sstream>
#include <iomanip>
#include <utility>
#define G4warn G4cout
@@ -1302,7 +1303,7 @@ void G4VisCommandsViewerSet::SetNewValue
if (iEnd == G4String::npos) {
iEnd = newValue.length();
}
G4String name(newValue.substr(iBegin,iEnd-iBegin));
const G4String& name(newValue.substr(iBegin,iEnd-iBegin));
iBegin = newValue.find_first_not_of(' ',iEnd);
if (iBegin == G4String::npos) {
if (verbosity >= G4VisManager::warnings) {
@@ -80,19 +80,34 @@
#include <vector>
#include <sstream>
#ifdef G4MULTITHREADED
# include "G4Threading.hh"
# include "G4AutoLock.hh"
# include "G4GeometryWorkspace.hh" // no_geant4_module_check(!G4MULTITHREADED)
# include "G4SolidsWorkspace.hh"
# include <deque>
# include <typeinfo>
# include <chrono>
# include <thread>
#endif
#include "G4Threading.hh"
#include "G4AutoLock.hh"
#include "G4GeometryWorkspace.hh" // no_geant4_module_check(!G4MULTITHREADED)
#include "G4SolidsWorkspace.hh"
#include <deque>
#include <typeinfo>
#include <chrono>
#include <thread>
#include <utility>
#define G4warn G4cout
// Local threading related variables
namespace {
G4bool mtRunInProgress = false;
std::deque<const G4Event*> mtVisEventQueue;
G4Thread* mtVisSubThread = 0;
[[maybe_unused]] G4Mutex mtVisSubThreadMutex = G4MUTEX_INITIALIZER;
// G4Mutex visBeginOfRunMutex = G4MUTEX_INITIALIZER;
// G4Mutex visBeginOfEventMutex = G4MUTEX_INITIALIZER;
G4Mutex visEndOfEventMutex = G4MUTEX_INITIALIZER;
// G4Mutex visEndOfRunMutex = G4MUTEX_INITIALIZER;
G4bool isSubEventRunManagerType = false;
G4bool isValidViewForRun = false;
G4bool isFakeRun = false;
}
// Class statics
G4VisManager* G4VisManager::fpInstance = 0;
G4VisManager::Verbosity G4VisManager::fVerbosity = G4VisManager::warnings;
@@ -125,10 +140,8 @@ G4VisManager::G4VisManager (const G4String& verbosityString)
, fIsDrawGroup (false)
, fDrawGroupNestingDepth (0)
, fIgnoreStateChanges (false)
#ifdef G4MULTITHREADED
, fMaxEventQueueSize (100)
, fWaitOnEventQueueFull (true)
#endif
// All other objects use default constructors.
{
fpTrajDrawModelMgr = new G4VisModelManager<G4VTrajectoryModel>("/vis/modeling/trajectories");
@@ -494,13 +507,11 @@ void G4VisManager::RegisterMessengers () {
RegisterMessenger(new G4VisCommandGeometrySetForceWireframe);
RegisterMessenger(new G4VisCommandGeometrySetVisibility);
#ifdef G4MULTITHREADED
directory = new G4UIdirectory ("/vis/multithreading/");
directory -> SetGuidance("Commands unique to multithreading mode.");
fDirectoryList.push_back (directory);
RegisterMessenger(new G4VisCommandMultithreadingActionOnEventQueueFull);
RegisterMessenger(new G4VisCommandMultithreadingMaxEventQueueSize);
#endif
directory = new G4UIdirectory ("/vis/set/");
directory -> SetGuidance
@@ -745,7 +756,7 @@ void G4VisManager::Enable() {
if (fVerbosity >= warnings) {
std::size_t nKeptEvents = 0;
const G4Run* run = G4RunManager::GetRunManager()->GetCurrentRun();
if (run) nKeptEvents = run->GetEventVector()->size();
if (run) nKeptEvents = run->GetNumberOfKeptEvents();
G4String isare("are"),plural("s");
if (nKeptEvents == 1) {isare = "is"; plural = "";}
G4cout <<
@@ -913,9 +924,8 @@ void G4VisManager::SelectTrajectoryModel(const G4String& model)
void G4VisManager::BeginDraw (const G4Transform3D& objectTransform)
{
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
fDrawGroupNestingDepth++;
if (fDrawGroupNestingDepth > 1) {
G4Exception
@@ -934,9 +944,8 @@ void G4VisManager::BeginDraw (const G4Transform3D& objectTransform)
void G4VisManager::EndDraw ()
{
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
fDrawGroupNestingDepth--;
if (fDrawGroupNestingDepth != 0) {
if (fDrawGroupNestingDepth < 0) fDrawGroupNestingDepth = 0;
@@ -950,9 +959,8 @@ void G4VisManager::EndDraw ()
void G4VisManager::BeginDraw2D (const G4Transform3D& objectTransform)
{
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
fDrawGroupNestingDepth++;
if (fDrawGroupNestingDepth > 1) {
G4Exception
@@ -971,9 +979,8 @@ void G4VisManager::BeginDraw2D (const G4Transform3D& objectTransform)
void G4VisManager::EndDraw2D ()
{
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
fDrawGroupNestingDepth--;
if (fDrawGroupNestingDepth != 0) {
if (fDrawGroupNestingDepth < 0) fDrawGroupNestingDepth = 0;
@@ -987,9 +994,8 @@ void G4VisManager::EndDraw2D ()
template <class T> void G4VisManager::DrawT
(const T& graphics_primitive, const G4Transform3D& objectTransform) {
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
if (fIsDrawGroup) {
if (objectTransform != fpSceneHandler->GetObjectTransformation()) {
G4Exception
@@ -1010,9 +1016,8 @@ template <class T> void G4VisManager::DrawT
template <class T> void G4VisManager::DrawT2D
(const T& graphics_primitive, const G4Transform3D& objectTransform) {
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
if (fIsDrawGroup) {
if (objectTransform != fpSceneHandler->GetObjectTransformation()) {
G4Exception
@@ -1104,9 +1109,8 @@ void G4VisManager::Draw2D (const G4Text& text,
}
void G4VisManager::Draw (const G4VHit& hit) {
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
if (fIsDrawGroup) {
fpSceneHandler -> AddCompound (hit);
} else {
@@ -1118,9 +1122,8 @@ void G4VisManager::Draw (const G4VHit& hit) {
}
void G4VisManager::Draw (const G4VDigi& digi) {
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
if (fIsDrawGroup) {
fpSceneHandler -> AddCompound (digi);
} else {
@@ -1132,9 +1135,8 @@ void G4VisManager::Draw (const G4VDigi& digi) {
}
void G4VisManager::Draw (const G4VTrajectory& traj) {
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
// A trajectory needs a trajectories model to provide G4Atts, etc.
static G4TrajectoriesModel trajectoriesModel;
trajectoriesModel.SetCurrentTrajectory(&traj);
@@ -1165,9 +1167,8 @@ void G4VisManager::Draw (const G4VTrajectory& traj) {
void G4VisManager::Draw (const G4LogicalVolume& logicalVol,
const G4VisAttributes& attribs,
const G4Transform3D& objectTransform) {
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
// Find corresponding solid.
G4VSolid* pSol = logicalVol.GetSolid ();
Draw (*pSol, attribs, objectTransform);
@@ -1176,9 +1177,8 @@ void G4VisManager::Draw (const G4LogicalVolume& logicalVol,
void G4VisManager::Draw (const G4VSolid& solid,
const G4VisAttributes& attribs,
const G4Transform3D& objectTransform) {
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
if (fIsDrawGroup) {
fpSceneHandler -> PreAddSolid (objectTransform, attribs);
solid.DescribeYourselfTo (*fpSceneHandler);
@@ -1196,9 +1196,8 @@ void G4VisManager::Draw (const G4VSolid& solid,
void G4VisManager::Draw (const G4VPhysicalVolume& physicalVol,
const G4VisAttributes& attribs,
const G4Transform3D& objectTransform) {
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
// Note: It is tempting to use a temporary model here, as for
// trajectories, in order to get at the G4Atts of the physical
// volume. I tried it (JA). But it's not easy to pass the
@@ -1867,13 +1866,15 @@ void G4VisManager::PrintAvailableUserVisActions (Verbosity) const
void G4VisManager::PrintAvailableColours (Verbosity) const {
G4cout <<
"Some /vis commands (optionally) take a string to specify colour."
"\nAvailable colours:\n ";
const std::map<G4String, G4Colour>& map = G4Colour::GetMap();
for (std::map<G4String, G4Colour>::const_iterator i = map.begin();
i != map.end();) {
G4cout << i->first;
if (++i != map.end()) G4cout << ", ";
"Some /vis commands (optionally) take a string to specify colour."
"\nThey are also available in your C++ code, e.g:"
"\n G4Colour niceColour; // Default - white"
"\n G4Colour::GetColour(\"pink\", niceColour);"
"\n logical->SetVisAttributes(niceColour);"
"\nSee G4Colour.hh."
"\nAvailable colours";
for (const auto& i: G4Colour::GetMap()) {
G4cout << ", " << i.first;
}
G4cout << G4endl;
}
@@ -1903,17 +1904,10 @@ void G4VisManager::PrintInvalidPointers () const {
}
}
#ifdef G4MULTITHREADED
namespace {
G4bool mtRunInProgress = false;
std::deque<const G4Event*> mtVisEventQueue;
G4Thread* mtVisSubThread = 0;
G4Mutex mtVisSubThreadMutex = G4MUTEX_INITIALIZER;
}
G4ThreadFunReturnType G4VisManager::G4VisSubThread(G4ThreadFunArgType p)
{
#ifdef G4MULTITHREADED
G4VisManager* pVisManager = (G4VisManager*)p;
G4VSceneHandler* pSceneHandler = pVisManager->GetCurrentSceneHandler();
if (!pSceneHandler) return 0;
@@ -1924,9 +1918,6 @@ G4ThreadFunReturnType G4VisManager::G4VisSubThread(G4ThreadFunArgType p)
G4UImanager::GetUIpointer()->SetUpForSpecialThread("G4VIS");
// G4cout << "G4VisManager::G4VisSubThread: thread: "
// << G4Threading::G4GetThreadId() << std::endl;
// Set up geometry and navigation for a thread
G4GeometryWorkspace::GetPool()->CreateAndUseWorkspace();
G4SolidsWorkspace::GetPool()->CreateAndUseWorkspace();
@@ -1949,11 +1940,6 @@ G4ThreadFunReturnType G4VisManager::G4VisSubThread(G4ThreadFunArgType p)
G4MUTEXLOCK(&mtVisSubThreadMutex);
const G4Event* event = mtVisEventQueue.front();
G4MUTEXUNLOCK(&mtVisSubThreadMutex);
// G4int eventID = event->GetEventID();
// G4cout
// << "G4VisManager::G4VisSubThread: Vis sub-thread: Dealing with event:
// "
// << eventID << G4endl;
// Here comes the event drawing
pVisManager->SetTransientsDrawnThisEvent(false);
@@ -1973,26 +1959,12 @@ G4ThreadFunReturnType G4VisManager::G4VisSubThread(G4ThreadFunArgType p)
pSceneHandler->DrawEvent(event);
++pVisManager->fNoOfEventsDrawnThisRun;
if (pScene->GetRefreshAtEndOfEvent()) {
// ShowView guarantees the view is flushed to the screen. It also
// triggers other features such picking (if enabled) and allows
// file-writing viewers to close the file.
pViewer->ShowView();
pSceneHandler->SetMarkForClearingTransientStore(true);
}
// Testing.
// std::this_thread::sleep_for(std::chrono::seconds(5));
// Then pop and release event
G4MUTEXLOCK(&mtVisSubThreadMutex);
mtVisEventQueue.pop_front();
pVisManager->EndOfEventCleanup(event, event->GetEventID());
pVisManager->EndOfEventCleanup(event);
eventQueueSize = mtVisEventQueue.size();
G4MUTEXUNLOCK(&mtVisSubThreadMutex);
// G4cout << "Event queue size (B): " << eventQueueSize << G4endl;
}
G4MUTEXLOCK(&mtVisSubThreadMutex);
@@ -2011,46 +1983,35 @@ G4ThreadFunReturnType G4VisManager::G4VisSubThread(G4ThreadFunArgType p)
// Inform viewer that we have finished all sub-thread drawing
pViewer->DoneWithVisSubThread();
pViewer->MovingToMasterThread();
// G4cout << "G4VisManager::G4VisSubThread: Vis sub-thread: ending" << G4endl;
return nullptr;
}
namespace {
// G4Mutex visBeginOfRunMutex = G4MUTEX_INITIALIZER;
// G4Mutex visBeginOfEventMutex = G4MUTEX_INITIALIZER;
G4Mutex visEndOfEventMutex = G4MUTEX_INITIALIZER;
// G4Mutex visEndOfRunMutex = G4MUTEX_INITIALIZER;
}
#else
G4ConsumeParameters(p);
#endif
namespace {
G4bool isSubEventRunManagerType = false;
return nullptr;
}
void G4VisManager::BeginOfRun ()
{
if (fIgnoreStateChanges) return;
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
// G4cout << "G4VisManager::BeginOfRun: thread: "
// << G4Threading::G4GetThreadId() << G4endl;
if (!GetConcreteInstance()) return;
// Check if view is valid
// Protect IsValidView() with fpSceneHandler to prevent warning messages in batch
isValidViewForRun = fpSceneHandler && IsValidView();
if (!isValidViewForRun) return;
// For a fake run...
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
isFakeRun = (nEventsToBeProcessed == 0);
if (isFakeRun) return;
// Is the run manager a sub-event type?
G4RunManager::RMType rmType = runManager->GetRunManagerType();
isSubEventRunManagerType =
(rmType == G4RunManager::subEventMasterRM) ||
(rmType == G4RunManager::subEventWorkerRM);
// If sub-event active, ignore if invoked from worker thread
if(isSubEventRunManagerType && G4Threading::IsWorkerThread()) return;
// For a fake run...
G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
if (nEventsToBeProcessed == 0) return;
fNKeepForPostProcessingRequests = 0;
fNKeepTheEventRequests = 0;
fEventKeepingSuspended = false;
@@ -2064,19 +2025,13 @@ void G4VisManager::BeginOfRun ()
// The function is called again later when needed.
CurrentTrajDrawModel();
#ifdef G4MULTITHREADED
// There is a static method G4Threading::IsMultithreadedApplication()
// that returns true only if G4MTRunManager is instantiated with MT
// installation. Thus method returns false if G4RunManager base class is
// instantiated even with the MT installation, or of course with sequential
// installation.
// Actions only in MT mode
if (G4Threading::IsMultithreadedApplication()) {
// Inform viewer that we have finished all master thread drawing for now...
if (fpViewer) fpViewer->DoneWithMasterThread();
// Start vis sub-thread
// G4cout << "G4VisManager::BeginOfRun: Starting vis sub-thread" << G4endl;
G4MUTEXLOCK(&mtVisSubThreadMutex);
mtRunInProgress = true;
G4MUTEXUNLOCK(&mtVisSubThreadMutex);
@@ -2091,21 +2046,17 @@ void G4VisManager::BeginOfRun ()
// - Go ahead
if (fpViewer) fpViewer->MovingToVisSubThread();
}
#endif
}
void G4VisManager::BeginOfEvent ()
{
if (fIgnoreStateChanges) return;
if (!GetConcreteInstance()) return;
if (isSubEventRunManagerType) return;
// G4cout << "G4VisManager::BeginOfEvent: thread: "
// << G4Threading::G4GetThreadId() << G4endl;
if (!isValidViewForRun) return;
if (isFakeRun) return;
// Some instructions that should NOT be in multithreaded version.
// TODO: protect with G4Threading::IsMultithreadedApplication() instead?
#ifndef G4MULTITHREADED
// These instructions are in G4VisSubThread for multithreading.
fTransientsDrawnThisEvent = false;
@@ -2113,52 +2064,51 @@ void G4VisManager::BeginOfEvent ()
#endif
}
#ifdef G4MULTITHREADED
void G4VisManager::EventReadyForVis(const G4Event* event)
// This is invoked by G4SubEvtRunManager.
// The event is passed to EndOfEventKernel.
{
if (fIgnoreStateChanges) return;
if (!GetConcreteInstance()) return;
G4bool valid = fpSceneHandler && IsValidView();
if (!valid) return;
G4AutoLock al(&visEndOfEventMutex);
EndOfEventKernel(event);
}
#endif
// Here begins a sequence of functions that deal with end-of-event.
// Sequential/Serial mode:
// EndOfEvent is invoked by a state change on the master thread:
// EndOfEvent pulls the event from the Event Manager and calls EndOfEventKernel.
// EndOfEventKernel draws the event and calls EndOfEventCleanup.
// (Unless the user him/herself has requested keeping, EndOfEventKernel
// also sets KeepTheEvent for a certain number (adjustable, default 100)
// of events. The run manager keeps these events until the beginning of the next
// run, so, for example, the vis manager can redraw/rebuild if required.)
// Multithreading/Tasking:
// EndOfEvent is invoked by a state change on each worker thread:
// EndOfEvent pulls the event from the (worker) Event Manager and calls EndOfEventKernel.
// EndOfEventKernel pushes it to the vis queue, and returns. The events
// are marked KeepForPostProcessing so that the worker does not delete them until
// PostProcessingFinished in EndOfEventCleanup.
// EndOfEventKernel also sets KeepTheEvent as above.
// The vis sub thread pulls events from the vis queue, draws them and
// calls EndOfEventCleanup, which calls PostProcessingFinished.
// Sub-event parallelism:
// EndOfEvent is invoked by a state change on each worker thread, as for
// multithreading, but actually, the event is not complete. Workers are
// employed on sub-events, so we ignore such state changes. Only
// G4SubEvtRunManager knows when the event is complete.
// Events are pushed to the Vis Manager by G4SubEvtRunManager via EventReadyForVis
// when the event is ready. EventReadyForVis calls EndOfEventKernel and
// processsing continues as for Multithreading.
void G4VisManager::EndOfEvent ()
{
if (fIgnoreStateChanges) return;
if (!GetConcreteInstance()) return;
if (!isValidViewForRun) return;
if (isFakeRun) return;
// For sub-event parallelism, this is not the true end of event
if (isSubEventRunManagerType) return;
// G4cout << "G4VisManager::EndOfEvent: thread: "
// << G4Threading::G4GetThreadId() << G4endl;
#ifdef G4MULTITHREADED
G4AutoLock al(&visEndOfEventMutex);
// Testing.
// std::this_thread::sleep_for(std::chrono::seconds(5));
#endif
// Don't call IsValidView unless there is a scene handler. This
// avoids WARNING message at end of event and run when the user has
// not instantiated a scene handler, e.g., in batch mode.
G4bool valid = fpSceneHandler && IsValidView();
if (!valid) return;
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
const G4Run* currentRun = runManager->GetCurrentRun();
if (!currentRun) return;
// This gets the thread-local event manager
// This gets the appropriate event manager
G4EventManager* eventManager = G4EventManager::GetEventManager();
const G4Event* currentEvent = eventManager->GetConstCurrentEvent();
if (!currentEvent) return;
@@ -2167,72 +2117,22 @@ void G4VisManager::EndOfEvent ()
EndOfEventKernel(currentEvent);
}
G4bool G4VisManager::Relinquishable (G4int eventID, G4int nKeptEvents, G4int nRequests)
// Figures out if event is relinquishable, i.e., the run manager(s) may delete.
// If _not_ relinquishable, KeepCurrentEvent is called as soon as event is recieved.
// If relinquishable, PostProcesssingFinshed is called when drawing finished.
// nKeptEvents is number of events currently kept by the run manager.
// nRequests is the number of requests for keeping made by the vis maanager.
void G4VisManager::EventReadyForVis(const G4Event* event)
// This is invoked by G4SubEvtRunManager.
// The event is passed to EndOfEventKernel.
{
G4bool relinquishable = false;
if (fIgnoreStateChanges) return;
if (!GetConcreteInstance()) return;
if (!isValidViewForRun) return;
if (isFakeRun) return;
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
if (fpScene->GetRefreshAtEndOfEvent()) {
// Unless last event (in which case wait end of run)...
if (eventID < nEventsToBeProcessed - 1) {
relinquishable = true;
} else { // Last event - relinquish too if user has kept some
if (nKeptEvents > 0) {
relinquishable = true;
}
}
fpSceneHandler->SetMarkForClearingTransientStore(true);
} else { // Accumulating events...
G4int maxNumberOfKeptEvents = fpScene->GetMaxNumberOfKeptEvents();
if (maxNumberOfKeptEvents >= 0 &&
nRequests >= maxNumberOfKeptEvents) {
fEventKeepingSuspended = true;
static G4bool warned = false;
if (!warned) {
if (fVerbosity >= warnings) {
G4warn <<
"WARNING: G4VisManager::EndOfEvent: Automatic event keeping suspended."
<< G4endl;
if (maxNumberOfKeptEvents > 0) {
G4warn <<
"\n The number of events exceeds the maximum, "
<< maxNumberOfKeptEvents <<
", that may be kept by\n the vis manager."
<< G4endl;
}
}
warned = true;
}
relinquishable = true;
} else if (maxNumberOfKeptEvents != 0) { // i.e., indefinite keeping
// Relinquish anyway if disabled or suspended
if (!GetConcreteInstance() || fEventKeepingSuspended) {
relinquishable = true;
}
}
}
return relinquishable;
G4AutoLock al(&visEndOfEventMutex);
EndOfEventKernel(event);
}
void G4VisManager::EndOfEventKernel (const G4Event* currentEvent)
{
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
const G4Run* currentRun = runManager->GetCurrentRun();
G4EventManager* eventManager = G4EventManager::GetEventManager();
// Note: we are still subject to the mutex lock with visEndOfEventMutex
// Discard event if fDrawEventOnlyIfToBeKept flag is set unless the
// user has requested the event to be kept.
@@ -2242,19 +2142,16 @@ void G4VisManager::EndOfEventKernel (const G4Event* currentEvent)
if (G4Threading::IsMultithreadedApplication()) {
#ifdef G4MULTITHREADED
// Wait if too many events in the queue.
G4MUTEXLOCK(&mtVisSubThreadMutex);
std::size_t eventQueueSize = mtVisEventQueue.size();
G4MUTEXUNLOCK(&mtVisSubThreadMutex);
// G4cout << "Event queue size (1): " << eventQueueSize << G4endl;
G4bool eventQueueFull = false;
while (fMaxEventQueueSize > 0 && (G4int)eventQueueSize >= fMaxEventQueueSize) {
// G4cout << "Event queue size (2): " << eventQueueSize << G4endl;
if (fWaitOnEventQueueFull) {
static G4bool warned = false;
if (!warned) {
G4warn <<
@@ -2274,11 +2171,12 @@ void G4VisManager::EndOfEventKernel (const G4Event* currentEvent)
<< G4endl;
warned = true;
}
// G4cout << "Event queue size (3): " << eventQueueSize << G4endl;
// Wait a while to give event drawing time to reduce the queue...
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// G4cout << "Event queue size (4): " << eventQueueSize << G4endl;
} else {
static G4bool warned = false;
if (!warned) {
G4warn <<
@@ -2292,6 +2190,7 @@ void G4VisManager::EndOfEventKernel (const G4Event* currentEvent)
<< G4endl;
warned = true;
}
eventQueueFull = true; // Causes event to be discarded for drawing.
break;
}
@@ -2302,37 +2201,29 @@ void G4VisManager::EndOfEventKernel (const G4Event* currentEvent)
}
if (!eventQueueFull) {
if (RequiredToBeKeptForVis(currentEvent->GetEventID())) {
currentEvent->KeepTheEvent();
fNKeepTheEventRequests++; // Counts number of calls to KeepTheEvent
}
G4MUTEXLOCK(&mtVisSubThreadMutex);
// Keep while post processing (i.e., drawing), relinquished in EndOfEventCleanup
// Make sure the event is not deleted by the run manager while in the vis queue
currentEvent->KeepForPostProcessing();
fNKeepForPostProcessingRequests++;
if (!Relinquishable(currentEvent->GetEventID(),
(G4int)currentRun->GetEventVector()->size(),
fNKeepTheEventRequests)) {
eventManager->KeepTheCurrentEvent();
fNKeepTheEventRequests++; // Counts number of calls to KeepTheCurrentEvent
}
G4MUTEXLOCK(&mtVisSubThreadMutex);
// Put event on vis queue
mtVisEventQueue.push_back(currentEvent);
G4MUTEXUNLOCK(&mtVisSubThreadMutex);
}
// G4MUTEXLOCK(&mtVisSubThreadMutex);
// G4int eQS = mtVisEventQueue.size();
// G4MUTEXUNLOCK(&mtVisSubThreadMutex);
// G4cout << "Event queue size (5): " << eQS << G4endl;
#endif
} else {
// Sequential mode
G4int eventID = -2; // (If no run manager, triggers ShowView as normal.)
if (currentRun) {
eventID = currentEvent->GetEventID();
}
// We are about to draw the event (trajectories, etc.), but first we
// have to clear the previous event(s) if necessary. If this event
// needs to be drawn afresh, e.g., the first event or any event when
@@ -2343,59 +2234,103 @@ void G4VisManager::EndOfEventKernel (const G4Event* currentEvent)
// See, for example, G4HepRepFileSceneHandler::ClearTransientStore.
ClearTransientStoreIfMarked();
// Keep - but relinquish (PostProcessingFinished) later if not needed
// Keep while post processing (i.e., drawing), relinquished in EndOfEventCleanup
currentEvent->KeepForPostProcessing();
if (!Relinquishable(currentEvent->GetEventID(),
(G4int)currentRun->GetEventVector()->size(),
fNKeepTheEventRequests)) {
eventManager->KeepTheCurrentEvent();
fNKeepTheEventRequests++; // Counts number of calls to KeepTheCurrentEvent
fNKeepForPostProcessingRequests++;
if (RequiredToBeKeptForVis(currentEvent->GetEventID())) {
currentEvent->KeepTheEvent();
fNKeepTheEventRequests++; // Counts number of calls to KeepTheEvent
}
// Now draw the event...
fpSceneHandler->DrawEvent(currentEvent);
++fNoOfEventsDrawnThisRun;
EndOfEventCleanup(currentEvent,eventID);
EndOfEventCleanup(currentEvent);
}
}
void G4VisManager::EndOfEventCleanup
(const G4Event* currentEvent,
G4int eventID) // See EndOfEventKernel: can be == -2?
void G4VisManager::EndOfEventCleanup(const G4Event* currentEvent)
{
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
G4int nKeptEvents = 0;
const G4Run* currentRun = runManager->GetCurrentRun();
if (currentRun) {
const std::vector<const G4Event*>* events = currentRun->GetEventVector();
if (events) nKeptEvents = (G4int)events->size();
if (fpScene->GetRefreshAtEndOfEvent()) {
fpSceneHandler->SetMarkForClearingTransientStore(true);
// ShowView guarantees the view is flushed to the screen. It also
// triggers other features such as picking (if enabled) and allows
// file-writing viewers to close the file.
fpViewer->ShowView();
}
// Seems to relinquish every event - probably becuase it doesn't get here soon enough.
// In fact, it makes sense to do this - immediate post processing is finished,
// and a user-requested number of events have been kept. So great!
if (Relinquishable(eventID, nKeptEvents, fNKeepForPostProcessingRequests)) {
currentEvent->PostProcessingFinished();
if (fpScene->GetRefreshAtEndOfEvent()) { // && eventID == -2?
// ShowView guarantees the view is flushed to the screen. It also
// triggers other features such picking (if enabled) and allows
// file-writing viewers to close the file.
fpViewer->ShowView();
currentEvent->PostProcessingFinished();
}
G4bool G4VisManager::RequiredToBeKeptForVis (G4int eventID)
// i.e., kept by the run manager at least to the beginning of the next run.
{
G4bool requiredToBeKept = false;
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
if (fpScene->GetRefreshAtEndOfEvent()) { // Refreshing every event
// Keep last event only
if (eventID == nEventsToBeProcessed - 1) {
requiredToBeKept = true;
}
} else { // Accumulating events
G4int maxNumberOfKeptEvents = fpScene->GetMaxNumberOfKeptEvents();
if (maxNumberOfKeptEvents >= 0) { // Event keeping requested
if (fNKeepTheEventRequests < maxNumberOfKeptEvents) {
// Not yet reached the limit
requiredToBeKept = true;
} else {
// We have already reached the limit
fEventKeepingSuspended = true;
static G4bool warned = false;
if (!warned) {
if (fVerbosity >= warnings) {
G4warn <<
"WARNING: G4VisManager::EndOfEvent: Automatic event keeping suspended."
<< G4endl;
if (maxNumberOfKeptEvents > 0) {
G4warn <<
"\n The number of events exceeds the maximum, "
<< maxNumberOfKeptEvents <<
", that may be kept by\n the vis manager."
<< G4endl;
}
}
warned = true;
}
}
} else { // Indefinite event keeping (maxNumberOfKeptEvents < 0)
requiredToBeKept = true;
}
}
return requiredToBeKept;
}
void G4VisManager::EndOfRun ()
{
if (fIgnoreStateChanges) return;
#ifdef G4MULTITHREADED
if (G4Threading::IsWorkerThread()) return;
#endif
// G4cout << "G4VisManager::EndOfRun: thread: "
// << G4Threading::G4GetThreadId() << G4endl;
if (!GetConcreteInstance()) return;
if (!isValidViewForRun) return;
if (isFakeRun) return;
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
@@ -2406,7 +2341,6 @@ void G4VisManager::EndOfRun ()
const G4Run* currentRun = runManager->GetCurrentRun();
if (!currentRun) return;
#ifdef G4MULTITHREADED
// G4AutoLock al(&visEndOfRunMutex); ???
if (G4Threading::IsMultithreadedApplication()) {
// Reset flag so that sub-thread exits when it has finished processing.
@@ -2416,16 +2350,10 @@ void G4VisManager::EndOfRun ()
// Wait for sub-thread to finish.
G4THREADJOIN(*mtVisSubThread);
delete mtVisSubThread;
if (fpViewer) fpViewer->SwitchToMasterThread();
fpViewer->SwitchToMasterThread();
}
#endif
#ifdef G4MULTITHREADED
// Print warning about discarded events, if any.
// Don't call IsValidView unless there is a scene handler. This
// avoids WARNING message from IsValidView() when the user has
// not instantiated a scene handler, e.g., in batch mode.
if (fpSceneHandler && IsValidView()) { // Events should have been drawn
if (G4Threading::IsMultithreadedApplication()) {
G4int noOfEventsRequested = runManager->GetNumberOfEventsToBeProcessed();
if (fNoOfEventsDrawnThisRun != noOfEventsRequested) {
if (!fWaitOnEventQueueFull && fVerbosity >= warnings) {
@@ -2438,18 +2366,14 @@ void G4VisManager::EndOfRun ()
}
}
}
#endif
G4int nKeptEvents = 0;
const std::vector<const G4Event*>* events = currentRun->GetEventVector();
if (events) nKeptEvents = (G4int)events->size();
G4int nKeptEvents = currentRun->GetNumberOfKeptEvents();
if (fVerbosity >= warnings && nKeptEvents > 0) {
G4warn << nKeptEvents;
if (nKeptEvents == 1) G4warn << " event has";
else G4warn << " events have";
G4warn << " been kept for refreshing and/or reviewing." << G4endl;
if (nKeptEvents != fNKeepTheEventRequests) {
G4warn << " (Note: ";
if (fNKeepTheEventRequests == 0) {
G4warn << "No keep requests were";
} else if (fNKeepTheEventRequests == 1) {
@@ -2460,10 +2384,12 @@ void G4VisManager::EndOfRun ()
G4warn << " made by the vis manager.";
if (fNKeepTheEventRequests == 0) {
G4warn <<
"\n The kept events are those you have asked to be kept in your user action(s).)";
"\n The kept events are those you have asked to be kept in your user action(s).";
} else {
G4warn <<
"\n The same or further events may have been kept by you in your user action(s).)";
"\n The same or further events may have been kept by you in your user action(s)."
"\n To turn off event keeping by the vis manager: /vis/drawOnlyToBeKeptEvents"
"\n or use /vis/scene/endOfEventAction <refresh|accumulate> 0";
}
G4warn << G4endl;
}
@@ -2491,39 +2417,32 @@ void G4VisManager::EndOfRun ()
}
}
// Don't call IsValidView unless there is a scene handler. This
// avoids WARNING message at end of event and run when the user has
// not instantiated a scene handler, e.g., in batch mode.
G4bool valid = fpSceneHandler && IsValidView();
if (GetConcreteInstance() && valid) {
// // ???? I can't remember why
// // if (!fpSceneHandler->GetMarkForClearingTransientStore()) {
// // is here. It prevents ShowView at end of run, which seems to be OK
// // for sequential mode, but MT mode seems to need it (I have not
// // figured out why). ???? JA ????
// if (!fpSceneHandler->GetMarkForClearingTransientStore()) {
if (fpScene->GetRefreshAtEndOfRun()) {
fpSceneHandler->DrawEndOfRunModels();
// An extra refresh for auto-refresh viewers.
// ???? I DON'T WHY THIS IS NECESSARY ???? JA ????
if (fpViewer->GetViewParameters().IsAutoRefresh()) {
fpViewer->RefreshView();
}
// ShowView guarantees the view is flushed to the screen. It also
// triggers other features such picking (if enabled) and allows
// file-writing viewers to close the file.
fpViewer->ShowView();
fpSceneHandler->SetMarkForClearingTransientStore(true);
} else {
if (fpGraphicsSystem->GetFunctionality() ==
G4VGraphicsSystem::fileWriter) {
if (fVerbosity >= warnings) {
G4warn << "\"/vis/viewer/update\" to close file." << G4endl;
}
}
if (fpScene->GetRefreshAtEndOfRun()) {
fpSceneHandler->DrawEndOfRunModels();
// An extra refresh for auto-refresh viewers.
// ???? I DON'T WHY THIS IS NECESSARY ???? JA ????
if (fpViewer->GetViewParameters().IsAutoRefresh()) {
fpViewer->RefreshView();
}
// ShowView guarantees the view is flushed to the screen. It also
// triggers other features such picking (if enabled) and allows
// file-writing viewers to close the file.
fpViewer->ShowView();
fpSceneHandler->SetMarkForClearingTransientStore(true);
} else {
if (fpGraphicsSystem->GetFunctionality() ==
G4VGraphicsSystem::fileWriter) {
if (fVerbosity >= warnings) {
G4warn << "\"/vis/viewer/update\" to close file." << G4endl;
}
// }
}
}
//}
fEventRefreshing = false;
}
@@ -2554,7 +2473,7 @@ void G4VisManager::ResetTransientsDrawnFlags()
}
G4String G4VisManager::ViewerShortName (const G4String& viewerName) const {
G4String viewerShortName = viewerName.substr(0, viewerName.find (' '));
const G4String& viewerShortName = viewerName.substr(0, viewerName.find (' '));
return G4StrUtil::strip_copy(viewerShortName);
}
@@ -2596,9 +2515,19 @@ G4String G4VisManager::VerbosityString(Verbosity verbosity) {
return rs;
}
void G4VisManager::PrintAvailableVerbosity(std::ostream& os)
{
os << "Available verbosity options:";
for (std::size_t i = 0; i < VerbosityGuidanceStrings.size(); ++i) {
os << '\n' << VerbosityGuidanceStrings[i];
}
os << "\nCurrent verbosity: " << G4VisManager::VerbosityString(fVerbosity);
os << std::endl;
}
G4VisManager::Verbosity
G4VisManager::GetVerbosityValue(const G4String& verbosityString) {
G4String ss = G4StrUtil::to_lower_copy(verbosityString);
G4String ss = G4StrUtil::to_lower_copy(verbosityString);
Verbosity verbosity;
if (ss[0] == 'q') verbosity = quiet;
else if (ss[0] == 's') verbosity = startup;
@@ -2608,18 +2537,16 @@ G4VisManager::GetVerbosityValue(const G4String& verbosityString) {
else if (ss[0] == 'p') verbosity = parameters;
else if (ss[0] == 'a') verbosity = all;
else {
// Could be an integer
G4int intVerbosity;
std::istringstream is(ss);
is >> intVerbosity;
if (!is) {
G4warn << "ERROR: G4VisManager::GetVerbosityValue: invalid verbosity \""
<< verbosityString << "\"";
for (std::size_t i = 0; i < VerbosityGuidanceStrings.size(); ++i) {
G4warn << '\n' << VerbosityGuidanceStrings[i];
}
verbosity = warnings;
G4warn << "\n Returning " << VerbosityString(verbosity)
<< G4endl;
<< verbosityString << "\"\n";
PrintAvailableVerbosity(G4warn);
// Return existing verbosity
return fVerbosity;
}
else {
verbosity = GetVerbosityValue(intVerbosity);
@@ -2767,12 +2694,13 @@ G4VisManager::RegisterModelFactories()
}
}
#ifdef G4MULTITHREADED
void G4VisManager::SetUpForAThread()
{
// TODO: protect with G4Threading::IsMultithreadedApplication() instead?
#ifdef G4MULTITHREADED
new G4VisStateDependent(this);
}
#endif
}
void G4VisManager::IgnoreStateChanges(G4bool val)
{