File indexing completed on 2026-09-15 08:28:27
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
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #include "DetectorConstruction.hh"
0044
0045 #include "DetectorMessenger.hh"
0046
0047 #include "G4Box.hh"
0048 #include "G4Colour.hh"
0049 #include "G4GeometryManager.hh"
0050 #include "G4LogicalVolume.hh"
0051 #include "G4LogicalVolumeStore.hh"
0052 #include "G4NistManager.hh"
0053 #include "G4PVPlacement.hh"
0054 #include "G4PVReplica.hh"
0055 #include "G4PhysicalVolumeStore.hh"
0056 #include "G4ProductionCuts.hh"
0057 #include "G4Region.hh"
0058 #include "G4RegionStore.hh"
0059 #include "G4RunManager.hh"
0060 #include "G4SolidStore.hh"
0061 #include "G4SystemOfUnits.hh"
0062 #include "G4TransportationManager.hh"
0063 #include "G4UnitsTable.hh"
0064 #include "G4VisAttributes.hh"
0065 #include "G4ios.hh"
0066
0067
0068
0069 DetectorConstruction::DetectorConstruction()
0070 : G4VUserDetectorConstruction(),
0071 fCalMaterial(0),
0072 fVertMaterial(0),
0073 fAbsMaterial(0),
0074 fWorldMaterial(0),
0075 fYorkMaterial(0),
0076 fLogicWorld(0),
0077 fLogicCal(0),
0078 fLogicA1(0),
0079 fLogicA2(0),
0080 fLogicA3(0),
0081 fLogicA4(0),
0082 fVertexRegion(0),
0083 fMuonRegion(0),
0084 fVertexDetectorCuts(0),
0085 fMuonDetectorCuts(0),
0086 fDetectorMessenger(0)
0087 {
0088 fDetectorMessenger = new DetectorMessenger(this);
0089
0090 fEcalLength = 36. * cm;
0091 fEcalWidth = 6. * cm;
0092 fVertexLength = 3. * cm;
0093 fPadLength = 0.1 * mm;
0094 fPadWidth = 0.02 * mm;
0095 fAbsLength = 2. * mm;
0096 fWorldZ = 0.0;
0097 fLogicWorld = 0;
0098 fLogicCal = 0;
0099 fLogicA1 = 0;
0100 fLogicA2 = 0;
0101 fLogicA3 = 0;
0102 fLogicA4 = 0;
0103 fVertexRegion = 0;
0104 fMuonRegion = 0;
0105
0106 DefineMaterials();
0107 fVertexDetectorCuts = new G4ProductionCuts();
0108 fMuonDetectorCuts = new G4ProductionCuts();
0109 }
0110
0111
0112
0113 DetectorConstruction::~DetectorConstruction()
0114 {
0115 delete fDetectorMessenger;
0116 delete fVertexDetectorCuts;
0117 delete fMuonDetectorCuts;
0118 }
0119
0120
0121
0122 G4VPhysicalVolume* DetectorConstruction::Construct()
0123 {
0124 return ConstructVolumes();
0125 }
0126
0127
0128
0129 void DetectorConstruction::DefineMaterials()
0130 {
0131
0132
0133 G4NistManager* man = G4NistManager::Instance();
0134
0135 fWorldMaterial = man->FindOrBuildMaterial("G4_AIR");
0136 fAbsMaterial = man->FindOrBuildMaterial("G4_Al");
0137 fVertMaterial = man->FindOrBuildMaterial("G4_Si");
0138 fYorkMaterial = man->FindOrBuildMaterial("G4_Fe");
0139 fCalMaterial = man->FindOrBuildMaterial("G4_CESIUM_IODIDE");
0140 }
0141
0142
0143
0144 G4VPhysicalVolume* DetectorConstruction::ConstructVolumes()
0145 {
0146
0147
0148 G4GeometryManager::GetInstance()->OpenGeometry();
0149
0150 if (G4NistManager::Instance()->GetVerbose() > 0)
0151 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0152
0153 if (fVertexRegion) {
0154 delete fVertexRegion;
0155 delete fMuonRegion;
0156 }
0157 fVertexRegion = new G4Region("VertexDetector");
0158 fVertexRegion->SetProductionCuts(fVertexDetectorCuts);
0159
0160 fMuonRegion = new G4Region("MuonDetector");
0161 fMuonRegion->SetProductionCuts(fMuonDetectorCuts);
0162
0163 G4SolidStore::GetInstance()->Clean();
0164 G4LogicalVolumeStore::GetInstance()->Clean();
0165 G4PhysicalVolumeStore::GetInstance()->Clean();
0166
0167 if (fVertexLength < fPadLength * 5.0) fVertexLength = fPadLength * 5.0;
0168 G4double gap = 0.01 * mm;
0169 G4double biggap = 2. * cm;
0170 G4double york = 10. * cm;
0171
0172 fWorldZ = 2. * fVertexLength + 3. * fAbsLength + 0.5 * (fEcalLength + york) + biggap * 2.;
0173
0174 G4double worldX = fEcalWidth * 3.0;
0175 G4double vertexZ = -fWorldZ + fVertexLength * 2.0 + fAbsLength + biggap;
0176 G4double absZ2 = -fWorldZ + fVertexLength * 4.0 + fAbsLength * 3.5 + biggap;
0177 G4double ecalZ =
0178 -fWorldZ + fVertexLength * 4.0 + fAbsLength * 4.0 + fEcalLength * 0.5 + 2. * biggap;
0179 G4double yorkZ =
0180 -fWorldZ + fVertexLength * 4.0 + fAbsLength * 5.0 + fEcalLength + york * 0.5 + 3. * biggap;
0181
0182
0183
0184
0185 G4Box* solidW = new G4Box("World", worldX, worldX, fWorldZ);
0186 fLogicWorld = new G4LogicalVolume(solidW, fWorldMaterial, "World");
0187 G4VPhysicalVolume* world =
0188 new G4PVPlacement(0, G4ThreeVector(), "World", fLogicWorld, 0, false, 0);
0189
0190
0191
0192
0193 G4Box* solidE = new G4Box("VolE", worldX, worldX, fEcalLength * 0.5 + gap);
0194 G4LogicalVolume* logicECal = new G4LogicalVolume(solidE, fWorldMaterial, "VolE");
0195 G4VPhysicalVolume* physE =
0196 new G4PVPlacement(0, G4ThreeVector(0., 0., ecalZ), "VolE", logicECal, world, false, 0);
0197
0198 G4Box* solidC = new G4Box("Ecal", fEcalWidth * 0.5, fEcalWidth * 0.5, fEcalLength * 0.5);
0199 fLogicCal = new G4LogicalVolume(solidC, fCalMaterial, "Ecal");
0200
0201 G4cout << "Ecal is " << G4BestUnit(fEcalLength, "Length") << " of " << fCalMaterial->GetName()
0202 << G4endl;
0203
0204
0205
0206 G4double x0 = -(fEcalWidth + gap) * 2.0;
0207 G4double y = x0;
0208 G4double x;
0209 G4int k = 0;
0210 G4int i, j;
0211
0212 for (i = 0; i < 5; i++) {
0213 x = x0;
0214 for (j = 0; j < 5; j++) {
0215 new G4PVPlacement(0, G4ThreeVector(x, y, 0.), "Ecal", fLogicCal, physE, false, k);
0216 k++;
0217 x += fEcalWidth + gap;
0218 }
0219 y += fEcalWidth + gap;
0220 }
0221
0222
0223
0224 G4Box* solidA = new G4Box("Abso", worldX, worldX, fAbsLength * 0.5);
0225 fLogicA2 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs2");
0226 new G4PVPlacement(0, G4ThreeVector(0., 0., absZ2), "Abs2", fLogicA2, world, false, 0);
0227
0228 G4cout << "Absorber is " << G4BestUnit(fAbsLength, "Length") << " of " << fAbsMaterial->GetName()
0229 << G4endl;
0230
0231
0232
0233 G4Box* solidYV = new G4Box("VolY", worldX, worldX, york * 0.5 + fAbsLength);
0234 G4LogicalVolume* logicYV = new G4LogicalVolume(solidYV, fYorkMaterial, "VolY");
0235 G4VPhysicalVolume* physYV =
0236 new G4PVPlacement(0, G4ThreeVector(0., 0., yorkZ), "VolY", logicYV, world, false, 0);
0237
0238 G4Box* solidY = new G4Box("York", worldX, worldX, york * 0.5);
0239 G4LogicalVolume* logicY = new G4LogicalVolume(solidY, fYorkMaterial, "York");
0240 new G4PVPlacement(0, G4ThreeVector(), "York", logicY, physYV, false, 0);
0241
0242 fLogicA3 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs3");
0243 fLogicA4 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs4");
0244
0245 new G4PVPlacement(0, G4ThreeVector(0., 0., -(york + fAbsLength) * 0.5), "Abs3", fLogicA3, physYV,
0246 false, 0);
0247 new G4PVPlacement(0, G4ThreeVector(0., 0., (york + fAbsLength) * 0.5), "Abs4", fLogicA4, physYV,
0248 false, 0);
0249
0250
0251 G4Box* solidVV = new G4Box("VolV", worldX, worldX, fVertexLength * 2. + fAbsLength + gap);
0252 G4LogicalVolume* logicVV = new G4LogicalVolume(solidVV, fWorldMaterial, "VolV");
0253 G4VPhysicalVolume* physVV =
0254 new G4PVPlacement(0, G4ThreeVector(0., 0., vertexZ), "VolV", logicVV, world, false, 0);
0255
0256
0257 fLogicA1 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs1");
0258 new G4PVPlacement(0, G4ThreeVector(0., 0., fVertexLength * 2. - fAbsLength * 0.5), "Abs1",
0259 fLogicA1, physVV, false, 0);
0260
0261
0262 G4double vertWidth = fEcalWidth / 5.;
0263 G4int npads = (G4int)(vertWidth / fPadWidth);
0264
0265
0266
0267 npads = (npads / 2) * 2 + 1;
0268 x0 = -0.5 * (fPadWidth + vertWidth);
0269 G4double x1 = 0.5 * vertWidth + gap;
0270 G4double z = -(fVertexLength + fAbsLength);
0271
0272 G4Box* solidVD = new G4Box("VertDet", x1, fEcalWidth * 0.5 + gap, fPadLength * 0.5);
0273 G4LogicalVolume* logicVD = new G4LogicalVolume(solidVD, fVertMaterial, "VertDet");
0274 logicVD->SetSolid(solidVD);
0275
0276 G4Box* solidV = new G4Box("Vert", fPadWidth * 0.5, fEcalWidth * 0.5, fPadLength * 0.5);
0277 G4LogicalVolume* logicV = new G4LogicalVolume(solidV, fVertMaterial, "Vert");
0278
0279 for (i = 0; i < 3; i++) {
0280 new G4PVPlacement(0, G4ThreeVector(0., 0., z), "VertDet", logicVD, physVV, false, i);
0281 z += fVertexLength;
0282 }
0283 x = x0;
0284
0285 for (j = 0; j < npads; j++) {
0286 new G4PVPlacement(0, G4ThreeVector(x, 0., 0.), logicV, "Vert", logicVD, false, k);
0287 x += fPadWidth;
0288 }
0289
0290 G4cout << "Vertex is " << G4BestUnit(fVertexLength, "Length") << " of 3 layers of Si of "
0291 << G4BestUnit(fPadLength, "Length") << " npads= " << npads << G4endl;
0292
0293
0294 fVertexRegion->AddRootLogicalVolume(logicVV);
0295 fVertexRegion->AddRootLogicalVolume(fLogicA3);
0296
0297
0298 fMuonRegion->AddRootLogicalVolume(logicYV);
0299
0300
0301 logicVV->SetVisAttributes(G4VisAttributes::GetInvisible());
0302 logicV->SetVisAttributes(G4VisAttributes::GetInvisible());
0303 logicECal->SetVisAttributes(G4VisAttributes::GetInvisible());
0304 logicYV->SetVisAttributes(G4VisAttributes::GetInvisible());
0305
0306 G4VisAttributes* regWcolor = new G4VisAttributes(G4Colour(0.3, 0.3, 0.3));
0307 fLogicWorld->SetVisAttributes(regWcolor);
0308
0309 G4VisAttributes* regVcolor = new G4VisAttributes(G4Colour(0., 0.3, 0.7));
0310 logicVD->SetVisAttributes(regVcolor);
0311
0312 G4VisAttributes* regCcolor = new G4VisAttributes(G4Colour(0., 0.7, 0.3));
0313 fLogicCal->SetVisAttributes(regCcolor);
0314
0315 G4VisAttributes* regAcolor = new G4VisAttributes(G4Colour(1., 0.5, 0.5));
0316 fLogicA1->SetVisAttributes(regAcolor);
0317 fLogicA2->SetVisAttributes(regAcolor);
0318 fLogicA3->SetVisAttributes(regAcolor);
0319 fLogicA4->SetVisAttributes(regAcolor);
0320
0321 G4VisAttributes* regMcolor = new G4VisAttributes(G4Colour(1., 1., 0.));
0322 logicY->SetVisAttributes(regMcolor);
0323
0324
0325 G4cout << "### New geometry is constructed" << G4endl;
0326
0327 return world;
0328 }
0329
0330
0331
0332 void DetectorConstruction::SetEcalMaterial(const G4String& mat)
0333 {
0334
0335 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(mat);
0336 if (pttoMaterial && pttoMaterial != fCalMaterial) {
0337 fCalMaterial = pttoMaterial;
0338 if (fLogicCal) {
0339 fLogicCal->SetMaterial(fCalMaterial);
0340 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0341 }
0342 }
0343 }
0344
0345
0346
0347 void DetectorConstruction::SetAbsMaterial(const G4String& mat)
0348 {
0349
0350 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(mat);
0351 if (pttoMaterial && pttoMaterial != fAbsMaterial) {
0352 fAbsMaterial = pttoMaterial;
0353 if (fLogicA1) {
0354 fLogicA1->SetMaterial(fAbsMaterial);
0355 fLogicA2->SetMaterial(fAbsMaterial);
0356 fLogicA3->SetMaterial(fAbsMaterial);
0357 fLogicA4->SetMaterial(fAbsMaterial);
0358 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0359 }
0360 }
0361 }
0362
0363
0364
0365 void DetectorConstruction::UpdateGeometry()
0366 {
0367 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0368 G4RunManager::GetRunManager()->DefineWorldVolume(ConstructVolumes());
0369 }
0370
0371
0372
0373 void DetectorConstruction::SetEcalLength(G4double val)
0374 {
0375 if (val > 0.0) {
0376 fEcalLength = val;
0377 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0378 }
0379 }
0380
0381
0382
0383 void DetectorConstruction::SetEcalWidth(G4double val)
0384 {
0385 if (val > 0.0) {
0386 fEcalWidth = val;
0387 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0388 }
0389 }
0390
0391
0392
0393 void DetectorConstruction::SetVertexLength(G4double val)
0394 {
0395 if (val > 0.0) {
0396 fVertexLength = val;
0397 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0398 }
0399 }
0400
0401
0402
0403 void DetectorConstruction::SetPadLength(G4double val)
0404 {
0405 if (val > 0.0) {
0406 fPadLength = val;
0407 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0408 }
0409 }
0410
0411
0412
0413 void DetectorConstruction::SetPadWidth(G4double val)
0414 {
0415 if (val > 0.0) {
0416 fPadWidth = val;
0417 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0418 }
0419 }
0420
0421
0422
0423 void DetectorConstruction::SetAbsLength(G4double val)
0424 {
0425 if (val > 0.0) {
0426 fAbsLength = val;
0427 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0428 }
0429 }
0430
0431