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 /// \file field/field01/src/F01DetectorConstruction.cc 27 /// \brief Implementation of the F01DetectorConstruction class 28 // 29 // 30 // 31 // 32 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 33 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 34 35 #include "F01DetectorConstruction.hh" 36 37 #include "F01CalorimeterSD.hh" 38 #include "F01DetectorMessenger.hh" 39 40 #include "G4AutoDelete.hh" 41 #include "G4GeometryManager.hh" 42 #include "G4FieldBuilder.hh" 43 #include "G4LogicalVolume.hh" 44 #include "G4LogicalVolumeStore.hh" 45 #include "G4Material.hh" 46 #include "G4PVPlacement.hh" 47 #include "G4PhysicalConstants.hh" 48 #include "G4PhysicalVolumeStore.hh" 49 #include "G4RunManager.hh" 50 #include "G4SDManager.hh" 51 #include "G4SolidStore.hh" 52 #include "G4SystemOfUnits.hh" 53 #include "G4Tubs.hh" 54 #include "G4UniformMagField.hh" 55 56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 57 58 F01DetectorConstruction::F01DetectorConstruction() 59 { 60 // create commands for interactive definition of the calorimeter 61 62 G4cout << "F01DetectorConstruction::F01DetectorConstruction()" << G4endl; 63 64 fDetectorMessenger = new F01DetectorMessenger(this); 65 66 // create field builder 67 // this will create commands for field configuration 68 G4FieldBuilder::Instance(); 69 // G4FieldBuilder::Instance()->SetVerboseLevel(2); 70 71 // create materials 72 73 DefineMaterials(); 74 } 75 76 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 77 78 F01DetectorConstruction::~F01DetectorConstruction() 79 { 80 // delete fDetectorMessenger; 81 } 82 83 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 84 85 G4VPhysicalVolume* F01DetectorConstruction::Construct() 86 { 87 return ConstructCalorimeter(); 88 } 89 90 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 91 92 void F01DetectorConstruction::DefineMaterials() 93 { 94 // This function illustrates the possible ways to define materials 95 96 G4String name, symbol; // a=mass of a mole; 97 G4double a, z, density; // z=mean number of protons; 98 G4int nel; 99 G4int ncomponents; 100 G4double fractionmass, pressure, temperature; 101 102 // 103 // define Elements 104 // 105 106 a = 1.01 * g / mole; 107 auto elH = new G4Element(name = "Hydrogen", symbol = "H", z = 1., a); 108 109 a = 12.01 * g / mole; 110 auto elC = new G4Element(name = "Carbon", symbol = "C", z = 6., a); 111 112 a = 14.01 * g / mole; 113 auto elN = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a); 114 115 a = 16.00 * g / mole; 116 auto elO = new G4Element(name = "Oxygen", symbol = "O", z = 8., a); 117 118 a = 39.948 * g / mole; 119 auto elAr = new G4Element(name = "Argon", symbol = "Ar", z = 18., a); 120 121 // 122 // define simple materials 123 // 124 125 // Mylar 126 127 density = 1.39 * g / cm3; 128 auto mylar = new G4Material(name = "Mylar", density, nel = 3); 129 mylar->AddElement(elO, 2); 130 mylar->AddElement(elC, 5); 131 mylar->AddElement(elH, 4); 132 133 // Polypropelene 134 135 auto CH2 = new G4Material("Polypropelene", 0.91 * g / cm3, 2); 136 CH2->AddElement(elH, 2); 137 CH2->AddElement(elC, 1); 138 139 // Krypton as detector gas, STP 140 141 density = 3.700 * mg / cm3; 142 a = 83.80 * g / mole; 143 auto Kr = new G4Material(name = "Kr", z = 36., a, density); 144 145 // Dry air (average composition) 146 147 density = 1.7836 * mg / cm3; // STP 148 auto argon = new G4Material(name = "Argon", density, ncomponents = 1); 149 argon->AddElement(elAr, 1); 150 151 density = 1.25053 * mg / cm3; // STP 152 auto nitrogen = new G4Material(name = "N2", density, ncomponents = 1); 153 nitrogen->AddElement(elN, 2); 154 155 density = 1.4289 * mg / cm3; // STP 156 auto oxygen = new G4Material(name = "O2", density, ncomponents = 1); 157 oxygen->AddElement(elO, 2); 158 159 density = 1.2928 * mg / cm3; // STP 160 density *= 1.0e-8; // pumped vacuum 161 162 temperature = STP_Temperature; 163 pressure = 1.0e-8 * STP_Pressure; 164 165 auto air = 166 new G4Material(name = "Air", density, ncomponents = 3, kStateGas, temperature, pressure); 167 air->AddMaterial(nitrogen, fractionmass = 0.7557); 168 air->AddMaterial(oxygen, fractionmass = 0.2315); 169 170 air->AddMaterial(argon, fractionmass = 0.0128); 171 172 // Xenon as detector gas, STP 173 174 density = 5.858 * mg / cm3; 175 a = 131.29 * g / mole; 176 auto Xe = new G4Material(name = "Xenon", z = 54., a, density); 177 178 // Carbon dioxide, STP 179 180 density = 1.842 * mg / cm3; 181 auto CarbonDioxide = new G4Material(name = "CO2", density, nel = 2); 182 CarbonDioxide->AddElement(elC, 1); 183 CarbonDioxide->AddElement(elO, 2); 184 185 // 80% Xe + 20% CO2, STP 186 187 density = 5.0818 * mg / cm3; 188 auto Xe20CO2 = new G4Material(name = "Xe20CO2", density, ncomponents = 2); 189 Xe20CO2->AddMaterial(Xe, fractionmass = 0.922); 190 Xe20CO2->AddMaterial(CarbonDioxide, fractionmass = 0.078); 191 192 // 80% Kr + 20% CO2, STP 193 194 density = 3.601 * mg / cm3; 195 auto Kr20CO2 = new G4Material(name = "Kr20CO2", density, ncomponents = 2); 196 Kr20CO2->AddMaterial(Kr, fractionmass = 0.89); 197 Kr20CO2->AddMaterial(CarbonDioxide, fractionmass = 0.11); 198 199 // Print material table -- silence it for now 200 // G4cout << *(G4Material::GetMaterialTable()) << G4endl; 201 G4cout << "F01DetectorConstruction: not printing material table - to see it edit the source." 202 << G4endl; 203 204 // default materials of the calorimeter 205 206 fAbsorberMaterial = air; // Kr20CO2; // XeCO2CF4; 207 208 fWorldMaterial = air; 209 } 210 211 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 212 213 G4VPhysicalVolume* F01DetectorConstruction::ConstructCalorimeter() 214 { 215 // In case an old geometry is present... clean it up 216 217 if (fPhysiWorld) { 218 G4GeometryManager::GetInstance()->OpenGeometry(); 219 G4PhysicalVolumeStore::GetInstance()->Clean(); 220 G4LogicalVolumeStore::GetInstance()->Clean(); 221 G4SolidStore::GetInstance()->Clean(); 222 } 223 224 // Compute the Calor parameters definition and Print 225 226 ComputeCalorParameters(); 227 PrintCalorParameters(); 228 229 // World 230 231 fSolidWorld = new G4Tubs("World", // its name 232 0., fWorldSizeR, fWorldSizeZ / 2., 0., twopi); // its size 233 234 fLogicWorld = new G4LogicalVolume(fSolidWorld, // its solid 235 fWorldMaterial, // its material 236 "World"); // its name 237 238 fPhysiWorld = new G4PVPlacement(nullptr, // no rotation 239 G4ThreeVector(), // at (0,0,0) 240 "World", // its name 241 fLogicWorld, // its logical volume 242 nullptr, // its mother volume 243 false, // no boolean op. 244 0); // copy number 245 // Absorber 246 247 fSolidAbsorber = 248 new G4Tubs("Absorber", 1.0 * mm, fAbsorberRadius, fAbsorberThickness / 2., 0.0, twopi); 249 250 fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, fAbsorberMaterial, "Absorber"); 251 252 fPhysiAbsorber = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fZAbsorber), "Absorber", 253 fLogicAbsorber, fPhysiWorld, false, 0); 254 255 return fPhysiWorld; 256 } 257 258 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 259 260 void F01DetectorConstruction::PrintCalorParameters() 261 { 262 G4cout << "\n The WORLD is made of " << fWorldSizeZ / mm << "mm of " 263 << fWorldMaterial->GetName(); 264 G4cout << ", the transverse size (R) of the world is " << fWorldSizeR / mm << " mm. " << G4endl; 265 G4cout << " The ABSORBER is made of " << fAbsorberThickness / mm << "mm of " 266 << fAbsorberMaterial->GetName(); 267 G4cout << ", the transverse size (R) is " << fAbsorberRadius / mm << " mm. " << G4endl; 268 G4cout << " Z position of the (middle of the) absorber " << fZAbsorber / mm << " mm." << G4endl; 269 G4cout << G4endl; 270 } 271 272 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 273 274 void F01DetectorConstruction::SetAbsorberMaterial(G4String materialChoice) 275 { 276 // get the pointer to the material table 277 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable(); 278 279 // search the material by its name 280 G4Material* material; 281 for (size_t j = 0; j < theMaterialTable->size(); j++) { 282 material = (*theMaterialTable)[j]; 283 if (material->GetName() == materialChoice) { 284 fAbsorberMaterial = material; 285 fLogicAbsorber->SetMaterial(material); 286 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 287 } 288 } 289 } 290 291 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 292 293 void F01DetectorConstruction::SetWorldMaterial(G4String materialChoice) 294 { 295 // get the pointer to the material table 296 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable(); 297 298 // search the material by its name 299 G4Material* material; 300 for (size_t j = 0; j < theMaterialTable->size(); j++) { 301 material = (*theMaterialTable)[j]; 302 if (material->GetName() == materialChoice) { 303 fWorldMaterial = material; 304 fLogicWorld->SetMaterial(material); 305 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 306 } 307 } 308 } 309 310 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 311 312 void F01DetectorConstruction::SetAbsorberThickness(G4double val) 313 { 314 // change Absorber thickness and recompute the calorimeter parameters 315 fAbsorberThickness = val; 316 ComputeCalorParameters(); 317 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 318 } 319 320 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 321 322 void F01DetectorConstruction::SetAbsorberRadius(G4double val) 323 { 324 // change the transverse size and recompute the calorimeter parameters 325 fAbsorberRadius = val; 326 ComputeCalorParameters(); 327 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 328 } 329 330 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 331 332 void F01DetectorConstruction::SetWorldSizeZ(G4double val) 333 { 334 fWorldSizeZ = val; 335 ComputeCalorParameters(); 336 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 337 } 338 339 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 340 341 void F01DetectorConstruction::SetWorldSizeR(G4double val) 342 { 343 fWorldSizeR = val; 344 ComputeCalorParameters(); 345 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 346 } 347 348 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 349 350 void F01DetectorConstruction::SetAbsorberZpos(G4double val) 351 { 352 fZAbsorber = val; 353 ComputeCalorParameters(); 354 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 355 } 356 357 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 358 359 void F01DetectorConstruction::SetFieldValue(G4ThreeVector value) 360 { 361 fFieldVector = value; 362 363 G4UniformMagField* magField = nullptr; 364 if (fFieldVector != G4ThreeVector(0.,0.,0.)) { 365 magField = new G4UniformMagField(fFieldVector); 366 } 367 368 // Set field to the field builder 369 auto fieldBuilder = G4FieldBuilder::Instance(); 370 fieldBuilder->SetGlobalField(magField); 371 } 372 373 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 374 #include "G4FieldManager.hh" 375 376 void F01DetectorConstruction::ConstructSDandField() 377 { 378 // Sensitive Detectors: Absorber 379 380 if (!fCalorimeterSD.Get()) { 381 auto calorimeterSD = new F01CalorimeterSD("CalorSD", this); 382 fCalorimeterSD.Put(calorimeterSD); 383 } 384 G4SDManager::GetSDMpointer()->AddNewDetector(fCalorimeterSD.Get()); 385 SetSensitiveDetector(fLogicAbsorber, fCalorimeterSD.Get()); 386 387 // Create detector field 388 SetFieldValue(fFieldVector); 389 390 // Construct all Geant4 field objects 391 auto fieldBuilder = G4FieldBuilder::Instance(); 392 fieldBuilder->ConstructFieldSetup(); 393 } 394 395 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 396