00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <iomanip>
00039 #include "G4GeometryMessenger.hh"
00040
00041 #include "G4TransportationManager.hh"
00042 #include "G4GeometryManager.hh"
00043 #include "G4VPhysicalVolume.hh"
00044 #include "G4Navigator.hh"
00045
00046 #include "G4UIdirectory.hh"
00047 #include "G4UIcommand.hh"
00048 #include "G4UIcmdWith3VectorAndUnit.hh"
00049 #include "G4UIcmdWith3Vector.hh"
00050 #include "G4UIcmdWithoutParameter.hh"
00051 #include "G4UIcmdWithABool.hh"
00052 #include "G4UIcmdWithAnInteger.hh"
00053 #include "G4UIcmdWithADouble.hh"
00054 #include "G4UIcmdWithADoubleAndUnit.hh"
00055
00056 #include "G4GeomTestStreamLogger.hh"
00057 #include "G4GeomTestVolume.hh"
00058
00059
00060
00061
00062 G4GeometryMessenger::G4GeometryMessenger(G4TransportationManager* tman)
00063 : x(0,0,0), p(0,0,1), grdRes(100,100,100), cylRes(90,50,50),
00064 cylfZ(0.8), cylfR(0.8), newtol(false), tol(1E-4),
00065 recLevel(0), recDepth(-1), tmanager(tman), tlogger(0), tvolume(0)
00066 {
00067 geodir = new G4UIdirectory( "/geometry/" );
00068 geodir->SetGuidance( "Geometry control commands." );
00069
00070
00071
00072
00073 navdir = new G4UIdirectory( "/geometry/navigator/" );
00074 navdir->SetGuidance( "Geometry navigator control setup." );
00075
00076 resCmd = new G4UIcmdWithoutParameter( "/geometry/navigator/reset", this );
00077 resCmd->SetGuidance( "Reset navigator and navigation history." );
00078 resCmd->SetGuidance( "NOTE: must be called only after kernel has been" );
00079 resCmd->SetGuidance( " initialized once through the run manager!" );
00080 resCmd->AvailableForStates(G4State_Idle);
00081
00082 verbCmd = new G4UIcmdWithAnInteger( "/geometry/navigator/verbose", this );
00083 verbCmd->SetGuidance( "Set run-time verbosity for the navigator." );
00084 verbCmd->SetGuidance(" 0 : Silent (default)");
00085 verbCmd->SetGuidance(" 1 : Display volume positioning and step lengths");
00086 verbCmd->SetGuidance(" 2 : Display step/safety info on point location");
00087 verbCmd->SetGuidance(" 3 : Display minimal state at -every- step");
00088 verbCmd->SetGuidance(" 4 : Maximum verbosity (very detailed!)");
00089 verbCmd->SetGuidance( "NOTE: this command has effect -only- if Geant4 has" );
00090 verbCmd->SetGuidance( " been installed with the G4VERBOSE flag set!" );
00091 verbCmd->SetParameterName("level",true);
00092 verbCmd->SetDefaultValue(0);
00093 verbCmd->SetRange("level >=0 && level <=4");
00094
00095 chkCmd = new G4UIcmdWithABool( "/geometry/navigator/check_mode", this );
00096 chkCmd->SetGuidance( "Set navigator in -check_mode- state." );
00097 chkCmd->SetGuidance( "This will cause extra checks to be applied during" );
00098 chkCmd->SetGuidance( "navigation. More strict and less tolerant conditions" );
00099 chkCmd->SetGuidance( "are applied. A run-time performance penalty may be" );
00100 chkCmd->SetGuidance( "observed when the -check_mode- state is activated." );
00101 chkCmd->SetGuidance( "NOTE: this command has effect -only- if Geant4 has" );
00102 chkCmd->SetGuidance( " been installed with the G4VERBOSE flag set!" );
00103 chkCmd->SetParameterName("checkFlag",true);
00104 chkCmd->SetDefaultValue(false);
00105 chkCmd->AvailableForStates(G4State_Idle);
00106
00107 pchkCmd = new G4UIcmdWithABool( "/geometry/navigator/push_notify", this );
00108 pchkCmd->SetGuidance( "Set navigator verbosity push notifications." );
00109 pchkCmd->SetGuidance( "This allows to disable/re-enable verbosity in" );
00110 pchkCmd->SetGuidance( "navigation, when tracks may get stuck and require" );
00111 pchkCmd->SetGuidance( "one artificial push along the direction by the" );
00112 pchkCmd->SetGuidance( "navigator. Notification is active by default." );
00113 pchkCmd->SetGuidance( "NOTE: this command has effect -only- if Geant4 has" );
00114 pchkCmd->SetGuidance( " been installed with the G4VERBOSE flag set!" );
00115 pchkCmd->SetParameterName("pushFlag",true);
00116 pchkCmd->SetDefaultValue(true);
00117 pchkCmd->AvailableForStates(G4State_Idle);
00118
00119
00120
00121
00122 testdir = new G4UIdirectory( "/geometry/test/" );
00123 testdir->SetGuidance( "Geometry verification control setup." );
00124 testdir->SetGuidance( "Helps in detecting possible overlapping regions." );
00125
00126 tolCmd = new G4UIcmdWithADoubleAndUnit( "/geometry/test/tolerance",this );
00127 tolCmd->SetGuidance( "Set error tolerance value." );
00128 tolCmd->SetGuidance( "Initial default value: 1E-4*mm." );
00129 tolCmd->SetParameterName( "Tolerance", true, true );
00130 tolCmd->SetDefaultValue( 1E-4 );
00131 tolCmd->SetDefaultUnit( "mm" );
00132 tolCmd->SetUnitCategory( "Length" );
00133
00134 posCmd = new G4UIcmdWith3VectorAndUnit( "/geometry/test/position", this );
00135 posCmd->SetGuidance( "Set starting position for the line_test." );
00136 posCmd->SetParameterName( "X", "Y", "Z", true, true );
00137 posCmd->SetDefaultUnit( "cm" );
00138
00139 dirCmd = new G4UIcmdWith3VectorAndUnit( "/geometry/test/direction", this );
00140 dirCmd->SetGuidance( "Set momentum direction for the line_test." );
00141 dirCmd->SetGuidance( "Direction needs not to be a unit vector." );
00142 dirCmd->SetParameterName( "Px", "Py", "Pz", true, true );
00143 dirCmd->SetRange( "Px != 0 || Py != 0 || Pz != 0" );
00144
00145 linCmd = new G4UIcmdWithABool( "/geometry/test/line_test", this );
00146 linCmd->SetGuidance( "Performs test along a single specified direction/position." );
00147 linCmd->SetGuidance( "Use position and direction commands to change default." );
00148 linCmd->SetGuidance( "Initial default: position(0,0,0), direction(0,0,1)." );
00149 linCmd->SetGuidance( "If recursion flag is set to TRUE, the intersection checks" );
00150 linCmd->SetGuidance( "will be performed recursively in the geometry tree." );
00151 linCmd->SetParameterName("recursionFlag",true);
00152 linCmd->SetDefaultValue(false);
00153 linCmd->AvailableForStates(G4State_Idle);
00154
00155 grzCmd = new G4UIcmdWith3Vector( "/geometry/test/grid_cells", this );
00156 grzCmd->SetGuidance( "Define resolution of grid geometry as number of cells," );
00157 grzCmd->SetGuidance( "specifying them for each dimension, X, Y and Z." );
00158 grzCmd->SetGuidance( "Will be applied to grid_test and recursive_test commands." );
00159 grzCmd->SetGuidance( "Initial default values: X=100, Y=100, Z=100." );
00160 grzCmd->SetParameterName( "X", "Y", "Z", true, true );
00161 grzCmd->SetDefaultValue( G4ThreeVector(100, 100, 100) );
00162
00163 grdCmd = new G4UIcmdWithABool( "/geometry/test/grid_test", this );
00164 grdCmd->SetGuidance( "Start running the default grid test." );
00165 grdCmd->SetGuidance( "A grid of lines parallel to a cartesian axis is used;" );
00166 grdCmd->SetGuidance( "By default, only direct daughters of the mother volumes are checked." );
00167 grdCmd->SetGuidance( "If recursion flag is set to TRUE, the intersection checks" );
00168 grdCmd->SetGuidance( "will be performed recursively in the geometry tree." );
00169 grdCmd->SetGuidance( "NOTE: the recursion may take a very long time," );
00170 grdCmd->SetGuidance( " depending on the geometry complexity !");
00171 grdCmd->SetParameterName("recursionFlag",true);
00172 grdCmd->SetDefaultValue(false);
00173 grdCmd->AvailableForStates(G4State_Idle);
00174
00175 cyzCmd = new G4UIcmdWith3Vector( "/geometry/test/cylinder_geometry", this );
00176 cyzCmd->SetGuidance( "Define details of the cylinder geometry, specifying:" );
00177 cyzCmd->SetGuidance( " nPhi - number of lines per Phi" );
00178 cyzCmd->SetGuidance( " nZ - number of Z points" );
00179 cyzCmd->SetGuidance( " nRho - number of Rho points" );
00180 cyzCmd->SetGuidance( "Will be applied to the cylinder_test command." );
00181 cyzCmd->SetGuidance( "Initial default values: nPhi=90, nZ=50, nRho=50." );
00182 cyzCmd->SetParameterName( "nPhi", "nZ", "nRho", true, true );
00183 cyzCmd->SetDefaultValue( G4ThreeVector(90, 50, 50) );
00184
00185 cfzCmd = new G4UIcmdWithADouble( "/geometry/test/cylinder_scaleZ", this );
00186 cfzCmd->SetGuidance( "Define the resolution of the cylinder geometry, specifying" );
00187 cfzCmd->SetGuidance( "the fraction scale for points along Z." );
00188 cfzCmd->SetGuidance( "Initial default values: fracZ=0.8" );
00189 cfzCmd->SetParameterName("fracZ",true);
00190 cfzCmd->SetDefaultValue(0.8);
00191
00192 cfrCmd = new G4UIcmdWithADouble( "/geometry/test/cylinder_scaleRho", this );
00193 cfrCmd->SetGuidance( "Define the resolution of the cylinder geometry, specifying" );
00194 cfrCmd->SetGuidance( "the fraction scale for points along Rho." );
00195 cfrCmd->SetGuidance( "Initial default values: fracRho=0.8" );
00196 cfrCmd->SetParameterName("fracRho",true);
00197 cfrCmd->SetDefaultValue(0.8);
00198
00199 cylCmd = new G4UIcmdWithABool( "/geometry/test/cylinder_test", this );
00200 cylCmd->SetGuidance( "Start running the cylinder test." );
00201 cylCmd->SetGuidance( "A set of lines in a cylindrical pattern of gradually" );
00202 cylCmd->SetGuidance( "increasing mesh size." );
00203 cylCmd->SetGuidance( "By default, only direct daughters of the mother volumes are checked." );
00204 cylCmd->SetGuidance( "If recursion flag is set to TRUE, the intersection checks" );
00205 cylCmd->SetGuidance( "will be performed recursively in the geometry tree." );
00206 cylCmd->SetGuidance( "NOTE: the recursion may take a very long time," );
00207 cylCmd->SetGuidance( " depending on the geometry complexity !");
00208 cylCmd->SetParameterName("recursionFlag",true);
00209 cylCmd->SetDefaultValue(false);
00210 cylCmd->AvailableForStates(G4State_Idle);
00211
00212 rcsCmd = new G4UIcmdWithAnInteger( "/geometry/test/recursion_start", this );
00213 rcsCmd->SetGuidance( "Set the initial level in the geometry tree for recursion." );
00214 rcsCmd->SetGuidance( "recursive_test will then start from the specified level." );
00215 rcsCmd->SetParameterName("initial_level",true);
00216 rcsCmd->SetDefaultValue(0);
00217
00218 rcdCmd = new G4UIcmdWithAnInteger( "/geometry/test/recursion_depth", this );
00219 rcdCmd->SetGuidance( "Set the depth in the geometry tree for recursion." );
00220 rcdCmd->SetGuidance( "recursive_test will then stop after reached the specified depth." );
00221 rcdCmd->SetGuidance( "By default, recursion will proceed for the whole depth." );
00222 rcdCmd->SetParameterName("recursion_depth",true);
00223 rcdCmd->SetDefaultValue(-1);
00224
00225
00226
00227 runCmd = new G4UIcmdWithABool( "/geometry/test/run", this );
00228 runCmd->SetGuidance( "Start running the default grid test." );
00229 runCmd->SetGuidance( "Same as the grid_test command." );
00230 runCmd->SetGuidance( "If recursion flag is set to TRUE, the intersection checks" );
00231 runCmd->SetGuidance( "will be performed recursively in the geometry tree." );
00232 runCmd->SetGuidance( "NOTE: the recursion may take a very long time," );
00233 runCmd->SetGuidance( " depending on the geometry complexity !");
00234 runCmd->SetParameterName("recursionFlag",true);
00235 runCmd->SetDefaultValue(false);
00236 runCmd->AvailableForStates(G4State_Idle);
00237
00238 recCmd = new G4UIcmdWithoutParameter( "/geometry/test/recursive_test", this );
00239 recCmd->SetGuidance( "Start running the recursive grid test." );
00240 recCmd->SetGuidance( "A grid of lines along a cartesian axis is recursively" );
00241 recCmd->SetGuidance( "to all daughters and daughters of daughters, etc." );
00242 recCmd->SetGuidance( "NOTE: it may take a very long time," );
00243 recCmd->SetGuidance( " depending on the geometry complexity !");
00244 recCmd->AvailableForStates(G4State_Idle);
00245 }
00246
00247
00248
00249
00250 G4GeometryMessenger::~G4GeometryMessenger()
00251 {
00252 delete linCmd; delete posCmd; delete dirCmd;
00253 delete grzCmd; delete grdCmd; delete recCmd; delete runCmd;
00254 delete rcsCmd; delete rcdCmd;
00255 delete cyzCmd; delete cfzCmd; delete cfrCmd; delete cylCmd;
00256 delete tolCmd;
00257 delete resCmd; delete verbCmd; delete pchkCmd; delete chkCmd;
00258 delete geodir; delete navdir; delete testdir;
00259 delete tvolume; delete tlogger;
00260 }
00261
00262
00263
00264
00265 void
00266 G4GeometryMessenger::Init()
00267 {
00268
00269
00270 if (tlogger) delete tlogger;
00271 if (tvolume) delete tvolume;
00272
00273
00274
00275 tlogger = new G4GeomTestStreamLogger(std::cout);
00276
00277
00278
00279 G4VPhysicalVolume* world =
00280 tmanager->GetNavigatorForTracking()->GetWorldVolume();
00281
00282
00283
00284 tvolume = new G4GeomTestVolume(world, tlogger);
00285 }
00286
00287
00288
00289
00290 void
00291 G4GeometryMessenger::SetNewValue( G4UIcommand* command, G4String newValues )
00292 {
00293 if (command == resCmd) {
00294 ResetNavigator();
00295 }
00296 else if (command == verbCmd) {
00297 SetVerbosity( newValues );
00298 }
00299 else if (command == chkCmd) {
00300 SetCheckMode( newValues );
00301 }
00302 else if (command == posCmd) {
00303 x = posCmd->GetNew3VectorValue( newValues );
00304 }
00305 else if (command == dirCmd) {
00306 p = dirCmd->GetNew3VectorValue( newValues );
00307 if (p.mag() < DBL_MIN) {
00308 G4cerr << "Please specify non-zero momentum!" << G4endl;
00309 p = G4ThreeVector(0,0,1);
00310 }
00311 }
00312 else if (command == tolCmd) {
00313 tol = tolCmd->GetNewDoubleValue( newValues );
00314 newtol = true;
00315 }
00316 else if (command == linCmd) {
00317 Init();
00318 if (linCmd->GetNewBoolValue( newValues ))
00319 RecursiveLineTest();
00320 else
00321 LineTest();
00322 }
00323 else if ((command == grdCmd) || (command == runCmd)){
00324 Init();
00325 if (grdCmd->GetNewBoolValue( newValues ) || runCmd->GetNewBoolValue( newValues ))
00326 RecursiveGridTest();
00327 else
00328 GridTest();
00329 }
00330 else if (command == grzCmd) {
00331 grdRes = grzCmd->GetNew3VectorValue( newValues );
00332 if (grdRes.mag() < DBL_MIN) {
00333 G4cerr << "Please specify non-zero resolution!" << G4endl;
00334 grdRes = G4ThreeVector(100,100,100);
00335 }
00336 }
00337 else if (command == cyzCmd) {
00338 cylRes = cyzCmd->GetNew3VectorValue( newValues );
00339 }
00340 else if (command == cfzCmd) {
00341 cylfZ = cfzCmd->GetNewDoubleValue( newValues );
00342 }
00343 else if (command == cfrCmd) {
00344 cylfR = cfrCmd->GetNewDoubleValue( newValues );
00345 }
00346 else if (command == rcsCmd) {
00347 recLevel = rcsCmd->GetNewIntValue( newValues );
00348 }
00349 else if (command == rcdCmd) {
00350 recDepth = rcdCmd->GetNewIntValue( newValues );
00351 }
00352 else if (command == recCmd) {
00353 Init();
00354 RecursiveGridTest();
00355 }
00356 else if (command == cylCmd) {
00357 Init();
00358 if (cylCmd->GetNewBoolValue( newValues ))
00359 RecursiveCylinderTest();
00360 else
00361 CylinderTest();
00362 }
00363 }
00364
00365
00366
00367
00368 G4String
00369 G4GeometryMessenger::GetCurrentValue(G4UIcommand* command )
00370 {
00371 G4String cv = "";
00372 if (command == posCmd) {
00373 cv = posCmd->ConvertToString( x, "cm" );
00374 }
00375 else if (command == tolCmd) {
00376 cv = tolCmd->ConvertToString( tol, "mm" );
00377 }
00378 else if (command == dirCmd) {
00379 cv = dirCmd->ConvertToString( p, "GeV" );
00380 }
00381 return cv;
00382 }
00383
00384
00385
00386
00387 void
00388 G4GeometryMessenger::CheckGeometry()
00389 {
00390
00391
00392 G4GeometryManager* geomManager = G4GeometryManager::GetInstance();
00393 if (!geomManager->IsGeometryClosed()) {
00394 geomManager->OpenGeometry();
00395 geomManager->CloseGeometry(true);
00396 }
00397 }
00398
00399
00400
00401
00402 void
00403 G4GeometryMessenger::ResetNavigator()
00404 {
00405
00406
00407 CheckGeometry();
00408
00409
00410
00411 G4ThreeVector pt(0,0,0);
00412 G4Navigator* navigator = tmanager->GetNavigatorForTracking();
00413 navigator->LocateGlobalPointAndSetup(pt,0,false);
00414 }
00415
00416
00417
00418
00419 void
00420 G4GeometryMessenger::SetVerbosity(G4String input)
00421 {
00422 G4int level = verbCmd->GetNewIntValue(input);
00423 G4Navigator* navigator = tmanager->GetNavigatorForTracking();
00424 navigator->SetVerboseLevel(level);
00425 }
00426
00427
00428
00429
00430 void
00431 G4GeometryMessenger::SetCheckMode(G4String input)
00432 {
00433 G4bool mode = chkCmd->GetNewBoolValue(input);
00434 G4Navigator* navigator = tmanager->GetNavigatorForTracking();
00435 navigator->CheckMode(mode);
00436 }
00437
00438
00439
00440
00441 void
00442 G4GeometryMessenger::SetPushFlag(G4String input)
00443 {
00444 G4bool mode = pchkCmd->GetNewBoolValue(input);
00445 G4Navigator* navigator = tmanager->GetNavigatorForTracking();
00446 navigator->SetPushVerbosity(mode);
00447 }
00448
00449
00450
00451
00452 void
00453 G4GeometryMessenger::LineTest()
00454 {
00455
00456
00457 CheckGeometry();
00458
00459
00460
00461 if (newtol) tvolume->SetTolerance(tol);
00462
00463
00464
00465 tvolume->TestOneLine( x, p );
00466
00467
00468
00469 tvolume->ReportErrors();
00470 }
00471
00472
00473
00474
00475 void
00476 G4GeometryMessenger::RecursiveLineTest()
00477 {
00478
00479
00480 CheckGeometry();
00481
00482
00483
00484 if (newtol) tvolume->SetTolerance(tol);
00485
00486
00487
00488 tvolume->TestRecursiveLine( x, p, recLevel, recDepth );
00489
00490
00491
00492 tvolume->ReportErrors();
00493 }
00494
00495
00496
00497
00498 void
00499 G4GeometryMessenger::GridTest()
00500 {
00501
00502
00503 CheckGeometry();
00504
00505
00506
00507 if (newtol) tvolume->SetTolerance(tol);
00508
00509
00510
00511 tvolume->TestCartGridXYZ( G4int(grdRes.x()),
00512 G4int(grdRes.y()),
00513 G4int(grdRes.z()) );
00514
00515
00516
00517 tvolume->ReportErrors();
00518 }
00519
00520
00521
00522
00523 void
00524 G4GeometryMessenger::RecursiveGridTest()
00525 {
00526
00527
00528 CheckGeometry();
00529
00530
00531
00532 if (newtol) tvolume->SetTolerance(tol);
00533
00534
00535
00536 tvolume->TestRecursiveCartGrid( G4int(grdRes.x()),
00537 G4int(grdRes.y()),
00538 G4int(grdRes.z()),
00539 recLevel, recDepth );
00540
00541
00542
00543 tvolume->ReportErrors();
00544 }
00545
00546
00547
00548
00549 void
00550 G4GeometryMessenger::CylinderTest()
00551 {
00552
00553
00554 CheckGeometry();
00555
00556
00557
00558 if (newtol) tvolume->SetTolerance(tol);
00559
00560
00561
00562
00563 tvolume->TestCylinder(G4int(cylRes.x()),
00564 G4int(cylRes.y()),
00565 G4int(cylRes.z()),
00566 cylfZ, cylfR, true);
00567
00568
00569
00570 tvolume->ReportErrors();
00571 }
00572
00573
00574
00575
00576 void
00577 G4GeometryMessenger::RecursiveCylinderTest()
00578 {
00579
00580
00581 CheckGeometry();
00582
00583
00584
00585 if (newtol) tvolume->SetTolerance(tol);
00586
00587
00588
00589
00590 tvolume->TestRecursiveCylinder(G4int(cylRes.x()),
00591 G4int(cylRes.y()),
00592 G4int(cylRes.z()),
00593 cylfZ, cylfR, true,
00594 recLevel, recDepth );
00595
00596
00597
00598 tvolume->ReportErrors();
00599 }