Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:20:45

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