Files
geant4/source/geometry/navigation/src/G4GeometryMessenger.cc
T
2020-12-04 12:30:43 +01:00

350 lines
12 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4GeometryMessenger implementation
//
// Author: G.Cosmo, CERN
// --------------------------------------------------------------------
#include <iomanip>
#include "G4GeometryMessenger.hh"
#include "G4TransportationManager.hh"
#include "G4GeometryManager.hh"
#include "G4VPhysicalVolume.hh"
#include "G4Navigator.hh"
#include "G4PropagatorInField.hh"
#include "G4UIdirectory.hh"
#include "G4UIcommand.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIcmdWithABool.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4GeomTestVolume.hh"
//
// Constructor
//
G4GeometryMessenger::G4GeometryMessenger(G4TransportationManager* tman)
: tmanager(tman)
{
geodir = new G4UIdirectory( "/geometry/" );
geodir->SetGuidance( "Geometry control commands." );
//
// Geometry navigator commands
//
navdir = new G4UIdirectory( "/geometry/navigator/" );
navdir->SetGuidance( "Geometry navigator control setup." );
resCmd = new G4UIcmdWithoutParameter( "/geometry/navigator/reset", this );
resCmd->SetGuidance( "Reset navigator and navigation history." );
resCmd->SetGuidance( "NOTE: must be called only after kernel has been" );
resCmd->SetGuidance( " initialized once through the run manager!" );
resCmd->AvailableForStates(G4State_Idle);
verbCmd = new G4UIcmdWithAnInteger( "/geometry/navigator/verbose", this );
verbCmd->SetGuidance( "Set run-time verbosity for the navigator." );
verbCmd->SetGuidance(" 0 : Silent (default)");
verbCmd->SetGuidance(" 1 : Display volume positioning and step lengths");
verbCmd->SetGuidance(" 2 : Display step/safety info on point location");
verbCmd->SetGuidance(" 3 : Display minimal state at -every- step");
verbCmd->SetGuidance(" 4 : Maximum verbosity (very detailed!)");
verbCmd->SetGuidance( "NOTE: this command has effect -only- if Geant4 has" );
verbCmd->SetGuidance( " been installed with the G4VERBOSE flag set!" );
verbCmd->SetParameterName("level",true);
verbCmd->SetDefaultValue(0);
verbCmd->SetRange("level >=0 && level <=4");
chkCmd = new G4UIcmdWithABool( "/geometry/navigator/check_mode", this );
chkCmd->SetGuidance( "Set navigator in -check_mode- state." );
chkCmd->SetGuidance( "This will cause extra checks to be applied during" );
chkCmd->SetGuidance( "navigation. More strict and less tolerant conditions" );
chkCmd->SetGuidance( "are applied. A run-time performance penalty may be" );
chkCmd->SetGuidance( "observed when the -check_mode- state is activated." );
chkCmd->SetGuidance( "NOTE: this command has effect -only- if Geant4 has" );
chkCmd->SetGuidance( " been installed with the G4VERBOSE flag set!" );
chkCmd->SetParameterName("checkFlag",true);
chkCmd->SetDefaultValue(false);
chkCmd->AvailableForStates(G4State_Idle);
pchkCmd = new G4UIcmdWithABool( "/geometry/navigator/push_notify", this );
pchkCmd->SetGuidance( "Set navigator verbosity push notifications." );
pchkCmd->SetGuidance( "This allows one to disable/re-enable verbosity in" );
pchkCmd->SetGuidance( "navigation, when tracks may get stuck and require" );
pchkCmd->SetGuidance( "one artificial push along the direction by the" );
pchkCmd->SetGuidance( "navigator. Notification is active by default." );
pchkCmd->SetGuidance( "NOTE: this command has effect -only- if Geant4 has" );
pchkCmd->SetGuidance( " been installed with the G4VERBOSE flag set!" );
pchkCmd->SetParameterName("pushFlag",true);
pchkCmd->SetDefaultValue(true);
pchkCmd->AvailableForStates(G4State_Idle);
//
// Geometry verification test commands
//
testdir = new G4UIdirectory( "/geometry/test/" );
testdir->SetGuidance( "Geometry verification control setup." );
testdir->SetGuidance( "Helps in detecting possible overlapping regions." );
tolCmd = new G4UIcmdWithADoubleAndUnit( "/geometry/test/tolerance",this );
tolCmd->SetGuidance( "Define tolerance (in mm) by which overlaps reports" );
tolCmd->SetGuidance( "should be reported. By default, all overlaps are" );
tolCmd->SetGuidance( "reported, i.e. tolerance is set to: 0*mm." );
tolCmd->SetParameterName( "Tolerance", true, true );
tolCmd->SetDefaultValue( 0 );
tolCmd->SetDefaultUnit( "mm" );
tolCmd->SetUnitCategory( "Length" );
verCmd = new G4UIcmdWithABool( "/geometry/test/verbosity", this );
verCmd->SetGuidance( "Specify if running in verbosity mode or not." );
verCmd->SetGuidance( "By default verbosity is set to ON (TRUE)." );
verCmd->SetParameterName("verbosity",true);
verCmd->SetDefaultValue(true);
verCmd->AvailableForStates(G4State_Idle);
rslCmd = new G4UIcmdWithAnInteger( "/geometry/test/resolution", this );
rslCmd->SetGuidance( "Set the number of points on surface to be generated for" );
rslCmd->SetGuidance( "checking overlaps." );
rslCmd->SetParameterName("resolution",true);
rslCmd->SetDefaultValue(10000);
rcsCmd = new G4UIcmdWithAnInteger( "/geometry/test/recursion_start", this );
rcsCmd->SetGuidance( "Set the initial level in the geometry tree for recursion." );
rcsCmd->SetGuidance( "recursive_test will then start from the specified level." );
rcsCmd->SetParameterName("initial_level",true);
rcsCmd->SetDefaultValue(0);
rcdCmd = new G4UIcmdWithAnInteger( "/geometry/test/recursion_depth", this );
rcdCmd->SetGuidance( "Set the depth in the geometry tree for recursion." );
rcdCmd->SetGuidance( "recursive_test will then stop after reached the specified depth." );
rcdCmd->SetGuidance( "By default, recursion will proceed for the whole depth." );
rcdCmd->SetParameterName("recursion_depth",true);
rcdCmd->SetDefaultValue(-1);
errCmd = new G4UIcmdWithAnInteger( "/geometry/test/maximum_errors", this );
errCmd->SetGuidance( "Set the maximum number of overlap errors to report" );
errCmd->SetGuidance( "for each single volume being checked." );
errCmd->SetGuidance( "Once reached the maximum number specified, overlaps" );
errCmd->SetGuidance( "affecting that volume further than that are simply ignored." );
errCmd->SetParameterName("maximum_errors",true);
errCmd->SetDefaultValue(1);
recCmd = new G4UIcmdWithoutParameter( "/geometry/test/run", this );
recCmd->SetGuidance( "Start running the recursive overlap check." );
recCmd->SetGuidance( "Volumes are recursively asked to verify for overlaps" );
recCmd->SetGuidance( "for points generated on the surface against their" );
recCmd->SetGuidance( "respective mother volume and sisters at the same" );
recCmd->SetGuidance( "level, performing for all daughters and daughters of" );
recCmd->SetGuidance( "daughters, etc." );
recCmd->SetGuidance( "NOTE: it may take a very long time," );
recCmd->SetGuidance( " depending on the geometry complexity !");
recCmd->AvailableForStates(G4State_Idle);
}
//
// Destructor
//
G4GeometryMessenger::~G4GeometryMessenger()
{
delete verCmd; delete recCmd; delete rslCmd;
delete resCmd; delete rcsCmd; delete rcdCmd; delete errCmd;
delete tolCmd;
delete verbCmd; delete pchkCmd; delete chkCmd;
delete geodir; delete navdir; delete testdir;
delete tvolume;
}
//
// Init
//
void
G4GeometryMessenger::Init()
{
// Create checker...
//
if (tvolume == nullptr)
{
// Get the world volume
//
G4VPhysicalVolume* world =
tmanager->GetNavigatorForTracking()->GetWorldVolume();
// Test the actual detector...
//
tvolume = new G4GeomTestVolume(world);
}
}
//
// SetNewValue
//
void
G4GeometryMessenger::SetNewValue( G4UIcommand* command, G4String newValues )
{
if (command == resCmd) {
ResetNavigator();
}
else if (command == verbCmd) {
SetVerbosity( newValues );
}
else if (command == chkCmd) {
SetCheckMode( newValues );
}
else if (command == pchkCmd) {
SetPushFlag( newValues );
}
else if (command == tolCmd) {
Init();
tol = tolCmd->GetNewDoubleValue( newValues )
* tolCmd->GetNewUnitValue( newValues );
tvolume->SetTolerance(tol);
}
else if (command == verCmd) {
Init();
tvolume->SetVerbosity(verCmd->GetNewBoolValue( newValues ));
}
else if (command == rslCmd) {
Init();
tvolume->SetResolution(rslCmd->GetNewIntValue( newValues ));
}
else if (command == rcsCmd) {
recLevel = rcsCmd->GetNewIntValue( newValues );
}
else if (command == rcdCmd) {
recDepth = rcdCmd->GetNewIntValue( newValues );
}
else if (command == errCmd) {
Init();
tvolume->SetErrorsThreshold(errCmd->GetNewIntValue( newValues ));
}
else if (command == recCmd) {
Init();
G4cout << "Running geometry overlaps check..." << G4endl;
RecursiveOverlapTest();
G4cout << "Geometry overlaps check completed !" << G4endl;
}
}
//
// GetCurrentValue
//
G4String
G4GeometryMessenger::GetCurrentValue( G4UIcommand* command )
{
G4String cv = "";
if (command == tolCmd)
{
cv = tolCmd->ConvertToString( tol, "mm" );
}
return cv;
}
//
// CheckGeometry
//
void
G4GeometryMessenger::CheckGeometry()
{
// Verify that the geometry is closed
//
G4GeometryManager* geomManager = G4GeometryManager::GetInstance();
if (!geomManager->IsGeometryClosed())
{
geomManager->OpenGeometry();
geomManager->CloseGeometry(true);
}
}
//
// ResetNavigator
//
void
G4GeometryMessenger::ResetNavigator()
{
// Close geometry and reset optimisation if necessary
//
CheckGeometry();
// Reset navigator's state
//
G4ThreeVector pt(0,0,0);
G4Navigator* navigator = tmanager->GetNavigatorForTracking();
navigator->LocateGlobalPointAndSetup(pt,0,false);
}
//
// Set navigator verbosity
//
void
G4GeometryMessenger::SetVerbosity(G4String input)
{
G4int level = verbCmd->GetNewIntValue(input);
G4Navigator* navigator = tmanager->GetNavigatorForTracking();
navigator->SetVerboseLevel(level);
}
//
// Set navigator mode
//
void
G4GeometryMessenger::SetCheckMode(G4String input)
{
G4bool mode = chkCmd->GetNewBoolValue(input);
G4Navigator* navigator = tmanager->GetNavigatorForTracking();
navigator->CheckMode(mode);
G4PropagatorInField* pField = tmanager->GetPropagatorInField();
if (pField != nullptr) { pField->CheckMode(mode); }
}
//
// Set navigator verbosity for push notifications
//
void
G4GeometryMessenger::SetPushFlag(G4String input)
{
G4bool mode = pchkCmd->GetNewBoolValue(input);
G4Navigator* navigator = tmanager->GetNavigatorForTracking();
navigator->SetPushVerbosity(mode);
}
//
// Recursive Overlap Test
//
void
G4GeometryMessenger::RecursiveOverlapTest()
{
// Close geometry if necessary
//
CheckGeometry();
// Make test on single line supplied by user recursively
//
tvolume->TestRecursiveOverlap( recLevel, recDepth );
}