File indexing completed on 2025-01-18 09:17:16
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 "DetectorConstruction.hh"
0031
0032 #include "G4AutoDelete.hh"
0033 #include "G4Box.hh"
0034 #include "G4Colour.hh"
0035 #include "G4GlobalMagFieldMessenger.hh"
0036 #include "G4LogicalVolume.hh"
0037 #include "G4Material.hh"
0038 #include "G4MultiFunctionalDetector.hh"
0039 #include "G4NistManager.hh"
0040 #include "G4PSEnergyDeposit.hh"
0041 #include "G4PSTrackLength.hh"
0042 #include "G4PVPlacement.hh"
0043 #include "G4PVReplica.hh"
0044 #include "G4PhysicalConstants.hh"
0045 #include "G4SDChargedFilter.hh"
0046 #include "G4SDManager.hh"
0047 #include "G4SystemOfUnits.hh"
0048 #include "G4VPrimitiveScorer.hh"
0049 #include "G4VisAttributes.hh"
0050
0051 namespace B4d
0052 {
0053
0054
0055
0056 G4ThreadLocal G4GlobalMagFieldMessenger* DetectorConstruction::fMagFieldMessenger = nullptr;
0057
0058
0059
0060 G4VPhysicalVolume* DetectorConstruction::Construct()
0061 {
0062
0063 DefineMaterials();
0064
0065
0066 return DefineVolumes();
0067 }
0068
0069
0070
0071 void DetectorConstruction::DefineMaterials()
0072 {
0073
0074 auto nistManager = G4NistManager::Instance();
0075 nistManager->FindOrBuildMaterial("G4_Pb");
0076
0077
0078 G4double a;
0079 G4double z;
0080 G4double density;
0081 new G4Material("liquidArgon", z = 18., a = 39.95 * g / mole, density = 1.390 * g / cm3);
0082
0083
0084
0085 new G4Material("Galactic", z = 1., a = 1.01 * g / mole, density = universe_mean_density,
0086 kStateGas, 2.73 * kelvin, 3.e-18 * pascal);
0087
0088
0089 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0090 }
0091
0092
0093
0094 G4VPhysicalVolume* DetectorConstruction::DefineVolumes()
0095 {
0096
0097 G4int nofLayers = 10;
0098 G4double absoThickness = 10. * mm;
0099 G4double gapThickness = 5. * mm;
0100 G4double calorSizeXY = 10. * cm;
0101
0102 auto layerThickness = absoThickness + gapThickness;
0103 auto calorThickness = nofLayers * layerThickness;
0104 auto worldSizeXY = 1.2 * calorSizeXY;
0105 auto worldSizeZ = 1.2 * calorThickness;
0106
0107
0108 auto defaultMaterial = G4Material::GetMaterial("Galactic");
0109 auto absorberMaterial = G4Material::GetMaterial("G4_Pb");
0110 auto gapMaterial = G4Material::GetMaterial("liquidArgon");
0111
0112 if (!defaultMaterial || !absorberMaterial || !gapMaterial) {
0113 G4ExceptionDescription msg;
0114 msg << "Cannot retrieve materials already defined.";
0115 G4Exception("DetectorConstruction::DefineVolumes()", "MyCode0001", FatalException, msg);
0116 }
0117
0118
0119
0120
0121 auto worldS = new G4Box("World",
0122 worldSizeXY / 2, worldSizeXY / 2, worldSizeZ / 2);
0123
0124 auto worldLV = new G4LogicalVolume(worldS,
0125 defaultMaterial,
0126 "World");
0127
0128 auto worldPV = new G4PVPlacement(nullptr,
0129 G4ThreeVector(),
0130 worldLV,
0131 "World",
0132 nullptr,
0133 false,
0134 0,
0135 fCheckOverlaps);
0136
0137
0138
0139
0140 auto calorimeterS = new G4Box("Calorimeter",
0141 calorSizeXY / 2, calorSizeXY / 2, calorThickness / 2);
0142
0143 auto calorLV = new G4LogicalVolume(calorimeterS,
0144 defaultMaterial,
0145 "Calorimeter");
0146
0147 new G4PVPlacement(nullptr,
0148 G4ThreeVector(),
0149 calorLV,
0150 "Calorimeter",
0151 worldLV,
0152 false,
0153 0,
0154 fCheckOverlaps);
0155
0156
0157
0158
0159 auto layerS = new G4Box("Layer",
0160 calorSizeXY / 2, calorSizeXY / 2, layerThickness / 2);
0161
0162 auto layerLV = new G4LogicalVolume(layerS,
0163 defaultMaterial,
0164 "Layer");
0165
0166 new G4PVReplica("Layer",
0167 layerLV,
0168 calorLV,
0169 kZAxis,
0170 nofLayers,
0171 layerThickness);
0172
0173
0174
0175
0176 auto absorberS = new G4Box("Abso",
0177 calorSizeXY / 2, calorSizeXY / 2, absoThickness / 2);
0178
0179 auto absorberLV = new G4LogicalVolume(absorberS,
0180 absorberMaterial,
0181 "AbsoLV");
0182
0183 new G4PVPlacement(nullptr,
0184 G4ThreeVector(0., 0., -gapThickness / 2),
0185 absorberLV,
0186 "Abso",
0187 layerLV,
0188 false,
0189 0,
0190 fCheckOverlaps);
0191
0192
0193
0194
0195 auto gapS = new G4Box("Gap",
0196 calorSizeXY / 2, calorSizeXY / 2, gapThickness / 2);
0197
0198 auto gapLV = new G4LogicalVolume(gapS,
0199 gapMaterial,
0200 "GapLV");
0201
0202 new G4PVPlacement(nullptr,
0203 G4ThreeVector(0., 0., absoThickness / 2),
0204 gapLV,
0205 "Gap",
0206 layerLV,
0207 false,
0208 0,
0209 fCheckOverlaps);
0210
0211
0212
0213
0214 G4cout << G4endl << "------------------------------------------------------------" << G4endl
0215 << "---> The calorimeter is " << nofLayers << " layers of: [ " << absoThickness / mm
0216 << "mm of " << absorberMaterial->GetName() << " + " << gapThickness / mm << "mm of "
0217 << gapMaterial->GetName() << " ] " << G4endl
0218 << "------------------------------------------------------------" << G4endl;
0219
0220
0221
0222
0223 worldLV->SetVisAttributes(G4VisAttributes::GetInvisible());
0224 calorLV->SetVisAttributes(G4VisAttributes(G4Colour::White()));
0225
0226
0227
0228
0229 return worldPV;
0230 }
0231
0232
0233
0234 void DetectorConstruction::ConstructSDandField()
0235 {
0236 G4SDManager::GetSDMpointer()->SetVerboseLevel(1);
0237
0238
0239
0240
0241
0242
0243 auto absDetector = new G4MultiFunctionalDetector("Absorber");
0244 G4SDManager::GetSDMpointer()->AddNewDetector(absDetector);
0245
0246 G4VPrimitiveScorer* primitive;
0247 primitive = new G4PSEnergyDeposit("Edep");
0248 absDetector->RegisterPrimitive(primitive);
0249
0250 primitive = new G4PSTrackLength("TrackLength");
0251 auto charged = new G4SDChargedFilter("chargedFilter");
0252 primitive->SetFilter(charged);
0253 absDetector->RegisterPrimitive(primitive);
0254
0255 SetSensitiveDetector("AbsoLV", absDetector);
0256
0257
0258
0259 auto gapDetector = new G4MultiFunctionalDetector("Gap");
0260 G4SDManager::GetSDMpointer()->AddNewDetector(gapDetector);
0261
0262 primitive = new G4PSEnergyDeposit("Edep");
0263 gapDetector->RegisterPrimitive(primitive);
0264
0265 primitive = new G4PSTrackLength("TrackLength");
0266 primitive->SetFilter(charged);
0267 gapDetector->RegisterPrimitive(primitive);
0268
0269 SetSensitiveDetector("GapLV", gapDetector);
0270
0271
0272
0273
0274
0275
0276
0277 G4ThreeVector fieldValue;
0278 fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue);
0279 fMagFieldMessenger->SetVerboseLevel(1);
0280
0281
0282 G4AutoDelete::Register(fMagFieldMessenger);
0283 }
0284
0285
0286
0287 }