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