Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-07 07:53:55

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 DetectorConstruction.cc
0027 /// \brief Implementation of the DetectorConstruction class
0028 
0029 #include "DetectorConstruction.hh"
0030 
0031 #include "DetectorMessenger.hh"
0032 
0033 #include "G4GeometryManager.hh"
0034 #include "G4LogicalVolume.hh"
0035 #include "G4LogicalVolumeStore.hh"
0036 #include "G4Material.hh"
0037 #include "G4PVPlacement.hh"
0038 #include "G4PhysicalConstants.hh"
0039 #include "G4PhysicalVolumeStore.hh"
0040 #include "G4SolidStore.hh"
0041 #include "G4SystemOfUnits.hh"
0042 #include "G4Tubs.hh"
0043 #include "G4UnitsTable.hh"
0044 
0045 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0046 
0047 DetectorConstruction::DetectorConstruction()
0048   : fMaterial_World(0),
0049     fMaterial_Frame(0),
0050     fMaterial_ExitWindow(0),
0051     fMaterial_ScatterFoil(0),
0052     fMaterial_MonitorChbr(0),
0053     fMaterial_Bag(0),
0054     fMaterial_Gas(0),
0055     fMaterial_Ring(0),
0056     fPvol_World(0),
0057     fPvol_Frame(0),
0058     fDetectorMessenger(0)
0059 {
0060   // materials
0061   DefineMaterials();
0062 
0063   // geometry
0064   GeometryParameters();
0065 
0066   // create commands for interactive definition of the calorimeter
0067   fDetectorMessenger = new DetectorMessenger(this);
0068 }
0069 
0070 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0071 
0072 DetectorConstruction::~DetectorConstruction()
0073 {
0074   delete fDetectorMessenger;
0075 }
0076 
0077 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0078 
0079 G4VPhysicalVolume* DetectorConstruction::Construct()
0080 {
0081   return ConstructVolumes();
0082 }
0083 
0084 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0085 
0086 void DetectorConstruction::DefineMaterials()
0087 {
0088   G4double a, z, density;
0089   G4int ncomponents, natoms;
0090   G4double fractionmass;
0091   G4double temperature, pressure;
0092 
0093   // define Elements
0094   //
0095   G4Element* H = new G4Element("Hydrogen", "H", z = 1, a = 1.0079 * g / mole);
0096   G4Element* He = new G4Element("Helium", "He", z = 2, a = 4.0026 * g / mole);
0097   G4Element* Be = new G4Element("Beryllium", "Be", z = 4, a = 9.1218 * g / mole);
0098   G4Element* C = new G4Element("Carbon", "C", z = 6, a = 12.0107 * g / mole);
0099   G4Element* N = new G4Element("Nitrogen", "N", z = 7, a = 14.0067 * g / mole);
0100   G4Element* O = new G4Element("Oxygen", "O", z = 8, a = 15.9994 * g / mole);
0101   G4Element* Al = new G4Element("Aluminium", "Al", z = 13, a = 26.9815 * g / mole);
0102   G4Element* Ar = new G4Element("Argon", "Ar", z = 18, a = 39.9480 * g / mole);
0103   G4Element* Ti = new G4Element("Titanium", "Ti", z = 22, a = 47.8670 * g / mole);
0104   G4Element* Va = new G4Element("Vanadium", "Va", z = 23, a = 50.9415 * g / mole);
0105   G4Element* Cu = new G4Element("Copper", "Cu", z = 29, a = 63.5460 * g / mole);
0106   G4Element* Ta = new G4Element("Tantalum", "Ta", z = 73, a = 180.9479 * g / mole);
0107   G4Element* Au = new G4Element("Gold", "Au", z = 79, a = 196.9666 * g / mole);
0108 
0109   // Air
0110   //
0111   G4Material* Air = new G4Material("Air", density = 1.205 * mg / cm3, ncomponents = 4, kStateGas,
0112                                    293. * kelvin, 1. * atmosphere);
0113   Air->AddElement(C, fractionmass = 0.000124);
0114   Air->AddElement(N, fractionmass = 0.755267);
0115   Air->AddElement(O, fractionmass = 0.231782);
0116   Air->AddElement(Ar, fractionmass = 0.012827);
0117 
0118   // Titanium
0119   //
0120   G4Material* Titanium = new G4Material("Titanium", density = 4.42 * g / cm3, ncomponents = 3);
0121   Titanium->AddElement(Ti, fractionmass = 0.90);
0122   Titanium->AddElement(Al, fractionmass = 0.06);
0123   Titanium->AddElement(Va, fractionmass = 0.04);
0124 
0125   // Mylar
0126   //
0127   G4Material* Mylar = new G4Material("Mylar", density = 1.40 * g / cm3, ncomponents = 3);
0128   Mylar->AddElement(H, natoms = 4);
0129   Mylar->AddElement(C, natoms = 5);
0130   Mylar->AddElement(O, natoms = 2);
0131 
0132   // Helium
0133   //
0134   G4Material* Helium = new G4Material("Helium", density = 0.166 * mg / cm3, ncomponents = 1,
0135                                       kStateGas, 293. * kelvin, 1. * atmosphere);
0136   Helium->AddElement(He, fractionmass = 1.0);
0137 
0138   // Aluminium
0139   //
0140   G4Material* Aluminium = new G4Material("Aluminium", density = 2.7 * g / cm3, ncomponents = 1);
0141   Aluminium->AddElement(Al, fractionmass = 1.0);
0142 
0143   // Beryllium
0144   //
0145   G4Material* Beryllium = new G4Material("Beryllium", density = 1.85 * g / cm3, ncomponents = 1);
0146   Beryllium->AddElement(Be, fractionmass = 1.0);
0147 
0148   // Graphite
0149   //
0150   G4Material* Graphite = new G4Material("Graphite", density = 2.18 * g / cm3, ncomponents = 1);
0151   Graphite->AddElement(C, fractionmass = 1.0);
0152 
0153   // Copper
0154   //
0155   G4Material* Copper = new G4Material("Copper", density = 8.92 * g / cm3, ncomponents = 1);
0156   Copper->AddElement(Cu, fractionmass = 1.0);
0157 
0158   // Tantalum
0159   //
0160   G4Material* Tantalum = new G4Material("Tantalum", density = 16.65 * g / cm3, ncomponents = 1);
0161   Tantalum->AddElement(Ta, fractionmass = 1.0);
0162 
0163   // Gold
0164   //
0165   G4Material* Gold = new G4Material("Gold", density = 19.30 * g / cm3, ncomponents = 1);
0166   Gold->AddElement(Au, fractionmass = 1.0);
0167 
0168   // example of vacuum
0169   //
0170   density = universe_mean_density;  // from PhysicalConstants.h
0171   pressure = 3.e-18 * pascal;
0172   temperature = 2.73 * kelvin;
0173   G4Material* Vacuum = new G4Material("Galactic", z = 1, a = 1.01 * g / mole, density, kStateGas,
0174                                       temperature, pressure);
0175 
0176   // print
0177   //
0178   G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0179 
0180   // assign materials
0181   //
0182   fMaterial_World = Vacuum;
0183   fMaterial_Frame = Air;
0184   fMaterial_ExitWindow = Titanium;
0185   fMaterial_ScatterFoil = fMaterial_Frame;
0186   fMaterial_MonitorChbr = Mylar;
0187   fMaterial_Bag = Mylar;
0188   fMaterial_Gas = Helium;
0189   fMaterial_Ring = Aluminium;
0190 }
0191 
0192 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0193 
0194 void DetectorConstruction::GeometryParameters()
0195 {
0196   fZfront_ExitWindow = 0.0 * um;
0197   fThickness_ExitWindow = 41.2 * um;
0198 
0199   fZfront_ScatterFoil = 2.65 * cm;
0200   fThickness_ScatterFoil = 0.0 * um;
0201 
0202   fZfront_MonitorChbr = 50. * mm;
0203   fThickness_MonitorChbr = 112.7 * um;
0204 
0205   fZfront_Bag = 64.975 * mm;
0206   fThickness_Bag = 110.0050 * cm;
0207 
0208   fThickness_Gas = 110. * cm;
0209 
0210   fThickness_Ring = 14. * mm;
0211   fInnerRadius_Ring = 20. * cm;
0212 
0213   fZfront_Frame = 2.0 * um;
0214   fThickness_Frame = 118.2 * cm;
0215 
0216   fThickness_World = fZfront_Frame + fThickness_Frame;
0217   fRadius_World = 23.3 * cm;
0218 }
0219 
0220 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0221 
0222 G4VPhysicalVolume* DetectorConstruction::ConstructVolumes()
0223 {
0224   // Cleanup old geometry
0225   //
0226   G4GeometryManager::GetInstance()->OpenGeometry();
0227   G4PhysicalVolumeStore::GetInstance()->Clean();
0228   G4LogicalVolumeStore::GetInstance()->Clean();
0229   G4SolidStore::GetInstance()->Clean();
0230 
0231   // World
0232   //
0233   G4Tubs* svol_World = new G4Tubs("World",  // name
0234                                   0 * cm, fRadius_World,  // r1, r2
0235                                   0.5 * fThickness_World,  // half-length
0236                                   0., twopi);  // theta1, theta2
0237 
0238   G4LogicalVolume* lvol_World = new G4LogicalVolume(svol_World,  // its solid
0239                                                     fMaterial_World,  // its material
0240                                                     "World");  // its name
0241 
0242   fPvol_World = new G4PVPlacement(0,  // no rotation
0243                                   G4ThreeVector(),  // no translation
0244                                   lvol_World,  // its logical volume
0245                                   "World",  // its name
0246                                   0,  // its mother  volume
0247                                   false,  // no boolean operation
0248                                   0);  // copy number
0249 
0250   // Frame
0251   //
0252   G4Tubs* svol_Frame = new G4Tubs("Frame",  // name
0253                                   0 * cm, fRadius_World,  // r1, r2
0254                                   0.5 * fThickness_Frame,  // half-length
0255                                   0., twopi);  // theta1, theta2
0256 
0257   G4LogicalVolume* lvol_Frame = new G4LogicalVolume(svol_Frame,  // its solid
0258                                                     fMaterial_Frame,  // its material
0259                                                     "Frame");  // its name
0260 
0261   G4double zpos = fZfront_Frame;
0262 
0263   fPvol_Frame = new G4PVPlacement(0,  // no rotation
0264                                   G4ThreeVector(0, 0, zpos),  // translation
0265                                   lvol_Frame,  // its logical volume
0266                                   "Frame",  // its name
0267                                   lvol_World,  // its mother  volume
0268                                   false,  // no boolean operation
0269                                   0);  // copy number
0270 
0271   // ExitWindow
0272   //
0273   G4Tubs* svol_ExitWindow = new G4Tubs("ExitWindow",  // name
0274                                        0 * cm, fRadius_World,  // r1, r2
0275                                        0.5 * fThickness_ExitWindow,  // half-length
0276                                        0., twopi);  // theta1, theta2
0277 
0278   G4LogicalVolume* lvol_ExitWindow = new G4LogicalVolume(svol_ExitWindow,  // solid
0279                                                          fMaterial_ExitWindow,  // material
0280                                                          "ExitWindow");  // name
0281 
0282   zpos = fZfront_ExitWindow + 0.5 * fThickness_ExitWindow - 0.5 * fThickness_Frame;
0283 
0284   new G4PVPlacement(0,  // no rotation
0285                     G4ThreeVector(0, 0, zpos),  // translation
0286                     lvol_ExitWindow,  // logical volume
0287                     "ExitWindow",  // name
0288                     lvol_Frame,  // mother volume
0289                     false,  // no boolean operation
0290                     0);  // copy number
0291 
0292   // Monitor Chamber
0293   //
0294   G4Tubs* svol_MonitorChbr = new G4Tubs("MonitorChbr",  // name
0295                                         0 * cm, fRadius_World,  // r1, r2
0296                                         0.5 * fThickness_MonitorChbr,  // half-length
0297                                         0., twopi);  // theta1, theta2
0298 
0299   G4LogicalVolume* lvol_MonitorChbr = new G4LogicalVolume(svol_MonitorChbr,  // solid
0300                                                           fMaterial_MonitorChbr,  // material
0301                                                           "MonitorChbr");  // name
0302 
0303   zpos = fZfront_MonitorChbr + 0.5 * fThickness_MonitorChbr - 0.5 * fThickness_Frame;
0304 
0305   new G4PVPlacement(0,  // no rotation
0306                     G4ThreeVector(0, 0, zpos),  // translation
0307                     lvol_MonitorChbr,  // logical volume
0308                     "MonitorChbr",  // name
0309                     lvol_Frame,  // mother volume
0310                     false,  // no boolean operation
0311                     0);  // copy number
0312 
0313   // Bag
0314   //
0315   G4Tubs* svol_Bag = new G4Tubs("Bag",  // name
0316                                 0 * cm, fRadius_World,  // r1, r2
0317                                 0.5 * fThickness_Bag,  // half-length
0318                                 0., twopi);  // theta1, theta2
0319 
0320   G4LogicalVolume* lvol_Bag = new G4LogicalVolume(svol_Bag,  // solid
0321                                                   fMaterial_Bag,  // material
0322                                                   "Bag");  // name
0323 
0324   zpos = fZfront_Bag + 0.5 * fThickness_Bag - 0.5 * fThickness_Frame;
0325 
0326   new G4PVPlacement(0,  // no rotation
0327                     G4ThreeVector(0, 0, zpos),  // translation
0328                     lvol_Bag,  // logical volume
0329                     "Bag",  // name
0330                     lvol_Frame,  // mother volume
0331                     false,  // no boolean operation
0332                     0);  // copy number
0333 
0334   // Gas
0335   //
0336   G4Tubs* svol_Gas = new G4Tubs("Gas",  // name
0337                                 0 * cm, fRadius_World,  // r1, r2
0338                                 0.5 * fThickness_Gas,  // half-length
0339                                 0., twopi);  // theta1, theta2
0340 
0341   G4LogicalVolume* lvol_Gas = new G4LogicalVolume(svol_Gas,  // solid
0342                                                   fMaterial_Gas,  // material
0343                                                   "Gas");  // name
0344 
0345   new G4PVPlacement(0,  // no rotation
0346                     G4ThreeVector(),  // no translation
0347                     lvol_Gas,  // logical volume
0348                     "Gas",  // name
0349                     lvol_Bag,  // mother volume
0350                     false,  // no boolean operation
0351                     0);  // copy number
0352 
0353   // Rings
0354   //
0355   G4Tubs* svol_Ring = new G4Tubs("Ring",  // name
0356                                  fInnerRadius_Ring, fRadius_World,  // r1, r2
0357                                  0.5 * fThickness_Ring,  // half-length
0358                                  0., twopi);  // theta1, theta2
0359 
0360   G4LogicalVolume* lvol_Ring = new G4LogicalVolume(svol_Ring,  // solid
0361                                                    fMaterial_Ring,  // material
0362                                                    "Ring");  // name
0363 
0364   zpos = 0.5 * (fThickness_Gas - fThickness_Ring);
0365 
0366   new G4PVPlacement(0,  // no rotation
0367                     G4ThreeVector(0, 0, zpos),  // translation
0368                     lvol_Ring,  // logical volume
0369                     "Ring",  // name
0370                     lvol_Gas,  // mother volume
0371                     false,  // no boolean operation
0372                     1);  // copy number
0373 
0374   new G4PVPlacement(0,  // no rotation
0375                     G4ThreeVector(0, 0, -zpos),  // translation
0376                     lvol_Ring,  // logical volume
0377                     "Ring",  // name
0378                     lvol_Gas,  // mother volume
0379                     false,  // no boolean operation
0380                     2);  // copy number
0381 
0382   // ScatterFoil (only if it is not Air)
0383   //
0384   if ((fMaterial_ScatterFoil != fMaterial_Frame) && (fThickness_ScatterFoil > 0.)) {
0385     G4Tubs* svol_ScatterFoil = new G4Tubs("ScatterFoil",  // name
0386                                           0 * cm, fRadius_World,  // r1, r2
0387                                           0.5 * fThickness_ScatterFoil,  // half-length
0388                                           0., twopi);  // theta1, theta2
0389 
0390     G4LogicalVolume* lvol_ScatterFoil = new G4LogicalVolume(svol_ScatterFoil,  // solid
0391                                                             fMaterial_ScatterFoil,  // material
0392                                                             "ScatterFoil");  // name
0393 
0394     zpos = fZfront_ScatterFoil + 0.5 * fThickness_ScatterFoil - 0.5 * fThickness_Frame;
0395 
0396     new G4PVPlacement(0,  // no rotation
0397                       G4ThreeVector(0, 0, zpos),  // translation
0398                       lvol_ScatterFoil,  // logical volume
0399                       "ScatterFoil",  // name
0400                       lvol_Frame,  // mother volume
0401                       false,  // no boolean operation
0402                       0);  // copy number
0403   }
0404 
0405   PrintGeometry();
0406 
0407   // always return the physical World
0408   //
0409   return fPvol_World;
0410 }
0411 
0412 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0413 
0414 void DetectorConstruction::PrintGeometry()
0415 {
0416   // choose printing format
0417   std::ios::fmtflags mode = G4cout.flags();
0418   G4cout.setf(std::ios::fixed, std::ios::floatfield);
0419   G4int prec = G4cout.precision(6);
0420 
0421   G4cout << "\n \t \t"
0422          << "Material \t"
0423          << "Z_front \t"
0424          << "Thickness \n";
0425 
0426   G4cout << "\n  ExitWindow \t" << fMaterial_ExitWindow->GetName() << "\t"
0427          << G4BestUnit(fZfront_ExitWindow, "Length") << "\t"
0428          << G4BestUnit(fThickness_ExitWindow, "Length");
0429 
0430   if (fMaterial_ScatterFoil != fMaterial_Frame) {
0431     G4cout << "\n  ScatterFoil \t" << fMaterial_ScatterFoil->GetName() << "\t"
0432            << "\t" << G4BestUnit(fZfront_ScatterFoil, "Length") << "\t"
0433            << G4BestUnit(fThickness_ScatterFoil, "Length");
0434   }
0435 
0436   G4cout << "\n  MonitorChbr \t" << fMaterial_MonitorChbr->GetName() << "\t"
0437          << "\t" << G4BestUnit(fZfront_MonitorChbr, "Length") << "\t"
0438          << G4BestUnit(fThickness_MonitorChbr, "Length");
0439 
0440   G4double thickBagWindow = 0.5 * (fThickness_Bag - fThickness_Gas);
0441   G4double zfrontGas = fZfront_Bag + thickBagWindow;
0442   G4double zfrontBagWindow2 = zfrontGas + fThickness_Gas;
0443 
0444   G4cout << "\n  BagWindow1 \t" << fMaterial_Bag->GetName() << "\t"
0445          << "\t" << G4BestUnit(fZfront_Bag, "Length") << "\t"
0446          << G4BestUnit(thickBagWindow, "Length");
0447 
0448   G4cout << "\n  Gas       \t" << fMaterial_Gas->GetName() << "\t"
0449          << "\t" << G4BestUnit(zfrontGas, "Length") << "\t" << G4BestUnit(fThickness_Gas, "Length");
0450 
0451   G4cout << "\n  BagWindow2 \t" << fMaterial_Bag->GetName() << "\t"
0452          << "\t" << G4BestUnit(zfrontBagWindow2, "Length") << "\t"
0453          << G4BestUnit(thickBagWindow, "Length");
0454 
0455   G4cout << "\n  ScoringPlane \t" << fMaterial_Frame->GetName() << "\t"
0456          << "\t" << G4BestUnit(fThickness_Frame, "Length") << "\n"
0457          << G4endl;
0458 
0459   // restaure default formats
0460   G4cout.setf(mode, std::ios::floatfield);
0461   G4cout.precision(prec);
0462 }
0463 
0464 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0465 
0466 void DetectorConstruction::SetMaterialScatter(G4String material)
0467 {
0468   // search the material by its name
0469   G4Material* pMaterial = G4Material::GetMaterial(material);
0470 
0471   if (pMaterial) fMaterial_ScatterFoil = pMaterial;
0472 }
0473 
0474 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0475 
0476 void DetectorConstruction::SetThicknessScatter(G4double val)
0477 {
0478   fThickness_ScatterFoil = val;
0479 }
0480 
0481 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0482 
0483 #include "G4RunManager.hh"
0484 
0485 void DetectorConstruction::UpdateGeometry()
0486 {
0487   G4RunManager::GetRunManager()->DefineWorldVolume(ConstructVolumes());
0488 }
0489 
0490 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......