File indexing completed on 2025-10-18 08:28:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #include "ExGflashDetectorConstruction.hh"
0036
0037 #include "ExGflashHomoShowerTuning.hh"
0038 #include "ExGflashMessenger.hh"
0039 #include "ExGflashSensitiveDetector.hh"
0040
0041
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
0058 #include "GFlashHitMaker.hh"
0059 #include "GFlashHomoShowerParameterisation.hh"
0060 #include "GFlashParticleBounds.hh"
0061 #include "GFlashShowerModel.hh"
0062
0063 #include "G4FastSimulationManager.hh"
0064
0065
0066
0067 const G4int kMaxBin = 500;
0068
0069
0070
0071 ExGflashDetectorConstruction::ExGflashDetectorConstruction()
0072 {
0073 if (fVerbose > 3) G4cout << "ExGflashDetectorConstruction::Detector constructor" << G4endl;
0074 fGflashMessenger = new ExGflashMessenger(this);
0075
0076
0077 fCrystalWidth = 3 * cm;
0078 fCrystalLength = 140 * cm;
0079
0080 DefineMaterials();
0081 SetMaterial("G4_PbWO4");
0082 }
0083
0084
0085
0086 ExGflashDetectorConstruction::~ExGflashDetectorConstruction()
0087 {
0088 delete fGflashMessenger;
0089 delete fFastShowerModel;
0090 delete fParameterisation;
0091 delete fParticleBounds;
0092 delete fHitMaker;
0093 }
0094
0095
0096
0097 void ExGflashDetectorConstruction::DefineMaterials()
0098 {
0099 if (fVerbose > 3) G4cout << "Defining the materials" << G4endl;
0100
0101 G4NistManager* nistManager = G4NistManager::Instance();
0102
0103 fHallMat = nistManager->FindOrBuildMaterial("G4_AIR");
0104 fDetMat = nistManager->FindOrBuildMaterial("G4_PbWO4");
0105 nistManager->FindOrBuildMaterial("G4_CESIUM_IODIDE");
0106 }
0107
0108
0109
0110 G4VPhysicalVolume* ExGflashDetectorConstruction::Construct()
0111 {
0112
0113
0114
0115
0116
0117
0118
0119
0120 G4double calo_xside = (fCrystalWidth * fNbOfCrystals);
0121 G4double calo_yside = (fCrystalWidth * fNbOfCrystals);
0122 G4double calo_zside = fCrystalLength;
0123
0124
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",
0130 experimentalHall_x,
0131 experimentalHall_y,
0132 experimentalHall_z);
0133
0134 auto experimentalHall_log = new G4LogicalVolume(experimentalHall_box, fHallMat, "expHall_log",
0135 nullptr,
0136 nullptr,
0137 nullptr);
0138 G4VPhysicalVolume* experimentalHall_phys =
0139 new G4PVPlacement(nullptr,
0140 G4ThreeVector(),
0141 "expHall", experimentalHall_log, nullptr, false, 0);
0142
0143 auto calo_box = new G4Box("Calorimeter",
0144 calo_xside / 2.,
0145 calo_yside / 2., calo_zside / 2.);
0146 auto calo_log = new G4LogicalVolume(calo_box,
0147 fHallMat,
0148 "calo_log",
0149 nullptr,
0150 nullptr,
0151 nullptr);
0152
0153 G4double xpos = 0.0;
0154 G4double ypos = 0.0;
0155 G4double zpos = calo_zside / 2.;
0156
0157 new G4PVPlacement(nullptr, G4ThreeVector(xpos, ypos, zpos), calo_log, "calorimeter",
0158 experimentalHall_log, false, 1);
0159
0160
0161 G4VSolid* crystal_box = new G4Box("Crystal",
0162 fCrystalWidth / 2, fCrystalWidth / 2, fCrystalLength / 2);
0163
0164 fCrystal_log = new G4LogicalVolume(crystal_box,
0165 fDetMat,
0166 "Crystal_log");
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,
0174 crystalPos,
0175 fCrystal_log,
0176 "crystal",
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
0195
0196 fRegion = new G4Region("crystals");
0197 calo_log->SetRegion(fRegion);
0198 fRegion->AddRootLogicalVolume(calo_log);
0199
0200 return experimentalHall_phys;
0201 }
0202
0203
0204
0205 void ExGflashDetectorConstruction::ConstructSDandField()
0206 {
0207
0208
0209
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
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
0234 fParticleBounds = new GFlashParticleBounds();
0235 fFastShowerModel->SetParticleBounds(*fParticleBounds);
0236
0237 fHitMaker = new GFlashHitMaker();
0238 fFastShowerModel->SetHitMaker(*fHitMaker);
0239 if (fVerbose > 3) G4cout << "end shower parameterization." << G4endl;
0240 }
0241
0242
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
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
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
0282
0283 void ExGflashDetectorConstruction::SetMaterial(G4String mat)
0284 {
0285
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