File indexing completed on 2025-02-23 09:22:31
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 G4cout << "ExGflashDetectorConstruction::Detector constructor" << G4endl;
0074 fGflashMessenger = new ExGflashMessenger(this);
0075
0076
0077 fCrystalWidth = 3 * cm;
0078 fCrystalLength = 24 * cm;
0079 }
0080
0081
0082
0083 ExGflashDetectorConstruction::~ExGflashDetectorConstruction()
0084 {
0085 delete fGflashMessenger;
0086 delete fFastShowerModel;
0087 delete fParameterisation;
0088 delete fParticleBounds;
0089 delete fHitMaker;
0090 }
0091
0092
0093
0094 G4VPhysicalVolume* ExGflashDetectorConstruction::Construct()
0095 {
0096
0097 G4cout << "Defining the materials" << G4endl;
0098
0099 G4NistManager* nistManager = G4NistManager::Instance();
0100
0101 G4Material* air = nistManager->FindOrBuildMaterial("G4_AIR");
0102 G4Material* pbWO4 = nistManager->FindOrBuildMaterial("G4_PbWO4");
0103
0104 fDetMat = pbWO4;
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 G4double calo_xside = (fCrystalWidth * fNbOfCrystals);
0115 G4double calo_yside = (fCrystalWidth * fNbOfCrystals);
0116 G4double calo_zside = fCrystalLength;
0117
0118
0119 G4double experimentalHall_x = calo_xside * 4;
0120 G4double experimentalHall_y = calo_yside * 4;
0121 G4double experimentalHall_z = calo_zside * 4;
0122
0123 G4VSolid* experimentalHall_box = new G4Box("expHall_box",
0124 experimentalHall_x,
0125 experimentalHall_y,
0126 experimentalHall_z);
0127
0128 auto experimentalHall_log = new G4LogicalVolume(experimentalHall_box, air, "expHall_log",
0129 nullptr,
0130 nullptr,
0131 nullptr);
0132 G4VPhysicalVolume* experimentalHall_phys =
0133 new G4PVPlacement(nullptr,
0134 G4ThreeVector(),
0135 "expHall", experimentalHall_log, nullptr, false, 0);
0136
0137 auto calo_box = new G4Box("Calorimeter",
0138 calo_xside / 2.,
0139 calo_yside / 2., calo_zside / 2.);
0140 auto calo_log = new G4LogicalVolume(calo_box,
0141 air,
0142 "calo_log",
0143 nullptr,
0144 nullptr,
0145 nullptr);
0146
0147 G4double xpos = 0.0;
0148 G4double ypos = 0.0;
0149 G4double zpos = calo_zside / 2.;
0150
0151 new G4PVPlacement(nullptr, G4ThreeVector(xpos, ypos, zpos), calo_log, "calorimeter",
0152 experimentalHall_log, false, 1);
0153
0154
0155 G4VSolid* crystal_box = new G4Box("Crystal",
0156 fCrystalWidth / 2, fCrystalWidth / 2, fCrystalLength / 2);
0157
0158 fCrystal_log = new G4LogicalVolume(crystal_box,
0159 fDetMat,
0160 "Crystal_log");
0161
0162 for (G4int i = 0; i < fNbOfCrystals; i++) {
0163 for (G4int j = 0; j < fNbOfCrystals; j++) {
0164 G4int n = i * 10 + j;
0165 G4ThreeVector crystalPos((i * fCrystalWidth) - (calo_xside - fCrystalWidth) / 2.,
0166 (j * fCrystalWidth) - (calo_yside - fCrystalWidth) / 2., 0);
0167 new G4PVPlacement(nullptr,
0168 crystalPos,
0169 fCrystal_log,
0170 "crystal",
0171 calo_log, false, n);
0172 }
0173 }
0174 G4cout << "There are " << fNbOfCrystals << " crystals per row in the calorimeter, so in total "
0175 << fNbOfCrystals * fNbOfCrystals << " crystals" << G4endl;
0176 G4cout << "Total Calorimeter size" << calo_xside / cm << " cm x " << calo_yside / cm << " cm x "
0177 << calo_zside / cm << " cm" << G4endl;
0178 G4cout << "They have width of " << fCrystalWidth / cm << " cm and a length of "
0179 << fCrystalLength / cm << " cm. The Material is " << fDetMat
0180 << " Total: " << fCrystalLength / fDetMat->GetRadlen() << " X0" << G4endl;
0181
0182 experimentalHall_log->SetVisAttributes(G4VisAttributes::GetInvisible());
0183 auto caloVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0184 auto crystalVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 0.0));
0185 calo_log->SetVisAttributes(caloVisAtt);
0186 fCrystal_log->SetVisAttributes(crystalVisAtt);
0187
0188
0189 G4cout << "\n ---> DetectorConstruction Region Definition" << G4endl;
0190 fRegion = new G4Region("crystals");
0191 calo_log->SetRegion(fRegion);
0192 fRegion->AddRootLogicalVolume(calo_log);
0193
0194 return experimentalHall_phys;
0195 }
0196
0197
0198
0199 void ExGflashDetectorConstruction::ConstructSDandField()
0200 {
0201
0202
0203 G4SDManager* SDman = G4SDManager::GetSDMpointer();
0204
0205 auto SD = new ExGflashSensitiveDetector("Calorimeter", this);
0206
0207 SDman->AddNewDetector(SD);
0208 if (fCrystal_log != nullptr) {
0209 fCrystal_log->SetSensitiveDetector(SD);
0210 }
0211
0212
0213
0214
0215
0216 G4cout << "\n--> Creating shower parameterization models" << G4endl;
0217 fFastShowerModel = new GFlashShowerModel("fFastShowerModel", fRegion);
0218 fParameterisation = new GFlashHomoShowerParameterisation(fDetMat, new ExGflashHomoShowerTuning());
0219 fFastShowerModel->SetParameterisation(*fParameterisation);
0220
0221 fParticleBounds = new GFlashParticleBounds();
0222 fFastShowerModel->SetParticleBounds(*fParticleBounds);
0223
0224 fHitMaker = new GFlashHitMaker();
0225 fFastShowerModel->SetHitMaker(*fHitMaker);
0226 G4cout << "end shower parameterization." << G4endl;
0227
0228
0229 fSDRadLen = fDetMat->GetRadlen();
0230 }
0231
0232
0233
0234 void ExGflashDetectorConstruction::SetLBining(G4ThreeVector Value)
0235 {
0236 fNLtot = (G4int)Value(0);
0237 if (fNLtot > kMaxBin) {
0238 G4cout << "\n ---> warning from SetLBining: " << fNLtot << " truncated to " << kMaxBin
0239 << G4endl;
0240 fNLtot = kMaxBin;
0241 }
0242 fDLradl = Value(1);
0243 }
0244
0245
0246
0247 void ExGflashDetectorConstruction::SetRBining(G4ThreeVector Value)
0248 {
0249 fNRtot = (G4int)Value(0);
0250 if (fNRtot > kMaxBin) {
0251 G4cout << "\n ---> warning from SetRBining: " << fNRtot << " truncated to " << kMaxBin
0252 << G4endl;
0253 fNRtot = kMaxBin;
0254 }
0255 fDRradl = Value(1);
0256 }
0257
0258
0259
0260 void ExGflashDetectorConstruction::SetMaterial(G4String mat)
0261 {
0262
0263 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(mat);
0264
0265 if (pttoMaterial != nullptr && fDetMat != pttoMaterial) {
0266 fDetMat = pttoMaterial;
0267 if (fCrystal_log != nullptr) {
0268 fCrystal_log->SetMaterial(fDetMat);
0269 }
0270 if (fParameterisation != nullptr) {
0271 fParameterisation->SetMaterial(fDetMat);
0272 fParameterisation->PrintMaterial(fDetMat);
0273
0274 fSDRadLen = fDetMat->GetRadlen();
0275 }
0276 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0277 }
0278 }
0279
0280