File indexing completed on 2025-02-23 09:20:45
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 #include "GB03DetectorConstruction.hh"
0031
0032 #include "GB03BOptrGeometryBasedBiasing.hh"
0033 #include "GB03DetectorMessenger.hh"
0034
0035 #include "G4Box.hh"
0036 #include "G4Colour.hh"
0037 #include "G4LogicalVolume.hh"
0038 #include "G4Material.hh"
0039 #include "G4MultiFunctionalDetector.hh"
0040 #include "G4PSEnergyDeposit.hh"
0041 #include "G4PSFlatSurfaceFlux.hh"
0042 #include "G4PVPlacement.hh"
0043 #include "G4PVReplica.hh"
0044 #include "G4PhysicalConstants.hh"
0045 #include "G4RunManager.hh"
0046 #include "G4SDChargedFilter.hh"
0047 #include "G4SDManager.hh"
0048 #include "G4SDNeutralFilter.hh"
0049 #include "G4SystemOfUnits.hh"
0050 #include "G4VisAttributes.hh"
0051 #include "G4ios.hh"
0052
0053 G4int GB03DetectorConstruction::fNumberOfLayers = 40;
0054 G4ThreadLocal G4bool GB03DetectorConstruction::fConstructedSDandField = false;
0055
0056
0057
0058 GB03DetectorConstruction::GB03DetectorConstruction()
0059 : G4VUserDetectorConstruction(),
0060 fTotalThickness(2.0 * m),
0061 fLayerThickness(0.),
0062 fConstructed(false),
0063 fWorldMaterial(0),
0064 fAbsorberMaterial(0),
0065 fGapMaterial(0),
0066 fLayerSolid(0),
0067 fGapSolid(0),
0068 fWorldLogical(0),
0069 fCalorLogical(0),
0070 fLayerLogical(0),
0071 fGapLogical(0),
0072 fWorldPhysical(0),
0073 fCalorPhysical(0),
0074 fLayerPhysical(0),
0075 fGapPhysical(0),
0076 fDetectorMessenger(0),
0077 fVerboseLevel(1)
0078 {
0079 fLayerThickness = fTotalThickness / fNumberOfLayers;
0080 fCalName = "Calor";
0081 fDetectorMessenger = new GB03DetectorMessenger(this);
0082 }
0083
0084
0085
0086 GB03DetectorConstruction::~GB03DetectorConstruction()
0087 {
0088 delete fDetectorMessenger;
0089 }
0090
0091
0092
0093 G4VPhysicalVolume* GB03DetectorConstruction::Construct()
0094 {
0095 if (!fConstructed) {
0096 fConstructed = true;
0097 DefineMaterials();
0098 SetupGeometry();
0099 }
0100 if (GetVerboseLevel() > 0) {
0101 PrintCalorParameters();
0102 }
0103
0104 return fWorldPhysical;
0105 }
0106
0107
0108
0109 void GB03DetectorConstruction::ConstructSDandField()
0110 {
0111 if (!fConstructedSDandField) {
0112 fConstructedSDandField = true;
0113 SetupDetectors();
0114 SetupBiasing();
0115 }
0116 }
0117
0118
0119
0120 void GB03DetectorConstruction::DefineMaterials()
0121 {
0122 G4String name, symbol;
0123 G4double a, z, density;
0124 G4int iz;
0125 G4int n;
0126
0127 G4int ncomponents, natoms;
0128 G4double abundance, fractionmass;
0129 G4double temperature, pressure;
0130
0131
0132
0133
0134
0135 a = 1.01 * g / mole;
0136 G4Element* H = new G4Element(name = "Hydrogen", symbol = "H", z = 1., a);
0137
0138 a = 12.01 * g / mole;
0139 G4Element* C = new G4Element(name = "Carbon", symbol = "C", z = 6., a);
0140
0141 a = 14.01 * g / mole;
0142 G4Element* N = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a);
0143
0144 a = 16.00 * g / mole;
0145 G4Element* O = new G4Element(name = "Oxygen", symbol = "O", z = 8., a);
0146
0147
0148
0149
0150
0151 G4Isotope* U5 = new G4Isotope(name = "U235", iz = 92, n = 235, a = 235.01 * g / mole);
0152 G4Isotope* U8 = new G4Isotope(name = "U238", iz = 92, n = 238, a = 238.03 * g / mole);
0153
0154 G4Element* U = new G4Element(name = "enriched Uranium", symbol = "U", ncomponents = 2);
0155 U->AddIsotope(U5, abundance = 90. * perCent);
0156 U->AddIsotope(U8, abundance = 10. * perCent);
0157
0158
0159
0160
0161
0162 new G4Material(name = "Aluminium", z = 13., a = 26.98 * g / mole, density = 2.700 * g / cm3);
0163 new G4Material(name = "Silicon", z = 14., a = 28.09 * g / mole, density = 2.33 * g / cm3);
0164 new G4Material(name = "Iron", z = 26., a = 55.85 * g / mole, density = 7.87 * g / cm3);
0165 new G4Material(name = "ArgonGas", z = 18., a = 39.95 * g / mole, density = 1.782 * mg / cm3);
0166 new G4Material(name = "He", z = 2., a = 4.0 * g / mole, density = 0.1786e-03 * g / cm3);
0167
0168 density = 1.390 * g / cm3;
0169 a = 39.95 * g / mole;
0170 new G4Material(name = "liquidArgon", z = 18., a, density);
0171
0172 density = 11.35 * g / cm3;
0173 a = 207.19 * g / mole;
0174 G4Material* Pb = new G4Material(name = "Lead", z = 82., a, density);
0175
0176
0177
0178
0179
0180 density = 1.000 * g / cm3;
0181 G4Material* H2O = new G4Material(name = "Water", density, ncomponents = 2);
0182 H2O->AddElement(H, natoms = 2);
0183 H2O->AddElement(O, natoms = 1);
0184
0185 density = 1.032 * g / cm3;
0186 G4Material* Sci = new G4Material(name = "Scintillator", density, ncomponents = 2);
0187 Sci->AddElement(C, natoms = 9);
0188 Sci->AddElement(H, natoms = 10);
0189
0190
0191
0192
0193
0194 density = 1.290 * mg / cm3;
0195 G4Material* Air = new G4Material(name = "Air", density, ncomponents = 2);
0196 Air->AddElement(N, fractionmass = 0.7);
0197 Air->AddElement(O, fractionmass = 0.3);
0198
0199
0200
0201
0202
0203 density = universe_mean_density;
0204 pressure = 3.e-18 * pascal;
0205 temperature = 2.73 * kelvin;
0206 G4Material* Vacuum = new G4Material(name = "Galactic", z = 1., a = 1.01 * g / mole, density,
0207 kStateGas, temperature, pressure);
0208
0209 if (GetVerboseLevel() > 1) {
0210 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0211 }
0212
0213
0214 fWorldMaterial = Vacuum;
0215 fAbsorberMaterial = Pb;
0216 fGapMaterial = Sci;
0217 }
0218
0219
0220
0221 void GB03DetectorConstruction::SetupGeometry()
0222 {
0223
0224
0225
0226 G4VSolid* worldSolid = new G4Box("World", 2. * m, 2. * m, fTotalThickness * 2.);
0227 fWorldLogical = new G4LogicalVolume(worldSolid, fWorldMaterial, "World");
0228 fWorldPhysical = new G4PVPlacement(0, G4ThreeVector(), fWorldLogical, "World", 0, false, 0);
0229
0230
0231
0232
0233 G4VSolid* calorSolid = new G4Box("Calor", 0.5 * m, 0.5 * m, fTotalThickness / 2.);
0234 fCalorLogical = new G4LogicalVolume(calorSolid, fAbsorberMaterial, fCalName);
0235 fCalorPhysical = new G4PVPlacement(0, G4ThreeVector(0., 0., 0.), fCalorLogical, fCalName,
0236 fWorldLogical, false, 0);
0237
0238
0239
0240
0241 fLayerSolid = new G4Box("Layer", 0.5 * m, 0.5 * m, fLayerThickness / 2.);
0242 fLayerLogical = new G4LogicalVolume(fLayerSolid, fAbsorberMaterial, fCalName + "_LayerLog");
0243 fLayerPhysical = new G4PVReplica(fCalName + "_Layer", fLayerLogical, fCalorLogical, kZAxis,
0244 fNumberOfLayers, fLayerThickness);
0245
0246
0247
0248
0249 fGapSolid = new G4Box("Gap", 0.5 * m, 0.5 * m, fLayerThickness / 4.);
0250 fGapLogical = new G4LogicalVolume(fGapSolid, fGapMaterial, fCalName + "_Gap");
0251 fGapPhysical = new G4PVPlacement(0, G4ThreeVector(0., 0., fLayerThickness / 4.), fGapLogical,
0252 fCalName + "_gap", fLayerLogical, false, 0);
0253
0254
0255
0256
0257 fWorldLogical->SetVisAttributes(G4VisAttributes::GetInvisible());
0258 G4VisAttributes* simpleBoxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0259 simpleBoxVisAtt->SetVisibility(true);
0260 fCalorLogical->SetVisAttributes(simpleBoxVisAtt);
0261 fLayerLogical->SetVisAttributes(simpleBoxVisAtt);
0262 fGapLogical->SetVisAttributes(simpleBoxVisAtt);
0263 }
0264
0265
0266
0267 void GB03DetectorConstruction::SetupDetectors()
0268 {
0269 G4SDManager::GetSDMpointer()->SetVerboseLevel(1);
0270 G4String filterName;
0271
0272 G4SDNeutralFilter* neutralFilter = new G4SDNeutralFilter(filterName = "neutralFilter");
0273 G4SDChargedFilter* chargedFilter = new G4SDChargedFilter(filterName = "chargedFilter");
0274
0275 for (G4int j = 0; j < 2; j++) {
0276
0277
0278 G4String detName = fCalName;
0279 if (j == 0) {
0280 detName += "_abs";
0281 }
0282 else {
0283 detName += "_gap";
0284 }
0285 G4MultiFunctionalDetector* det = new G4MultiFunctionalDetector(detName);
0286 G4SDManager::GetSDMpointer()->AddNewDetector(det);
0287
0288
0289
0290
0291
0292
0293
0294 G4VPrimitiveScorer* primitive;
0295 primitive = new G4PSEnergyDeposit("eDep", j);
0296 det->RegisterPrimitive(primitive);
0297 primitive = new G4PSFlatSurfaceFlux("nNeutral", 1, j);
0298 primitive->SetFilter(neutralFilter);
0299 det->RegisterPrimitive(primitive);
0300 primitive = new G4PSFlatSurfaceFlux("nCharged", 1, j);
0301 primitive->SetFilter(chargedFilter);
0302 det->RegisterPrimitive(primitive);
0303
0304 if (j == 0) {
0305 SetSensitiveDetector(fLayerLogical, det);
0306 }
0307 else {
0308 SetSensitiveDetector(fGapLogical, det);
0309 }
0310 }
0311 G4SDManager::GetSDMpointer()->SetVerboseLevel(0);
0312 }
0313
0314
0315
0316 void GB03DetectorConstruction::SetupBiasing()
0317 {
0318 GB03BOptrGeometryBasedBiasing* biasingOperator = new GB03BOptrGeometryBasedBiasing();
0319 biasingOperator->AttachTo(fLayerLogical);
0320 }
0321
0322
0323
0324 void GB03DetectorConstruction::PrintCalorParameters() const
0325 {
0326 G4cout << "--------------------------------------------------------" << G4endl;
0327 G4cout << " Absorber is made of " << fAbsorberMaterial->GetName() << G4endl << " Gap is made of "
0328 << fGapMaterial->GetName() << G4endl
0329 << "--------------------------------------------------------" << G4endl;
0330 }
0331
0332
0333
0334 void GB03DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
0335 {
0336
0337 G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
0338 if (pttoMaterial) {
0339 fAbsorberMaterial = pttoMaterial;
0340 if (fConstructed) {
0341 fCalorLogical->SetMaterial(fAbsorberMaterial);
0342 fLayerLogical->SetMaterial(fAbsorberMaterial);
0343 }
0344 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0345 if (GetVerboseLevel() > 1) {
0346 PrintCalorParameters();
0347 }
0348 }
0349 else {
0350 G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl;
0351 }
0352 }
0353
0354
0355
0356 G4String GB03DetectorConstruction::GetAbsorberMaterial() const
0357 {
0358 return fAbsorberMaterial->GetName();
0359 }
0360
0361
0362
0363 void GB03DetectorConstruction::SetGapMaterial(G4String materialChoice)
0364 {
0365
0366 G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
0367 if (pttoMaterial) {
0368 fGapMaterial = pttoMaterial;
0369 if (fConstructed) {
0370 fGapLogical->SetMaterial(fGapMaterial);
0371 }
0372 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0373 if (GetVerboseLevel() > 1) {
0374 PrintCalorParameters();
0375 }
0376 }
0377 else {
0378 G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl;
0379 }
0380 }
0381
0382
0383
0384 G4String GB03DetectorConstruction::GetGapMaterial() const
0385 {
0386 return fGapMaterial->GetName();
0387 }
0388
0389
0390
0391 void GB03DetectorConstruction::SetNumberOfLayers(G4int nl)
0392 {
0393 fNumberOfLayers = nl;
0394 fLayerThickness = fTotalThickness / fNumberOfLayers;
0395 if (!fConstructed) return;
0396
0397 fLayerSolid->SetZHalfLength(fLayerThickness / 2.);
0398 fGapSolid->SetZHalfLength(fLayerThickness / 4.);
0399
0400 fCalorLogical->RemoveDaughter(fLayerPhysical);
0401 delete fLayerPhysical;
0402 fLayerPhysical = new G4PVReplica(fCalName + "_Layer", fLayerLogical, fCalorLogical, kZAxis,
0403 fNumberOfLayers, fLayerThickness);
0404 fGapPhysical->SetTranslation(G4ThreeVector(0., 0., fLayerThickness / 4.));
0405
0406 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0407 }
0408
0409