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 DetectorConstruction.cc 27 /// \brief Implementation of the DetectorConstruction class 28 29 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 30 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 31 32 #include "DetectorConstruction.hh" 33 34 #include "DetectorMessenger.hh" 35 36 #include "G4Box.hh" 37 #include "G4Colour.hh" 38 #include "G4GeometryManager.hh" 39 #include "G4LogicalVolume.hh" 40 #include "G4LogicalVolumeStore.hh" 41 #include "G4Material.hh" 42 #include "G4NistManager.hh" 43 #include "G4PVPlacement.hh" 44 #include "G4PVReplica.hh" 45 #include "G4PhysicalVolumeStore.hh" 46 #include "G4RunManager.hh" 47 #include "G4SolidStore.hh" 48 #include "G4StateManager.hh" 49 #include "G4SystemOfUnits.hh" 50 #include "G4VisAttributes.hh" 51 52 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 53 54 DetectorConstruction::DetectorConstruction() 55 { 56 ComputeCalorParameters(); 57 58 // materials 59 DefineMaterials(); 60 SetAbsorberMaterial("G4_Pb"); 61 SetGapMaterial("G4_lAr"); 62 63 // create commands for interactive definition of the calorimeter 64 fDetectorMessenger = new DetectorMessenger(this); 65 } 66 67 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 68 69 DetectorConstruction::~DetectorConstruction() 70 { 71 delete fDetectorMessenger; 72 } 73 74 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 75 76 G4VPhysicalVolume* DetectorConstruction::Construct() 77 { 78 return ConstructCalorimeter(); 79 } 80 81 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 82 83 void DetectorConstruction::DefineMaterials() 84 { 85 // use G4-NIST materials data base 86 // 87 G4NistManager* man = G4NistManager::Instance(); 88 fDefaultMaterial = man->FindOrBuildMaterial("G4_Galactic"); 89 man->FindOrBuildMaterial("G4_Pb"); 90 man->FindOrBuildMaterial("G4_lAr"); 91 92 // print table 93 // 94 G4cout << *(G4Material::GetMaterialTable()) << G4endl; 95 } 96 97 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 98 99 G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter() 100 { 101 // Clean old geometry, if any 102 // 103 G4GeometryManager::GetInstance()->OpenGeometry(); 104 G4PhysicalVolumeStore::GetInstance()->Clean(); 105 G4LogicalVolumeStore::GetInstance()->Clean(); 106 G4SolidStore::GetInstance()->Clean(); 107 108 // complete the Calor parameters definition 109 ComputeCalorParameters(); 110 111 // 112 // World 113 // 114 fSolidWorld = new G4Box("World", // its name 115 fWorldSizeX / 2, fWorldSizeYZ / 2, fWorldSizeYZ / 2); // its size 116 117 fLogicWorld = new G4LogicalVolume(fSolidWorld, // its solid 118 fDefaultMaterial, // its material 119 "World"); // its name 120 121 fPhysiWorld = new G4PVPlacement(nullptr, // no rotation 122 G4ThreeVector(), // at (0,0,0) 123 fLogicWorld, // its logical volume 124 "World", // its name 125 nullptr, // its mother volume 126 false, // no boolean operation 127 0); // copy number 128 129 // 130 // Calorimeter 131 // 132 fSolidCalor = nullptr; 133 fLogicCalor = nullptr; 134 fPhysiCalor = nullptr; 135 fSolidLayer = nullptr; 136 fLogicLayer = nullptr; 137 fPhysiLayer = nullptr; 138 139 if (fCalorThickness > 0.) { 140 fSolidCalor = new G4Box("Calorimeter", // its name 141 fCalorThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2); // size 142 143 fLogicCalor = new G4LogicalVolume(fSolidCalor, // its solid 144 fDefaultMaterial, // its material 145 "Calorimeter"); // its name 146 147 fPhysiCalor = new G4PVPlacement(nullptr, // no rotation 148 G4ThreeVector(), // at (0,0,0) 149 fLogicCalor, // its logical volume 150 "Calorimeter", // its name 151 fLogicWorld, // its mother volume 152 false, // no boolean operation 153 0); // copy number 154 155 // 156 // Layer 157 // 158 fSolidLayer = new G4Box("Layer", // its name 159 fLayerThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2); // size 160 161 fLogicLayer = new G4LogicalVolume(fSolidLayer, // its solid 162 fDefaultMaterial, // its material 163 "Layer"); // its name 164 if (fNbOfLayers > 1) { 165 fPhysiLayer = new G4PVReplica("Layer", // its name 166 fLogicLayer, // its logical volume 167 fLogicCalor, // its mother 168 kXAxis, // axis of replication 169 fNbOfLayers, // number of replica 170 fLayerThickness); // witdth of replica 171 } 172 else { 173 fPhysiLayer = new G4PVPlacement(nullptr, // no rotation 174 G4ThreeVector(), // at (0,0,0) 175 fLogicLayer, // its logical volume 176 "Layer", // its name 177 fLogicCalor, // its mother volume 178 false, // no boolean operation 179 0); // copy number 180 } 181 } 182 183 // 184 // Absorber 185 // 186 fSolidAbsorber = nullptr; 187 fLogicAbsorber = nullptr; 188 fPhysiAbsorber = nullptr; 189 190 if (fAbsorberThickness > 0.) { 191 fSolidAbsorber = new G4Box("Absorber", // its name 192 fAbsorberThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2); // size 193 194 fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, // its solid 195 fAbsorberMaterial, // its material 196 fAbsorberMaterial->GetName()); // name 197 198 fPhysiAbsorber = new G4PVPlacement(nullptr, // no rotation 199 G4ThreeVector(-fGapThickness / 2, 0., 0.), // its position 200 fLogicAbsorber, // its logical volume 201 fAbsorberMaterial->GetName(), // its name 202 fLogicLayer, // its mother 203 false, // no boulean operat 204 0); // copy number 205 } 206 207 // 208 // Gap 209 // 210 fSolidGap = nullptr; 211 fLogicGap = nullptr; 212 fPhysiGap = nullptr; 213 214 if (fGapThickness > 0.) { 215 fSolidGap = new G4Box("Gap", fGapThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2); 216 217 fLogicGap = new G4LogicalVolume(fSolidGap, fGapMaterial, fGapMaterial->GetName()); 218 219 fPhysiGap = new G4PVPlacement(nullptr, // no rotation 220 G4ThreeVector(fAbsorberThickness / 2, 0., 0.), // its position 221 fLogicGap, // its logical volume 222 fGapMaterial->GetName(), // its name 223 fLogicLayer, // its mother 224 false, // no boulean operat 225 0); // copy number 226 } 227 228 PrintCalorParameters(); 229 230 // 231 // Visualization attributes 232 // 233 fLogicWorld->SetVisAttributes(G4VisAttributes::GetInvisible()); 234 235 auto simpleBoxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0)); 236 simpleBoxVisAtt->SetVisibility(true); 237 fLogicCalor->SetVisAttributes(simpleBoxVisAtt); 238 239 // 240 // always return the physical World 241 // 242 return fPhysiWorld; 243 } 244 245 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 246 247 void DetectorConstruction::PrintCalorParameters() 248 { 249 G4cout << "\n------------------------------------------------------------" 250 << "\n---> The calorimeter is " << fNbOfLayers << " layers of: [ " 251 << fAbsorberThickness / mm << "mm of " << fAbsorberMaterial->GetName() << " + " 252 << fGapThickness / mm << "mm of " << fGapMaterial->GetName() << " ] " 253 << "\n------------------------------------------------------------\n"; 254 } 255 256 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 257 258 void DetectorConstruction::SetAbsorberMaterial(const G4String& materialChoice) 259 { 260 // search the material by its name 261 auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); 262 if (material != nullptr) { 263 fAbsorberMaterial = material; 264 if (fLogicAbsorber != nullptr) { 265 fLogicAbsorber->SetMaterial(fAbsorberMaterial); 266 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 267 } 268 } 269 } 270 271 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 272 273 void DetectorConstruction::SetGapMaterial(const G4String& materialChoice) 274 { 275 auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); 276 if (material != nullptr) { 277 fGapMaterial = material; 278 if (fLogicGap != nullptr) { 279 fLogicGap->SetMaterial(fGapMaterial); 280 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 281 } 282 } 283 } 284 285 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 286 287 void DetectorConstruction::SetAbsorberThickness(G4double value) 288 { 289 // change Absorber thickness and recompute the calorimeter parameters 290 fAbsorberThickness = value; 291 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) { 292 G4RunManager::GetRunManager()->ReinitializeGeometry(); 293 } 294 } 295 296 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 297 298 void DetectorConstruction::SetGapThickness(G4double value) 299 { 300 // change Gap thickness and recompute the calorimeter parameters 301 fGapThickness = value; 302 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) { 303 G4RunManager::GetRunManager()->ReinitializeGeometry(); 304 } 305 } 306 307 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 308 309 void DetectorConstruction::SetCalorSizeYZ(G4double value) 310 { 311 // change the transverse size and recompute the calorimeter parameters 312 fCalorSizeYZ = value; 313 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) { 314 G4RunManager::GetRunManager()->ReinitializeGeometry(); 315 } 316 } 317 318 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 319 320 void DetectorConstruction::SetNbOfLayers(G4int value) 321 { 322 fNbOfLayers = value; 323 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) { 324 G4RunManager::GetRunManager()->ReinitializeGeometry(); 325 } 326 } 327 328 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 329