Geant4 Cross Reference |
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 // Gorad (Geant4 Open-source Radiation Analysis and Design) 27 // 28 // Author : Makoto Asai (SLAC National Accelerator Laboratory) 29 // 30 // Development of Gorad is funded by NASA Johnson Space Center (JSC) 31 // under the contract NNJ15HK11B. 32 // 33 // ******************************************************************** 34 // 35 // GRDetectorConstruction.cc 36 // Read a GDML file to set up the geometry. 37 // This class also takes care of several utility methods on geometry 38 // and creates a parallel world for geometry importance biasing if 39 // requested. 40 // 41 // History 42 // September 8th, 2020 : first implementation 43 // 44 // ******************************************************************** 45 46 #include "GRDetectorConstruction.hh" 47 48 #include "G4GDMLParser.hh" 49 #include "GRDetectorConstructionMessenger.hh" 50 #include "GRGeomImpBiasWorld.hh" 51 52 #include "G4VPhysicalVolume.hh" 53 #include "G4RunManager.hh" 54 #include "G4LogicalVolume.hh" 55 #include "G4Box.hh" 56 #include <algorithm> 57 58 G4double GRDetectorConstruction::worldSize = -1.; 59 60 GRDetectorConstruction::GRDetectorConstruction() 61 : gdmlFile("noName"), fWorld(nullptr), initialized(false) 62 { 63 messenger = new GRDetectorConstructionMessenger(this); 64 parser = new G4GDMLParser(); 65 } 66 67 GRDetectorConstruction::~GRDetectorConstruction() 68 { 69 delete messenger; 70 delete parser; 71 } 72 73 G4VPhysicalVolume* GRDetectorConstruction::Construct() 74 { 75 if(!initialized) 76 { 77 Read(); 78 if(applyGeomImpBias) 79 { 80 G4String wName = "GeomBias"; 81 geomImpBiasWorld = new GRGeomImpBiasWorld(wName,this); 82 RegisterParallelWorld(geomImpBiasWorld); 83 } 84 } 85 return fWorld; 86 } 87 88 void GRDetectorConstruction::ConstructSDAndField() 89 { ; } 90 91 G4bool GRDetectorConstruction::SetGDMLFile(G4String& gdml) 92 { 93 G4bool valid = true; // parser->IsValid(gdml); ## GDML parser fix needed 94 if(valid) 95 { 96 if(initialized) 97 { 98 parser->Clear(); 99 G4RunManager::GetRunManager()->ReinitializeGeometry(true); 100 } 101 gdmlFile = gdml; 102 } 103 return valid; 104 } 105 106 void GRDetectorConstruction::Read() 107 { 108 parser->Read(gdmlFile); 109 fWorld = parser->GetWorldVolume(); 110 const G4Box* worldBox = dynamic_cast<const G4Box*>(fWorld->GetLogicalVolume()->GetSolid()); 111 if(!worldBox) 112 { 113 G4ExceptionDescription ed; 114 ed << "PANIC!!! World volume defined in "<<gdmlFile<<" is not Box!!!"; 115 G4Exception("GRDetectorConstruction::Read()","GOoradGeom00012",FatalException,ed); 116 } 117 worldSize = std::min( {worldBox->GetXHalfLength(), worldBox->GetYHalfLength(), worldBox->GetZHalfLength()}, 118 [](G4double a,G4double b) {return a<b;} ); 119 initialized = true; 120 } 121 122 #include "G4UnitsTable.hh" 123 #include "G4VSolid.hh" 124 #include "G4SolidStore.hh" 125 void GRDetectorConstruction::ListSolids(G4int lvl) 126 { 127 G4cout << "*********** List of registered solids *************" << G4endl; 128 auto store = G4SolidStore::GetInstance(); 129 auto itr = store->begin(); 130 for(;itr!=store->end();itr++) 131 { 132 switch(lvl) 133 { 134 case 0: 135 G4cout << (*itr)->GetName() << G4endl; 136 break; 137 case 1: 138 G4cout << (*itr)->GetName() 139 << "\t volume = " << G4BestUnit((*itr)->GetCubicVolume(),"Volume") 140 << "\t surface = " << G4BestUnit((*itr)->GetSurfaceArea(),"Surface") 141 << G4endl; 142 break; 143 default: 144 (*itr)->DumpInfo(); 145 break; 146 } 147 } 148 } 149 150 #include "G4LogicalVolume.hh" 151 #include "G4LogicalVolumeStore.hh" 152 #include "G4Material.hh" 153 #include "G4VSensitiveDetector.hh" 154 void GRDetectorConstruction::ListLogVols(G4int lvl) 155 { 156 G4cout << "*********** List of registered logical volumes *************" << G4endl; 157 auto store = G4LogicalVolumeStore::GetInstance(); 158 auto itr = store->begin(); 159 for(;itr!=store->end();itr++) 160 { 161 G4cout << (*itr)->GetName() << "\t Solid = " << (*itr)->GetSolid()->GetName(); 162 if((*itr)->GetMaterial()) 163 { G4cout << "\t Material = " << (*itr)->GetMaterial()->GetName() << G4endl; } 164 else 165 { G4cout << "\t Material : not defined " << G4endl; } 166 if(lvl<1) continue; 167 G4cout << "\t region = "; 168 if((*itr)->GetRegion()) 169 { G4cout << (*itr)->GetRegion()->GetName(); } 170 else 171 { G4cout << "not defined"; } 172 G4cout << "\t sensitive detector = "; 173 if((*itr)->GetSensitiveDetector()) 174 { G4cout << (*itr)->GetSensitiveDetector()->GetName(); } 175 else 176 { G4cout << "not defined"; } 177 G4cout << G4endl; 178 G4cout << "\t daughters = " << (*itr)->GetNoDaughters(); 179 if((*itr)->GetNoDaughters()>0) 180 { 181 switch((*itr)->CharacteriseDaughters()) 182 { 183 case kNormal: 184 G4cout << " (placement)"; break; 185 case kReplica: 186 G4cout << " (replica : " << (*itr)->GetDaughter(0)->GetMultiplicity() << ")"; break; 187 case kParameterised: 188 G4cout << " (parameterized : " << (*itr)->GetDaughter(0)->GetMultiplicity() << ")"; break; 189 default: 190 ; 191 } 192 } 193 G4cout << G4endl; 194 if(lvl<2) continue; 195 if((*itr)->GetMaterial()) 196 { G4cout << "\t weight = " << G4BestUnit((*itr)->GetMass(),"Mass") << G4endl; } 197 else 198 { G4cout << "\t weight : not available" << G4endl; } 199 } 200 } 201 202 #include "G4VPhysicalVolume.hh" 203 #include "G4PhysicalVolumeStore.hh" 204 void GRDetectorConstruction::ListPhysVols(G4int lvl) 205 { 206 G4cout << "*********** List of registered physical volumes *************" << G4endl; 207 auto store = G4PhysicalVolumeStore::GetInstance(); 208 auto itr = store->begin(); 209 for(;itr!=store->end();itr++) 210 { 211 switch(lvl) 212 { 213 case 0: 214 G4cout << (*itr)->GetName() << G4endl; 215 break; 216 case 1: 217 G4cout << (*itr)->GetName() 218 << "\t logical volume = " << (*itr)->GetLogicalVolume()->GetName() 219 << "\t mother logical = "; 220 if((*itr)->GetMotherLogical()) 221 { G4cout << (*itr)->GetMotherLogical()->GetName(); } 222 else 223 { G4cout << "not defined"; } 224 G4cout << G4endl; 225 break; 226 default: 227 G4cout << (*itr)->GetName() 228 << "\t logical volume = " << (*itr)->GetLogicalVolume()->GetName() 229 << "\t mother logical = "; 230 if((*itr)->GetMotherLogical()) 231 { G4cout << (*itr)->GetMotherLogical()->GetName(); } 232 else 233 { G4cout << "not defined"; } 234 G4cout << "\t type = "; 235 switch((*itr)->VolumeType()) 236 { 237 case kNormal: 238 G4cout << "placement"; break; 239 case kReplica: 240 G4cout << "replica"; break; 241 case kParameterised: 242 G4cout << "parameterized"; break; 243 default: 244 ; 245 } 246 G4cout << G4endl; 247 } 248 } 249 } 250 251 G4bool GRDetectorConstruction::CheckOverlap(G4String& physVolName, G4int nSpots, 252 G4int maxErr, G4double tol) 253 { 254 G4cout << "*********** Checking overlap for <" << physVolName << "> *************" << G4endl; 255 G4bool checkAll = (physVolName=="**ALL**"); 256 auto store = G4PhysicalVolumeStore::GetInstance(); 257 auto itr = store->begin(); 258 G4VPhysicalVolume* physVol = nullptr; 259 for(;itr!=store->end();itr++) 260 { 261 if(checkAll || (*itr)->GetName()==physVolName) 262 { 263 physVol = (*itr); 264 physVol->CheckOverlaps(nSpots,tol,true,maxErr); 265 if(!checkAll) break; 266 } 267 } 268 return (physVol!=nullptr); 269 } 270 271 #include "G4Region.hh" 272 #include "G4RegionStore.hh" 273 #include "G4RunManagerKernel.hh" 274 void GRDetectorConstruction::ListRegions(G4int lvl) 275 { 276 if(lvl==2) 277 { 278 G4RunManagerKernel::GetRunManagerKernel()->DumpRegion(); 279 return; 280 } 281 G4cout << "*********** List of registered regions *************" << G4endl; 282 auto store = G4RegionStore::GetInstance(); 283 auto itr = store->begin(); 284 for(;itr!=store->end();itr++) 285 { 286 G4cout << (*itr)->GetName(); 287 if((*itr)->GetWorldPhysical()) 288 { 289 G4cout << "\t in the world volume <" << (*itr)->GetWorldPhysical()->GetName() << "> "; 290 if((*itr)->IsInMassGeometry()) G4cout << "-- mass world"; 291 if((*itr)->IsInParallelGeometry()) G4cout << "-- parallel world"; 292 } 293 else 294 { G4cout << " -- is not associated to any world."; } 295 G4cout << G4endl; 296 if(lvl==0) continue; 297 G4cout << "\t\t Root logical volume(s) : "; 298 size_t nRootLV = (*itr)->GetNumberOfRootVolumes(); 299 std::vector<G4LogicalVolume*>::iterator lvItr = (*itr)->GetRootLogicalVolumeIterator(); 300 for(size_t j=0;j<nRootLV;j++) 301 { G4cout << (*lvItr)->GetName() << " "; lvItr++; } 302 G4cout << G4endl; 303 G4cout << "\t\t Pointers : G4VUserRegionInformation[" << (*itr)->GetUserInformation() 304 << "], G4UserLimits[" << (*itr)->GetUserLimits() 305 << "], G4FastSimulationManager[" << (*itr)->GetFastSimulationManager() 306 << "], G4UserSteppingAction[" << (*itr)->GetRegionalSteppingAction() << "]" << G4endl; 307 } 308 } 309 310 G4bool GRDetectorConstruction::CreateRegion(G4String& regionName,G4String& logVolName) 311 { 312 auto logVolStore = G4LogicalVolumeStore::GetInstance(); 313 auto itr = logVolStore->begin(); 314 G4LogicalVolume* logVol = nullptr; 315 for(;itr!=logVolStore->end();itr++) 316 { 317 if((*itr)->GetName() == logVolName) 318 { logVol = (*itr); break; } 319 } 320 if(!logVol) return false; 321 322 auto regionStore = G4RegionStore::GetInstance(); 323 auto region = regionStore->FindOrCreateRegion(regionName); 324 logVol->SetRegion(region); 325 region->AddRootLogicalVolume(logVol); 326 return true; 327 } 328 329 #include "G4MaterialTable.hh" 330 void GRDetectorConstruction::ListAllMaterial() 331 { 332 auto materialTable = G4Material::GetMaterialTable(); 333 auto matItr = materialTable->begin(); 334 G4cout << "*********** List of instantiated materials **************" << G4endl; 335 G4int i = 0; 336 for(;matItr!=materialTable->end();matItr++) 337 { 338 G4cout << (*matItr)->GetName() << "\t"; 339 if(++i%5==0) G4cout << G4endl; 340 } 341 G4cout << G4endl; 342 } 343 344 G4bool GRDetectorConstruction::ListMaterial(G4String& matName) 345 { 346 auto materialTable = G4Material::GetMaterialTable(); 347 auto matItr = materialTable->begin(); 348 for(;matItr!=materialTable->end();matItr++) 349 { 350 if((*matItr)->GetName()==matName) 351 { 352 G4cout << *matItr << G4endl; 353 return true; 354 } 355 } 356 return false; 357 } 358 359 #include "G4NistManager.hh" 360 void GRDetectorConstruction::DumpNistMaterials() 361 { 362 auto nameVec = G4NistManager::Instance()->GetNistMaterialNames(); 363 auto itr = nameVec.begin(); 364 G4int i = 0; 365 for(;itr!=nameVec.end();itr++) 366 { 367 G4cout << std::setw(26) << *itr; 368 if(++i%3==0) G4cout << G4endl; 369 } 370 G4cout << G4endl; 371 } 372 373 G4bool GRDetectorConstruction::CreateMaterial(G4String& matName) 374 { 375 auto mat = G4NistManager::Instance()->FindOrBuildMaterial(matName); 376 return (mat!=nullptr); 377 } 378 379 G4bool GRDetectorConstruction::GetMaterial(G4String& logVol) 380 { 381 auto store = G4LogicalVolumeStore::GetInstance(); 382 std::vector<G4LogicalVolume*>::iterator itr = store->begin(); 383 for(;itr!=store->end();itr++) 384 { 385 if((*itr)->GetName()==logVol) 386 { 387 G4cout << "Logical volume <" << (*itr)->GetName() << "> is made of <" 388 << (*itr)->GetMaterial()->GetName() << ">" << G4endl; 389 return true; 390 } 391 } 392 return false; 393 } 394 395 G4int GRDetectorConstruction::SetMaterial(G4String& logVolName,G4String& matName) 396 { 397 G4LogicalVolume* logVol = nullptr; 398 G4Material* mat = nullptr; 399 400 auto store = G4LogicalVolumeStore::GetInstance(); 401 auto itr = store->begin(); 402 for(;itr!=store->end();itr++) 403 { 404 if((*itr)->GetName()==logVolName) 405 { 406 logVol = *itr; 407 break; 408 } 409 } 410 411 auto materialTable = G4Material::GetMaterialTable(); 412 auto matItr = materialTable->begin(); 413 for(;matItr!=materialTable->end();matItr++) 414 { 415 if((*matItr)->GetName()==matName) 416 { 417 mat = *matItr; 418 break; 419 } 420 } 421 422 G4int retVal = 0; 423 if(!logVol && !mat) 424 { retVal = 3; } 425 else if(!logVol) 426 { retVal = 1; } 427 else if(!mat) 428 { retVal = 2; } 429 else 430 { logVol->SetMaterial(mat); } 431 432 return retVal; 433 } 434 435 436