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