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