File indexing completed on 2026-04-04 07:52:37
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 "F01DetectorConstruction.hh"
0030
0031 #include "F01CalorimeterSD.hh"
0032 #include "F01DetectorMessenger.hh"
0033
0034 #include "G4AutoDelete.hh"
0035 #include "G4GeometryManager.hh"
0036 #include "G4FieldBuilder.hh"
0037 #include "G4LogicalVolume.hh"
0038 #include "G4LogicalVolumeStore.hh"
0039 #include "G4Material.hh"
0040 #include "G4PVPlacement.hh"
0041 #include "G4PhysicalConstants.hh"
0042 #include "G4PhysicalVolumeStore.hh"
0043 #include "G4RunManager.hh"
0044 #include "G4SDManager.hh"
0045 #include "G4SolidStore.hh"
0046 #include "G4SystemOfUnits.hh"
0047 #include "G4Tubs.hh"
0048 #include "G4UniformMagField.hh"
0049
0050
0051
0052 F01DetectorConstruction::F01DetectorConstruction()
0053 {
0054
0055
0056 G4cout << "F01DetectorConstruction::F01DetectorConstruction()" << G4endl;
0057
0058 fDetectorMessenger = new F01DetectorMessenger(this);
0059
0060
0061
0062 G4FieldBuilder::Instance();
0063
0064
0065
0066
0067 DefineMaterials();
0068 }
0069
0070
0071
0072 F01DetectorConstruction::~F01DetectorConstruction()
0073 {
0074
0075 }
0076
0077
0078
0079 G4VPhysicalVolume* F01DetectorConstruction::Construct()
0080 {
0081 return ConstructCalorimeter();
0082 }
0083
0084
0085
0086 void F01DetectorConstruction::DefineMaterials()
0087 {
0088
0089
0090 G4String name, symbol;
0091 G4double a, z, density;
0092 G4int nel;
0093 G4int ncomponents;
0094 G4double fractionmass, pressure, temperature;
0095
0096
0097
0098
0099
0100 a = 1.01 * g / mole;
0101 auto elH = new G4Element(name = "Hydrogen", symbol = "H", z = 1., a);
0102
0103 a = 12.01 * g / mole;
0104 auto elC = new G4Element(name = "Carbon", symbol = "C", z = 6., a);
0105
0106 a = 14.01 * g / mole;
0107 auto elN = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a);
0108
0109 a = 16.00 * g / mole;
0110 auto elO = new G4Element(name = "Oxygen", symbol = "O", z = 8., a);
0111
0112 a = 39.948 * g / mole;
0113 auto elAr = new G4Element(name = "Argon", symbol = "Ar", z = 18., a);
0114
0115
0116
0117
0118
0119
0120
0121 density = 1.39 * g / cm3;
0122 auto mylar = new G4Material(name = "Mylar", density, nel = 3);
0123 mylar->AddElement(elO, 2);
0124 mylar->AddElement(elC, 5);
0125 mylar->AddElement(elH, 4);
0126
0127
0128
0129 auto CH2 = new G4Material("Polypropelene", 0.91 * g / cm3, 2);
0130 CH2->AddElement(elH, 2);
0131 CH2->AddElement(elC, 1);
0132
0133
0134
0135 density = 3.700 * mg / cm3;
0136 a = 83.80 * g / mole;
0137 auto Kr = new G4Material(name = "Kr", z = 36., a, density);
0138
0139
0140
0141 density = 1.7836 * mg / cm3;
0142 auto argon = new G4Material(name = "Argon", density, ncomponents = 1);
0143 argon->AddElement(elAr, 1);
0144
0145 density = 1.25053 * mg / cm3;
0146 auto nitrogen = new G4Material(name = "N2", density, ncomponents = 1);
0147 nitrogen->AddElement(elN, 2);
0148
0149 density = 1.4289 * mg / cm3;
0150 auto oxygen = new G4Material(name = "O2", density, ncomponents = 1);
0151 oxygen->AddElement(elO, 2);
0152
0153 density = 1.2928 * mg / cm3;
0154 density *= 1.0e-8;
0155
0156 temperature = STP_Temperature;
0157 pressure = 1.0e-8 * STP_Pressure;
0158
0159 auto air =
0160 new G4Material(name = "Air", density, ncomponents = 3, kStateGas, temperature, pressure);
0161 air->AddMaterial(nitrogen, fractionmass = 0.7557);
0162 air->AddMaterial(oxygen, fractionmass = 0.2315);
0163
0164 air->AddMaterial(argon, fractionmass = 0.0128);
0165
0166
0167
0168 density = 5.858 * mg / cm3;
0169 a = 131.29 * g / mole;
0170 auto Xe = new G4Material(name = "Xenon", z = 54., a, density);
0171
0172
0173
0174 density = 1.842 * mg / cm3;
0175 auto CarbonDioxide = new G4Material(name = "CO2", density, nel = 2);
0176 CarbonDioxide->AddElement(elC, 1);
0177 CarbonDioxide->AddElement(elO, 2);
0178
0179
0180
0181 density = 5.0818 * mg / cm3;
0182 auto Xe20CO2 = new G4Material(name = "Xe20CO2", density, ncomponents = 2);
0183 Xe20CO2->AddMaterial(Xe, fractionmass = 0.922);
0184 Xe20CO2->AddMaterial(CarbonDioxide, fractionmass = 0.078);
0185
0186
0187
0188 density = 3.601 * mg / cm3;
0189 auto Kr20CO2 = new G4Material(name = "Kr20CO2", density, ncomponents = 2);
0190 Kr20CO2->AddMaterial(Kr, fractionmass = 0.89);
0191 Kr20CO2->AddMaterial(CarbonDioxide, fractionmass = 0.11);
0192
0193
0194
0195 G4cout << "F01DetectorConstruction: not printing material table - to see it edit the source."
0196 << G4endl;
0197
0198
0199
0200 fAbsorberMaterial = air;
0201
0202 fWorldMaterial = air;
0203 }
0204
0205
0206
0207 G4VPhysicalVolume* F01DetectorConstruction::ConstructCalorimeter()
0208 {
0209
0210
0211 if (fPhysiWorld) {
0212 G4GeometryManager::GetInstance()->OpenGeometry();
0213 G4PhysicalVolumeStore::GetInstance()->Clean();
0214 G4LogicalVolumeStore::GetInstance()->Clean();
0215 G4SolidStore::GetInstance()->Clean();
0216 }
0217
0218
0219
0220 ComputeCalorParameters();
0221 PrintCalorParameters();
0222
0223
0224
0225 fSolidWorld = new G4Tubs("World",
0226 0., fWorldSizeR, fWorldSizeZ / 2., 0., twopi);
0227
0228 fLogicWorld = new G4LogicalVolume(fSolidWorld,
0229 fWorldMaterial,
0230 "World");
0231
0232 fPhysiWorld = new G4PVPlacement(nullptr,
0233 G4ThreeVector(),
0234 "World",
0235 fLogicWorld,
0236 nullptr,
0237 false,
0238 0);
0239
0240
0241 fSolidAbsorber =
0242 new G4Tubs("Absorber", 1.0 * mm, fAbsorberRadius, fAbsorberThickness / 2., 0.0, twopi);
0243
0244 fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, fAbsorberMaterial, "Absorber");
0245
0246 fPhysiAbsorber = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fZAbsorber), "Absorber",
0247 fLogicAbsorber, fPhysiWorld, false, 0);
0248
0249 return fPhysiWorld;
0250 }
0251
0252
0253
0254 void F01DetectorConstruction::PrintCalorParameters()
0255 {
0256 G4cout << "\n The WORLD is made of " << fWorldSizeZ / mm << "mm of "
0257 << fWorldMaterial->GetName();
0258 G4cout << ", the transverse size (R) of the world is " << fWorldSizeR / mm << " mm. " << G4endl;
0259 G4cout << " The ABSORBER is made of " << fAbsorberThickness / mm << "mm of "
0260 << fAbsorberMaterial->GetName();
0261 G4cout << ", the transverse size (R) is " << fAbsorberRadius / mm << " mm. " << G4endl;
0262 G4cout << " Z position of the (middle of the) absorber " << fZAbsorber / mm << " mm." << G4endl;
0263 G4cout << G4endl;
0264 }
0265
0266
0267
0268 void F01DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
0269 {
0270
0271 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
0272
0273
0274 G4Material* material;
0275 for (size_t j = 0; j < theMaterialTable->size(); j++) {
0276 material = (*theMaterialTable)[j];
0277 if (material->GetName() == materialChoice) {
0278 fAbsorberMaterial = material;
0279 fLogicAbsorber->SetMaterial(material);
0280 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0281 }
0282 }
0283 }
0284
0285
0286
0287 void F01DetectorConstruction::SetWorldMaterial(G4String materialChoice)
0288 {
0289
0290 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
0291
0292
0293 G4Material* material;
0294 for (size_t j = 0; j < theMaterialTable->size(); j++) {
0295 material = (*theMaterialTable)[j];
0296 if (material->GetName() == materialChoice) {
0297 fWorldMaterial = material;
0298 fLogicWorld->SetMaterial(material);
0299 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0300 }
0301 }
0302 }
0303
0304
0305
0306 void F01DetectorConstruction::SetAbsorberThickness(G4double val)
0307 {
0308
0309 fAbsorberThickness = val;
0310 ComputeCalorParameters();
0311 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0312 }
0313
0314
0315
0316 void F01DetectorConstruction::SetAbsorberRadius(G4double val)
0317 {
0318
0319 fAbsorberRadius = val;
0320 ComputeCalorParameters();
0321 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0322 }
0323
0324
0325
0326 void F01DetectorConstruction::SetWorldSizeZ(G4double val)
0327 {
0328 fWorldSizeZ = val;
0329 ComputeCalorParameters();
0330 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0331 }
0332
0333
0334
0335 void F01DetectorConstruction::SetWorldSizeR(G4double val)
0336 {
0337 fWorldSizeR = val;
0338 ComputeCalorParameters();
0339 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0340 }
0341
0342
0343
0344 void F01DetectorConstruction::SetAbsorberZpos(G4double val)
0345 {
0346 fZAbsorber = val;
0347 ComputeCalorParameters();
0348 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0349 }
0350
0351
0352
0353 void F01DetectorConstruction::SetFieldValue(G4ThreeVector value)
0354 {
0355 fFieldVector = value;
0356
0357 G4UniformMagField* magField = nullptr;
0358 if (fFieldVector != G4ThreeVector(0.,0.,0.)) {
0359 magField = new G4UniformMagField(fFieldVector);
0360 }
0361
0362
0363 auto fieldBuilder = G4FieldBuilder::Instance();
0364 fieldBuilder->SetGlobalField(magField);
0365 }
0366
0367
0368 #include "G4FieldManager.hh"
0369
0370 void F01DetectorConstruction::ConstructSDandField()
0371 {
0372
0373
0374 if (!fCalorimeterSD.Get()) {
0375 auto calorimeterSD = new F01CalorimeterSD("CalorSD", this);
0376 fCalorimeterSD.Put(calorimeterSD);
0377 }
0378 G4SDManager::GetSDMpointer()->AddNewDetector(fCalorimeterSD.Get());
0379 SetSensitiveDetector(fLogicAbsorber, fCalorimeterSD.Get());
0380
0381
0382 SetFieldValue(fFieldVector);
0383
0384
0385 auto fieldBuilder = G4FieldBuilder::Instance();
0386 fieldBuilder->ConstructFieldSetup();
0387 }
0388
0389