Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-17 07:42:01

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