Warning, file /geant4/examples/basic/B2/B2b/src/DetectorConstruction.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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 }