Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 /// \file RE06/src/RE06DetectorConstruction.cc 27 /// \brief Implementation of the RE06DetectorC 28 // 29 // 30 31 #include "RE06DetectorConstruction.hh" 32 33 #include "RE06DetectorMessenger.hh" 34 #include "RE06ParallelWorld.hh" 35 #include "RE06PrimaryGeneratorAction.hh" 36 37 #include "G4Box.hh" 38 #include "G4Colour.hh" 39 #include "G4LogicalVolume.hh" 40 #include "G4Material.hh" 41 #include "G4MultiFunctionalDetector.hh" 42 #include "G4PSEnergyDeposit.hh" 43 #include "G4PSMinKinEAtGeneration.hh" 44 #include "G4PSNofSecondary.hh" 45 #include "G4PSNofStep.hh" 46 #include "G4PSTrackLength.hh" 47 #include "G4PVPlacement.hh" 48 #include "G4PVReplica.hh" 49 #include "G4PhysicalConstants.hh" 50 #include "G4RunManager.hh" 51 #include "G4SDManager.hh" 52 #include "G4SDParticleFilter.hh" 53 #include "G4SystemOfUnits.hh" 54 #include "G4VPrimitiveScorer.hh" 55 #include "G4VSDFilter.hh" 56 #include "G4VisAttributes.hh" 57 #include "G4ios.hh" 58 59 //....oooOO0OOooo........oooOO0OOooo........oo 60 61 G4ThreadLocal G4bool RE06DetectorConstruction: 62 63 RE06DetectorConstruction::RE06DetectorConstruc 64 : G4VUserDetectorConstruction(), 65 fNumberOfLayers(40), 66 fTotalThickness(2.0 * m), 67 fLayerThickness(0.), 68 fConstructed(false), 69 fWorldMaterial(0), 70 fAbsorberMaterial(0), 71 fGapMaterial(0), 72 fLayerSolid(0), 73 fGapSolid(0), 74 fWorldLogical(0), 75 fWorldPhysical(0), 76 fSerial(false), 77 fDetectorMessenger(0), 78 fVerboseLevel(1) 79 { 80 fLayerThickness = fTotalThickness / fNumberO 81 82 for (size_t i = 0; i < 3; i++) { 83 fCalorLogical[i] = 0; 84 fLayerLogical[i] = 0; 85 fGapLogical[i] = 0; 86 fCalorPhysical[i] = 0; 87 fLayerPhysical[i] = 0; 88 fGapPhysical[i] = 0; 89 } 90 91 fCalName[0] = "Calor-A"; 92 fCalName[1] = "Calor-B"; 93 fCalName[2] = "Calor-C"; 94 95 fDetectorMessenger = new RE06DetectorMesseng 96 } 97 98 //....oooOO0OOooo........oooOO0OOooo........oo 99 100 RE06DetectorConstruction::~RE06DetectorConstru 101 { 102 delete fDetectorMessenger; 103 } 104 105 G4VPhysicalVolume* RE06DetectorConstruction::C 106 { 107 if (!fConstructed) { 108 fConstructed = true; 109 DefineMaterials(); 110 SetupGeometry(); 111 } 112 if (GetVerboseLevel() > 0) { 113 PrintCalorParameters(); 114 } 115 return fWorldPhysical; 116 } 117 118 void RE06DetectorConstruction::ConstructSDandF 119 { 120 if (!fConstructedSDandField) { 121 fConstructedSDandField = true; 122 SetupDetectors(); 123 } 124 } 125 126 //....oooOO0OOooo........oooOO0OOooo........oo 127 128 void RE06DetectorConstruction::DefineMaterials 129 { 130 G4String name, symbol; // a=mass of a mole; 131 G4double a, z, density; // z=mean number of 132 G4int iz; // iz=number of protons in an is 133 G4int n; // n=number of nucleons in an isot 134 135 G4int ncomponents, natoms; 136 G4double abundance, fractionmass; 137 G4double temperature, pressure; 138 139 // 140 // define Elements 141 // 142 143 a = 1.01 * g / mole; 144 G4Element* H = new G4Element(name = "Hydroge 145 146 a = 12.01 * g / mole; 147 G4Element* C = new G4Element(name = "Carbon" 148 149 a = 14.01 * g / mole; 150 G4Element* N = new G4Element(name = "Nitroge 151 152 a = 16.00 * g / mole; 153 G4Element* O = new G4Element(name = "Oxygen" 154 155 // 156 // define an Element from isotopes, by relat 157 // 158 159 G4Isotope* U5 = new G4Isotope(name = "U235", 160 G4Isotope* U8 = new G4Isotope(name = "U238", 161 162 G4Element* U = new G4Element(name = "enriche 163 U->AddIsotope(U5, abundance = 90. * perCent) 164 U->AddIsotope(U8, abundance = 10. * perCent) 165 166 // 167 // define simple materials 168 // 169 170 new G4Material(name = "Aluminium", z = 13., 171 new G4Material(name = "Silicon", z = 14., a 172 new G4Material(name = "Iron", z = 26., a = 5 173 new G4Material(name = "ArgonGas", z = 18., a 174 new G4Material(name = "He", z = 2., a = 4.0 175 176 density = 1.390 * g / cm3; 177 a = 39.95 * g / mole; 178 G4Material* lAr = new G4Material(name = "liq 179 180 density = 11.35 * g / cm3; 181 a = 207.19 * g / mole; 182 G4Material* Pb = new G4Material(name = "Lead 183 184 // 185 // define a material from elements. case 1 186 // 187 188 density = 1.000 * g / cm3; 189 G4Material* H2O = new G4Material(name = "Wat 190 H2O->AddElement(H, natoms = 2); 191 H2O->AddElement(O, natoms = 1); 192 193 density = 1.032 * g / cm3; 194 G4Material* Sci = new G4Material(name = "Sci 195 Sci->AddElement(C, natoms = 9); 196 Sci->AddElement(H, natoms = 10); 197 198 // 199 // define a material from elements. case 2 200 // 201 202 density = 1.290 * mg / cm3; 203 G4Material* Air = new G4Material(name = "Air 204 Air->AddElement(N, fractionmass = 0.7); 205 Air->AddElement(O, fractionmass = 0.3); 206 207 // 208 // examples of vacuum 209 // 210 211 density = universe_mean_density; 212 pressure = 3.e-18 * pascal; 213 temperature = 2.73 * kelvin; 214 G4Material* Vacuum = new G4Material(name = " 215 kStateGa 216 217 if (GetVerboseLevel() > 1) { 218 G4cout << *(G4Material::GetMaterialTable() 219 } 220 221 // default materials of the calorimeter 222 fWorldMaterial = Vacuum; 223 fAbsorberMaterial = Pb; 224 fGapMaterial = lAr; 225 } 226 227 //....oooOO0OOooo........oooOO0OOooo........oo 228 229 void RE06DetectorConstruction::SetupGeometry() 230 { 231 // 232 // World 233 // 234 G4VSolid* worldSolid = new G4Box("World", 2. 235 fWorldLogical = new G4LogicalVolume(worldSol 236 fWorldPhysical = new G4PVPlacement(0, G4Thre 237 238 // 239 // Calorimeter 240 // 241 G4VSolid* calorSolid = new G4Box("Calor", 0. 242 G4int i; 243 for (i = 0; i < 3; i++) { 244 fCalorLogical[i] = new G4LogicalVolume(cal 245 if (fSerial) { 246 fCalorPhysical[i] = 247 new G4PVPlacement(0, G4ThreeVector(0., 248 fCalorLogical[i], fC 249 } 250 else { 251 fCalorPhysical[i] = new G4PVPlacement(0, 252 fC 253 } 254 } 255 256 // 257 // Layers --- as absorbers 258 // 259 fLayerSolid = new G4Box("Layer", 0.5 * m, 0. 260 for (i = 0; i < 3; i++) { 261 fLayerLogical[i] = 262 new G4LogicalVolume(fLayerSolid, fAbsorb 263 fLayerPhysical[i] = new G4PVReplica(fCalNa 264 kZAxis 265 } 266 267 // 268 // Gap 269 // 270 fGapSolid = new G4Box("Gap", 0.5 * m, 0.5 * 271 for (i = 0; i < 3; i++) { 272 fGapLogical[i] = new G4LogicalVolume(fGapS 273 fGapPhysical[i] = 274 new G4PVPlacement(0, G4ThreeVector(0., 0 275 fCalName[i] + "_gap", 276 } 277 278 // 279 // Regions 280 // 281 for (i = 0; i < 3; i++) { 282 G4Region* aRegion = new G4Region(fCalName[ 283 fCalorLogical[i]->SetRegion(aRegion); 284 aRegion->AddRootLogicalVolume(fCalorLogica 285 } 286 287 // 288 // Visualization attributes 289 // 290 fWorldLogical->SetVisAttributes(G4VisAttribu 291 G4VisAttributes* simpleBoxVisAtt = new G4Vis 292 simpleBoxVisAtt->SetVisibility(true); 293 for (i = 0; i < 3; i++) { 294 fCalorLogical[i]->SetVisAttributes(simpleB 295 fLayerLogical[i]->SetVisAttributes(simpleB 296 fGapLogical[i]->SetVisAttributes(simpleBox 297 } 298 } 299 300 //....oooOO0OOooo........oooOO0OOooo........oo 301 302 void RE06DetectorConstruction::SetupDetectors( 303 { 304 G4SDManager::GetSDMpointer()->SetVerboseLeve 305 G4String filterName, particleName; 306 307 G4SDParticleFilter* gammaFilter = 308 new G4SDParticleFilter(filterName = "gamma 309 G4SDParticleFilter* electronFilter = 310 new G4SDParticleFilter(filterName = "elect 311 G4SDParticleFilter* positronFilter = 312 new G4SDParticleFilter(filterName = "posit 313 G4SDParticleFilter* epFilter = new G4SDParti 314 epFilter->add(particleName = "e-"); 315 epFilter->add(particleName = "e+"); 316 317 for (G4int i = 0; i < 3; i++) { 318 for (G4int j = 0; j < 2; j++) { 319 // Loop counter j = 0 : absorber 320 // = 1 : gap 321 G4String detName = fCalName[i]; 322 if (j == 0) { 323 detName += "_abs"; 324 } 325 else { 326 detName += "_gap"; 327 } 328 G4MultiFunctionalDetector* det = new G4M 329 G4SDManager::GetSDMpointer()->AddNewDete 330 331 // The second argument in each primitive 332 // hierarchy, the copy number of that le 333 // G4THitsMap. 334 // For absorber (j = 0), the copy number 335 // For gap (j = 1), the copy number of i 336 // since there is only one physical volu 337 // to its mother. 338 G4VPrimitiveScorer* primitive; 339 primitive = new G4PSEnergyDeposit("eDep" 340 det->RegisterPrimitive(primitive); 341 primitive = new G4PSNofSecondary("nGamma 342 primitive->SetFilter(gammaFilter); 343 det->RegisterPrimitive(primitive); 344 primitive = new G4PSNofSecondary("nElect 345 primitive->SetFilter(electronFilter); 346 det->RegisterPrimitive(primitive); 347 primitive = new G4PSNofSecondary("nPosit 348 primitive->SetFilter(positronFilter); 349 det->RegisterPrimitive(primitive); 350 primitive = new G4PSMinKinEAtGeneration( 351 primitive->SetFilter(gammaFilter); 352 det->RegisterPrimitive(primitive); 353 primitive = new G4PSMinKinEAtGeneration( 354 primitive->SetFilter(electronFilter); 355 det->RegisterPrimitive(primitive); 356 primitive = new G4PSMinKinEAtGeneration( 357 primitive->SetFilter(positronFilter); 358 det->RegisterPrimitive(primitive); 359 primitive = new G4PSTrackLength("trackLe 360 primitive->SetFilter(epFilter); 361 det->RegisterPrimitive(primitive); 362 primitive = new G4PSNofStep("nStep", j); 363 primitive->SetFilter(epFilter); 364 det->RegisterPrimitive(primitive); 365 366 if (j == 0) { 367 SetSensitiveDetector(fLayerLogical[i], 368 } 369 else { 370 SetSensitiveDetector(fGapLogical[i], d 371 } 372 } 373 } 374 G4SDManager::GetSDMpointer()->SetVerboseLeve 375 } 376 377 void RE06DetectorConstruction::PrintCalorParam 378 { 379 G4cout << "--------------------------------- 380 if (fSerial) { 381 G4cout << " Calorimeters are placed in ser 382 } 383 else { 384 G4cout << " Calorimeters are placed in par 385 } 386 G4cout << " Absorber is made of " << fAbsorb 387 << fGapMaterial->GetName() << G4endl 388 << "--------------------------------- 389 } 390 391 //....oooOO0OOooo........oooOO0OOooo........oo 392 393 void RE06DetectorConstruction::SetAbsorberMate 394 { 395 // search the material by its name 396 G4Material* pttoMaterial = G4Material::GetMa 397 if (pttoMaterial) { 398 fAbsorberMaterial = pttoMaterial; 399 if (fConstructed) 400 for (size_t i = 0; i < 3; i++) { 401 fCalorLogical[i]->SetMaterial(fAbsorbe 402 fLayerLogical[i]->SetMaterial(fAbsorbe 403 } 404 G4RunManager::GetRunManager()->GeometryHas 405 if (GetVerboseLevel() > 1) { 406 PrintCalorParameters(); 407 } 408 } 409 else { 410 G4cerr << materialChoice << " is not defin 411 } 412 } 413 414 //....oooOO0OOooo........oooOO0OOooo........oo 415 416 G4String RE06DetectorConstruction::GetAbsorber 417 { 418 return fAbsorberMaterial->GetName(); 419 } 420 421 //....oooOO0OOooo........oooOO0OOooo........oo 422 423 void RE06DetectorConstruction::SetGapMaterial( 424 { 425 // search the material by its name 426 G4Material* pttoMaterial = G4Material::GetMa 427 if (pttoMaterial) { 428 fGapMaterial = pttoMaterial; 429 if (fConstructed) 430 for (size_t i = 0; i < 3; i++) { 431 fGapLogical[i]->SetMaterial(fGapMateri 432 } 433 G4RunManager::GetRunManager()->GeometryHas 434 if (GetVerboseLevel() > 1) { 435 PrintCalorParameters(); 436 } 437 } 438 else { 439 G4cerr << materialChoice << " is not defin 440 } 441 } 442 443 G4String RE06DetectorConstruction::GetGapMater 444 { 445 return fGapMaterial->GetName(); 446 } 447 448 //....oooOO0OOooo........oooOO0OOooo........oo 449 450 void RE06DetectorConstruction::SetSerialGeomet 451 { 452 if (fSerial == serial) return; 453 fSerial = serial; 454 RE06PrimaryGeneratorAction* gen = 455 (RE06PrimaryGeneratorAction*)(G4RunManager 456 if (gen) gen->SetSerial(fSerial); 457 if (!fConstructed) return; 458 for (G4int i = 0; i < 3; i++) { 459 if (fSerial) { 460 fCalorPhysical[i]->SetTranslation(G4Thre 461 } 462 else { 463 fCalorPhysical[i]->SetTranslation(G4Thre 464 } 465 } 466 ((RE06ParallelWorld*)GetParallelWorld(0))->S 467 G4RunManager::GetRunManager()->GeometryHasBe 468 } 469 470 //....oooOO0OOooo........oooOO0OOooo........oo 471 472 void RE06DetectorConstruction::SetNumberOfLaye 473 { 474 fNumberOfLayers = nl; 475 fLayerThickness = fTotalThickness / fNumberO 476 if (!fConstructed) return; 477 478 fLayerSolid->SetZHalfLength(fLayerThickness 479 fGapSolid->SetZHalfLength(fLayerThickness / 480 for (size_t i = 0; i < 3; i++) { 481 fCalorLogical[i]->RemoveDaughter(fLayerPhy 482 delete fLayerPhysical[i]; 483 fLayerPhysical[i] = new G4PVReplica(fCalNa 484 kZAxis 485 fGapPhysical[i]->SetTranslation(G4ThreeVec 486 } 487 G4RunManager::GetRunManager()->GeometryHasBe 488 } 489 490 //....oooOO0OOooo........oooOO0OOooo........oo 491 492 void RE06DetectorConstruction::AddMaterial() 493 { 494 static G4bool isAdded = false; 495 496 if (isAdded) return; 497 498 G4String name, symbol; // a=mass of a mole; 499 G4double a, z, density; // z=mean number of 500 501 G4int ncomponents, natoms; 502 503 // 504 // define simple materials 505 // 506 507 new G4Material(name = "Copper", z = 29., a = 508 new G4Material(name = "Tungsten", z = 74., a 509 510 G4Element* C = G4Element::GetElement("Carbon 511 G4Element* O = G4Element::GetElement("Oxygen 512 513 G4Material* CO2 = new G4Material("CarbonicGa 514 kStateGas, 515 CO2->AddElement(C, natoms = 1); 516 CO2->AddElement(O, natoms = 2); 517 518 isAdded = true; 519 } 520 521 //....oooOO0OOooo........oooOO0OOooo........oo 522