Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-04 07:52:37

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 F01DetectorConstruction.cc
0027 /// \brief Implementation of the F01DetectorConstruction class
0028 
0029 #include "F01DetectorConstruction.hh"
0030 
0031 #include "F01CalorimeterSD.hh"
0032 #include "F01DetectorMessenger.hh"
0033 
0034 #include "G4AutoDelete.hh"
0035 #include "G4GeometryManager.hh"
0036 #include "G4FieldBuilder.hh"
0037 #include "G4LogicalVolume.hh"
0038 #include "G4LogicalVolumeStore.hh"
0039 #include "G4Material.hh"
0040 #include "G4PVPlacement.hh"
0041 #include "G4PhysicalConstants.hh"
0042 #include "G4PhysicalVolumeStore.hh"
0043 #include "G4RunManager.hh"
0044 #include "G4SDManager.hh"
0045 #include "G4SolidStore.hh"
0046 #include "G4SystemOfUnits.hh"
0047 #include "G4Tubs.hh"
0048 #include "G4UniformMagField.hh"
0049 
0050 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0051 
0052 F01DetectorConstruction::F01DetectorConstruction()
0053 {
0054   // create commands for interactive definition of the calorimeter
0055 
0056   G4cout << "F01DetectorConstruction::F01DetectorConstruction()" << G4endl;
0057 
0058   fDetectorMessenger = new F01DetectorMessenger(this);
0059 
0060   // create field builder
0061   // this will create commands for field configuration
0062   G4FieldBuilder::Instance();
0063   // G4FieldBuilder::Instance()->SetVerboseLevel(2);
0064 
0065   // create materials
0066 
0067   DefineMaterials();
0068 }
0069 
0070 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0071 
0072 F01DetectorConstruction::~F01DetectorConstruction()
0073 {
0074   // delete fDetectorMessenger;
0075 }
0076 
0077 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0078 
0079 G4VPhysicalVolume* F01DetectorConstruction::Construct()
0080 {
0081   return ConstructCalorimeter();
0082 }
0083 
0084 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0085 
0086 void F01DetectorConstruction::DefineMaterials()
0087 {
0088   // This function illustrates the possible ways to define materials
0089 
0090   G4String name, symbol;  // a=mass of a mole;
0091   G4double a, z, density;  // z=mean number of protons;
0092   G4int nel;
0093   G4int ncomponents;
0094   G4double fractionmass, pressure, temperature;
0095 
0096   //
0097   // define Elements
0098   //
0099 
0100   a = 1.01 * g / mole;
0101   auto elH = new G4Element(name = "Hydrogen", symbol = "H", z = 1., a);
0102 
0103   a = 12.01 * g / mole;
0104   auto elC = new G4Element(name = "Carbon", symbol = "C", z = 6., a);
0105 
0106   a = 14.01 * g / mole;
0107   auto elN = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a);
0108 
0109   a = 16.00 * g / mole;
0110   auto elO = new G4Element(name = "Oxygen", symbol = "O", z = 8., a);
0111 
0112   a = 39.948 * g / mole;
0113   auto elAr = new G4Element(name = "Argon", symbol = "Ar", z = 18., a);
0114 
0115   //
0116   // define simple materials
0117   //
0118 
0119   // Mylar
0120 
0121   density = 1.39 * g / cm3;
0122   auto mylar = new G4Material(name = "Mylar", density, nel = 3);
0123   mylar->AddElement(elO, 2);
0124   mylar->AddElement(elC, 5);
0125   mylar->AddElement(elH, 4);
0126 
0127   // Polypropelene
0128 
0129   auto CH2 = new G4Material("Polypropelene", 0.91 * g / cm3, 2);
0130   CH2->AddElement(elH, 2);
0131   CH2->AddElement(elC, 1);
0132 
0133   // Krypton as detector gas, STP
0134 
0135   density = 3.700 * mg / cm3;
0136   a = 83.80 * g / mole;
0137   auto Kr = new G4Material(name = "Kr", z = 36., a, density);
0138 
0139   // Dry air (average composition)
0140 
0141   density = 1.7836 * mg / cm3;  // STP
0142   auto argon = new G4Material(name = "Argon", density, ncomponents = 1);
0143   argon->AddElement(elAr, 1);
0144 
0145   density = 1.25053 * mg / cm3;  // STP
0146   auto nitrogen = new G4Material(name = "N2", density, ncomponents = 1);
0147   nitrogen->AddElement(elN, 2);
0148 
0149   density = 1.4289 * mg / cm3;  // STP
0150   auto oxygen = new G4Material(name = "O2", density, ncomponents = 1);
0151   oxygen->AddElement(elO, 2);
0152 
0153   density = 1.2928 * mg / cm3;  // STP
0154   density *= 1.0e-8;  // pumped vacuum
0155 
0156   temperature = STP_Temperature;
0157   pressure = 1.0e-8 * STP_Pressure;
0158 
0159   auto air =
0160     new G4Material(name = "Air", density, ncomponents = 3, kStateGas, temperature, pressure);
0161   air->AddMaterial(nitrogen, fractionmass = 0.7557);
0162   air->AddMaterial(oxygen, fractionmass = 0.2315);
0163 
0164   air->AddMaterial(argon, fractionmass = 0.0128);
0165 
0166   // Xenon as detector gas, STP
0167 
0168   density = 5.858 * mg / cm3;
0169   a = 131.29 * g / mole;
0170   auto Xe = new G4Material(name = "Xenon", z = 54., a, density);
0171 
0172   // Carbon dioxide, STP
0173 
0174   density = 1.842 * mg / cm3;
0175   auto CarbonDioxide = new G4Material(name = "CO2", density, nel = 2);
0176   CarbonDioxide->AddElement(elC, 1);
0177   CarbonDioxide->AddElement(elO, 2);
0178 
0179   // 80% Xe + 20% CO2, STP
0180 
0181   density = 5.0818 * mg / cm3;
0182   auto Xe20CO2 = new G4Material(name = "Xe20CO2", density, ncomponents = 2);
0183   Xe20CO2->AddMaterial(Xe, fractionmass = 0.922);
0184   Xe20CO2->AddMaterial(CarbonDioxide, fractionmass = 0.078);
0185 
0186   // 80% Kr + 20% CO2, STP
0187 
0188   density = 3.601 * mg / cm3;
0189   auto Kr20CO2 = new G4Material(name = "Kr20CO2", density, ncomponents = 2);
0190   Kr20CO2->AddMaterial(Kr, fractionmass = 0.89);
0191   Kr20CO2->AddMaterial(CarbonDioxide, fractionmass = 0.11);
0192 
0193   // Print material table -- silence it for now
0194   // G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0195   G4cout << "F01DetectorConstruction: not printing material table - to see it edit the source."
0196          << G4endl;
0197 
0198   // default materials of the calorimeter
0199 
0200   fAbsorberMaterial = air;  //  Kr20CO2;   // XeCO2CF4;
0201 
0202   fWorldMaterial = air;
0203 }
0204 
0205 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0206 
0207 G4VPhysicalVolume* F01DetectorConstruction::ConstructCalorimeter()
0208 {
0209   // In case an old geometry is present... clean it up
0210 
0211   if (fPhysiWorld) {
0212     G4GeometryManager::GetInstance()->OpenGeometry();
0213     G4PhysicalVolumeStore::GetInstance()->Clean();
0214     G4LogicalVolumeStore::GetInstance()->Clean();
0215     G4SolidStore::GetInstance()->Clean();
0216   }
0217 
0218   // Compute the Calor parameters definition and Print
0219 
0220   ComputeCalorParameters();
0221   PrintCalorParameters();
0222 
0223   // World
0224 
0225   fSolidWorld = new G4Tubs("World",  // its name
0226                            0., fWorldSizeR, fWorldSizeZ / 2., 0., twopi);  // its size
0227 
0228   fLogicWorld = new G4LogicalVolume(fSolidWorld,  // its solid
0229                                     fWorldMaterial,  // its material
0230                                     "World");  // its name
0231 
0232   fPhysiWorld = new G4PVPlacement(nullptr,  // no rotation
0233                                   G4ThreeVector(),  // at (0,0,0)
0234                                   "World",  // its name
0235                                   fLogicWorld,  // its logical volume
0236                                   nullptr,  // its mother  volume
0237                                   false,  // no boolean op.
0238                                   0);  // copy number
0239   // Absorber
0240 
0241   fSolidAbsorber =
0242     new G4Tubs("Absorber", 1.0 * mm, fAbsorberRadius, fAbsorberThickness / 2., 0.0, twopi);
0243 
0244   fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, fAbsorberMaterial, "Absorber");
0245 
0246   fPhysiAbsorber = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fZAbsorber), "Absorber",
0247                                      fLogicAbsorber, fPhysiWorld, false, 0);
0248 
0249   return fPhysiWorld;
0250 }
0251 
0252 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0253 
0254 void F01DetectorConstruction::PrintCalorParameters()
0255 {
0256   G4cout << "\n The  WORLD   is made of " << fWorldSizeZ / mm << "mm of "
0257          << fWorldMaterial->GetName();
0258   G4cout << ", the transverse size (R) of the world is " << fWorldSizeR / mm << " mm. " << G4endl;
0259   G4cout << " The ABSORBER is made of " << fAbsorberThickness / mm << "mm of "
0260          << fAbsorberMaterial->GetName();
0261   G4cout << ", the transverse size (R) is " << fAbsorberRadius / mm << " mm. " << G4endl;
0262   G4cout << " Z position of the (middle of the) absorber " << fZAbsorber / mm << "  mm." << G4endl;
0263   G4cout << G4endl;
0264 }
0265 
0266 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0267 
0268 void F01DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
0269 {
0270   // get the pointer to the material table
0271   const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
0272 
0273   // search the material by its name
0274   G4Material* material;
0275   for (size_t j = 0; j < theMaterialTable->size(); j++) {
0276     material = (*theMaterialTable)[j];
0277     if (material->GetName() == materialChoice) {
0278       fAbsorberMaterial = material;
0279       fLogicAbsorber->SetMaterial(material);
0280       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0281     }
0282   }
0283 }
0284 
0285 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0286 
0287 void F01DetectorConstruction::SetWorldMaterial(G4String materialChoice)
0288 {
0289   // get the pointer to the material table
0290   const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
0291 
0292   // search the material by its name
0293   G4Material* material;
0294   for (size_t j = 0; j < theMaterialTable->size(); j++) {
0295     material = (*theMaterialTable)[j];
0296     if (material->GetName() == materialChoice) {
0297       fWorldMaterial = material;
0298       fLogicWorld->SetMaterial(material);
0299       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0300     }
0301   }
0302 }
0303 
0304 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0305 
0306 void F01DetectorConstruction::SetAbsorberThickness(G4double val)
0307 {
0308   // change Absorber thickness and recompute the calorimeter parameters
0309   fAbsorberThickness = val;
0310   ComputeCalorParameters();
0311   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0312 }
0313 
0314 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0315 
0316 void F01DetectorConstruction::SetAbsorberRadius(G4double val)
0317 {
0318   // change the transverse size and recompute the calorimeter parameters
0319   fAbsorberRadius = val;
0320   ComputeCalorParameters();
0321   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0322 }
0323 
0324 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0325 
0326 void F01DetectorConstruction::SetWorldSizeZ(G4double val)
0327 {
0328   fWorldSizeZ = val;
0329   ComputeCalorParameters();
0330   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0331 }
0332 
0333 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0334 
0335 void F01DetectorConstruction::SetWorldSizeR(G4double val)
0336 {
0337   fWorldSizeR = val;
0338   ComputeCalorParameters();
0339   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0340 }
0341 
0342 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0343 
0344 void F01DetectorConstruction::SetAbsorberZpos(G4double val)
0345 {
0346   fZAbsorber = val;
0347   ComputeCalorParameters();
0348   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0349 }
0350 
0351 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0352 
0353 void F01DetectorConstruction::SetFieldValue(G4ThreeVector value)
0354 {
0355   fFieldVector = value;
0356 
0357   G4UniformMagField* magField = nullptr;
0358   if (fFieldVector != G4ThreeVector(0.,0.,0.)) {
0359     magField = new G4UniformMagField(fFieldVector);
0360   }
0361 
0362   // Set field to the field builder
0363   auto fieldBuilder = G4FieldBuilder::Instance();
0364   fieldBuilder->SetGlobalField(magField);
0365 }
0366 
0367 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0368 #include "G4FieldManager.hh"
0369 
0370 void F01DetectorConstruction::ConstructSDandField()
0371 {
0372   // Sensitive Detectors: Absorber
0373 
0374   if (!fCalorimeterSD.Get()) {
0375     auto calorimeterSD = new F01CalorimeterSD("CalorSD", this);
0376     fCalorimeterSD.Put(calorimeterSD);
0377   }
0378   G4SDManager::GetSDMpointer()->AddNewDetector(fCalorimeterSD.Get());
0379   SetSensitiveDetector(fLogicAbsorber, fCalorimeterSD.Get());
0380 
0381   // Create detector field
0382   SetFieldValue(fFieldVector);
0383 
0384   // Construct all Geant4 field objects
0385   auto fieldBuilder = G4FieldBuilder::Instance();
0386   fieldBuilder->ConstructFieldSetup();
0387 }
0388 
0389 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......