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.hh 27 /// \brief Definition of the DetectorConstruction class 28 // 29 // 30 31 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 32 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 33 34 #include "DetectorConstruction.hh" 35 36 #include "DetectorMessenger.hh" 37 #include "PrimaryGeneratorAction.hh" 38 39 #include "G4Box.hh" 40 #include "G4Cons.hh" 41 #include "G4FieldManager.hh" 42 #include "G4GeometryManager.hh" 43 #include "G4LogicalVolume.hh" 44 #include "G4LogicalVolumeStore.hh" 45 #include "G4Material.hh" 46 #include "G4PVPlacement.hh" 47 #include "G4PVReplica.hh" 48 #include "G4PhysicalConstants.hh" 49 #include "G4PhysicalVolumeStore.hh" 50 #include "G4RotationMatrix.hh" 51 #include "G4RunManager.hh" 52 #include "G4SDManager.hh" 53 #include "G4SolidStore.hh" 54 #include "G4SystemOfUnits.hh" 55 #include "G4ThreeVector.hh" 56 #include "G4TransportationManager.hh" 57 #include "G4Tubs.hh" 58 #include "G4UniformMagField.hh" 59 #include "globals.hh" 60 61 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 62 63 DetectorConstruction::DetectorConstruction() 64 : fVacuum(nullptr), 65 fIron(nullptr), 66 fCopper(nullptr), 67 fTungsten(nullptr), 68 fLead(nullptr), 69 fUranium(nullptr), 70 fPbWO4(nullptr), 71 fPolystyrene(nullptr), 72 fLiquidArgon(nullptr), 73 fSilicon(nullptr), 74 fQuartz(nullptr), 75 fBrass(nullptr), 76 fAluminium(nullptr), 77 fGraphite(nullptr), 78 fAbsorberMaterial(nullptr), 79 fActiveMaterial(nullptr), 80 fExperimentalHall_log(nullptr), 81 fExperimentalHall_phys(nullptr), 82 fLogicCalo(nullptr), 83 fPhysiCalo(nullptr), 84 fLogicModule(nullptr), 85 fPhysiModule(nullptr), 86 fLogicAbsorber(nullptr), 87 fPhysiAbsorber(nullptr), 88 fLogicActive(nullptr), 89 fPhysiActive(nullptr), 90 fFieldMgr(nullptr), 91 fUniformMagField(nullptr), 92 fDetectorMessenger(nullptr), 93 // Default values. ***LOOKHERE*** 94 fIsCalHomogeneous(false), // Sampling calorimeter. 95 fIsUnitInLambda(false), // Unit of length for the absorber total length. 96 fAbsorberTotalLength(2.0 * CLHEP::m), 97 fCalorimeterRadius(1.0 * CLHEP::m), 98 fActiveLayerNumber(50), 99 fActiveLayerSize(4.0 * CLHEP::mm), 100 fIsRadiusUnitInLambda(false), // Unit of length for the radius bin size. 101 // Extra 102 fCaloLength(2.0 * CLHEP::m), 103 // Scoring part 104 fLogicScoringUpDown(nullptr), 105 fPhysiScoringUpstream(nullptr), 106 fPhysiScoringDownstream(nullptr), 107 fLogicScoringSide(nullptr), 108 fPhysiScoringSide(nullptr) 109 { 110 fFieldMgr = G4TransportationManager::GetTransportationManager()->GetFieldManager(); 111 DefineMaterials(); 112 fAbsorberMaterial = fIron; 113 fActiveMaterial = fPolystyrene; 114 fDetectorMessenger = new DetectorMessenger(this); 115 } 116 117 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 118 119 DetectorConstruction::~DetectorConstruction() 120 { 121 delete fDetectorMessenger; 122 delete fUniformMagField; 123 } 124 125 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 126 127 G4VPhysicalVolume* DetectorConstruction::Construct() 128 { 129 return ConstructCalorimeter(); 130 } 131 132 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 133 134 void DetectorConstruction::ConstructSDandField() {} 135 136 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 137 138 void DetectorConstruction::DefineMaterials() 139 { 140 G4double a; // atomic mass 141 G4double z; // atomic number 142 G4double density, pressure, temperature, fractionmass; 143 G4String name, symbol; 144 G4int nel, natoms; 145 146 //--- elements 147 148 a = 1.01 * g / mole; 149 G4Element* elH = new G4Element(name = "Hydrogen", symbol = "H2", z = 1., a); 150 151 a = 2.01 * g / mole; 152 // G4Element* elD = new G4Element( name="Deuterium", symbol="D", z=1., a ); 153 154 a = 4. * g / mole; 155 // G4Element* elHe = new G4Element( name="Helium", symbol="He", z=2., a ); 156 157 a = 6.94 * g / mole; 158 // G4Element* elLi = new G4Element( name="Lithium", symbol="Li", z=3., a ); 159 160 a = 9.01 * g / mole; 161 // G4Element* elBe = new G4Element( name="Berillium", symbol="Be", z=4., a ); 162 163 a = 12.01 * g / mole; 164 G4Element* elC = new G4Element(name = "Carbon", symbol = "C", z = 6., a); 165 166 a = 14.01 * g / mole; 167 G4Element* elN = new G4Element(name = "Nitrogen", symbol = "N2", z = 7., a); 168 169 a = 16. * g / mole; 170 G4Element* elO = new G4Element(name = "Oxygen", symbol = "O2", z = 8., a); 171 172 a = 20.18 * g / mole; 173 // G4Element* elNe = new G4Element( name="Neon", symbol="Ne", z=10., a ); 174 175 a = 22.99 * g / mole; 176 // G4Element* elNa = new G4Element( name="Sodium", symbol="Na", z=11., a ); 177 178 a = 26.98 * g / mole; 179 // G4Element* elAl = new G4Element( name="Aluminium", symbol="Al", z=13., a ); 180 181 a = 28.085 * g / mole; 182 G4Element* elSi = new G4Element(name = "Silicon", symbol = "Si", z = 14., a); 183 184 a = 40.08 * g / mole; 185 // G4Element* elCa = new G4Element( name="Calcium", symbol="Ca", z=20., a ); 186 187 a = 55.850 * g / mole; 188 // G4Element* elFe = new G4Element( name="Iron", symbol="Fe", z=26., a ); 189 190 a = 63.54 * g / mole; 191 G4Element* elCu = new G4Element(name = "Copper", symbol = "Cu", z = 29., a); 192 193 a = 65.41 * g / mole; 194 G4Element* elZn = new G4Element(name = "Zinc", symbol = "Zn", z = 30., a); 195 196 a = 183.85 * g / mole; 197 G4Element* elW = new G4Element(name = "Tungstenm", symbol = "W", z = 74., a); 198 199 a = 207.19 * g / mole; 200 G4Element* elPb = new G4Element(name = "Lead", symbol = "Pb", z = 82., a); 201 202 a = 238.03 * g / mole; 203 // G4Element* elU = new G4Element(name="Uranium", symbol="U", z=92., a); 204 205 //--- simple materials 206 207 // Iron has a X0 = 1.7585 cm and lambda_I = 16.760 cm. 208 density = 7.87 * g / cm3; 209 a = 55.85 * g / mole; 210 fIron = new G4Material(name = "Iron", z = 26., a, density); 211 212 // Copper has a X0 = 1.4353 cm and lambda_I = 15.056 cm. 213 density = 8.96 * g / cm3; 214 a = 63.54 * g / mole; 215 fCopper = new G4Material(name = "Copper", z = 29., a, density); 216 217 // Tungsten has a X0 = 0.35 cm and lambda_I = 9.5855 cm. 218 density = 19.3 * g / cm3; 219 a = 183.85 * g / mole; 220 fTungsten = new G4Material(name = "Tungsten", z = 74., a, density); 221 222 // Lead has a X0 = 0.56120 cm and lambda_I = 17.092 cm. 223 density = 11.35 * g / cm3; 224 a = 207.19 * g / mole; 225 fLead = new G4Material(name = "Lead", z = 82., a, density); 226 227 // Uranium has a X0 = 0.31662 cm and lambda_I = 10.501 cm. 228 density = 18.95 * g / cm3; 229 a = 238.03 * g / mole; 230 fUranium = new G4Material(name = "Uranium", z = 92., a, density); 231 232 // Liquid Argon has a X0 = 10.971 cm and lambda_I = 65.769 cm. 233 density = 1.4 * g / cm3; 234 a = 39.95 * g / mole; 235 fLiquidArgon = new G4Material(name = "LiquidArgon", z = 18., a, density); 236 237 density = 0.002 * g / cm3; 238 a = 39.95 * g / mole; 239 // G4Material* ArgonGas = new G4Material( name="ArgonGas", z=18., a, density ); 240 241 // Silicon has a X0 = 9.3688 cm and lambda_I = 46.5436 cm 242 density = 2.33 * g / cm3; 243 a = 28.085 * g / mole; 244 fSilicon = new G4Material(name = "Silicon", z = 14., a, density); 245 246 // Aluminium has a X0 = 8.8959 cm and lambda_I = 39.7184 cm 247 density = 2.7 * g / cm3; 248 a = 26.98 * g / mole; 249 fAluminium = new G4Material(name = "Aluminium", z = 13., a, density); 250 251 // Graphite has a X0 = 19.3213 cm and lambda_I = 38.8235 cm 252 density = 2.210 * g / cm3; 253 a = 12.0107 * g / mole; 254 fGraphite = new G4Material(name = "Graphite", z = 6., a, density); 255 256 density = 8.96 * g / cm3; 257 a = 58.69 * g / mole; 258 // G4Material* Nickel = new G4Material( name="Nickel", z=28., a, density ); 259 260 //--- mixtures 261 262 density = 1.290 * mg / cm3; 263 G4Material* Air = new G4Material(name = "Air", density, nel = 2); 264 Air->AddElement(elN, 0.7); 265 Air->AddElement(elO, 0.3); 266 267 density = 1.e-5 * g / cm3; 268 pressure = 2.e-2 * bar; 269 temperature = STP_Temperature; // From PhysicalConstants.h . 270 fVacuum = new G4Material(name = "Vacuum", density, nel = 1, kStateGas, temperature, pressure); 271 fVacuum->AddMaterial(Air, fractionmass = 1.); 272 273 // Plastic scintillator tiles (used both in CMS hadron calorimeter 274 // and ATLAS hadron barrel calorimeter): 275 // X0 = 42.4 cm and lambda_I = 79.360 cm. 276 density = 1.032 * g / cm3; 277 fPolystyrene = new G4Material(name = "Polystyrene", density, nel = 2); 278 fPolystyrene->AddElement(elC, natoms = 19); 279 fPolystyrene->AddElement(elH, natoms = 21); 280 281 // PbWO4 CMS crystals. It has a X0 = 0.89 cm and lambda_I = 22.4 cm. 282 density = 8.28 * g / cm3; 283 fPbWO4 = new G4Material(name = "PbWO4", density, nel = 3); 284 fPbWO4->AddElement(elPb, natoms = 1); 285 fPbWO4->AddElement(elW, natoms = 1); 286 fPbWO4->AddElement(elO, natoms = 4); 287 288 fQuartz = new G4Material(name = "Quartz", density = 2.200 * g / cm3, nel = 2); 289 fQuartz->AddElement(elSi, 1); 290 fQuartz->AddElement(elO, 2); 291 292 fBrass = new G4Material(name = "Brass", density = 8.6 * g / cm3, nel = 2); 293 fBrass->AddElement(elCu, 0.7); 294 fBrass->AddElement(elZn, 0.3); 295 } 296 297 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 298 299 G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter() 300 { 301 if (!AreParametersOK()) { 302 G4cout << " DetectorConstruction::ConstructCalorimeter() : ***ERROR*** " << G4endl 303 << "\t PARAMETERS NOT WELL-DEFINED! GEOMETRY UNCHANGED." << G4endl; 304 return fExperimentalHall_phys; 305 } 306 307 // Clean old geometry, if any. 308 G4GeometryManager::GetInstance()->OpenGeometry(); 309 G4PhysicalVolumeStore::GetInstance()->Clean(); 310 G4LogicalVolumeStore::GetInstance()->Clean(); 311 G4SolidStore::GetInstance()->Clean(); 312 313 G4double lambda = 0.0; // G4double X0 = 0.0; 314 if (fIsUnitInLambda) { 315 if (fAbsorberMaterial == fIron) { 316 lambda = 16.760 * cm; // X0 = 1.7585*cm; 317 } 318 else if (fAbsorberMaterial == fCopper) { 319 lambda = 15.056 * cm; // X0 = 1.4353*cm; 320 } 321 else if (fAbsorberMaterial == fBrass) { 322 lambda = 15.056 * cm; // Lack of PDG data: I am assuming the same as Copper. // X0=1.4353*cm 323 } 324 else if (fAbsorberMaterial == fTungsten) { 325 lambda = 9.5855 * cm; // X0 = 0.35*cm; 326 } 327 else if (fAbsorberMaterial == fLead) { 328 lambda = 17.092 * cm; // X0 = 0.56120*cm; 329 } 330 else if (fAbsorberMaterial == fPbWO4) { 331 lambda = 22.4 * cm; // X0 = 0.89*cm; 332 } 333 else if (fAbsorberMaterial == fUranium) { 334 lambda = 10.501 * cm; // X0 = 0.31662*cm; 335 } 336 else if (fAbsorberMaterial == fGraphite) { 337 lambda = 38.82 * cm; // X0 = 19.32*cm; 338 } 339 else { 340 std::cout << "ERROR: absorber material not recognized" << std::endl; 341 } 342 } 343 344 //------------------- volumes -------------------------- 345 346 G4double absorberTotalLength = fAbsorberTotalLength; 347 G4double calorimeterRadius = fCalorimeterRadius; 348 if (fIsUnitInLambda) { 349 absorberTotalLength *= lambda; 350 calorimeterRadius *= lambda; 351 } 352 353 // --- experimental hall (world volume) ***LOOKHERE*** 354 // beam line along the Z-axis 355 G4double expHall_x = 10.0 * m; // half dimension along x 356 G4double expHall_y = 10.0 * m; // half dimension along y 357 G4double expHall_z = 10.0 * m; // half dimension along z 358 359 G4Box* experimentalHall_box = new G4Box("expHall_box", expHall_x, expHall_y, expHall_z); 360 fExperimentalHall_log = new G4LogicalVolume(experimentalHall_box, // solid 361 fVacuum, // material 362 "expHall_log", // name 363 0, // field manager 364 0, // sensitive detector 365 0); // user limits 366 fExperimentalHall_phys = new G4PVPlacement(0, // rotation 367 G4ThreeVector(), // translation 368 "expHall", // name 369 fExperimentalHall_log, // logical volume 370 0, // mother physical volume 371 false, // boolean operation 372 0); // copy number 373 374 // --- Detector 375 // The idea is to use Replica placement. 376 // To do that, we have to define two extra volumes: the "calorimeter" volume 377 // and the "module". The former, which has the world as its mother volume, 378 // is the mother of the module volume. The calorimeter volume is completely 379 // filled by a number (theActiveLayerNumber) of replicas of the module volume. 380 // A module volume, in its turn, is the mother volume of the absorber layer + 381 // active layer. 382 383 // --- absorber layer : logical 384 G4double zAbsorber = absorberTotalLength / static_cast<double>(fActiveLayerNumber); 385 // In the case of homogenous calorimeter the "active" part must be 386 // subtracted because it is made of the same material 387 // (the material of the "active" part is set to be the same as 388 // the aborber). 389 if (fIsCalHomogeneous) { 390 fActiveMaterial = fAbsorberMaterial; 391 zAbsorber -= fActiveLayerSize; 392 } 393 zAbsorber /= 2.0; // half dimension along z 394 G4Tubs* solidAbsorber = new G4Tubs("solidAbsorber", // name 395 0.0, // inner radius 396 calorimeterRadius, // outer radius 397 zAbsorber, // half cylinder length in z 398 0.0, // starting phi angle in rad 399 2.0 * pi); // final phi angle in rad 400 fLogicAbsorber = new G4LogicalVolume(solidAbsorber, // solid 401 fAbsorberMaterial, // material 402 "logicAbsorber", // name 403 0, // field manager 404 0, // sensitive detector 405 0); // user limits 406 407 // --- active layer : logical 408 G4double zActive = fActiveLayerSize / 2.0; // half dimension along z 409 G4Tubs* solidActive = new G4Tubs("solidActive", // name 410 0.0, // inner radius 411 calorimeterRadius, // outer radius 412 zActive, // half cylinder length in z 413 0.0, // starting phi angle in rad 414 2.0 * pi); // final phi angle in rad 415 fLogicActive = new G4LogicalVolume(solidActive, // solid 416 fActiveMaterial, // material 417 "logicActive", // name 418 0, // field manager 419 0, // sensitive detector 420 0); // user limits 421 422 // --- module : logical 423 G4double zModule = zAbsorber + zActive; // half dimension along z 424 G4Tubs* solidModule = new G4Tubs("solidModule", // name 425 0.0, // inner radius 426 calorimeterRadius, // outer radius 427 zModule, // half cylinder length in z 428 0.0, // starting phi angle in rad 429 2.0 * pi); // final phi angle in rad 430 fLogicModule = new G4LogicalVolume(solidModule, // solid 431 fLead, // material, it does NOT matter 432 "logicModule", // name 433 0, // field manager 434 0, // sensitive detector 435 0); // user limits 436 437 // --- calorimeter : logical 438 G4int numberOfModules = fActiveLayerNumber; 439 G4double zCalo = numberOfModules * zModule; // half dimension along z 440 fCaloLength = 2.0 * zCalo; 441 G4Tubs* solidCalo = new G4Tubs("solidCalo", // name 442 0.0, // inner radius 443 calorimeterRadius, // outer radius 444 zCalo, // half cylinder length in z 445 0.0, // starting phi angle in rad 446 2.0 * pi); // final phi angle in rad 447 fLogicCalo = new G4LogicalVolume(solidCalo, // solid 448 fLead, // material, it does NOT matter 449 "logicCalo", // name 450 0, // field manager 451 0, // sensitive detector 452 0); // user limits 453 454 // --- absorber layer : physical 455 G4double zpos = -zActive; 456 fPhysiAbsorber = new G4PVPlacement(0, // rotation 457 G4ThreeVector(0, 0, zpos), // translation 458 fLogicAbsorber, // logical volume 459 "physiAbsorber", // name 460 fLogicModule, // mother logical volume 461 false, // boolean operation 462 1000); // copy number 463 464 // --- active layer : physical 465 zpos += zAbsorber + zActive; 466 fPhysiActive = new G4PVPlacement(0, // rotation 467 G4ThreeVector(0, 0, zpos), // translation 468 fLogicActive, // logical volume 469 "physiActive", // name 470 fLogicModule, // mother logical volume 471 false, // boolean operation 472 2000); // copy number 473 474 // --- module : physical (using replica) 475 fPhysiModule = new G4PVReplica("Calo", // name 476 fLogicModule, // logical volume 477 fLogicCalo, // mother logical volume 478 kZAxis, // axis of replication 479 numberOfModules, // number of replica 480 2 * (zAbsorber + zActive)); // (full) width of replica 481 482 // --- calorimeter : physical 483 fPhysiCalo = new G4PVPlacement(0, // rotation 484 G4ThreeVector(), // translation 485 "physiCalo", // its name 486 fLogicCalo, // logical volume 487 fExperimentalHall_phys, // mother physical volume 488 false, // boolean operation 489 100); // copy number 490 491 // Three scoring volumes: one thin layer downstream of the calorimeter ("down") 492 // one thin layer surrounding (lateral) of the calorimeter ("side") 493 // one thin layer upstream of the calorimeter ("up") 494 G4Tubs* solidScoringUpDown = new G4Tubs("solidScoringUpDown", // name 495 0.0, // inner radius 496 calorimeterRadius, // outer radius 497 0.5 * fScoringThickness, // half cylinder length in z 498 0.0, // starting phi angle in rad 499 2.0 * pi); // final phi angle in rad 500 fLogicScoringUpDown = new G4LogicalVolume(solidScoringUpDown, // solid 501 fVacuum, // material 502 "logicScoringUpDown", // name 503 0, // field manager 504 0, // sensitive detector 505 0); // user limits 506 G4double zScoringUpDown = 0.5 * (fCaloLength + fScoringThickness); 507 fPhysiScoringUpstream = new G4PVPlacement(0, // rotation 508 G4ThreeVector(0.0, 0.0, -zScoringUpDown), 509 // translation 510 "physiScoringUpstream", // name 511 fLogicScoringUpDown, // logical volume 512 fExperimentalHall_phys, // mother physical volume 513 false, // boolean operation 514 0); // copy number 515 fPhysiScoringDownstream = new G4PVPlacement(0, // rotation 516 G4ThreeVector(0.0, 0.0, zScoringUpDown), 517 // translation 518 "physiScoringDownstream", // name 519 fLogicScoringUpDown, // logical volume 520 fExperimentalHall_phys, // mother physical volume 521 false, // boolean operation 522 0); // copy number 523 524 G4Tubs* solidScoringSide = new G4Tubs("solidScoringSide", // name 525 calorimeterRadius, // inner radius 526 calorimeterRadius + fScoringThickness, // outer radius 527 0.5 * fCaloLength, // half cylinder length in z 528 0.0, // starting phi angle in rad 529 2.0 * pi); // final phi angle in rad 530 fLogicScoringSide = new G4LogicalVolume(solidScoringSide, // solid 531 fVacuum, // material 532 "logicScoringSide", // name 533 0, // field manager 534 0, // sensitive detector 535 0); // user limits 536 fPhysiScoringSide = new G4PVPlacement(0, // rotation 537 G4ThreeVector(0.0, 0.0, 0.0), // translation 538 "physiScoringSide", // name 539 fLogicScoringSide, // logical volume 540 fExperimentalHall_phys, // mother physical volume 541 false, // boolean operation 542 0); // copy number 543 544 return fExperimentalHall_phys; 545 } 546 547 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 548 549 G4bool DetectorConstruction::AreParametersOK() 550 { 551 bool isOk = true; 552 if (!fAbsorberMaterial) { 553 isOk = false; 554 G4cout << " DetectorConstruction::AreParametersOK() : UNDEFINED absorber material" << G4endl; 555 } 556 if (!fActiveMaterial) { 557 isOk = false; 558 G4cout << " DetectorConstruction::AreParametersOK() : UNDEFINED active material" << G4endl; 559 } 560 if (fAbsorberTotalLength <= 0.0) { 561 isOk = false; 562 G4cout << " DetectorConstruction::AreParametersOK() : fAbsorberTotalLength = " 563 << fAbsorberTotalLength << G4endl; 564 } 565 if (fCalorimeterRadius <= 0.0) { 566 isOk = false; 567 G4cout << " DetectorConstruction::AreParametersOK() : fCalorimeterRadius = " 568 << fCalorimeterRadius << G4endl; 569 } 570 if (fActiveLayerNumber <= 0) { 571 isOk = false; 572 G4cout << " DetectorConstruction::AreParametersOK() : fActiveLayerNumber = " 573 << fActiveLayerNumber << G4endl; 574 } 575 if (fActiveLayerSize <= 0.0) { 576 isOk = false; 577 G4cout << " DetectorConstruction::AreParametersOK() : fActiveLayerSize = " << fActiveLayerSize 578 << G4endl; 579 } 580 return isOk; 581 } 582 583 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 584 585 void DetectorConstruction::SetMagField(const G4double fieldValue) 586 { 587 if (fUniformMagField) { 588 delete fUniformMagField; 589 } 590 if (std::abs(fieldValue) > 0.0) { 591 // Apply a global uniform magnetic field along the Y axis. 592 // Notice that only if the magnetic field is not zero, the Geant4 593 // transportion in field gets activated. 594 fUniformMagField = new G4UniformMagField(G4ThreeVector(0.0, fieldValue, 0.0)); 595 fFieldMgr->SetDetectorField(fUniformMagField); 596 fFieldMgr->CreateChordFinder(fUniformMagField); 597 } 598 } 599 600 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 601 602 void DetectorConstruction::SetAbsorberMaterial(const G4String name) 603 { 604 if (name == "Fe" || name == "Iron" || name == "iron") { 605 fAbsorberMaterial = fIron; 606 } 607 else if (name == "Cu" || name == "Copper" || name == "copper") { 608 fAbsorberMaterial = fCopper; 609 } 610 else if (name == "Brass" || name == "brass") { 611 fAbsorberMaterial = fBrass; 612 } 613 else if (name == "Pb" || name == "Lead" || name == "lead") { 614 fAbsorberMaterial = fLead; 615 } 616 else if (name == "PbWO4") { 617 fAbsorberMaterial = fPbWO4; 618 } 619 else if (name == "W" || name == "Tungsten" || name == "tungsten") { 620 fAbsorberMaterial = fTungsten; 621 } 622 else if (name == "U" || name == "Uranium" || name == "uranium") { 623 fAbsorberMaterial = fUranium; 624 } 625 else if (name == "C" || name == "Graphite" || name == "graphite") { 626 fAbsorberMaterial = fGraphite; 627 } 628 else { 629 G4cout << G4endl << G4endl << "WARNING: the name of the material has not been recognized!" 630 << G4endl << " ===> the default * Iron * will be used." << G4endl << G4endl; 631 fAbsorberMaterial = fIron; 632 } 633 fLogicAbsorber->SetMaterial(fAbsorberMaterial); 634 } 635 636 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 637 638 void DetectorConstruction::SetActiveMaterial(const G4String name) 639 { 640 if (name == "Scintillator" || name == "scintillator") { 641 fActiveMaterial = fPolystyrene; 642 } 643 else if (name == "LAr" || name == "LiquidArgon" || name == "liquidArgon") { 644 fActiveMaterial = fLiquidArgon; 645 } 646 else if (name == "PbWO4") { 647 fActiveMaterial = fPbWO4; 648 } 649 else if (name == "Si" || name == "Silicon" || name == "silicon") { 650 fActiveMaterial = fSilicon; 651 } 652 else if (name == "Quartz" || name == "quartz") { 653 fActiveMaterial = fQuartz; 654 } 655 else if (name == "C" || name == "Graphite" || name == "graphite") { 656 fActiveMaterial = fGraphite; 657 } 658 else { 659 G4cout << G4endl << G4endl << "WARNING: the name of the material has not been recognized!" 660 << G4endl << " ===> the default * Scintillator * will be used." << G4endl 661 << G4endl; 662 fActiveMaterial = fPolystyrene; 663 } 664 fLogicActive->SetMaterial(fActiveMaterial); 665 } 666 667 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 668 669 void DetectorConstruction::UpdateGeometry() 670 { 671 // G4RunManager::GetRunManager()->DefineWorldVolume( ConstructCalorimeter() ); 672 G4RunManager::GetRunManager()->ReinitializeGeometry(); 673 PrintParameters(); 674 // Update also the position of the gun 675 const PrimaryGeneratorAction* pPrimaryAction = dynamic_cast<const PrimaryGeneratorAction*>( 676 G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction()); 677 if (pPrimaryAction) pPrimaryAction->SetGunPosition(); 678 } 679 680 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 681 682 void DetectorConstruction::PrintParameters() 683 { 684 G4cout << G4endl << G4endl << " ------ DetectorConstruction::PrintParameters() ------ " << G4endl 685 << " Absorber Material = "; 686 if (fAbsorberMaterial) { 687 G4cout << fAbsorberMaterial->GetName(); 688 } 689 else { 690 G4cout << " UNDEFINED "; 691 } 692 G4cout << G4endl << " Active Material = "; 693 if (fActiveMaterial) { 694 G4cout << fActiveMaterial->GetName(); 695 } 696 else { 697 G4cout << " UNDEFINED "; 698 } 699 G4cout << G4endl << " Is the Calorimeter Homogeneous ? " << fIsCalHomogeneous; 700 G4cout << G4endl << " Is the Unit in Lambda ? " << fIsUnitInLambda; 701 G4cout << G4endl << " Absorber Total Length = "; 702 if (fIsUnitInLambda) { 703 G4cout << fAbsorberTotalLength << " lambdas"; 704 } 705 else { 706 G4cout << fAbsorberTotalLength / m << " m"; 707 } 708 G4cout << G4endl << " Calorimeter Radius = "; 709 if (fIsUnitInLambda) { 710 G4cout << fCalorimeterRadius << " lambdas"; 711 } 712 else { 713 G4cout << fCalorimeterRadius / m << " m"; 714 } 715 G4cout << G4endl << " Active Layer Number = " << fActiveLayerNumber; 716 G4cout << G4endl << " Active Layer Size = " << fActiveLayerSize / mm << " mm"; 717 G4cout << G4endl << " Is the Radius Unit in Lambda ? " << fIsRadiusUnitInLambda; 718 G4cout << G4endl << " Radius Bin Size = "; 719 G4cout << G4endl << " Magnetic field [T] = "; 720 if (fUniformMagField) { 721 G4cout << fUniformMagField->GetConstantFieldValue() / tesla; 722 } 723 else { 724 G4cout << "(0,0,0)"; 725 } 726 727 G4cout << G4endl << " -------------------------------------------------------- " << G4endl 728 << G4endl; 729 } 730 731 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 732