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 // 27 /// \file GB03DetectorConstruction.cc 28 /// \brief Implementation of the GB03DetectorConstruction class 29 30 #include "GB03DetectorConstruction.hh" 31 32 #include "GB03BOptrGeometryBasedBiasing.hh" 33 #include "GB03DetectorMessenger.hh" 34 35 #include "G4Box.hh" 36 #include "G4Colour.hh" 37 #include "G4LogicalVolume.hh" 38 #include "G4Material.hh" 39 #include "G4MultiFunctionalDetector.hh" 40 #include "G4PSEnergyDeposit.hh" 41 #include "G4PSFlatSurfaceFlux.hh" 42 #include "G4PVPlacement.hh" 43 #include "G4PVReplica.hh" 44 #include "G4PhysicalConstants.hh" 45 #include "G4RunManager.hh" 46 #include "G4SDChargedFilter.hh" 47 #include "G4SDManager.hh" 48 #include "G4SDNeutralFilter.hh" 49 #include "G4SystemOfUnits.hh" 50 #include "G4VisAttributes.hh" 51 #include "G4ios.hh" 52 53 G4int GB03DetectorConstruction::fNumberOfLayers = 40; 54 G4ThreadLocal G4bool GB03DetectorConstruction::fConstructedSDandField = false; 55 56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 57 58 GB03DetectorConstruction::GB03DetectorConstruction() 59 : G4VUserDetectorConstruction(), 60 fTotalThickness(2.0 * m), 61 fLayerThickness(0.), 62 fConstructed(false), 63 fWorldMaterial(0), 64 fAbsorberMaterial(0), 65 fGapMaterial(0), 66 fLayerSolid(0), 67 fGapSolid(0), 68 fWorldLogical(0), 69 fCalorLogical(0), 70 fLayerLogical(0), 71 fGapLogical(0), 72 fWorldPhysical(0), 73 fCalorPhysical(0), 74 fLayerPhysical(0), 75 fGapPhysical(0), 76 fDetectorMessenger(0), 77 fVerboseLevel(1) 78 { 79 fLayerThickness = fTotalThickness / fNumberOfLayers; 80 fCalName = "Calor"; 81 fDetectorMessenger = new GB03DetectorMessenger(this); 82 } 83 84 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 85 86 GB03DetectorConstruction::~GB03DetectorConstruction() 87 { 88 delete fDetectorMessenger; 89 } 90 91 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 92 93 G4VPhysicalVolume* GB03DetectorConstruction::Construct() 94 { 95 if (!fConstructed) { 96 fConstructed = true; 97 DefineMaterials(); 98 SetupGeometry(); 99 } 100 if (GetVerboseLevel() > 0) { 101 PrintCalorParameters(); 102 } 103 104 return fWorldPhysical; 105 } 106 107 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 108 109 void GB03DetectorConstruction::ConstructSDandField() 110 { 111 if (!fConstructedSDandField) { 112 fConstructedSDandField = true; 113 SetupDetectors(); 114 SetupBiasing(); 115 } 116 } 117 118 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 119 120 void GB03DetectorConstruction::DefineMaterials() 121 { 122 G4String name, symbol; // a=mass of a mole; 123 G4double a, z, density; // z=mean number of protons; 124 G4int iz; // iz=number of protons in an isotope; 125 G4int n; // n=number of nucleons in an isotope; 126 127 G4int ncomponents, natoms; 128 G4double abundance, fractionmass; 129 G4double temperature, pressure; 130 131 // 132 // define Elements 133 // 134 135 a = 1.01 * g / mole; 136 G4Element* H = new G4Element(name = "Hydrogen", symbol = "H", z = 1., a); 137 138 a = 12.01 * g / mole; 139 G4Element* C = new G4Element(name = "Carbon", symbol = "C", z = 6., a); 140 141 a = 14.01 * g / mole; 142 G4Element* N = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a); 143 144 a = 16.00 * g / mole; 145 G4Element* O = new G4Element(name = "Oxygen", symbol = "O", z = 8., a); 146 147 // 148 // define an Element from isotopes, by relative abundance 149 // 150 151 G4Isotope* U5 = new G4Isotope(name = "U235", iz = 92, n = 235, a = 235.01 * g / mole); 152 G4Isotope* U8 = new G4Isotope(name = "U238", iz = 92, n = 238, a = 238.03 * g / mole); 153 154 G4Element* U = new G4Element(name = "enriched Uranium", symbol = "U", ncomponents = 2); 155 U->AddIsotope(U5, abundance = 90. * perCent); 156 U->AddIsotope(U8, abundance = 10. * perCent); 157 158 // 159 // define simple materials 160 // 161 162 new G4Material(name = "Aluminium", z = 13., a = 26.98 * g / mole, density = 2.700 * g / cm3); 163 new G4Material(name = "Silicon", z = 14., a = 28.09 * g / mole, density = 2.33 * g / cm3); 164 new G4Material(name = "Iron", z = 26., a = 55.85 * g / mole, density = 7.87 * g / cm3); 165 new G4Material(name = "ArgonGas", z = 18., a = 39.95 * g / mole, density = 1.782 * mg / cm3); 166 new G4Material(name = "He", z = 2., a = 4.0 * g / mole, density = 0.1786e-03 * g / cm3); 167 168 density = 1.390 * g / cm3; 169 a = 39.95 * g / mole; 170 new G4Material(name = "liquidArgon", z = 18., a, density); 171 172 density = 11.35 * g / cm3; 173 a = 207.19 * g / mole; 174 G4Material* Pb = new G4Material(name = "Lead", z = 82., a, density); 175 176 // 177 // define a material from elements. case 1: chemical molecule 178 // 179 180 density = 1.000 * g / cm3; 181 G4Material* H2O = new G4Material(name = "Water", density, ncomponents = 2); 182 H2O->AddElement(H, natoms = 2); 183 H2O->AddElement(O, natoms = 1); 184 185 density = 1.032 * g / cm3; 186 G4Material* Sci = new G4Material(name = "Scintillator", density, ncomponents = 2); 187 Sci->AddElement(C, natoms = 9); 188 Sci->AddElement(H, natoms = 10); 189 190 // 191 // define a material from elements. case 2: mixture by fractional mass 192 // 193 194 density = 1.290 * mg / cm3; 195 G4Material* Air = new G4Material(name = "Air", density, ncomponents = 2); 196 Air->AddElement(N, fractionmass = 0.7); 197 Air->AddElement(O, fractionmass = 0.3); 198 199 // 200 // examples of vacuum 201 // 202 203 density = universe_mean_density; 204 pressure = 3.e-18 * pascal; 205 temperature = 2.73 * kelvin; 206 G4Material* Vacuum = new G4Material(name = "Galactic", z = 1., a = 1.01 * g / mole, density, 207 kStateGas, temperature, pressure); 208 209 if (GetVerboseLevel() > 1) { 210 G4cout << *(G4Material::GetMaterialTable()) << G4endl; 211 } 212 213 // default materials of the calorimeter 214 fWorldMaterial = Vacuum; 215 fAbsorberMaterial = Pb; 216 fGapMaterial = Sci; 217 } 218 219 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 220 221 void GB03DetectorConstruction::SetupGeometry() 222 { 223 // 224 // World 225 // 226 G4VSolid* worldSolid = new G4Box("World", 2. * m, 2. * m, fTotalThickness * 2.); 227 fWorldLogical = new G4LogicalVolume(worldSolid, fWorldMaterial, "World"); 228 fWorldPhysical = new G4PVPlacement(0, G4ThreeVector(), fWorldLogical, "World", 0, false, 0); 229 230 // 231 // Calorimeter 232 // 233 G4VSolid* calorSolid = new G4Box("Calor", 0.5 * m, 0.5 * m, fTotalThickness / 2.); 234 fCalorLogical = new G4LogicalVolume(calorSolid, fAbsorberMaterial, fCalName); 235 fCalorPhysical = new G4PVPlacement(0, G4ThreeVector(0., 0., 0.), fCalorLogical, fCalName, 236 fWorldLogical, false, 0); 237 238 // 239 // Layers --- as absorbers 240 // 241 fLayerSolid = new G4Box("Layer", 0.5 * m, 0.5 * m, fLayerThickness / 2.); 242 fLayerLogical = new G4LogicalVolume(fLayerSolid, fAbsorberMaterial, fCalName + "_LayerLog"); 243 fLayerPhysical = new G4PVReplica(fCalName + "_Layer", fLayerLogical, fCalorLogical, kZAxis, 244 fNumberOfLayers, fLayerThickness); 245 246 // 247 // Gap 248 // 249 fGapSolid = new G4Box("Gap", 0.5 * m, 0.5 * m, fLayerThickness / 4.); 250 fGapLogical = new G4LogicalVolume(fGapSolid, fGapMaterial, fCalName + "_Gap"); 251 fGapPhysical = new G4PVPlacement(0, G4ThreeVector(0., 0., fLayerThickness / 4.), fGapLogical, 252 fCalName + "_gap", fLayerLogical, false, 0); 253 254 // 255 // Visualization attributes 256 // 257 fWorldLogical->SetVisAttributes(G4VisAttributes::GetInvisible()); 258 G4VisAttributes* simpleBoxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0)); 259 simpleBoxVisAtt->SetVisibility(true); 260 fCalorLogical->SetVisAttributes(simpleBoxVisAtt); 261 fLayerLogical->SetVisAttributes(simpleBoxVisAtt); 262 fGapLogical->SetVisAttributes(simpleBoxVisAtt); 263 } 264 265 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 266 267 void GB03DetectorConstruction::SetupDetectors() 268 { 269 G4SDManager::GetSDMpointer()->SetVerboseLevel(1); 270 G4String filterName; 271 272 G4SDNeutralFilter* neutralFilter = new G4SDNeutralFilter(filterName = "neutralFilter"); 273 G4SDChargedFilter* chargedFilter = new G4SDChargedFilter(filterName = "chargedFilter"); 274 275 for (G4int j = 0; j < 2; j++) { 276 // Loop counter j = 0 : absorber 277 // = 1 : gap 278 G4String detName = fCalName; 279 if (j == 0) { 280 detName += "_abs"; 281 } 282 else { 283 detName += "_gap"; 284 } 285 G4MultiFunctionalDetector* det = new G4MultiFunctionalDetector(detName); 286 G4SDManager::GetSDMpointer()->AddNewDetector(det); 287 // The second argument in each primitive means the "level" of geometrical 288 // hierarchy, the copy number of that level is used as the key of the 289 // G4THitsMap. 290 // For absorber (j = 0), the copy number of its own physical volume is used. 291 // For gap (j = 1), the copy number of its mother physical volume is used, 292 // since there is only one physical volume of gap is placed with respect 293 // to its mother. 294 G4VPrimitiveScorer* primitive; 295 primitive = new G4PSEnergyDeposit("eDep", j); 296 det->RegisterPrimitive(primitive); 297 primitive = new G4PSFlatSurfaceFlux("nNeutral", 1, j); 298 primitive->SetFilter(neutralFilter); 299 det->RegisterPrimitive(primitive); 300 primitive = new G4PSFlatSurfaceFlux("nCharged", 1, j); 301 primitive->SetFilter(chargedFilter); 302 det->RegisterPrimitive(primitive); 303 304 if (j == 0) { 305 SetSensitiveDetector(fLayerLogical, det); 306 } 307 else { 308 SetSensitiveDetector(fGapLogical, det); 309 } 310 } 311 G4SDManager::GetSDMpointer()->SetVerboseLevel(0); 312 } 313 314 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 315 316 void GB03DetectorConstruction::SetupBiasing() 317 { 318 GB03BOptrGeometryBasedBiasing* biasingOperator = new GB03BOptrGeometryBasedBiasing(); 319 biasingOperator->AttachTo(fLayerLogical); 320 } 321 322 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 323 324 void GB03DetectorConstruction::PrintCalorParameters() const 325 { 326 G4cout << "--------------------------------------------------------" << G4endl; 327 G4cout << " Absorber is made of " << fAbsorberMaterial->GetName() << G4endl << " Gap is made of " 328 << fGapMaterial->GetName() << G4endl 329 << "--------------------------------------------------------" << G4endl; 330 } 331 332 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 333 334 void GB03DetectorConstruction::SetAbsorberMaterial(G4String materialChoice) 335 { 336 // search the material by its name 337 G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice); 338 if (pttoMaterial) { 339 fAbsorberMaterial = pttoMaterial; 340 if (fConstructed) { 341 fCalorLogical->SetMaterial(fAbsorberMaterial); 342 fLayerLogical->SetMaterial(fAbsorberMaterial); 343 } 344 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 345 if (GetVerboseLevel() > 1) { 346 PrintCalorParameters(); 347 } 348 } 349 else { 350 G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl; 351 } 352 } 353 354 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 355 356 G4String GB03DetectorConstruction::GetAbsorberMaterial() const 357 { 358 return fAbsorberMaterial->GetName(); 359 } 360 361 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 362 363 void GB03DetectorConstruction::SetGapMaterial(G4String materialChoice) 364 { 365 // search the material by its name 366 G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice); 367 if (pttoMaterial) { 368 fGapMaterial = pttoMaterial; 369 if (fConstructed) { 370 fGapLogical->SetMaterial(fGapMaterial); 371 } 372 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 373 if (GetVerboseLevel() > 1) { 374 PrintCalorParameters(); 375 } 376 } 377 else { 378 G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl; 379 } 380 } 381 382 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 383 384 G4String GB03DetectorConstruction::GetGapMaterial() const 385 { 386 return fGapMaterial->GetName(); 387 } 388 389 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 390 391 void GB03DetectorConstruction::SetNumberOfLayers(G4int nl) 392 { 393 fNumberOfLayers = nl; 394 fLayerThickness = fTotalThickness / fNumberOfLayers; 395 if (!fConstructed) return; 396 397 fLayerSolid->SetZHalfLength(fLayerThickness / 2.); 398 fGapSolid->SetZHalfLength(fLayerThickness / 4.); 399 400 fCalorLogical->RemoveDaughter(fLayerPhysical); 401 delete fLayerPhysical; 402 fLayerPhysical = new G4PVReplica(fCalName + "_Layer", fLayerLogical, fCalorLogical, kZAxis, 403 fNumberOfLayers, fLayerThickness); 404 fGapPhysical->SetTranslation(G4ThreeVector(0., 0., fLayerThickness / 4.)); 405 406 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 407 } 408 409 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 410