Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:21:00

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file electromagnetic/TestEm5/src/DetectorConstruction.cc
0027 /// \brief Implementation of the DetectorConstruction class
0028 //
0029 //
0030 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0031 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0032 
0033 #include "DetectorConstruction.hh"
0034 
0035 #include "DetectorMessenger.hh"
0036 
0037 #include "G4AutoDelete.hh"
0038 #include "G4Box.hh"
0039 #include "G4GeometryManager.hh"
0040 #include "G4GlobalMagFieldMessenger.hh"
0041 #include "G4LogicalVolume.hh"
0042 #include "G4LogicalVolumeStore.hh"
0043 #include "G4Material.hh"
0044 #include "G4NistManager.hh"
0045 #include "G4PVPlacement.hh"
0046 #include "G4PhysicalConstants.hh"
0047 #include "G4PhysicalVolumeStore.hh"
0048 #include "G4RunManager.hh"
0049 #include "G4SolidStore.hh"
0050 #include "G4SystemOfUnits.hh"
0051 #include "G4UniformMagField.hh"
0052 #include "G4UnitsTable.hh"
0053 
0054 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0055 
0056 DetectorConstruction::DetectorConstruction()
0057 {
0058   // default parameter values of the calorimeter
0059   fAbsorberThickness = 1. * cm;
0060   fAbsorberSizeYZ = 2. * cm;
0061   fXposAbs = 0. * cm;
0062   ComputeGeomParameters();
0063 
0064   // materials
0065   DefineMaterials();
0066   SetWorldMaterial("G4_Galactic");
0067   SetAbsorberMaterial("G4_Si");
0068 
0069   // create commands for interactive definition of the calorimeter
0070   fDetectorMessenger = new DetectorMessenger(this);
0071 }
0072 
0073 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0074 
0075 DetectorConstruction::~DetectorConstruction()
0076 {
0077   delete fDetectorMessenger;
0078 }
0079 
0080 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0081 
0082 void DetectorConstruction::DefineMaterials()
0083 {
0084   // This function illustrates the possible ways to define materials
0085 
0086   G4String symbol;  // a=mass of a mole;
0087   G4double a, z, density;  // z=mean number of protons;
0088 
0089   G4int ncomponents, natoms;
0090   G4double fractionmass;
0091   G4double temperature, pressure;
0092 
0093   //
0094   // define Elements
0095   //
0096 
0097   G4Element* H = new G4Element("Hydrogen", symbol = "H", z = 1, a = 1.01 * g / mole);
0098   G4Element* C = new G4Element("Carbon", symbol = "C", z = 6, a = 12.01 * g / mole);
0099   G4Element* N = new G4Element("Nitrogen", symbol = "N", z = 7, a = 14.01 * g / mole);
0100   G4Element* O = new G4Element("Oxygen", symbol = "O", z = 8, a = 16.00 * g / mole);
0101   G4Element* Na = new G4Element("Sodium", symbol = "Na", z = 11, a = 22.99 * g / mole);
0102   G4Element* Ar = new G4Element("Argon", symbol = "Ar", z = 18, a = 39.95 * g / mole);
0103   G4Element* I = new G4Element("Iodine", symbol = "I", z = 53, a = 126.90 * g / mole);
0104   G4Element* Xe = new G4Element("Xenon", symbol = "Xe", z = 54, a = 131.29 * g / mole);
0105 
0106   //
0107   // define simple materials
0108   //
0109 
0110   new G4Material("H2Liq", z = 1, a = 1.01 * g / mole, density = 70.8 * mg / cm3);
0111   new G4Material("Beryllium", z = 4, a = 9.01 * g / mole, density = 1.848 * g / cm3);
0112   new G4Material("Aluminium", z = 13, a = 26.98 * g / mole, density = 2.700 * g / cm3);
0113   new G4Material("Silicon", z = 14, a = 28.09 * g / mole, density = 2.330 * g / cm3);
0114 
0115   G4Material* lAr = new G4Material("liquidArgon", density = 1.390 * g / cm3, ncomponents = 1);
0116   lAr->AddElement(Ar, natoms = 1);
0117 
0118   new G4Material("Iron", z = 26, a = 55.85 * g / mole, density = 7.870 * g / cm3);
0119   new G4Material("Copper", z = 29, a = 63.55 * g / mole, density = 8.960 * g / cm3);
0120   new G4Material("Germanium", z = 32, a = 72.61 * g / mole, density = 5.323 * g / cm3);
0121   new G4Material("Silver", z = 47, a = 107.87 * g / mole, density = 10.50 * g / cm3);
0122   new G4Material("Tungsten", z = 74, a = 183.85 * g / mole, density = 19.30 * g / cm3);
0123   new G4Material("Gold", z = 79, a = 196.97 * g / mole, density = 19.32 * g / cm3);
0124   new G4Material("Lead", z = 82, a = 207.19 * g / mole, density = 11.35 * g / cm3);
0125 
0126   //
0127   // define a material from elements.   case 1: chemical molecule
0128   //
0129 
0130   G4Material* H2O = new G4Material("Water", density = 1.000 * g / cm3, ncomponents = 2);
0131   H2O->AddElement(H, natoms = 2);
0132   H2O->AddElement(O, natoms = 1);
0133   H2O->GetIonisation()->SetMeanExcitationEnergy(78 * eV);
0134 
0135   G4Material* CH = new G4Material("Plastic", density = 1.04 * g / cm3, ncomponents = 2);
0136   CH->AddElement(C, natoms = 1);
0137   CH->AddElement(H, natoms = 1);
0138 
0139   G4Material* NaI = new G4Material("NaI", density = 3.67 * g / cm3, ncomponents = 2);
0140   NaI->AddElement(Na, natoms = 1);
0141   NaI->AddElement(I, natoms = 1);
0142   NaI->GetIonisation()->SetMeanExcitationEnergy(452 * eV);
0143 
0144   //
0145   // define a material from elements.   case 2: mixture by fractional mass
0146   //
0147 
0148   G4Material* Air = new G4Material("Air", density = 1.290 * mg / cm3, ncomponents = 2);
0149   Air->AddElement(N, fractionmass = 0.7);
0150   Air->AddElement(O, fractionmass = 0.3);
0151 
0152   G4Material* Air20 = new G4Material("Air20", density = 1.205 * mg / cm3, ncomponents = 2,
0153                                      kStateGas, 293. * kelvin, 1. * atmosphere);
0154   Air20->AddElement(N, fractionmass = 0.7);
0155   Air20->AddElement(O, fractionmass = 0.3);
0156 
0157   // Graphite
0158   //
0159   G4Material* Graphite = new G4Material("Graphite", density = 1.7 * g / cm3, ncomponents = 1);
0160   Graphite->AddElement(C, fractionmass = 1.);
0161 
0162   // Havar
0163   //
0164   G4Element* Cr = new G4Element("Chrome", "Cr", z = 24, a = 51.996 * g / mole);
0165   G4Element* Fe = new G4Element("Iron", "Fe", z = 26, a = 55.845 * g / mole);
0166   G4Element* Co = new G4Element("Cobalt", "Co", z = 27, a = 58.933 * g / mole);
0167   G4Element* Ni = new G4Element("Nickel", "Ni", z = 28, a = 58.693 * g / mole);
0168   G4Element* W = new G4Element("Tungsten", "W", z = 74, a = 183.850 * g / mole);
0169 
0170   G4Material* Havar = new G4Material("Havar", density = 8.3 * g / cm3, ncomponents = 5);
0171   Havar->AddElement(Cr, fractionmass = 0.1785);
0172   Havar->AddElement(Fe, fractionmass = 0.1822);
0173   Havar->AddElement(Co, fractionmass = 0.4452);
0174   Havar->AddElement(Ni, fractionmass = 0.1310);
0175   Havar->AddElement(W, fractionmass = 0.0631);
0176 
0177   //
0178   // examples of gas
0179   //
0180   new G4Material("ArgonGas", z = 18, a = 39.948 * g / mole, density = 1.782 * mg / cm3, kStateGas,
0181                  273.15 * kelvin, 1 * atmosphere);
0182 
0183   new G4Material("XenonGas", z = 54, a = 131.29 * g / mole, density = 5.458 * mg / cm3, kStateGas,
0184                  293.15 * kelvin, 1 * atmosphere);
0185 
0186   G4Material* CO2 = new G4Material("CarbonicGas", density = 1.977 * mg / cm3, ncomponents = 2);
0187   CO2->AddElement(C, natoms = 1);
0188   CO2->AddElement(O, natoms = 2);
0189 
0190   G4Material* ArCO2 = new G4Material("ArgonCO2", density = 1.8223 * mg / cm3, ncomponents = 2);
0191   ArCO2->AddElement(Ar, fractionmass = 0.7844);
0192   ArCO2->AddMaterial(CO2, fractionmass = 0.2156);
0193 
0194   // another way to define mixture of gas per volume
0195   G4Material* NewArCO2 =
0196     new G4Material("NewArgonCO2", density = 1.8223 * mg / cm3, ncomponents = 3);
0197   NewArCO2->AddElement(Ar, natoms = 8);
0198   NewArCO2->AddElement(C, natoms = 2);
0199   NewArCO2->AddElement(O, natoms = 4);
0200 
0201   G4Material* ArCH4 = new G4Material("ArgonCH4", density = 1.709 * mg / cm3, ncomponents = 3);
0202   ArCH4->AddElement(Ar, natoms = 93);
0203   ArCH4->AddElement(C, natoms = 7);
0204   ArCH4->AddElement(H, natoms = 28);
0205 
0206   G4Material* XeCH = new G4Material("XenonMethanePropane", density = 4.9196 * mg / cm3,
0207                                     ncomponents = 3, kStateGas, 293.15 * kelvin, 1 * atmosphere);
0208   XeCH->AddElement(Xe, natoms = 875);
0209   XeCH->AddElement(C, natoms = 225);
0210   XeCH->AddElement(H, natoms = 700);
0211 
0212   G4Material* steam = new G4Material("WaterSteam", density = 1.0 * mg / cm3, ncomponents = 1);
0213   steam->AddMaterial(H2O, fractionmass = 1.);
0214   steam->GetIonisation()->SetMeanExcitationEnergy(71.6 * eV);
0215 
0216   G4Material* rock1 = new G4Material("StandardRock", 2.65 * CLHEP::g / CLHEP::cm3, 1, kStateSolid);
0217   rock1->AddElement(Na, 1);
0218 
0219   //
0220   // example of vacuum
0221   //
0222   density = universe_mean_density;  // from PhysicalConstants.h
0223   pressure = 3.e-18 * pascal;
0224   temperature = 2.73 * kelvin;
0225   new G4Material("Galactic", z = 1, a = 1.01 * g / mole, density, kStateGas, temperature, pressure);
0226 }
0227 
0228 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0229 
0230 void DetectorConstruction::ComputeGeomParameters()
0231 {
0232   // Compute derived parameters of the calorimeter
0233   fXstartAbs = fXposAbs - 0.5 * fAbsorberThickness;
0234   fXendAbs = fXposAbs + 0.5 * fAbsorberThickness;
0235 
0236   G4double xmax = std::max(std::abs(fXstartAbs), std::abs(fXendAbs));
0237   fWorldSizeX = 2.4 * xmax;
0238   fWorldSizeYZ = 1.2 * fAbsorberSizeYZ;
0239   if (nullptr != fPhysiWorld) {
0240     ChangeGeometry();
0241   }
0242 }
0243 
0244 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0245 
0246 G4VPhysicalVolume* DetectorConstruction::Construct()
0247 {
0248   if (nullptr != fPhysiWorld) {
0249     return fPhysiWorld;
0250   }
0251   // World
0252   //
0253   fSolidWorld = new G4Box("World",  // its name
0254                           fWorldSizeX / 2, fWorldSizeYZ / 2, fWorldSizeYZ / 2);  // its size
0255 
0256   fLogicWorld = new G4LogicalVolume(fSolidWorld,  // its solid
0257                                     fWorldMaterial,  // its material
0258                                     "World");  // its name
0259 
0260   fPhysiWorld = new G4PVPlacement(0,  // no rotation
0261                                   G4ThreeVector(0., 0., 0.),  // at (0,0,0)
0262                                   fLogicWorld,  // its logical volume
0263                                   "World",  // its name
0264                                   0,  // its mother  volume
0265                                   false,  // no boolean operation
0266                                   0);  // copy number
0267 
0268   // Absorber
0269   //
0270   fSolidAbsorber =
0271     new G4Box("Absorber", fAbsorberThickness / 2, fAbsorberSizeYZ / 2, fAbsorberSizeYZ / 2);
0272 
0273   fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber,  // its solid
0274                                        fAbsorberMaterial,  // its material
0275                                        "Absorber");  // its name
0276 
0277   fPhysiAbsorber = new G4PVPlacement(0,  // no rotation
0278                                      G4ThreeVector(fXposAbs, 0., 0.),  // its position
0279                                      fLogicAbsorber,  // its logical volume
0280                                      "Absorber",  // its name
0281                                      fLogicWorld,  // its mother
0282                                      false,  // no boulean operat
0283                                      0);  // copy number
0284 
0285   PrintGeomParameters();
0286 
0287   // always return the physical World
0288   //
0289   return fPhysiWorld;
0290 }
0291 
0292 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0293 
0294 void DetectorConstruction::PrintGeomParameters()
0295 {
0296   G4cout << "\n" << fWorldMaterial << G4endl;
0297   G4cout << "\n" << fAbsorberMaterial << G4endl;
0298 
0299   G4cout << "\n The  WORLD   is made of " << G4BestUnit(fWorldSizeX, "Length") << " of "
0300          << fWorldMaterial->GetName();
0301   G4cout << ". The transverse size (YZ) of the world is " << G4BestUnit(fWorldSizeYZ, "Length")
0302          << G4endl;
0303   G4cout << " The ABSORBER is made of " << G4BestUnit(fAbsorberThickness, "Length") << " of "
0304          << fAbsorberMaterial->GetName();
0305   G4cout << ". The transverse size (YZ) is " << G4BestUnit(fAbsorberSizeYZ, "Length") << G4endl;
0306   G4cout << " X position of the middle of the absorber " << G4BestUnit(fXposAbs, "Length");
0307   G4cout << G4endl;
0308 }
0309 
0310 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0311 
0312 void DetectorConstruction::SetAbsorberMaterial(const G4String& materialChoice)
0313 {
0314   // search the material by its name
0315   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0316 
0317   if (pttoMaterial && fAbsorberMaterial != pttoMaterial) {
0318     fAbsorberMaterial = pttoMaterial;
0319     if (fLogicAbsorber) {
0320       fLogicAbsorber->SetMaterial(fAbsorberMaterial);
0321     }
0322     G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0323   }
0324 }
0325 
0326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0327 
0328 void DetectorConstruction::SetWorldMaterial(const G4String& materialChoice)
0329 {
0330   // search the material by its name
0331   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0332 
0333   if (pttoMaterial && fWorldMaterial != pttoMaterial) {
0334     fWorldMaterial = pttoMaterial;
0335     if (fLogicWorld) {
0336       fLogicWorld->SetMaterial(fWorldMaterial);
0337     }
0338     G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0339   }
0340 }
0341 
0342 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0343 
0344 void DetectorConstruction::SetAbsorberThickness(G4double val)
0345 {
0346   fAbsorberThickness = val;
0347   ComputeGeomParameters();
0348 }
0349 
0350 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0351 
0352 void DetectorConstruction::SetAbsorberSizeYZ(G4double val)
0353 {
0354   fAbsorberSizeYZ = val;
0355   ComputeGeomParameters();
0356 }
0357 
0358 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0359 
0360 void DetectorConstruction::SetWorldSizeX(G4double val)
0361 {
0362   fWorldSizeX = val;
0363   ComputeGeomParameters();
0364 }
0365 
0366 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0367 
0368 void DetectorConstruction::SetWorldSizeYZ(G4double val)
0369 {
0370   fWorldSizeYZ = val;
0371   ComputeGeomParameters();
0372 }
0373 
0374 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0375 
0376 void DetectorConstruction::SetAbsorberXpos(G4double val)
0377 {
0378   fXposAbs = val;
0379   ComputeGeomParameters();
0380 }
0381 
0382 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0383 
0384 void DetectorConstruction::ConstructSDandField()
0385 {
0386   if (fFieldMessenger.Get() == 0) {
0387     // Create global magnetic field messenger.
0388     // Uniform magnetic field is then created automatically if
0389     // the field value is not zero.
0390     G4ThreeVector fieldValue = G4ThreeVector();
0391     G4GlobalMagFieldMessenger* msg = new G4GlobalMagFieldMessenger(fieldValue);
0392     // msg->SetVerboseLevel(1);
0393     G4AutoDelete::Register(msg);
0394     fFieldMessenger.Put(msg);
0395   }
0396 }
0397 
0398 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0399 
0400 void DetectorConstruction::ChangeGeometry()
0401 {
0402   fSolidWorld->SetXHalfLength(fWorldSizeX * 0.5);
0403   fSolidWorld->SetYHalfLength(fWorldSizeYZ * 0.5);
0404   fSolidWorld->SetZHalfLength(fWorldSizeYZ * 0.5);
0405 
0406   fSolidAbsorber->SetXHalfLength(fAbsorberThickness * 0.5);
0407   fSolidAbsorber->SetYHalfLength(fAbsorberSizeYZ * 0.5);
0408   fSolidAbsorber->SetZHalfLength(fAbsorberSizeYZ * 0.5);
0409 }
0410 
0411 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......