Back to home page

EIC code displayed by LXR

 
 

    


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

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