File indexing completed on 2025-01-31 09:22:50
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 "ChamberParameterisation.hh"
0033 #include "DetectorMessenger.hh"
0034 #include "TrackerSD.hh"
0035
0036 #include "G4AutoDelete.hh"
0037 #include "G4Box.hh"
0038 #include "G4Colour.hh"
0039 #include "G4GeometryManager.hh"
0040 #include "G4GeometryTolerance.hh"
0041 #include "G4GlobalMagFieldMessenger.hh"
0042 #include "G4LogicalVolume.hh"
0043 #include "G4Material.hh"
0044 #include "G4NistManager.hh"
0045 #include "G4PVParameterised.hh"
0046 #include "G4PVPlacement.hh"
0047 #include "G4SDManager.hh"
0048 #include "G4SystemOfUnits.hh"
0049 #include "G4ThreeVector.hh"
0050 #include "G4Tubs.hh"
0051 #include "G4UserLimits.hh"
0052 #include "G4VisAttributes.hh"
0053
0054 using namespace B2;
0055
0056 namespace B2b
0057 {
0058
0059
0060
0061 G4ThreadLocal G4GlobalMagFieldMessenger* DetectorConstruction::fMagFieldMessenger = nullptr;
0062
0063 DetectorConstruction::DetectorConstruction()
0064 {
0065 fMessenger = new DetectorMessenger(this);
0066 }
0067
0068
0069
0070 DetectorConstruction::~DetectorConstruction()
0071 {
0072 delete fStepLimit;
0073 delete fMessenger;
0074 }
0075
0076
0077
0078 G4VPhysicalVolume* DetectorConstruction::Construct()
0079 {
0080
0081 DefineMaterials();
0082
0083
0084 return DefineVolumes();
0085 }
0086
0087
0088
0089 void DetectorConstruction::DefineMaterials()
0090 {
0091
0092
0093 G4NistManager* nistManager = G4NistManager::Instance();
0094
0095
0096 nistManager->FindOrBuildMaterial("G4_AIR");
0097
0098
0099 fTargetMaterial = nistManager->FindOrBuildMaterial("G4_Pb");
0100
0101
0102 fChamberMaterial = nistManager->FindOrBuildMaterial("G4_Xe");
0103
0104
0105 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0106 }
0107
0108
0109
0110 G4VPhysicalVolume* DetectorConstruction::DefineVolumes()
0111 {
0112 G4Material* air = G4Material::GetMaterial("G4_AIR");
0113
0114
0115
0116 G4int NbOfChambers = 5;
0117 G4double chamberSpacing = 80 * cm;
0118
0119 G4double chamberWidth = 20.0 * cm;
0120 G4double targetLength = 5.0 * cm;
0121
0122 G4double trackerLength = (NbOfChambers + 1) * chamberSpacing;
0123
0124 G4double worldLength = 1.2 * (2 * targetLength + trackerLength);
0125
0126 G4double targetRadius = 0.5 * targetLength;
0127 targetLength = 0.5 * targetLength;
0128 G4double trackerSize = 0.5 * trackerLength;
0129
0130
0131
0132
0133
0134 G4GeometryManager::GetInstance()->SetWorldMaximumExtent(worldLength);
0135
0136 G4cout << "Computed tolerance = "
0137 << G4GeometryTolerance::GetInstance()->GetSurfaceTolerance() / mm << " mm" << G4endl;
0138
0139 auto worldS = new G4Box("world",
0140 worldLength / 2, worldLength / 2, worldLength / 2);
0141 auto worldLV = new G4LogicalVolume(worldS,
0142 air,
0143 "World");
0144
0145
0146
0147 auto worldPV = new G4PVPlacement(nullptr,
0148 G4ThreeVector(),
0149 worldLV,
0150 "World",
0151 nullptr,
0152 false,
0153 0,
0154 fCheckOverlaps);
0155
0156
0157
0158 G4ThreeVector positionTarget = G4ThreeVector(0, 0, -(targetLength + trackerSize));
0159
0160 auto targetS = new G4Tubs("target", 0., targetRadius, targetLength, 0. * deg, 360. * deg);
0161 fLogicTarget = new G4LogicalVolume(targetS, fTargetMaterial, "Target", nullptr, nullptr, nullptr);
0162 new G4PVPlacement(nullptr,
0163 positionTarget,
0164 fLogicTarget,
0165 "Target",
0166 worldLV,
0167 false,
0168 0,
0169 fCheckOverlaps);
0170
0171 G4cout << "Target is " << 2 * targetLength / cm << " cm of " << fTargetMaterial->GetName()
0172 << G4endl;
0173
0174
0175
0176 G4ThreeVector positionTracker = G4ThreeVector(0, 0, 0);
0177
0178 auto trackerS = new G4Tubs("tracker", 0, trackerSize, trackerSize, 0. * deg, 360. * deg);
0179 auto trackerLV = new G4LogicalVolume(trackerS, air, "Tracker", nullptr, nullptr, nullptr);
0180 new G4PVPlacement(nullptr,
0181 positionTracker,
0182 trackerLV,
0183 "Tracker",
0184 worldLV,
0185 false,
0186 0,
0187 fCheckOverlaps);
0188
0189
0190
0191
0192
0193
0194 auto chamberS = new G4Tubs("tracker", 0, 100 * cm, 100 * cm, 0. * deg, 360. * deg);
0195 fLogicChamber =
0196 new G4LogicalVolume(chamberS, fChamberMaterial, "Chamber", nullptr, nullptr, nullptr);
0197
0198 G4double firstPosition = -trackerSize + chamberSpacing;
0199 G4double firstLength = trackerLength / 10;
0200 G4double lastLength = trackerLength;
0201
0202 G4VPVParameterisation* chamberParam =
0203 new ChamberParameterisation(NbOfChambers,
0204 firstPosition,
0205 chamberSpacing,
0206 chamberWidth,
0207 firstLength,
0208 lastLength);
0209
0210
0211
0212 new G4PVParameterised("Chamber",
0213 fLogicChamber,
0214 trackerLV,
0215 kZAxis,
0216 NbOfChambers,
0217 chamberParam,
0218 fCheckOverlaps);
0219
0220 G4cout << "There are " << NbOfChambers << " chambers in the tracker region. " << G4endl
0221 << "The chambers are " << chamberWidth / cm << " cm of " << fChamberMaterial->GetName()
0222 << G4endl << "The distance between chamber is " << chamberSpacing / cm << " cm" << G4endl;
0223
0224
0225
0226 G4VisAttributes boxVisAtt(G4Colour::White());
0227
0228 worldLV->SetVisAttributes(boxVisAtt);
0229 fLogicTarget->SetVisAttributes(boxVisAtt);
0230 trackerLV->SetVisAttributes(boxVisAtt);
0231
0232 G4VisAttributes chamberVisAtt(G4Colour::Yellow());
0233 fLogicChamber->SetVisAttributes(chamberVisAtt);
0234
0235
0236
0237
0238
0239
0240
0241
0242 G4double maxStep = 0.5 * chamberWidth;
0243 fStepLimit = new G4UserLimits(maxStep);
0244 trackerLV->SetUserLimits(fStepLimit);
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 return worldPV;
0257 }
0258
0259
0260
0261 void DetectorConstruction::ConstructSDandField()
0262 {
0263
0264
0265 G4String trackerChamberSDname = "B2/TrackerChamberSD";
0266 auto trackerSD = new TrackerSD(trackerChamberSDname, "TrackerHitsCollection");
0267 G4SDManager::GetSDMpointer()->AddNewDetector(trackerSD);
0268 SetSensitiveDetector(fLogicChamber, trackerSD);
0269
0270
0271
0272
0273 G4ThreeVector fieldValue = G4ThreeVector();
0274 fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue);
0275 fMagFieldMessenger->SetVerboseLevel(1);
0276
0277
0278 G4AutoDelete::Register(fMagFieldMessenger);
0279 }
0280
0281
0282
0283 void DetectorConstruction::SetTargetMaterial(G4String materialName)
0284 {
0285 G4NistManager* nistManager = G4NistManager::Instance();
0286
0287 G4Material* pttoMaterial = nistManager->FindOrBuildMaterial(materialName);
0288
0289 if (fTargetMaterial != pttoMaterial) {
0290 if (pttoMaterial) {
0291 fTargetMaterial = pttoMaterial;
0292 if (fLogicTarget) fLogicTarget->SetMaterial(fTargetMaterial);
0293 G4cout << G4endl << "----> The target is made of " << materialName << G4endl;
0294 }
0295 else {
0296 G4cout << G4endl << "--> WARNING from SetTargetMaterial : " << materialName << " not found"
0297 << G4endl;
0298 }
0299 }
0300 }
0301
0302
0303
0304 void DetectorConstruction::SetChamberMaterial(G4String materialName)
0305 {
0306 G4NistManager* nistManager = G4NistManager::Instance();
0307
0308 G4Material* pttoMaterial = nistManager->FindOrBuildMaterial(materialName);
0309
0310 if (fChamberMaterial != pttoMaterial) {
0311 if (pttoMaterial) {
0312 fChamberMaterial = pttoMaterial;
0313 if (fLogicChamber) fLogicChamber->SetMaterial(fChamberMaterial);
0314 G4cout << G4endl << "----> The chambers are made of " << materialName << G4endl;
0315 }
0316 else {
0317 G4cout << G4endl << "--> WARNING from SetChamberMaterial : " << materialName << " not found"
0318 << G4endl;
0319 }
0320 }
0321 }
0322
0323
0324
0325 void DetectorConstruction::SetMaxStep(G4double maxStep)
0326 {
0327 if ((fStepLimit) && (maxStep > 0.)) fStepLimit->SetMaxAllowedStep(maxStep);
0328 }
0329
0330
0331
0332 }