Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-18 08:28:57

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 ExGflashDetectorConstruction.cc
0028 /// \brief Implementation of the ExGflashDetectorConstruction class
0029 //
0030 
0031 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0032 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0033 
0034 // User Classes
0035 #include "ExGflashDetectorConstruction.hh"
0036 
0037 #include "ExGflashHomoShowerTuning.hh"
0038 #include "ExGflashMessenger.hh"
0039 #include "ExGflashSensitiveDetector.hh"
0040 
0041 // G4 Classes
0042 #include "G4AutoDelete.hh"
0043 #include "G4Box.hh"
0044 #include "G4Colour.hh"
0045 #include "G4LogicalVolume.hh"
0046 #include "G4Material.hh"
0047 #include "G4NistManager.hh"
0048 #include "G4PVPlacement.hh"
0049 #include "G4RunManager.hh"
0050 #include "G4SDManager.hh"
0051 #include "G4SystemOfUnits.hh"
0052 #include "G4ThreeVector.hh"
0053 #include "G4VPhysicalVolume.hh"
0054 #include "G4VisAttributes.hh"
0055 #include "globals.hh"
0056 
0057 // fast simulation
0058 #include "GFlashHitMaker.hh"
0059 #include "GFlashHomoShowerParameterisation.hh"
0060 #include "GFlashParticleBounds.hh"
0061 #include "GFlashShowerModel.hh"
0062 
0063 #include "G4FastSimulationManager.hh"
0064 
0065 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0066 
0067 const G4int kMaxBin = 500;
0068 
0069 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0070 
0071 ExGflashDetectorConstruction::ExGflashDetectorConstruction()
0072 {
0073   if (fVerbose > 3) G4cout << "ExGflashDetectorConstruction::Detector constructor" << G4endl;
0074   fGflashMessenger = new ExGflashMessenger(this);
0075 
0076   // Crystall
0077   fCrystalWidth = 3 * cm;
0078   fCrystalLength = 140 * cm;
0079 
0080   DefineMaterials();
0081   SetMaterial("G4_PbWO4");
0082 }
0083 
0084 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0085 
0086 ExGflashDetectorConstruction::~ExGflashDetectorConstruction()
0087 {
0088   delete fGflashMessenger;
0089   delete fFastShowerModel;
0090   delete fParameterisation;
0091   delete fParticleBounds;
0092   delete fHitMaker;
0093 }
0094 
0095 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0096 
0097 void ExGflashDetectorConstruction::DefineMaterials()
0098 {
0099   if (fVerbose > 3) G4cout << "Defining the materials" << G4endl;
0100   // Get nist material manager
0101   G4NistManager* nistManager = G4NistManager::Instance();
0102   // Build materials
0103   fHallMat = nistManager->FindOrBuildMaterial("G4_AIR");
0104   fDetMat = nistManager->FindOrBuildMaterial("G4_PbWO4");
0105   nistManager->FindOrBuildMaterial("G4_CESIUM_IODIDE");
0106 }
0107 
0108 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0109 
0110 G4VPhysicalVolume* ExGflashDetectorConstruction::Construct()
0111 {
0112   //--------- Definitions of Solids, Logical Volumes, Physical Volumes ---------
0113 
0114   //------------------------------
0115   // Calorimeter segments
0116   //------------------------------
0117   // Simplified `CMS-like` PbWO4 crystal calorimeter
0118 
0119   // Calorimeter
0120   G4double calo_xside = (fCrystalWidth * fNbOfCrystals);
0121   G4double calo_yside = (fCrystalWidth * fNbOfCrystals);
0122   G4double calo_zside = fCrystalLength;
0123 
0124   // The Experimental Hall
0125   G4double experimentalHall_x = calo_xside * 4;
0126   G4double experimentalHall_y = calo_yside * 4;
0127   G4double experimentalHall_z = calo_zside * 4;
0128 
0129   G4VSolid* experimentalHall_box = new G4Box("expHall_box",  // World Volume
0130                                              experimentalHall_x,  // x size
0131                                              experimentalHall_y,  // y size
0132                                              experimentalHall_z);  // z size
0133 
0134   auto experimentalHall_log = new G4LogicalVolume(experimentalHall_box, fHallMat, "expHall_log",
0135                                                   nullptr,  // opt: fieldManager
0136                                                   nullptr,  // opt: SensitiveDetector
0137                                                   nullptr);  // opt: UserLimits
0138   G4VPhysicalVolume* experimentalHall_phys =
0139     new G4PVPlacement(nullptr,
0140                       G4ThreeVector(),  // at (0,0,0)
0141                       "expHall", experimentalHall_log, nullptr, false, 0);
0142 
0143   auto calo_box = new G4Box("Calorimeter",  // its name
0144                             calo_xside / 2.,  // size
0145                             calo_yside / 2., calo_zside / 2.);
0146   auto calo_log = new G4LogicalVolume(calo_box,  // its solid
0147                                       fHallMat,  // its material
0148                                       "calo_log",  // its name
0149                                       nullptr,  // opt: fieldManager
0150                                       nullptr,  // opt: SensitiveDetector
0151                                       nullptr);  // opt: UserLimit
0152 
0153   G4double xpos = 0.0;
0154   G4double ypos = 0.0;
0155   G4double zpos = calo_zside / 2.;  // face @ z= 0.0
0156 
0157   new G4PVPlacement(nullptr, G4ThreeVector(xpos, ypos, zpos), calo_log, "calorimeter",
0158                     experimentalHall_log, false, 1);
0159 
0160   // Crystals
0161   G4VSolid* crystal_box = new G4Box("Crystal",  // its name
0162                                     fCrystalWidth / 2, fCrystalWidth / 2, fCrystalLength / 2);
0163   // size
0164   fCrystal_log = new G4LogicalVolume(crystal_box,  // its solid
0165                                      fDetMat,  // its material
0166                                      "Crystal_log");  // its name
0167 
0168   for (G4int i = 0; i < fNbOfCrystals; i++) {
0169     for (G4int j = 0; j < fNbOfCrystals; j++) {
0170       G4int n = i * 10 + j;
0171       G4ThreeVector crystalPos((i * fCrystalWidth) - (calo_xside - fCrystalWidth) / 2.,
0172                                (j * fCrystalWidth) - (calo_yside - fCrystalWidth) / 2., 0);
0173       new G4PVPlacement(nullptr,  // no rotation
0174                         crystalPos,  // translation
0175                         fCrystal_log,
0176                         "crystal",  // its name
0177                         calo_log, false, n);
0178     }
0179   }
0180   G4cout << "There are " << fNbOfCrystals << " crystals per row in the calorimeter, so in total "
0181          << fNbOfCrystals * fNbOfCrystals << " crystals" << G4endl;
0182   G4cout << "They have width of  " << fCrystalWidth / cm << "  cm and a length of  "
0183          << fCrystalLength / cm << " cm." << G4endl;
0184   G4cout << fDetMat << G4endl;
0185   G4cout << "Total Calorimeter size " << calo_xside / cm << " cm x " << calo_yside / cm << " cm x "
0186          << calo_zside / cm << " cm" << G4endl;
0187 
0188   experimentalHall_log->SetVisAttributes(G4VisAttributes::GetInvisible());
0189   auto caloVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0190   auto crystalVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 0.0));
0191   calo_log->SetVisAttributes(caloVisAtt);
0192   fCrystal_log->SetVisAttributes(crystalVisAtt);
0193 
0194   // define the fParameterisation region
0195   //  G4cout << "\n ---> DetectorConstruction Region Definition" << G4endl;
0196   fRegion = new G4Region("crystals");
0197   calo_log->SetRegion(fRegion);
0198   fRegion->AddRootLogicalVolume(calo_log);
0199 
0200   return experimentalHall_phys;
0201 }
0202 
0203 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0204 
0205 void ExGflashDetectorConstruction::ConstructSDandField()
0206 {
0207   // -- fast simulation models:
0208   // **********************************************
0209   // * Initializing shower modell
0210   // ***********************************************
0211   if (fParameterisation != nullptr) {
0212     fParameterisation->SetMaterial(fDetMat);
0213     if (fVerbose > 3) G4cout << "Info " << __func__ << " Param Mat " << fDetMat << G4endl;
0214     fParameterisation->PrintMaterial(fDetMat);
0215   }
0216   else {
0217     // -- sensitive detectors:
0218 
0219     G4SDManager* SDman = G4SDManager::GetSDMpointer();
0220 
0221     auto SD = new ExGflashSensitiveDetector("Calorimeter", this);
0222 
0223     SDman->AddNewDetector(SD);
0224     if (fCrystal_log != nullptr) {
0225       fCrystal_log->SetSensitiveDetector(SD);
0226     }
0227 
0228     if (fVerbose > 3) G4cout << "\n--> Creating shower parameterization models" << G4endl;
0229     fFastShowerModel = new GFlashShowerModel("fFastShowerModel", fRegion);
0230     fParameterisation =
0231       new GFlashHomoShowerParameterisation(fDetMat, new ExGflashHomoShowerTuning());
0232     fFastShowerModel->SetParameterisation(*fParameterisation);
0233     // Energy Cuts to kill particles:
0234     fParticleBounds = new GFlashParticleBounds();
0235     fFastShowerModel->SetParticleBounds(*fParticleBounds);
0236     // Makes the EnergieSpots
0237     fHitMaker = new GFlashHitMaker();
0238     fFastShowerModel->SetHitMaker(*fHitMaker);
0239     if (fVerbose > 3) G4cout << "end shower parameterization." << G4endl;
0240   }
0241   // **********************************************
0242   // Get Rad Len and R moliere from parameterisation
0243   fSDRadLen = fParameterisation->GetX0();
0244   fSDRm = fParameterisation->GetRm();
0245   if (fVerbose > 2) {
0246     G4cout << "Info " << __func__ << "Total Calorimeter size" << G4endl;
0247     auto calo_xyside = fCrystalWidth * fNbOfCrystals;
0248     G4cout << "Info Z " << __func__ << " " << fCrystalLength / cm << " cm "
0249            << fCrystalLength / fSDRadLen << " RadLen " << G4endl;
0250     G4cout << "Info XY " << __func__ << " " << calo_xyside / cm << " cm " << calo_xyside / fSDRm
0251            << " Rm " << G4endl;
0252   }
0253 }
0254 
0255 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0256 
0257 void ExGflashDetectorConstruction::SetLBining(G4ThreeVector Value)
0258 {
0259   fNLtot = (G4int)Value(0);
0260   if (fNLtot > kMaxBin) {
0261     G4cout << "\n ---> warning from SetLBining: " << fNLtot << " truncated to " << kMaxBin
0262            << G4endl;
0263     fNLtot = kMaxBin;
0264   }
0265   fDLradl = Value(1);
0266 }
0267 
0268 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0269 
0270 void ExGflashDetectorConstruction::SetRBining(G4ThreeVector Value)
0271 {
0272   fNRtot = (G4int)Value(0);
0273   if (fNRtot > kMaxBin) {
0274     G4cout << "\n ---> warning from SetRBining: " << fNRtot << " truncated to " << kMaxBin
0275            << G4endl;
0276     fNRtot = kMaxBin;
0277   }
0278   fDRradl = Value(1);
0279 }
0280 
0281 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0282 
0283 void ExGflashDetectorConstruction::SetMaterial(G4String mat)
0284 {
0285   // search the material by its name
0286   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(mat);
0287 
0288   if (pttoMaterial != nullptr && fDetMat != pttoMaterial) {
0289     fDetMat = pttoMaterial;
0290     if (fCrystal_log != nullptr) {
0291       fCrystal_log->SetMaterial(fDetMat);
0292     }
0293     G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0294   }
0295 }
0296 
0297 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......