File indexing completed on 2026-04-29 07:39:55
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 #include "G02DetectorConstruction.hh"
0035
0036
0037
0038 #include "G4GeometryManager.hh"
0039 #include "G4VisAttributes.hh"
0040 #include "globals.hh"
0041
0042
0043
0044 #include "G4Material.hh"
0045
0046
0047
0048 #include "G4Box.hh"
0049 #include "G4LogicalVolume.hh"
0050 #include "G4PVParameterised.hh"
0051 #include "G4PVPlacement.hh"
0052 #include "G4Tubs.hh"
0053 #include "G4VPhysicalVolume.hh"
0054
0055
0056
0057 #include "G4AffineTransform.hh"
0058 #include "G4DisplacedSolid.hh"
0059 #include "G4ReflectedSolid.hh"
0060 #include "G4ReflectionFactory.hh"
0061 #include "G4RotationMatrix.hh"
0062 #include "G4Transform3D.hh"
0063
0064
0065
0066 #include "G4AssemblyVolume.hh"
0067
0068
0069
0070 #include "G02ChamberParameterisation.hh"
0071
0072
0073
0074 #include "G02DetectorMessenger.hh"
0075
0076
0077
0078 #include "G4GDMLParser.hh"
0079 #include "G4PhysicalConstants.hh"
0080 #include "G4SystemOfUnits.hh"
0081
0082
0083
0084
0085
0086 G02DetectorConstruction::G02DetectorConstruction()
0087 : G4VUserDetectorConstruction(), fAir(0), fAluminum(0), fPb(0), fXenon(0), fDetectorMessenger(0)
0088 {
0089 fExpHall_x = 5. * m;
0090
0091 fReadFile = "test.gdml";
0092 fWriteFile = "wtest.gdml";
0093 fStepFile = "mbb";
0094 fWritingChoice = 1;
0095
0096 fDetectorMessenger = new G02DetectorMessenger(this);
0097 }
0098
0099
0100
0101
0102
0103 G02DetectorConstruction::~G02DetectorConstruction()
0104 {
0105 if (fDetectorMessenger) delete fDetectorMessenger;
0106 }
0107
0108
0109
0110
0111
0112 G4VPhysicalVolume* G02DetectorConstruction::Construct()
0113 {
0114
0115
0116 G4VPhysicalVolume* fWorldPhysVol;
0117
0118 if (fWritingChoice == 0) {
0119
0120
0121
0122
0123
0124
0125
0126
0127 fParser.Read(fReadFile);
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0138
0139
0140
0141 fWorldPhysVol = fParser.GetWorldVolume();
0142 }
0143 else if (fWritingChoice == 1) {
0144
0145
0146
0147 ListOfMaterials();
0148 fWorldPhysVol = ConstructDetector();
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 fParser.Write(fWriteFile, fWorldPhysVol);
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 }
0197 else
0198 {
0199
0200
0201 ListOfMaterials();
0202
0203
0204
0205 const G4double expHall_y = fExpHall_x / 50.;
0206 const G4double expHall_z = fExpHall_x / 50.;
0207
0208
0209
0210 G4Box* experimentalHallBox = new G4Box("ExpHallBox", fExpHall_x / 50., expHall_y, expHall_z);
0211 G4LogicalVolume* experimentalHallLV =
0212 new G4LogicalVolume(experimentalHallBox, fAir, "ExpHallLV");
0213 fWorldPhysVol = new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), experimentalHallLV,
0214 "ExpHallPhys", 0, false, 0);
0215
0216
0217
0218 G4LogicalVolume* LogicalVolST = fParser.ParseST(fStepFile, fAir, fAluminum);
0219
0220
0221
0222 new G4PVPlacement(0, G4ThreeVector(10.0, 0.0, 0.0), LogicalVolST, "StepPhys",
0223 experimentalHallLV, false, 0);
0224 }
0225
0226
0227
0228 G4VisAttributes* BoxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0229 fWorldPhysVol->GetLogicalVolume()->SetVisAttributes(BoxVisAtt);
0230
0231 return fWorldPhysVol;
0232 }
0233
0234
0235
0236
0237
0238 void G02DetectorConstruction::ListOfMaterials()
0239 {
0240 G4double a;
0241 G4double z;
0242 G4double density, temperature, pressure;
0243 G4double fractionmass;
0244 G4String name, symbol;
0245 G4int ncomponents;
0246
0247
0248
0249 a = 14.01 * g / mole;
0250 G4Element* elN = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a);
0251
0252 a = 16.00 * g / mole;
0253 G4Element* elO = new G4Element(name = "Oxygen", symbol = "O", z = 8., a);
0254
0255 a = 26.98 * g / mole;
0256 G4Element* elAl = new G4Element(name = "Aluminum", symbol = "Al", z = 13., a);
0257
0258
0259
0260 G4cout << *(G4Element::GetElementTable()) << G4endl;
0261
0262
0263
0264 density = 1.29 * mg / cm3;
0265 fAir = new G4Material(name = "Air", density, ncomponents = 2);
0266 fAir->AddElement(elN, fractionmass = 0.7);
0267 fAir->AddElement(elO, fractionmass = 0.3);
0268
0269
0270
0271 density = 2.70 * g / cm3;
0272 fAluminum = new G4Material(name = "Aluminum", density, ncomponents = 1);
0273 fAluminum->AddElement(elAl, fractionmass = 1.0);
0274
0275
0276
0277 fPb = new G4Material("Lead", z = 82., a = 207.19 * g / mole, density = 11.35 * g / cm3);
0278
0279
0280
0281 fXenon = new G4Material("XenonGas", z = 54., a = 131.29 * g / mole, density = 5.458 * mg / cm3,
0282 kStateGas, temperature = 293.15 * kelvin, pressure = 1 * atmosphere);
0283
0284
0285
0286 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0287 }
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 G4VPhysicalVolume* G02DetectorConstruction::ConstructDetector()
0298 {
0299
0300
0301 const G4double expHall_y = fExpHall_x;
0302 const G4double expHall_z = fExpHall_x;
0303
0304
0305
0306 G4Box* experimentalHallBox = new G4Box("ExpHallBox", fExpHall_x, expHall_y, expHall_z);
0307 G4LogicalVolume* experimentalHallLV = new G4LogicalVolume(experimentalHallBox, fAir, "ExpHallLV");
0308 G4PVPlacement* experimentalHallPhys = new G4PVPlacement(
0309 0, G4ThreeVector(0.0, 0.0, 0.0), experimentalHallLV, "ExpHallPhys", 0, false, 0);
0310
0311
0312
0313 const G4double det_x = fExpHall_x * 0.8;
0314 const G4double det_y = fExpHall_x * 0.7;
0315 const G4double det_z = det_y;
0316
0317
0318
0319 G4Box* detectorBox = new G4Box("detectorBox", det_x, det_y, det_z);
0320 G4LogicalVolume* detectorLV = new G4LogicalVolume(detectorBox, fAir, "detLV");
0321
0322 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), detectorLV, "detPhys", experimentalHallLV,
0323 false, 0);
0324
0325
0326
0327 const G4double room_x = fExpHall_x / 20.;
0328 const G4double room_y = room_x;
0329 const G4double room_z = room_x;
0330
0331 G4Box* roomBox = new G4Box("roomBox", room_x, room_y, room_z);
0332 G4LogicalVolume* roomLV = new G4LogicalVolume(roomBox, fAir, "roomLV");
0333
0334 new G4PVPlacement(0, G4ThreeVector(fExpHall_x - room_x - 10., 0.0, 0.0), roomLV, "roomPhys",
0335 experimentalHallLV, false, 0);
0336
0337
0338
0339 const G4double bigL = fExpHall_x / 5. + 50.;
0340 G4LogicalVolume* subDetectorLV1 = ConstructSubDetector1();
0341
0342 new G4PVPlacement(0, G4ThreeVector(bigL, 0.0, 0.0), subDetectorLV1, "PhysSubDetector1",
0343 detectorLV, false, 0);
0344
0345
0346
0347
0348
0349
0350
0351 G4Translate3D translation(-bigL, 0., 0.);
0352 G4RotationMatrix* rotD3 = new G4RotationMatrix();
0353 G4Transform3D rotation = G4Rotate3D(*rotD3);
0354 G4ReflectX3D reflection;
0355 G4Transform3D transform = translation * rotation * reflection;
0356
0357
0358
0359 G4ReflectionFactory::Instance()->Place(transform, "reflSubDetector", subDetectorLV1, detectorLV,
0360 false, 0);
0361
0362
0363
0364 G4LogicalVolume* subDetectorLV3 = ConstructSubDetector2();
0365
0366 new G4PVPlacement(0, G4ThreeVector(0.0, bigL, 0.0), subDetectorLV3, "PhysSubDetectorFirst3",
0367 detectorLV, false, 0);
0368
0369
0370
0371 G4LogicalVolume* subDetectorLV4 = ConstructSubDetector2();
0372 G4LogicalVolume* subChamberLV = ConstructParametrisationChamber();
0373
0374 new G4PVPlacement(0, G4ThreeVector(0, 0.0, 0.0), subChamberLV, "AssemblyPhys", subDetectorLV4,
0375 false, 0);
0376
0377 new G4PVPlacement(0, G4ThreeVector(0.0, -bigL, 0.0), subDetectorLV4, "PhysSubDetectorSecond3",
0378 detectorLV, false, 0);
0379
0380 return experimentalHallPhys;
0381 }
0382
0383
0384
0385
0386
0387 G4LogicalVolume* G02DetectorConstruction::ConstructSubDetector1()
0388 {
0389 const G4double sub_x = fExpHall_x / 5.;
0390 const G4double sub_y = sub_x;
0391
0392
0393
0394 G4Tubs* subTub = new G4Tubs("subTub", 0., sub_x, sub_y, -90. * deg, 180 * deg);
0395 G4LogicalVolume* subTubLV = new G4LogicalVolume(subTub, fPb, "tubLV");
0396 G4LogicalVolume* AssemblyLV = ConstructAssembly();
0397
0398 new G4PVPlacement(0, G4ThreeVector(sub_x / 3, 0.0, 0.0), AssemblyLV, "AssemblyPhys", subTubLV,
0399 false, 0);
0400 return subTubLV;
0401 }
0402
0403
0404
0405
0406
0407 G4LogicalVolume* G02DetectorConstruction::ConstructSubDetector2()
0408 {
0409 const G4double sub_x = fExpHall_x / 10.;
0410 const G4double sub_y = sub_x * 2.;
0411 const G4double sub_z = sub_x;
0412
0413
0414
0415 G4Box* detHallBox = new G4Box("detHallBox", sub_x, sub_y, sub_z);
0416 G4LogicalVolume* detHallLV = new G4LogicalVolume(detHallBox, fAluminum, "detHallLV");
0417
0418 return detHallLV;
0419 }
0420
0421
0422
0423
0424
0425 G4LogicalVolume* G02DetectorConstruction::ConstructAssembly()
0426 {
0427 const G4double big_x = fExpHall_x / 17;
0428 const G4double big_y = big_x;
0429 const G4double big_z = big_x;
0430
0431
0432
0433 G4Box* OuterBox = new G4Box("OuterBox", big_x, big_y, big_z);
0434 G4LogicalVolume* OuterBoxLV = new G4LogicalVolume(OuterBox, fAir, "OuterBoxLV");
0435
0436 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), OuterBoxLV, "OuterBoxPhys", 0, false, 0);
0437
0438
0439
0440 const G4double bigL = big_x / 2.5;
0441 const G4double medL = big_x / 8;
0442 const G4double smalL = big_x / 12;
0443
0444 G4Box* BigBox = new G4Box("BBox", bigL, bigL, bigL);
0445 G4LogicalVolume* BigBoxLV = new G4LogicalVolume(BigBox, fAluminum, "AlBigBoxLV");
0446 G4Box* MedBox = new G4Box("MBox", medL, medL, medL);
0447 G4LogicalVolume* MedBoxLV1 = new G4LogicalVolume(MedBox, fAluminum, "AlMedBoxLV1");
0448 G4Box* SmallBox = new G4Box("SBox", smalL, smalL, smalL);
0449 G4LogicalVolume* SmallBoxLV = new G4LogicalVolume(SmallBox, fAluminum, "AlSmaBoxLV");
0450
0451 const G4double bigPlace = bigL + 10.;
0452 const G4double medPlace = medL + 10.;
0453
0454 new G4PVPlacement(0, G4ThreeVector(bigPlace, 0.0, 0.0), BigBoxLV, "AlPhysBig", OuterBoxLV, false,
0455 0);
0456
0457
0458
0459 G4Tubs* BigTube = new G4Tubs("BTube", 0, smalL, smalL, -pi / 2., pi);
0460
0461
0462
0463 G4ReflectX3D Xreflection;
0464 G4Translate3D translation(-bigPlace, 0., 0.);
0465 G4Transform3D transform = Xreflection;
0466
0467 G4ReflectedSolid* ReflBig = new G4ReflectedSolid("Refll_Big", BigTube, transform);
0468 G4LogicalVolume* ReflBigLV = new G4LogicalVolume(ReflBig, fXenon, "ReflBigAl");
0469 new G4PVPlacement(0, G4ThreeVector(0., 0.0, 0.0), ReflBigLV, "AlPhysBigTube", SmallBoxLV, false,
0470 0);
0471
0472
0473
0474
0475
0476
0477 G4AssemblyVolume* assembly = new G4AssemblyVolume();
0478 G4RotationMatrix* rot = new G4RotationMatrix();
0479 G4ThreeVector posBig(-bigPlace, 0, 0);
0480 G4ThreeVector posBig0(bigPlace / 4, 0, 0);
0481 G4ThreeVector posMed(-medPlace, 0, 0);
0482 G4ThreeVector posMed0(medPlace, 0, 0);
0483 G4ThreeVector position(0., 0., 0.);
0484
0485
0486
0487 assembly->AddPlacedVolume(MedBoxLV1, posMed0, rot);
0488
0489
0490
0491 assembly->AddPlacedVolume(SmallBoxLV, posMed, rot);
0492
0493
0494
0495 assembly->MakeImprint(BigBoxLV, posBig0, rot, 0);
0496
0497
0498
0499
0500
0501 G4Translate3D translation1(-bigPlace, 0., 0.);
0502 G4RotationMatrix* rotD3 = new G4RotationMatrix();
0503 G4Transform3D rotation = G4Rotate3D(*rotD3);
0504 G4ReflectX3D reflection;
0505 G4Transform3D transform1 = translation1 * rotation * reflection;
0506
0507 assembly->MakeImprint(OuterBoxLV, transform1, 0, 0);
0508
0509 return OuterBoxLV;
0510 }
0511
0512
0513
0514
0515
0516 G4LogicalVolume* G02DetectorConstruction::ConstructParametrisationChamber()
0517 {
0518 const G4double chamber_x = fExpHall_x / 12.;
0519 const G4double chamber_y = chamber_x;
0520 const G4double chamber_z = chamber_x;
0521
0522
0523
0524 G4Box* paramChamberBox = new G4Box("ChamberBox", chamber_x, chamber_y, chamber_z);
0525 G4LogicalVolume* paramChamberLV = new G4LogicalVolume(paramChamberBox, fAir, "ChamberLV");
0526
0527
0528
0529 G4int NbOfChambers = 5;
0530 G4double ChamberWidth = 2 * cm;
0531 G4double ChamberSpacing = 8 * cm;
0532 G4double fTrackerLength = (NbOfChambers + 1) * ChamberSpacing;
0533 G4double trackerSize = 0.5 * fTrackerLength;
0534
0535
0536
0537
0538 G4Box* solidChamber = new G4Box("chamber", 10 * cm, 10 * cm, 1 * cm);
0539 G4LogicalVolume* logicChamber = new G4LogicalVolume(solidChamber, fAluminum, "Chamber", 0, 0, 0);
0540
0541 G4double firstPosition = -trackerSize + 0.5 * ChamberWidth;
0542 G4double firstLength = fTrackerLength / 10;
0543 G4double lastLength = fTrackerLength;
0544
0545 G4VPVParameterisation* chamberParam =
0546 new G02ChamberParameterisation(NbOfChambers,
0547 firstPosition,
0548 ChamberSpacing,
0549 ChamberWidth,
0550 firstLength,
0551 lastLength);
0552
0553 new G4PVParameterised("Chamber",
0554 logicChamber,
0555 paramChamberLV,
0556 kZAxis,
0557 NbOfChambers,
0558 chamberParam);
0559 return paramChamberLV;
0560 }
0561
0562
0563
0564
0565
0566 void G02DetectorConstruction::SetReadFile(const G4String& File)
0567 {
0568 fReadFile = File;
0569 fWritingChoice = 0;
0570 }
0571
0572
0573
0574
0575
0576 void G02DetectorConstruction::SetWriteFile(const G4String& File)
0577 {
0578 fWriteFile = File;
0579 fWritingChoice = 1;
0580 }
0581
0582
0583
0584
0585
0586 void G02DetectorConstruction::SetStepFile(const G4String& File)
0587 {
0588 fStepFile = File;
0589 fWritingChoice = 3;
0590 }