Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4GeometryMessenger.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// Class G4GeometryMessenger implementation
27//
28// Author: Gabriele Cosmo (CERN), 24 October 2001.
29// --------------------------------------------------------------------
30
31#include <iomanip>
32
34
36#include "G4GeometryManager.hh"
37#include "G4VPhysicalVolume.hh"
38#include "G4Navigator.hh"
40
41#include "G4UIdirectory.hh"
42#include "G4UIcommand.hh"
44#include "G4UIcmdWithABool.hh"
47#include "G4UIcmdWithAString.hh"
48
49#include "G4GeomTestVolume.hh"
50
51//
52// Constructor
53//
55 : tmanager(tman)
56{
57 geodir = new G4UIdirectory( "/geometry/" );
58 geodir->SetGuidance( "Geometry control commands." );
59
60 //
61 // Geometry navigator commands
62 //
63 navdir = new G4UIdirectory( "/geometry/navigator/" );
64 navdir->SetGuidance( "Geometry navigator control setup." );
65
66 resCmd = new G4UIcmdWithoutParameter( "/geometry/navigator/reset", this );
67 resCmd->SetGuidance( "Reset navigator and navigation history." );
68 resCmd->SetGuidance( "NOTE: must be called only after kernel has been" );
69 resCmd->SetGuidance( " initialized once through the run manager!" );
70 resCmd->AvailableForStates(G4State_Idle);
71
72 verbCmd = new G4UIcmdWithAnInteger( "/geometry/navigator/verbose", this );
73 verbCmd->SetGuidance( "Set run-time verbosity for the navigator." );
74 verbCmd->SetGuidance(" 0 : Silent (default)");
75 verbCmd->SetGuidance(" 1 : Display volume positioning and step lengths");
76 verbCmd->SetGuidance(" 2 : Display step/safety info on point location");
77 verbCmd->SetGuidance(" 3 : Display minimal state at -every- step");
78 verbCmd->SetGuidance(" 4 : Maximum verbosity (very detailed!)");
79 verbCmd->SetGuidance( "NOTE: this command has effect -only- if Geant4 has" );
80 verbCmd->SetGuidance( " been installed with the G4VERBOSE flag set!" );
81 verbCmd->SetParameterName("level",true);
82 verbCmd->SetDefaultValue(0);
83 verbCmd->SetRange("level >=0 && level <=4");
84
85 chkCmd = new G4UIcmdWithABool( "/geometry/navigator/check_mode", this );
86 chkCmd->SetGuidance( "Set navigator in -check_mode- state." );
87 chkCmd->SetGuidance( "This will cause extra checks to be applied during" );
88 chkCmd->SetGuidance( "navigation. More strict and less tolerant conditions" );
89 chkCmd->SetGuidance( "are applied. A run-time performance penalty may be" );
90 chkCmd->SetGuidance( "observed when the -check_mode- state is activated." );
91 chkCmd->SetGuidance( "NOTE: this command has effect -only- if Geant4 has" );
92 chkCmd->SetGuidance( " been installed with the G4VERBOSE flag set!" );
93 chkCmd->SetParameterName("checkFlag",true);
94 chkCmd->SetDefaultValue(false);
95 chkCmd->AvailableForStates(G4State_Idle);
96
97 pchkCmd = new G4UIcmdWithABool( "/geometry/navigator/push_notify", this );
98 pchkCmd->SetGuidance( "Set navigator verbosity push notifications." );
99 pchkCmd->SetGuidance( "This allows one to disable/re-enable verbosity in" );
100 pchkCmd->SetGuidance( "navigation, when tracks may get stuck and require" );
101 pchkCmd->SetGuidance( "one artificial push along the direction by the" );
102 pchkCmd->SetGuidance( "navigator. Notification is active by default." );
103 pchkCmd->SetGuidance( "NOTE: this command has effect -only- if Geant4 has" );
104 pchkCmd->SetGuidance( " been installed with the G4VERBOSE flag set!" );
105 pchkCmd->SetParameterName("pushFlag",true);
106 pchkCmd->SetDefaultValue(true);
107 pchkCmd->AvailableForStates(G4State_Idle);
108
109 //
110 // Geometry verification test commands
111 //
112 testdir = new G4UIdirectory( "/geometry/test/" );
113 testdir->SetGuidance( "Geometry verification control setup." );
114 testdir->SetGuidance( "Helps in detecting possible overlapping regions." );
115
116 tolCmd = new G4UIcmdWithADoubleAndUnit( "/geometry/test/tolerance",this );
117 tolCmd->SetGuidance( "Define tolerance (in mm) by which overlaps reports" );
118 tolCmd->SetGuidance( "should be reported. By default, all overlaps are" );
119 tolCmd->SetGuidance( "reported, i.e. tolerance is set to: 0*mm." );
120 tolCmd->SetParameterName( "Tolerance", true, true );
121 tolCmd->SetDefaultValue( 0 );
122 tolCmd->SetDefaultUnit( "mm" );
123 tolCmd->SetUnitCategory( "Length" );
124
125 verCmd = new G4UIcmdWithABool( "/geometry/test/verbosity", this );
126 verCmd->SetGuidance( "Specify if running in verbosity mode or not." );
127 verCmd->SetGuidance( "By default verbosity is set to ON (TRUE)." );
128 verCmd->SetParameterName("verbosity",true);
129 verCmd->SetDefaultValue(true);
130 verCmd->AvailableForStates(G4State_Idle);
131
132 rslCmd = new G4UIcmdWithAnInteger( "/geometry/test/resolution", this );
133 rslCmd->SetGuidance( "Set the number of points on surface to be generated for" );
134 rslCmd->SetGuidance( "checking overlaps." );
135 rslCmd->SetParameterName("resolution",true);
136 rslCmd->SetDefaultValue(10000);
137
138 rcsCmd = new G4UIcmdWithAnInteger( "/geometry/test/recursion_start", this );
139 rcsCmd->SetGuidance( "Set the initial level in the geometry tree for recursion." );
140 rcsCmd->SetGuidance( "recursive_test will then start from the specified level." );
141 rcsCmd->SetParameterName("initial_level",true);
142 rcsCmd->SetDefaultValue(0);
143
144 rcdCmd = new G4UIcmdWithAnInteger( "/geometry/test/recursion_depth", this );
145 rcdCmd->SetGuidance( "Set the depth in the geometry tree for recursion." );
146 rcdCmd->SetGuidance( "recursive_test will then stop after reached the specified depth." );
147 rcdCmd->SetGuidance( "By default, recursion will proceed for the whole depth." );
148 rcdCmd->SetParameterName("recursion_depth",true);
149 rcdCmd->SetDefaultValue(-1);
150
151 errCmd = new G4UIcmdWithAnInteger( "/geometry/test/maximum_errors", this );
152 errCmd->SetGuidance( "Set the maximum number of overlap errors to report" );
153 errCmd->SetGuidance( "for each single volume being checked." );
154 errCmd->SetGuidance( "Once reached the maximum number specified, overlaps" );
155 errCmd->SetGuidance( "affecting that volume further than that are simply ignored." );
156 errCmd->SetParameterName("maximum_errors",true);
157 errCmd->SetDefaultValue(1);
158
159 parCmd = new G4UIcmdWithABool( "/geometry/test/check_parallel", this );
160 parCmd->SetGuidance( "Check for overlaps in parallel worlds." );
161 parCmd->SetGuidance( "By default, overlaps are only checked in the mass world (FALSE)." );
162 parCmd->SetParameterName("check_parallel",true);
163 parCmd->SetDefaultValue(true);
164
165 recCmd = new G4UIcmdWithAString( "/geometry/test/run", this );
166 recCmd->SetGuidance( "Start running the recursive overlap check." );
167 recCmd->SetGuidance( "Volumes are recursively asked to verify for overlaps" );
168 recCmd->SetGuidance( "for points generated on the surface against their" );
169 recCmd->SetGuidance( "respective mother volume and sisters at the same" );
170 recCmd->SetGuidance( "level, performing for all daughters and daughters of" );
171 recCmd->SetGuidance( "daughters, etc." );
172 recCmd->SetGuidance( "NOTE: it may take a very long time," );
173 recCmd->SetGuidance( " depending on the geometry complexity !");
174 recCmd->SetGuidance("Specify the overlap check mode.");
175 recCmd->SetGuidance(" placed: Check overlaps in all placed volumes (default)");
176 recCmd->SetGuidance(" This includes every instance of repeated placements");
177 recCmd->SetGuidance(" logical: Check overlaps only among daughters of each logical volume.");
178 recCmd->SetGuidance(" This avoids duplicate reports and improves performance.");
179 recCmd->SetParameterName("check_mode",true);
180
181 const std::string candidates_list = OverlapMode::placed
182 + " " + OverlapMode::logical;
183
184 recCmd->SetCandidates(candidates_list.c_str());
185 recCmd->SetDefaultValue(OverlapMode::placed.c_str());
186 recCmd->AvailableForStates(G4State_Idle);
187}
188
189//
190// Destructor
191//
193{
194 delete verCmd; delete recCmd; delete rslCmd;
195 delete resCmd; delete rcsCmd; delete rcdCmd;
196 delete errCmd; delete parCmd; delete tolCmd;
197 delete verbCmd; delete pchkCmd; delete chkCmd;
198 delete geodir; delete navdir; delete testdir;
199 for (const auto* tvolume: tvolumes) { delete tvolume; }
200}
201
202//
203// Init
204//
205void
206G4GeometryMessenger::Init()
207{
208 // Create checker...
209 //
210 if (tvolumes.empty())
211 {
212 // Get all world volumes
213 //
214 const auto noWorlds = tmanager->GetNoWorlds();
215 const auto fWorld = tmanager->GetWorldsIterator();
216
217 for( std::size_t i=0; i<noWorlds; ++i)
218 {
219 // Test the actual detector...
220 //
221 tvolumes.push_back(new G4GeomTestVolume(fWorld[i]));
222 }
223 }
224}
225
226//
227// SetNewValue
228//
229void
231{
232 if (command == resCmd) {
233 ResetNavigator();
234 }
235 else if (command == verbCmd) {
236 SetVerbosity( newValues );
237 }
238 else if (command == chkCmd) {
239 SetCheckMode( newValues );
240 }
241 else if (command == pchkCmd) {
242 SetPushFlag( newValues );
243 }
244 else if (command == tolCmd) {
245 Init();
246 tol = tolCmd->GetNewDoubleValue( newValues )
247 * tolCmd->GetNewUnitValue( newValues );
248 for(auto* tvolume: tvolumes)
249 {
250 tvolume->SetTolerance(tol);
251 }
252 }
253 else if (command == verCmd) {
254 Init();
255 for(auto* tvolume: tvolumes)
256 {
257 tvolume->SetVerbosity(verCmd->GetNewBoolValue( newValues ));
258 }
259 }
260 else if (command == rslCmd) {
261 Init();
262 for(auto* tvolume: tvolumes)
263 {
264 tvolume->SetResolution(rslCmd->GetNewIntValue( newValues ));
265 }
266 }
267 else if (command == rcsCmd) {
268 recLevel = rcsCmd->GetNewIntValue( newValues );
269 }
270 else if (command == rcdCmd) {
271 recDepth = rcdCmd->GetNewIntValue( newValues );
272 }
273 else if (command == parCmd) {
274 checkParallelWorlds = parCmd->GetNewBoolValue( newValues );
275 }
276 else if (command == errCmd) {
277 Init();
278 for(auto* tvolume: tvolumes)
279 {
280 tvolume->SetErrorsThreshold(errCmd->GetNewIntValue( newValues ));
281 }
282 }
283 else if (command == recCmd) {
284 Init();
285 G4cout << "Running geometry overlaps check..." << G4endl;
286 if( OverlapMode::placed == newValues ) {
287 RecursiveOverlapTest();
288 }
289 else if( OverlapMode::logical == newValues ) {
290 TreeOverlapTest();
291 }
292 G4cout << "Geometry overlaps check completed !" << G4endl;
293 }
294}
295
296//
297// GetCurrentValue
298//
301{
302 G4String cv = "";
303 if (command == tolCmd)
304 {
305 cv = tolCmd->ConvertToString( tol, "mm" );
306 }
307 return cv;
308}
309
310//
311// CheckGeometry
312//
313void
314G4GeometryMessenger::CheckGeometry()
315{
316 // Verify that the geometry is closed
317 //
319 if (!geomManager->IsGeometryClosed())
320 {
321 geomManager->OpenGeometry();
322 geomManager->CloseGeometry(true);
323 }
324}
325
326//
327// ResetNavigator
328//
329void
330G4GeometryMessenger::ResetNavigator()
331{
332 // Close geometry and reset optimisation if necessary
333 //
334 CheckGeometry();
335
336 // Reset navigator's state
337 //
338 G4ThreeVector pt(0,0,0);
339 G4Navigator* navigator = tmanager->GetNavigatorForTracking();
340 navigator->LocateGlobalPointAndSetup(pt,nullptr,false);
341}
342
343//
344// Set navigator verbosity
345//
346void
347G4GeometryMessenger::SetVerbosity(const G4String& input)
348{
349 G4int level = verbCmd->GetNewIntValue(input);
350 G4Navigator* navigator = tmanager->GetNavigatorForTracking();
351 navigator->SetVerboseLevel(level);
352}
353
354//
355// Set navigator mode
356//
357void
358G4GeometryMessenger::SetCheckMode(const G4String& input)
359{
360 G4bool mode = chkCmd->GetNewBoolValue(input);
361 G4Navigator* navigator = tmanager->GetNavigatorForTracking();
362 navigator->CheckMode(mode);
363 G4PropagatorInField* pField = tmanager->GetPropagatorInField();
364 if (pField != nullptr) { pField->CheckMode(mode); }
365}
366
367//
368// Set navigator verbosity for push notifications
369//
370void
371G4GeometryMessenger::SetPushFlag(const G4String& input)
372{
373 G4bool mode = pchkCmd->GetNewBoolValue(input);
374 G4Navigator* navigator = tmanager->GetNavigatorForTracking();
375 navigator->SetPushVerbosity(mode);
376}
377
378//
379// Recursive Overlap Test
380//
381void
382G4GeometryMessenger::RecursiveOverlapTest()
383{
384 // Close geometry if necessary
385 //
386 CheckGeometry();
387
388 // Make test on single line supplied by user recursively
389 //
390 if (checkParallelWorlds)
391 {
392 for(auto* tvolume: tvolumes)
393 {
394 tvolume->TestRecursiveOverlap( recLevel, recDepth );
395 }
396 }
397 else
398 {
399 tvolumes.front()->TestRecursiveOverlap( recLevel, recDepth );
400 }
401}
402
403//
404// Tree Overlap Test
405//
406void
407G4GeometryMessenger::TreeOverlapTest()
408{
409 // Close geometry if necessary
410 //
411 CheckGeometry();
412
413 // Make test on single line supplied by user recursively
414 //
415 if (checkParallelWorlds)
416 {
417 for(const auto* tvolume: tvolumes)
418 {
419 tvolume->TestOverlapInTree();
420 }
421 }
422 else
423 {
424 tvolumes.front()->TestOverlapInTree();
425 }
426}
427
@ G4State_Idle
CLHEP::Hep3Vector G4ThreeVector
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4GeomTestVolume allows to check for inconsistencies in the geometric boundaries of a physical volume...
G4GeometryManager is a singleton class responsible for high level geometrical functions,...
static G4GeometryManager * GetInstance()
G4bool CloseGeometry(G4bool pOptimise=true, G4bool verbose=false, G4VPhysicalVolume *vol=nullptr)
void OpenGeometry(G4VPhysicalVolume *vol=nullptr)
G4GeometryMessenger(G4TransportationManager *tman)
void SetNewValue(G4UIcommand *command, G4String newValues) override
G4String GetCurrentValue(G4UIcommand *command) override
void SetVerboseLevel(G4int level)
void SetPushVerbosity(G4bool mode)
void CheckMode(G4bool mode)
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
void CheckMode(G4bool mode)
G4TransportationManager is a singleton class which stores the navigator used by the transportation pr...
std::vector< G4VPhysicalVolume * >::iterator GetWorldsIterator()
std::size_t GetNoWorlds() const