Back to home page

EIC code displayed by LXR

 
 

    


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

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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0030 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0031 
0032 #include "DetectorConstruction.hh"
0033 
0034 #include "DetectorMessenger.hh"
0035 
0036 #include "G4Box.hh"
0037 #include "G4Colour.hh"
0038 #include "G4GeometryManager.hh"
0039 #include "G4LogicalVolume.hh"
0040 #include "G4LogicalVolumeStore.hh"
0041 #include "G4Material.hh"
0042 #include "G4NistManager.hh"
0043 #include "G4PVPlacement.hh"
0044 #include "G4PVReplica.hh"
0045 #include "G4PhysicalVolumeStore.hh"
0046 #include "G4RunManager.hh"
0047 #include "G4SolidStore.hh"
0048 #include "G4StateManager.hh"
0049 #include "G4SystemOfUnits.hh"
0050 #include "G4VisAttributes.hh"
0051 
0052 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0053 
0054 DetectorConstruction::DetectorConstruction()
0055 {
0056   ComputeCalorParameters();
0057 
0058   // materials
0059   DefineMaterials();
0060   SetAbsorberMaterial("G4_Pb");
0061   SetGapMaterial("G4_lAr");
0062 
0063   // create commands for interactive definition of the calorimeter
0064   fDetectorMessenger = new DetectorMessenger(this);
0065 }
0066 
0067 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0068 
0069 DetectorConstruction::~DetectorConstruction()
0070 {
0071   delete fDetectorMessenger;
0072 }
0073 
0074 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0075 
0076 G4VPhysicalVolume* DetectorConstruction::Construct()
0077 {
0078   return ConstructCalorimeter();
0079 }
0080 
0081 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0082 
0083 void DetectorConstruction::DefineMaterials()
0084 {
0085   // use G4-NIST materials data base
0086   //
0087   G4NistManager* man = G4NistManager::Instance();
0088   fDefaultMaterial = man->FindOrBuildMaterial("G4_Galactic");
0089   man->FindOrBuildMaterial("G4_Pb");
0090   man->FindOrBuildMaterial("G4_lAr");
0091 
0092   // print table
0093   //
0094   G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0095 }
0096 
0097 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0098 
0099 G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter()
0100 {
0101   // Clean old geometry, if any
0102   //
0103   G4GeometryManager::GetInstance()->OpenGeometry();
0104   G4PhysicalVolumeStore::GetInstance()->Clean();
0105   G4LogicalVolumeStore::GetInstance()->Clean();
0106   G4SolidStore::GetInstance()->Clean();
0107 
0108   // complete the Calor parameters definition
0109   ComputeCalorParameters();
0110 
0111   //
0112   // World
0113   //
0114   fSolidWorld = new G4Box("World",  // its name
0115                           fWorldSizeX / 2, fWorldSizeYZ / 2, fWorldSizeYZ / 2);  // its size
0116 
0117   fLogicWorld = new G4LogicalVolume(fSolidWorld,  // its solid
0118                                     fDefaultMaterial,  // its material
0119                                     "World");  // its name
0120 
0121   fPhysiWorld = new G4PVPlacement(nullptr,  // no rotation
0122                                   G4ThreeVector(),  // at (0,0,0)
0123                                   fLogicWorld,  // its logical volume
0124                                   "World",  // its name
0125                                   nullptr,  // its mother  volume
0126                                   false,  // no boolean operation
0127                                   0);  // copy number
0128 
0129   //
0130   // Calorimeter
0131   //
0132   fSolidCalor = nullptr;
0133   fLogicCalor = nullptr;
0134   fPhysiCalor = nullptr;
0135   fSolidLayer = nullptr;
0136   fLogicLayer = nullptr;
0137   fPhysiLayer = nullptr;
0138 
0139   if (fCalorThickness > 0.) {
0140     fSolidCalor = new G4Box("Calorimeter",  // its name
0141                             fCalorThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2);  // size
0142 
0143     fLogicCalor = new G4LogicalVolume(fSolidCalor,  // its solid
0144                                       fDefaultMaterial,  // its material
0145                                       "Calorimeter");  // its name
0146 
0147     fPhysiCalor = new G4PVPlacement(nullptr,  // no rotation
0148                                     G4ThreeVector(),  // at (0,0,0)
0149                                     fLogicCalor,  // its logical volume
0150                                     "Calorimeter",  // its name
0151                                     fLogicWorld,  // its mother  volume
0152                                     false,  // no boolean operation
0153                                     0);  // copy number
0154 
0155     //
0156     // Layer
0157     //
0158     fSolidLayer = new G4Box("Layer",  // its name
0159                             fLayerThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2);  // size
0160 
0161     fLogicLayer = new G4LogicalVolume(fSolidLayer,  // its solid
0162                                       fDefaultMaterial,  // its material
0163                                       "Layer");  // its name
0164     if (fNbOfLayers > 1) {
0165       fPhysiLayer = new G4PVReplica("Layer",  // its name
0166                                     fLogicLayer,  // its logical volume
0167                                     fLogicCalor,  // its mother
0168                                     kXAxis,  // axis of replication
0169                                     fNbOfLayers,  // number of replica
0170                                     fLayerThickness);  // witdth of replica
0171     }
0172     else {
0173       fPhysiLayer = new G4PVPlacement(nullptr,  // no rotation
0174                                       G4ThreeVector(),  // at (0,0,0)
0175                                       fLogicLayer,  // its logical volume
0176                                       "Layer",  // its name
0177                                       fLogicCalor,  // its mother  volume
0178                                       false,  // no boolean operation
0179                                       0);  // copy number
0180     }
0181   }
0182 
0183   //
0184   // Absorber
0185   //
0186   fSolidAbsorber = nullptr;
0187   fLogicAbsorber = nullptr;
0188   fPhysiAbsorber = nullptr;
0189 
0190   if (fAbsorberThickness > 0.) {
0191     fSolidAbsorber = new G4Box("Absorber",  // its name
0192                                fAbsorberThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2);  // size
0193 
0194     fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber,  // its solid
0195                                          fAbsorberMaterial,  // its material
0196                                          fAbsorberMaterial->GetName());  // name
0197 
0198     fPhysiAbsorber = new G4PVPlacement(nullptr,  // no rotation
0199                                        G4ThreeVector(-fGapThickness / 2, 0., 0.),  // its position
0200                                        fLogicAbsorber,  // its logical volume
0201                                        fAbsorberMaterial->GetName(),  // its name
0202                                        fLogicLayer,  // its mother
0203                                        false,  // no boulean operat
0204                                        0);  // copy number
0205   }
0206 
0207   //
0208   // Gap
0209   //
0210   fSolidGap = nullptr;
0211   fLogicGap = nullptr;
0212   fPhysiGap = nullptr;
0213 
0214   if (fGapThickness > 0.) {
0215     fSolidGap = new G4Box("Gap", fGapThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2);
0216 
0217     fLogicGap = new G4LogicalVolume(fSolidGap, fGapMaterial, fGapMaterial->GetName());
0218 
0219     fPhysiGap = new G4PVPlacement(nullptr,  // no rotation
0220                                   G4ThreeVector(fAbsorberThickness / 2, 0., 0.),  // its position
0221                                   fLogicGap,  // its logical volume
0222                                   fGapMaterial->GetName(),  // its name
0223                                   fLogicLayer,  // its mother
0224                                   false,  // no boulean operat
0225                                   0);  // copy number
0226   }
0227 
0228   PrintCalorParameters();
0229 
0230   //
0231   // Visualization attributes
0232   //
0233   fLogicWorld->SetVisAttributes(G4VisAttributes::GetInvisible());
0234 
0235   auto simpleBoxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0236   simpleBoxVisAtt->SetVisibility(true);
0237   fLogicCalor->SetVisAttributes(simpleBoxVisAtt);
0238 
0239   //
0240   // always return the physical World
0241   //
0242   return fPhysiWorld;
0243 }
0244 
0245 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0246 
0247 void DetectorConstruction::PrintCalorParameters()
0248 {
0249   G4cout << "\n------------------------------------------------------------"
0250          << "\n---> The calorimeter is " << fNbOfLayers << " layers of: [ "
0251          << fAbsorberThickness / mm << "mm of " << fAbsorberMaterial->GetName() << " + "
0252          << fGapThickness / mm << "mm of " << fGapMaterial->GetName() << " ] "
0253          << "\n------------------------------------------------------------\n";
0254 }
0255 
0256 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0257 
0258 void DetectorConstruction::SetAbsorberMaterial(const G4String& materialChoice)
0259 {
0260   // search the material by its name
0261   auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0262   if (material != nullptr) {
0263     fAbsorberMaterial = material;
0264     if (fLogicAbsorber != nullptr) {
0265       fLogicAbsorber->SetMaterial(fAbsorberMaterial);
0266       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0267     }
0268   }
0269 }
0270 
0271 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0272 
0273 void DetectorConstruction::SetGapMaterial(const G4String& materialChoice)
0274 {
0275   auto material = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0276   if (material != nullptr) {
0277     fGapMaterial = material;
0278     if (fLogicGap != nullptr) {
0279       fLogicGap->SetMaterial(fGapMaterial);
0280       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0281     }
0282   }
0283 }
0284 
0285 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0286 
0287 void DetectorConstruction::SetAbsorberThickness(G4double value)
0288 {
0289   // change Absorber thickness and recompute the calorimeter parameters
0290   fAbsorberThickness = value;
0291   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0292     G4RunManager::GetRunManager()->ReinitializeGeometry();
0293   }
0294 }
0295 
0296 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0297 
0298 void DetectorConstruction::SetGapThickness(G4double value)
0299 {
0300   // change Gap thickness and recompute the calorimeter parameters
0301   fGapThickness = value;
0302   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0303     G4RunManager::GetRunManager()->ReinitializeGeometry();
0304   }
0305 }
0306 
0307 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0308 
0309 void DetectorConstruction::SetCalorSizeYZ(G4double value)
0310 {
0311   // change the transverse size and recompute the calorimeter parameters
0312   fCalorSizeYZ = value;
0313   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0314     G4RunManager::GetRunManager()->ReinitializeGeometry();
0315   }
0316 }
0317 
0318 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0319 
0320 void DetectorConstruction::SetNbOfLayers(G4int value)
0321 {
0322   fNbOfLayers = value;
0323   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0324     G4RunManager::GetRunManager()->ReinitializeGeometry();
0325   }
0326 }
0327 
0328 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......