Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-13 07:40:40

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 GB03DetectorConstruction.cc
0027 /// \brief Implementation of the GB03DetectorConstruction class
0028 
0029 #include "GB03DetectorConstruction.hh"
0030 
0031 #include "GB03BOptrGeometryBasedBiasing.hh"
0032 #include "GB03HodoSD.hh"
0033 
0034 #include "G4Box.hh"
0035 #include "G4Colour.hh"
0036 #include "G4GenericMessenger.hh"
0037 #include "G4LogicalVolume.hh"
0038 #include "G4Material.hh"
0039 #include "G4PVPlacement.hh"
0040 #include "G4PVReplica.hh"
0041 #include "G4PhysicalConstants.hh"
0042 #include "G4RunManager.hh"
0043 #include "G4SDManager.hh"
0044 #include "G4SystemOfUnits.hh"
0045 #include "G4VisAttributes.hh"
0046 #include "G4ios.hh"
0047 
0048 G4int GB03DetectorConstruction::fNumberOfLayers = 40;
0049 G4ThreadLocal G4bool GB03DetectorConstruction::fConstructedSDandField = false;
0050 
0051 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0052 
0053 GB03DetectorConstruction::GB03DetectorConstruction(G4bool bf)
0054   : G4VUserDetectorConstruction(),
0055     fTotalThickness(2.0 * m),
0056     fLayerThickness(0.),
0057     fConstructed(false),
0058     fWorldMaterial(nullptr),
0059     fAbsorberMaterial(nullptr),
0060     fGapMaterial(nullptr),
0061     fLayerSolid(nullptr),
0062     fGapSolid(nullptr),
0063     fCalorLogical(nullptr),
0064     fLayerLogical(nullptr),
0065     fGapLogical(nullptr),
0066     fWorldPhysical(nullptr),
0067     fLayerPhysical(nullptr),
0068     fGapPhysical(nullptr),
0069     fDetectorMessenger(nullptr),
0070     fVerboseLevel(1),
0071     fBiasingFlag(bf)
0072 {
0073   fLayerThickness = fTotalThickness / fNumberOfLayers;
0074   fCalName = "Calor";
0075 
0076   DefineMaterials();
0077 
0078   // Material List
0079   G4String matList;
0080   const G4MaterialTable* matTbl = G4Material::GetMaterialTable();
0081   for (size_t i = 0; i < G4Material::GetNumberOfMaterials(); i++) {
0082     matList += (*matTbl)[i]->GetName();
0083     matList += " ";
0084   }
0085 
0086   // Detector Messenger
0087   fDetectorMessenger = new G4GenericMessenger(this, "/GB03/", "UI commands of this example");
0088   fDetectorMessenger
0089     ->DeclareMethod("setAbsMat", &GB03DetectorConstruction::SetAbsorberMaterial,
0090                     "Select Material of the Absorber.")
0091     .SetParameterName("material", false)
0092     .SetStates(G4State_Idle)
0093     .SetCandidates(matList);
0094 
0095   fDetectorMessenger
0096     ->DeclareMethod("setGapMat", &GB03DetectorConstruction::SetGapMaterial,
0097                     "Select Material of the Gap.")
0098     .SetParameterName("choice", false)
0099     .SetStates(G4State_Idle)
0100     .SetCandidates(matList);
0101 
0102   fDetectorMessenger
0103     ->DeclareMethod("numberOfLayers", &GB03DetectorConstruction::SetNumberOfLayers,
0104                     "Set number of layers.")
0105     .SetParameterName("nl", false)
0106     .SetStates(G4State_Idle)
0107     .SetRange("nl>0");
0108 
0109   fDetectorMessenger
0110     ->DeclareMethod("verbose", &GB03DetectorConstruction::SetVerboseLevel, "Set verbosity level.")
0111     .SetParameterName("verbose", false)
0112     .SetStates(G4State_Idle)
0113     .SetRange("verbose>=0");
0114 }
0115 
0116 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0117 
0118 GB03DetectorConstruction::~GB03DetectorConstruction()
0119 {
0120   delete fDetectorMessenger;
0121 }
0122 
0123 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0124 
0125 G4VPhysicalVolume* GB03DetectorConstruction::Construct()
0126 {
0127   if (!fConstructed) {
0128     fConstructed = true;
0129     SetupGeometry();
0130   }
0131   if (GetVerboseLevel() > 0) {
0132     PrintCalorParameters();
0133   }
0134 
0135   return fWorldPhysical;
0136 }
0137 
0138 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0139 
0140 void GB03DetectorConstruction::ConstructSDandField()
0141 {
0142   if (!fConstructedSDandField) {
0143     fConstructedSDandField = true;
0144     SetupDetectors();
0145     if (fBiasingFlag) {
0146       SetupBiasing();
0147     }
0148   }
0149 }
0150 
0151 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0152 
0153 void GB03DetectorConstruction::DefineMaterials()
0154 {
0155   G4String name, symbol;  // a=mass of a mole;
0156   G4double a, z, density;  // z=mean number of protons;
0157   G4int iz;  // iz=number of protons  in an isotope;
0158   G4int n;  // n=number of nucleons in an isotope;
0159 
0160   G4int ncomponents, natoms;
0161   G4double abundance, fractionmass;
0162   G4double temperature, pressure;
0163 
0164   //
0165   // define Elements
0166   //
0167 
0168   a = 1.01 * g / mole;
0169   auto H = new G4Element(name = "Hydrogen", symbol = "H", z = 1., a);
0170 
0171   a = 12.01 * g / mole;
0172   auto C = new G4Element(name = "Carbon", symbol = "C", z = 6., a);
0173 
0174   a = 14.01 * g / mole;
0175   auto N = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a);
0176 
0177   a = 16.00 * g / mole;
0178   auto O = new G4Element(name = "Oxygen", symbol = "O", z = 8., a);
0179 
0180   //
0181   // define an Element from isotopes, by relative abundance
0182   //
0183 
0184   auto U5 = new G4Isotope(name = "U235", iz = 92, n = 235, a = 235.01 * g / mole);
0185   auto U8 = new G4Isotope(name = "U238", iz = 92, n = 238, a = 238.03 * g / mole);
0186 
0187   auto U = new G4Element(name = "enriched Uranium", symbol = "U", ncomponents = 2);
0188   U->AddIsotope(U5, abundance = 90. * perCent);
0189   U->AddIsotope(U8, abundance = 10. * perCent);
0190 
0191   //
0192   // define simple materials
0193   //
0194 
0195   new G4Material(name = "Aluminium", z = 13., a = 26.98 * g / mole, density = 2.700 * g / cm3);
0196   new G4Material(name = "Silicon", z = 14., a = 28.09 * g / mole, density = 2.33 * g / cm3);
0197   new G4Material(name = "Iron", z = 26., a = 55.85 * g / mole, density = 7.87 * g / cm3);
0198   new G4Material(name = "ArgonGas", z = 18., a = 39.95 * g / mole, density = 1.782 * mg / cm3);
0199   new G4Material(name = "He", z = 2., a = 4.0 * g / mole, density = 0.1786e-03 * g / cm3);
0200 
0201   density = 1.390 * g / cm3;
0202   a = 39.95 * g / mole;
0203   new G4Material(name = "liquidArgon", z = 18., a, density);
0204 
0205   density = 11.35 * g / cm3;
0206   a = 207.19 * g / mole;
0207   auto Pb = new G4Material(name = "Lead", z = 82., a, density);
0208 
0209   //
0210   // define a material from elements.   case 1: chemical molecule
0211   //
0212 
0213   density = 1.000 * g / cm3;
0214   auto H2O = new G4Material(name = "Water", density, ncomponents = 2);
0215   H2O->AddElement(H, natoms = 2);
0216   H2O->AddElement(O, natoms = 1);
0217 
0218   density = 1.032 * g / cm3;
0219   auto Sci = new G4Material(name = "Scintillator", density, ncomponents = 2);
0220   Sci->AddElement(C, natoms = 9);
0221   Sci->AddElement(H, natoms = 10);
0222 
0223   //
0224   // define a material from elements.   case 2: mixture by fractional mass
0225   //
0226 
0227   density = 1.290 * mg / cm3;
0228   auto Air = new G4Material(name = "Air", density, ncomponents = 2);
0229   Air->AddElement(N, fractionmass = 0.7);
0230   Air->AddElement(O, fractionmass = 0.3);
0231 
0232   //
0233   // examples of vacuum
0234   //
0235 
0236   density = universe_mean_density;
0237   pressure = 3.e-18 * pascal;
0238   temperature = 2.73 * kelvin;
0239   auto Vacuum = new G4Material(name = "Galactic", z = 1., a = 1.01 * g / mole, density, kStateGas,
0240                                temperature, pressure);
0241 
0242   if (GetVerboseLevel() > 1) {
0243     G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0244   }
0245 
0246   // default materials of the calorimeter
0247   fWorldMaterial = Vacuum;
0248   fAbsorberMaterial = Pb;
0249   fGapMaterial = Sci;
0250   fHodoMaterial = Sci;
0251 }
0252 
0253 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0254 
0255 void GB03DetectorConstruction::SetupGeometry()
0256 {
0257   //
0258   // World
0259   //
0260   G4VSolid* worldSolid = new G4Box("World", 2. * m, 2. * m, fTotalThickness * 2.);
0261   auto* WorldLogical = new G4LogicalVolume(worldSolid, fWorldMaterial, "World");
0262   fWorldPhysical =
0263     new G4PVPlacement(nullptr, G4ThreeVector(), WorldLogical, "World", nullptr, false, 0);
0264 
0265   //
0266   // Calorimeter
0267   //
0268   G4VSolid* calorSolid = new G4Box("Calor", 0.5 * m, 0.5 * m, fTotalThickness / 2.);
0269   fCalorLogical = new G4LogicalVolume(calorSolid, fAbsorberMaterial, fCalName);
0270   new G4PVPlacement(nullptr, G4ThreeVector(0., 0., 0.), fCalorLogical, fCalName, WorldLogical,
0271                     false, 0);
0272 
0273   //
0274   // Layers --- as absorbers
0275   //
0276   fLayerSolid = new G4Box("Layer", 0.5 * m, 0.5 * m, fLayerThickness / 2.);
0277   fLayerLogical = new G4LogicalVolume(fLayerSolid, fAbsorberMaterial, fCalName + "_LayerLog");
0278   fLayerPhysical = new G4PVReplica(fCalName + "_Layer", fLayerLogical, fCalorLogical, kZAxis,
0279                                    fNumberOfLayers, fLayerThickness);
0280 
0281   //
0282   // Gap
0283   //
0284   fGapSolid = new G4Box("Gap", 0.5 * m, 0.5 * m, fLayerThickness / 4.);
0285   fGapLogical = new G4LogicalVolume(fGapSolid, fGapMaterial, fCalName + "_Gap");
0286   fGapPhysical = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fLayerThickness / 4.),
0287                                    fGapLogical, fCalName + "_gap", fLayerLogical, false, 0);
0288 
0289   //
0290   // Hodoscope plane
0291   //
0292   G4VSolid* measSolid = new G4Box("Hodo", 0.5 * m, 0.5 * m, 5 * cm);
0293   fHodoLogical = new G4LogicalVolume(measSolid, fHodoMaterial, "Hodo_l");
0294   new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fTotalThickness / 2. + 5 * cm), fHodoLogical,
0295                     "Hodo_p", WorldLogical, false, 0);
0296   //
0297   // Visualization attributes
0298   //
0299   WorldLogical->SetVisAttributes(G4VisAttributes::GetInvisible());
0300   auto simpleBoxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0301   auto GapBoxVisAtt = new G4VisAttributes(G4Colour::Blue());
0302   // auto LayerBoxVisAtt = new G4VisAttributes(G4Colour::Green());
0303   auto HodoBoxVisAtt = new G4VisAttributes(G4Colour::Red());
0304   simpleBoxVisAtt->SetVisibility(true);
0305   fCalorLogical->SetVisAttributes(simpleBoxVisAtt);
0306   fLayerLogical->SetVisAttributes(simpleBoxVisAtt);
0307   fGapLogical->SetVisAttributes(GapBoxVisAtt);
0308   fHodoLogical->SetVisAttributes(HodoBoxVisAtt);
0309 }
0310 
0311 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0312 
0313 void GB03DetectorConstruction::SetupDetectors()
0314 {
0315   // ---------------------------------------------------------------------------------
0316   // -- Attach sensitive detector to print information on particle exiting the shield:
0317   // ---------------------------------------------------------------------------------
0318   // -- create and register sensitive detector code module:
0319   G4SDManager* SDman = G4SDManager::GetSDMpointer();
0320   G4VSensitiveDetector* sd = new GB03HodoSD("HodoSD");
0321   SDman->AddNewDetector(sd);
0322   // -- Fetch volume for sensitivity and attach sensitive module to it:
0323   fHodoLogical->SetSensitiveDetector(sd);
0324 }
0325 
0326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0327 
0328 void GB03DetectorConstruction::SetupBiasing()
0329 {
0330   auto biasingOperator = new GB03BOptrGeometryBasedBiasing();
0331   biasingOperator->AttachTo(fLayerLogical);
0332 }
0333 
0334 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0335 
0336 void GB03DetectorConstruction::PrintCalorParameters() const
0337 {
0338   G4cout << "--------------------------------------------------------" << G4endl;
0339   G4cout << " Absorber is made of " << fAbsorberMaterial->GetName() << G4endl << " Gap is made of "
0340          << fGapMaterial->GetName() << G4endl
0341          << "--------------------------------------------------------" << G4endl;
0342 }
0343 
0344 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0345 
0346 void GB03DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
0347 {
0348   // search the material by its name
0349   G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
0350   if (pttoMaterial) {
0351     fAbsorberMaterial = pttoMaterial;
0352     if (fConstructed) {
0353       fCalorLogical->SetMaterial(fAbsorberMaterial);
0354       fLayerLogical->SetMaterial(fAbsorberMaterial);
0355     }
0356     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0357     if (GetVerboseLevel() > 1) {
0358       PrintCalorParameters();
0359     }
0360   }
0361   else {
0362     G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl;
0363   }
0364 }
0365 
0366 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0367 
0368 G4String GB03DetectorConstruction::GetAbsorberMaterial() const
0369 {
0370   return fAbsorberMaterial->GetName();
0371 }
0372 
0373 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0374 
0375 void GB03DetectorConstruction::SetGapMaterial(G4String materialChoice)
0376 {
0377   // search the material by its name
0378   G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
0379   if (pttoMaterial) {
0380     fGapMaterial = pttoMaterial;
0381     if (fConstructed) {
0382       fGapLogical->SetMaterial(fGapMaterial);
0383     }
0384     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0385     if (GetVerboseLevel() > 1) {
0386       PrintCalorParameters();
0387     }
0388   }
0389   else {
0390     G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl;
0391   }
0392 }
0393 
0394 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0395 
0396 G4String GB03DetectorConstruction::GetGapMaterial() const
0397 {
0398   return fGapMaterial->GetName();
0399 }
0400 
0401 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0402 
0403 void GB03DetectorConstruction::SetNumberOfLayers(G4int nl)
0404 {
0405   fNumberOfLayers = nl;
0406   fLayerThickness = fTotalThickness / fNumberOfLayers;
0407   if (!fConstructed) return;
0408 
0409   fLayerSolid->SetZHalfLength(fLayerThickness / 2.);
0410   fGapSolid->SetZHalfLength(fLayerThickness / 4.);
0411 
0412   fCalorLogical->RemoveDaughter(fLayerPhysical);
0413   delete fLayerPhysical;
0414   fLayerPhysical = new G4PVReplica(fCalName + "_Layer", fLayerLogical, fCalorLogical, kZAxis,
0415                                    fNumberOfLayers, fLayerThickness);
0416   fGapPhysical->SetTranslation(G4ThreeVector(0., 0., fLayerThickness / 4.));
0417 
0418   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0419 }
0420 
0421 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......