Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-08 07:52:56

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 "G4AutoDelete.hh"
0034 #include "G4Box.hh"
0035 #include "G4GeometryManager.hh"
0036 #include "G4GlobalMagFieldMessenger.hh"
0037 #include "G4LogicalVolume.hh"
0038 #include "G4LogicalVolumeStore.hh"
0039 #include "G4Material.hh"
0040 #include "G4NistManager.hh"
0041 #include "G4PVPlacement.hh"
0042 #include "G4PVReplica.hh"
0043 #include "G4PhysicalConstants.hh"
0044 #include "G4PhysicalVolumeStore.hh"
0045 #include "G4RunManager.hh"
0046 #include "G4SolidStore.hh"
0047 #include "G4SystemOfUnits.hh"
0048 #include "G4UImanager.hh"
0049 #include "G4UniformMagField.hh"
0050 #include "G4UnitsTable.hh"
0051 
0052 #include <iomanip>
0053 
0054 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0055 
0056 DetectorConstruction::DetectorConstruction()
0057 {
0058   // default parameter values of the absorbers
0059   fNbOfAbsor = 1;
0060   fAbsorThickness[0] = 0. * mm;  // dummy, for initialization
0061   fAbsorThickness[1] = 1. * mm;
0062   fAbsorSizeYZ = 1. * mm;
0063   for (G4int iAbs = 0; iAbs < kMaxAbsor; iAbs++) {
0064     fNbOfDivisions[iAbs] = 1;
0065   }
0066   ComputeParameters();
0067 
0068   // materials
0069   DefineMaterials();
0070   SetAbsorMaterial(1, "G4_Si");
0071 
0072   // create commands for interactive definition of the calorimeter
0073   fDetectorMessenger = new DetectorMessenger(this);
0074 }
0075 
0076 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0077 
0078 DetectorConstruction::~DetectorConstruction()
0079 {
0080   delete fDetectorMessenger;
0081 }
0082 
0083 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0084 
0085 G4VPhysicalVolume* DetectorConstruction::Construct()
0086 {
0087   return ConstructVolumes();
0088 }
0089 
0090 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0091 
0092 void DetectorConstruction::DefineMaterials()
0093 {
0094   G4NistManager* man = G4NistManager::Instance();
0095 
0096   man->FindOrBuildMaterial("G4_Al");
0097   man->FindOrBuildMaterial("G4_Si");
0098   man->FindOrBuildMaterial("G4_Fe");
0099   man->FindOrBuildMaterial("G4_Cu");
0100   man->FindOrBuildMaterial("G4_Ge");
0101   man->FindOrBuildMaterial("G4_Mo");
0102   man->FindOrBuildMaterial("G4_Ta");
0103   man->FindOrBuildMaterial("G4_W");
0104   man->FindOrBuildMaterial("G4_Au");
0105   man->FindOrBuildMaterial("G4_Pb");
0106   man->FindOrBuildMaterial("G4_PbWO4");
0107   man->FindOrBuildMaterial("G4_SODIUM_IODIDE");
0108 
0109   man->FindOrBuildMaterial("G4_AIR");
0110   man->FindOrBuildMaterial("G4_WATER");
0111 
0112   G4Element* H = man->FindOrBuildElement("H");
0113   G4Element* O = man->FindOrBuildElement("O");
0114 
0115   G4Material* H2O = new G4Material("Water", 1.000 * g / cm3, 2);
0116   H2O->AddElement(H, 2);
0117   H2O->AddElement(O, 1);
0118   H2O->GetIonisation()->SetMeanExcitationEnergy(78.0 * eV);
0119 
0120   G4double density = universe_mean_density;  // from PhysicalConstants.h
0121   G4double pressure = 3.e-18 * pascal;
0122   G4double temperature = 2.73 * kelvin;
0123   G4Material* Galactic =
0124     new G4Material("Galactic", 1., 1.008 * g / mole, density, kStateGas, temperature, pressure);
0125 
0126   fDefaultMaterial = Galactic;
0127 
0128   //  G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0129 }
0130 
0131 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0132 
0133 void DetectorConstruction::ComputeParameters()
0134 {
0135   // Compute total thickness of absorbers
0136   fAbsorSizeX = 0.;
0137   for (G4int iAbs = 1; iAbs <= fNbOfAbsor; iAbs++) {
0138     fAbsorSizeX += fAbsorThickness[iAbs];
0139   }
0140 }
0141 
0142 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0143 
0144 G4VPhysicalVolume* DetectorConstruction::ConstructVolumes()
0145 {
0146   // complete the Calor parameters definition
0147   ComputeParameters();
0148 
0149   // Cleanup old geometry
0150   G4GeometryManager::GetInstance()->OpenGeometry();
0151   G4PhysicalVolumeStore::GetInstance()->Clean();
0152   G4LogicalVolumeStore::GetInstance()->Clean();
0153   G4SolidStore::GetInstance()->Clean();
0154 
0155   //
0156   // World
0157   //
0158   G4Box* solidWorld = new G4Box("World",  // name
0159                                 fAbsorSizeX / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2);  // size
0160 
0161   G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld,  // solid
0162                                                     fDefaultMaterial,  // material
0163                                                     "World");  // name
0164 
0165   fPhysiWorld = new G4PVPlacement(0,  // no rotation
0166                                   G4ThreeVector(),  // at (0,0,0)
0167                                   logicWorld,  // logical volume
0168                                   "World",  // name
0169                                   0,  // mother volume
0170                                   false,  // no boolean operation
0171                                   0);  // copy number
0172 
0173   //
0174   // Absorbers
0175   //
0176   fXfront[0] = -0.5 * fAbsorSizeX;
0177   //
0178   for (G4int k = 1; k <= fNbOfAbsor; k++) {
0179     G4Material* material = fAbsorMaterial[k];
0180     G4String matname = material->GetName();
0181 
0182     G4Box* solidAbsor =
0183       new G4Box(matname, fAbsorThickness[k] / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2);
0184 
0185     G4LogicalVolume* logicAbsor = new G4LogicalVolume(solidAbsor,  // solid
0186                                                       material,  // material
0187                                                       matname);  // name
0188 
0189     fXfront[k] = fXfront[k - 1] + fAbsorThickness[k - 1];
0190     G4double xcenter = fXfront[k] + 0.5 * fAbsorThickness[k];
0191     G4ThreeVector position = G4ThreeVector(xcenter, 0., 0.);
0192 
0193     new G4PVPlacement(0,  // no rotation
0194                       position,  // position
0195                       logicAbsor,  // logical volume
0196                       matname,  // name
0197                       logicWorld,  // mother
0198                       false,  // no boulean operat
0199                       k);  // copy number
0200 
0201     // divisions, if any
0202     //
0203     G4double LayerThickness = fAbsorThickness[k] / fNbOfDivisions[k];
0204     G4Box* solidLayer = new G4Box(matname, LayerThickness / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2);
0205 
0206     G4LogicalVolume* logicLayer = new G4LogicalVolume(solidLayer,  // solid
0207                                                       material,  // material
0208                                                       matname);  // name
0209 
0210     new G4PVReplica(matname,  // name
0211                     logicLayer,  // logical volume
0212                     logicAbsor,  // mother
0213                     kXAxis,  // axis of replication
0214                     fNbOfDivisions[k],  // number of replica
0215                     LayerThickness);  // witdth of replica
0216   }
0217 
0218   PrintParameters();
0219 
0220   // always return the physical World
0221   //
0222   return fPhysiWorld;
0223 }
0224 
0225 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0226 
0227 void DetectorConstruction::PrintParameters()
0228 {
0229   G4cout << "\n-------------------------------------------------------------"
0230          << "\n ---> The Absorber is " << fNbOfAbsor << " layers of:";
0231   for (G4int i = 1; i <= fNbOfAbsor; i++) {
0232     G4cout << "\n \t" << std::setw(16) << fAbsorMaterial[i]->GetName() << ": " << std::setw(6)
0233            << G4BestUnit(fAbsorThickness[i], "Length") << "  divided in " << fNbOfDivisions[i]
0234            << " slices";
0235   }
0236   G4cout << "\n-------------------------------------------------------------\n" << G4endl;
0237 }
0238 
0239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0240 
0241 void DetectorConstruction::SetNbOfAbsor(G4int ival)
0242 {
0243   // set the number of Absorbers
0244   //
0245   if (ival < 1 || ival > (kMaxAbsor - 1)) {
0246     G4cout << "\n ---> warning from SetfNbOfAbsor: " << ival << " must be at least 1 and and most "
0247            << kMaxAbsor - 1 << ". Command refused" << G4endl;
0248     return;
0249   }
0250   fNbOfAbsor = ival;
0251   G4RunManager::GetRunManager()->ReinitializeGeometry();
0252 }
0253 
0254 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0255 
0256 void DetectorConstruction::SetAbsorMaterial(G4int iabs, const G4String& material)
0257 {
0258   // search the material by its name
0259   //
0260   if (iabs > fNbOfAbsor || iabs <= 0) {
0261     G4cout << "\n --->warning from SetfAbsorMaterial: absor number " << iabs
0262            << " out of range. Command refused" << G4endl;
0263     return;
0264   }
0265 
0266   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(material);
0267   if (pttoMaterial) {
0268     fAbsorMaterial[iabs] = pttoMaterial;
0269     G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0270     G4cout << "\n " << pttoMaterial << G4endl;
0271   }
0272 }
0273 
0274 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0275 
0276 void DetectorConstruction::SetAbsorThickness(G4int iabs, G4double val)
0277 {
0278   // change Absorber thickness
0279   //
0280   if (iabs > fNbOfAbsor || iabs <= 0) {
0281     G4cout << "\n --->warning from SetfAbsorThickness: absor number " << iabs
0282            << " out of range. Command refused" << G4endl;
0283     return;
0284   }
0285   if (val <= DBL_MIN) {
0286     G4cout << "\n --->warning from SetfAbsorThickness: thickness " << val
0287            << " out of range. Command refused" << G4endl;
0288     return;
0289   }
0290   fAbsorThickness[iabs] = val;
0291   G4RunManager::GetRunManager()->ReinitializeGeometry();
0292 }
0293 
0294 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0295 
0296 void DetectorConstruction::SetAbsorSizeYZ(G4double val)
0297 {
0298   // change the transverse size
0299   //
0300   if (val <= DBL_MIN) {
0301     G4cout << "\n --->warning from SetfAbsorSizeYZ: thickness " << val
0302            << " out of range. Command refused" << G4endl;
0303     return;
0304   }
0305   fAbsorSizeYZ = val;
0306   G4RunManager::GetRunManager()->ReinitializeGeometry();
0307 }
0308 
0309 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0310 
0311 void DetectorConstruction::SetNbOfDivisions(G4int iabs, G4int ival)
0312 {
0313   // set the number of divisions
0314   //
0315   if (iabs > fNbOfAbsor || iabs < 1) {
0316     G4cout << "\n --->warning from SetNbOfDivisions: absor number " << iabs
0317            << " out of range. Command refused" << G4endl;
0318     return;
0319   }
0320 
0321   if (ival < 1) {
0322     G4cout << "\n --->warning from SetNbOfDivisions: " << ival
0323            << " must be at least 1. Command refused" << G4endl;
0324     return;
0325   }
0326   fNbOfDivisions[iabs] = ival;
0327   G4RunManager::GetRunManager()->ReinitializeGeometry();
0328 }
0329 
0330 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0331 
0332 void DetectorConstruction::ConstructSDandField()
0333 {
0334   if (fFieldMessenger.Get() == 0) {
0335     // Create global magnetic field messenger.
0336     // Uniform magnetic field is then created automatically if
0337     // the field value is not zero.
0338     G4ThreeVector fieldValue = G4ThreeVector();
0339     G4GlobalMagFieldMessenger* msg = new G4GlobalMagFieldMessenger(fieldValue);
0340     // msg->SetVerboseLevel(1);
0341     G4AutoDelete::Register(msg);
0342     fFieldMessenger.Put(msg);
0343   }
0344 }
0345 
0346 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......