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 src/DetectorConstruction.cc 27 /// \brief Implementation of the DetectorConst 28 // 29 // 30 //....oooOO0OOooo........oooOO0OOooo........oo 31 //....oooOO0OOooo........oooOO0OOooo........oo 32 33 #include "DetectorConstruction.hh" 34 35 #include "DetectorMessenger.hh" 36 37 #include "G4Box.hh" 38 #include "G4LogicalVolume.hh" 39 #include "G4Material.hh" 40 #include "G4NistManager.hh" 41 #include "G4PVPlacement.hh" 42 #include "G4PVReplica.hh" 43 #include "G4PhysicalConstants.hh" 44 #include "G4ProductionCutsTable.hh" 45 #include "G4Region.hh" 46 #include "G4RunManager.hh" 47 #include "G4SystemOfUnits.hh" 48 #include "G4UnitsTable.hh" 49 50 #include <iomanip> 51 52 //....oooOO0OOooo........oooOO0OOooo........oo 53 54 DetectorConstruction::DetectorConstruction() 55 : fWorldMaterial(nullptr), 56 fLogicWorld(nullptr), 57 fPhysiWorld(nullptr), 58 fLogicLayerFront(nullptr), 59 fLogicLayerBack(nullptr) 60 { 61 for (G4int i = 0; i < kMaxAbsor; ++i) { 62 fAbsorMaterial[i] = nullptr; 63 fAbsorThickness[i] = 0.0; 64 fLogicAbsorFront[i] = nullptr; 65 fLogicAbsorBack[i] = nullptr; 66 } 67 68 // default parameter values of the calorimet 69 fNbOfAbsor = 2; 70 fAbsorThickness[1] = 2.3 * mm; 71 fAbsorThickness[2] = 5.7 * mm; 72 fNbOfLayers = 50; 73 fCalorSizeYZ = 40. * cm; 74 ComputeCalorParameters(); 75 76 // materials 77 SetWorldMaterial("G4_Galactic"); 78 SetAbsorMaterial(1, "G4_Pb"); 79 SetAbsorMaterial(2, "G4_lAr"); 80 81 // create commands for interactive definitio 82 fDetectorMessenger.reset(new DetectorMesseng 83 } 84 85 //....oooOO0OOooo........oooOO0OOooo........oo 86 87 void DetectorConstruction::ComputeCalorParamet 88 { 89 // Compute derived parameters of the calorim 90 fLayerThickness = 0.; 91 for (G4int iAbs = 1; iAbs <= fNbOfAbsor; iAb 92 fLayerThickness += fAbsorThickness[iAbs]; 93 } 94 fCalorThickness = fNbOfLayers * fLayerThickn 95 fWorldSizeX = 1.2 * fCalorThickness; 96 fWorldSizeYZ = 1.2 * fCalorSizeYZ; 97 } 98 99 //....oooOO0OOooo........oooOO0OOooo........oo 100 101 G4VPhysicalVolume* DetectorConstruction::Const 102 { 103 if (fPhysiWorld) { 104 return fPhysiWorld; 105 } 106 // complete the Calor parameters definition 107 ComputeCalorParameters(); 108 109 // 110 // World 111 // 112 auto* solidWorld = new G4Box("World", // it 113 fWorldSizeX / 2 114 fWorldSizeYZ / 115 116 fLogicWorld = new G4LogicalVolume(solidWorld 117 fWorldMate 118 "World"); 119 120 fPhysiWorld = new G4PVPlacement(0, // no ro 121 G4ThreeVecto 122 fLogicWorld, 123 "World", // 124 0, // its m 125 false, // n 126 0); // copy 127 // 128 // Calorimeter 129 // 130 131 auto* solidCalor = 132 new G4Box("Calorimeter", fCalorThickness / 133 134 auto* logicCalor = new G4LogicalVolume(solid 135 136 new G4PVPlacement(0, // no rotation 137 G4ThreeVector(), // at (0 138 logicCalor, // its fLogic 139 "Calorimeter", // its nam 140 fLogicWorld, // its mothe 141 false, // no boolean oper 142 0); // copy number 143 144 // 145 // Layers 146 // 147 148 auto* solidLayer = new G4Box("Layer", fLayer 149 150 fLogicLayerFront = new G4LogicalVolume(solid 151 fLogicLayerBack = new G4LogicalVolume(solidL 152 G4double xfront = -0.5 * fCalorThickness; 153 for (G4int l = 0; l < fNbOfLayers; ++l) { 154 G4double xcenter = xfront + 0.5 * fLayerTh 155 xfront += fLayerThickness; 156 G4LogicalVolume* logicLayer = fLogicLayerF 157 if (xcenter > 0) { 158 logicLayer = fLogicLayerBack; 159 } 160 161 new G4PVPlacement(0, G4ThreeVector(xcenter 162 } 163 164 // 165 // Regions 166 // 167 168 auto* regionFront = new G4Region("Front"); 169 regionFront->SetProductionCuts( 170 G4ProductionCutsTable::GetProductionCutsTa 171 regionFront->AddRootLogicalVolume(fLogicLaye 172 auto* regionBack = new G4Region("Back"); 173 regionBack->SetProductionCuts( 174 G4ProductionCutsTable::GetProductionCutsTa 175 regionBack->AddRootLogicalVolume(fLogicLayer 176 177 // 178 // Absorbers 179 // 180 181 xfront = -0.5 * fLayerThickness; 182 for (G4int k = 1; k <= fNbOfAbsor; ++k) { 183 auto* solidAbsor = new G4Box("Absorber", 184 fAbsorThickne 185 186 fLogicAbsorFront[k] = new G4LogicalVolume( 187 188 189 fLogicAbsorBack[k] = new G4LogicalVolume(s 190 f 191 f 192 193 G4double xcenter = xfront + 0.5 * fAbsorTh 194 xfront += fAbsorThickness[k]; 195 new G4PVPlacement(0, G4ThreeVector(xcenter 196 fAbsorMaterial[k]->GetNa 197 k); // copy number 198 new G4PVPlacement(0, G4ThreeVector(xcenter 199 fAbsorMaterial[k]->GetNa 200 k); // copy number 201 } 202 203 PrintCalorParameters(); 204 205 // always return the fPhysical World 206 // 207 return fPhysiWorld; 208 } 209 210 //....oooOO0OOooo........oooOO0OOooo........oo 211 212 void DetectorConstruction::PrintCalorParameter 213 { 214 G4cout << "\n------------------------------- 215 << "\n ---> The calorimeter is " << f 216 for (G4int i = 1; i <= fNbOfAbsor; ++i) { 217 G4cout << "\n \t" << std::setw(12) << fAbs 218 << G4BestUnit(fAbsorThickness[i], " 219 } 220 G4cout << "\n------------------------------- 221 222 G4cout << "\n" << fWorldMaterial << G4endl; 223 for (G4int j = 1; j <= fNbOfAbsor; ++j) { 224 G4cout << "\n" << fAbsorMaterial[j] << G4e 225 } 226 G4cout << "\n------------------------------- 227 } 228 229 //....oooOO0OOooo........oooOO0OOooo........oo 230 231 void DetectorConstruction::SetWorldMaterial(co 232 { 233 // search the material by its name 234 G4Material* pttoMaterial = G4NistManager::In 235 if (pttoMaterial) { 236 fWorldMaterial = pttoMaterial; 237 if (fLogicWorld) { 238 fLogicWorld->SetMaterial(fWorldMaterial) 239 fLogicLayerFront->SetMaterial(fWorldMate 240 fLogicLayerBack->SetMaterial(fWorldMater 241 G4RunManager::GetRunManager()->PhysicsHa 242 } 243 } 244 } 245 246 //....oooOO0OOooo........oooOO0OOooo........oo 247 248 void DetectorConstruction::SetNbOfLayers(G4int 249 { 250 // set the number of Layers 251 // 252 if (ival < 2) { 253 G4cout << "\n --->warning from SetfNbOfLay 254 << " must be at least 2. Command re 255 return; 256 } 257 fNbOfLayers = ival; 258 } 259 260 //....oooOO0OOooo........oooOO0OOooo........oo 261 262 void DetectorConstruction::SetNbOfAbsor(G4int 263 { 264 // set the number of Absorbers 265 // 266 if (ival < 1 || ival > (kMaxAbsor - 1)) { 267 G4cout << "\n ---> warning from SetfNbOfAb 268 << kMaxAbsor - 1 << ". Command refu 269 return; 270 } 271 fNbOfAbsor = ival; 272 } 273 274 //....oooOO0OOooo........oooOO0OOooo........oo 275 276 void DetectorConstruction::SetAbsorMaterial(G4 277 { 278 // search the material by its name 279 // 280 if (ival > fNbOfAbsor || ival <= 0) { 281 G4cout << "\n --->warning from SetAbsorMat 282 << " out of range. Command refused" 283 return; 284 } 285 286 G4Material* pttoMaterial = G4NistManager::In 287 if (pttoMaterial) { 288 fAbsorMaterial[ival] = pttoMaterial; 289 if (fLogicAbsorFront[ival]) { 290 fLogicAbsorFront[ival]->SetMaterial(ptto 291 fLogicAbsorBack[ival]->SetMaterial(pttoM 292 G4RunManager::GetRunManager()->PhysicsHa 293 } 294 } 295 } 296 297 //....oooOO0OOooo........oooOO0OOooo........oo 298 299 void DetectorConstruction::SetAbsorThickness(G 300 { 301 // change Absorber thickness 302 // 303 if (ival > fNbOfAbsor || ival <= 0) { 304 G4cout << "\n --->warning from SetAbsorThi 305 << " out of range. Command refused" 306 return; 307 } 308 if (val <= DBL_MIN) { 309 G4cout << "\n --->warning from SetAbsorThi 310 << " out of range. Command refused" 311 return; 312 } 313 fAbsorThickness[ival] = val; 314 } 315 316 //....oooOO0OOooo........oooOO0OOooo........oo 317 318 void DetectorConstruction::SetCalorSizeYZ(G4do 319 { 320 // change the transverse size 321 // 322 if (val <= DBL_MIN) { 323 G4cout << "\n --->warning from SetfCalorSi 324 << " out of range. Command refused" 325 return; 326 } 327 fCalorSizeYZ = val; 328 } 329 330 //....oooOO0OOooo........oooOO0OOooo........oo 331 332 #include "G4AutoDelete.hh" 333 #include "G4GlobalMagFieldMessenger.hh" 334 335 void DetectorConstruction::ConstructSDandField 336 { 337 if (fFieldMessenger.Get() == nullptr) { 338 // Create global magnetic field messenger. 339 // Uniform magnetic field is then created 340 // the field value is not zero. 341 G4ThreeVector fieldValue = G4ThreeVector() 342 G4GlobalMagFieldMessenger* msg = new G4Glo 343 // msg->SetVerboseLevel(1); 344 G4AutoDelete::Register(msg); 345 fFieldMessenger.Put(msg); 346 } 347 } 348 349 //....oooOO0OOooo........oooOO0OOooo........oo 350