File indexing completed on 2025-11-04 09:28:04
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 #include "GammaRayTelAnticoincidenceSD.hh"
0038 #include "GammaRayTelCalorimeterSD.hh"
0039 #include "GammaRayTelDetectorConstruction.hh"
0040 #include "GammaRayTelDetectorMessenger.hh"
0041 #include "GammaRayTelTrackerSD.hh"
0042 
0043 #include "G4AutoDelete.hh"
0044 #include "G4Box.hh"
0045 #include "G4Colour.hh"
0046 #include "G4FieldManager.hh"
0047 #include "G4GlobalMagFieldMessenger.hh"
0048 #include "G4LogicalVolume.hh"
0049 #include "G4Material.hh"
0050 #include "G4PhysicalConstants.hh"
0051 #include "G4PVPlacement.hh"
0052 #include "G4PVReplica.hh"
0053 #include "G4RegionStore.hh"
0054 #include "G4RunManager.hh"
0055 #include "G4SDManager.hh"
0056 #include "G4SystemOfUnits.hh"
0057 #include "G4TransportationManager.hh"
0058 #include "G4UImanager.hh"
0059 #include "G4UniformMagField.hh"
0060 #include "G4VisAttributes.hh"
0061 
0062 
0063 
0064 G4ThreadLocal G4GlobalMagFieldMessenger *GammaRayTelDetectorConstruction::fMagFieldMessenger = nullptr;
0065 
0066 GammaRayTelDetectorConstruction::GammaRayTelDetectorConstruction()
0067 {
0068     
0069     trackerSD.Put(nullptr);
0070     calorimeterSD.Put(nullptr);
0071     anticoincidenceSD.Put(nullptr);
0072 
0073     ComputePayloadParameters();
0074 
0075     
0076     detectorMessenger = new GammaRayTelDetectorMessenger(this);
0077 }
0078 
0079 
0080 
0081 GammaRayTelDetectorConstruction::~GammaRayTelDetectorConstruction() {
0082     delete detectorMessenger;
0083 }
0084 
0085 
0086 
0087 auto GammaRayTelDetectorConstruction::Construct() -> G4VPhysicalVolume* {
0088     DefineMaterials();
0089     return ConstructPayload();
0090 }
0091 
0092 
0093 
0094 void GammaRayTelDetectorConstruction::DefineMaterials() {
0095     G4String name;
0096     G4String symbol;
0097 
0098     G4int numberOfAtoms;
0099     G4int numberOfComponents;
0100 
0101     
0102     
0103     
0104 
0105     constexpr auto HYDROGEN_ATOMIC_NUMBER{1.};
0106     constexpr auto HYDROGEN_MOLAR_MASS{1.01 * g / mole};
0107     auto *hydrogen = new G4Element(name = "Hydrogen", symbol = "H", HYDROGEN_ATOMIC_NUMBER, HYDROGEN_MOLAR_MASS);
0108 
0109     constexpr auto CARBON_ATOMIC_NUMBER{6.};
0110     constexpr auto CARBON_MOLAR_MASS{12.01 * g / mole};
0111     auto *carbon = new G4Element(name = "Carbon", symbol = "C", CARBON_ATOMIC_NUMBER, CARBON_MOLAR_MASS);
0112 
0113     constexpr auto NITROGEN_ATOMIC_NUMBER{7.};
0114     constexpr auto NITROGEN_MOLAR_MASS{14.006 * g / mole};
0115     auto *nitrogen = new G4Element(name = "Nitrogen", symbol = "N", NITROGEN_ATOMIC_NUMBER, NITROGEN_MOLAR_MASS);
0116 
0117     constexpr auto OXYGEN_ATOMIC_NUMBER{8.};
0118     constexpr auto OXYGEN_MOLAR_MASS{15.99 * g / mole};
0119     auto *oxygen = new G4Element(name = "Oxygen", symbol = "O", OXYGEN_ATOMIC_NUMBER, OXYGEN_MOLAR_MASS);
0120 
0121     constexpr auto ALUMINIUM_ATOMIC_NUMBER{13.};
0122     constexpr auto ALUMINIUM_MOLAR_MASS{26.98 * g / mole};
0123     auto *aluminium = new G4Element(name = "Aluminum", symbol = "Al", ALUMINIUM_ATOMIC_NUMBER, ALUMINIUM_MOLAR_MASS);
0124 
0125     constexpr auto SILICON_ATOMIC_NUMBER{14.};
0126     constexpr auto SILICON_MOLAR_MASS{28.09 * g / mole};
0127     auto *silicon = new G4Element(name = "Silicon", symbol = "Si", SILICON_ATOMIC_NUMBER, SILICON_MOLAR_MASS);
0128 
0129     constexpr auto IRON_ATOMIC_NUMBER{26.};
0130     constexpr auto IRON_MOLAR_MASS{55.845 * g / mole};
0131     auto *iron = new G4Element(name = "Iron", symbol = "Fe", IRON_ATOMIC_NUMBER, IRON_MOLAR_MASS);
0132 
0133     constexpr auto IODINE_ATOMIC_NUMBER{53.};
0134     constexpr auto IODINE_MOLAR_MASS{126.904 * g / mole};
0135     auto *iodine = new G4Element(name = "Iodine", symbol = "I", IODINE_ATOMIC_NUMBER, IODINE_MOLAR_MASS);
0136 
0137     constexpr auto CESIUM_ATOMIC_NUMBER{55};
0138     constexpr auto CESIUM_MOLAR_MASS{132.905 * g / mole};
0139     auto *cesium = new G4Element(name = "Cesium", symbol = "Cs", CESIUM_ATOMIC_NUMBER, CESIUM_MOLAR_MASS);
0140 
0141     constexpr auto LEAD_ATOMIC_NUMBER{82};
0142     constexpr auto LEAD_MOLAR_MASS{207.19 * g / mole};
0143     auto *lead = new G4Element(name = "Lead", symbol = "Pb", LEAD_ATOMIC_NUMBER, LEAD_MOLAR_MASS);
0144 
0145     
0146     
0147     
0148 
0149     constexpr auto TUNGSTEN_ATOMIC_NUMBER{74.};
0150     constexpr auto TUNGSTEN_DENSITY{19.3 * g / cm3};
0151     constexpr auto TUNGSTEN_MOLAR_MASS{183.84 * g / mole};
0152     auto *tungsten = new G4Material(name = "Tungsten", TUNGSTEN_ATOMIC_NUMBER, TUNGSTEN_MOLAR_MASS, TUNGSTEN_DENSITY);
0153 
0154     
0155     
0156     
0157     
0158 
0159     constexpr auto SCINTILLATOR_MATERIAL_DENSITY{1.032 * g / cm3};
0160     auto *scintillatorMaterial = new G4Material(name = "Scintillator", SCINTILLATOR_MATERIAL_DENSITY, numberOfComponents = 2);
0161     scintillatorMaterial->AddElement(carbon, numberOfAtoms = 9);
0162     scintillatorMaterial->AddElement(hydrogen, numberOfAtoms = 10);
0163 
0164     constexpr auto CESIUM_IODIDE_DENSITY{4.53 * g / cm3};
0165     auto *cesiumIodide = new G4Material(name = "CesiumIodide", CESIUM_IODIDE_DENSITY, numberOfComponents = 2);
0166     cesiumIodide->AddElement(cesium, numberOfAtoms = 5);
0167     cesiumIodide->AddElement(iodine, numberOfAtoms = 5);
0168 
0169     
0170     
0171     
0172     
0173 
0174     constexpr auto AIR_DENSITY{1.290 * mg / cm3};
0175     constexpr auto AIR_NITROGEN_MASS_FRACTION{0.7};
0176     constexpr auto AIR_OXYGEN_MASS_FRACTION{0.3};
0177 
0178     auto *air = new G4Material(name = "Air", AIR_DENSITY, numberOfComponents = 2);
0179     air->AddElement(nitrogen, AIR_NITROGEN_MASS_FRACTION);
0180     air->AddElement(oxygen, AIR_OXYGEN_MASS_FRACTION);
0181 
0182     constexpr auto ALUMINIUM_DENSITY{2.700 * g / cm3};
0183     constexpr auto ALUMINIUM_MASS_FRACTION{1.};
0184     auto *Al = new G4Material(name = "Aluminum", ALUMINIUM_DENSITY, numberOfComponents = 1);
0185     Al->AddElement(aluminium, ALUMINIUM_MASS_FRACTION);
0186 
0187     constexpr auto SILICON_DENSITY{2.333 * g / cm3};
0188     constexpr auto SILICON_MASS_FRACTION{1.};
0189     auto *Si = new G4Material(name = "Silicon", SILICON_DENSITY, numberOfComponents = 1);
0190     Si->AddElement(silicon, SILICON_MASS_FRACTION);
0191 
0192     constexpr auto IRON_DENSITY{7.87 * g / cm3};
0193     constexpr auto IRON_MASS_FRACTION{1.};
0194     auto *Fe = new G4Material(name = "Iron", IRON_DENSITY, numberOfComponents = 1);
0195     Fe->AddElement(iron, IRON_MASS_FRACTION);
0196 
0197     constexpr auto LEAD_DENSITY{11.35 * g / cm3};
0198     constexpr auto LEAD_MASS_FRACTION{1.};
0199     auto *Pb = new G4Material(name = "Lead", LEAD_DENSITY, numberOfComponents = 1);
0200     Pb->AddElement(lead, LEAD_MASS_FRACTION);
0201 
0202     
0203     
0204     
0205     constexpr auto VACUUM_ATOMIC_NUMBER{1.};
0206     constexpr auto VACUUM_DENSITY{universe_mean_density}; 
0207     constexpr auto VACUUM_MOLAR_MASS{1.01 * g / mole};
0208     constexpr auto VACUUM_PRESSURE{3.e-18 * pascal};
0209     constexpr auto VACUUM_TEMPERATURE{2.73 * kelvin};
0210     auto *vacuum = new G4Material(name = "Galactic", VACUUM_ATOMIC_NUMBER, VACUUM_MOLAR_MASS, VACUUM_DENSITY, kStateGas, VACUUM_TEMPERATURE, VACUUM_PRESSURE);
0211 
0212     constexpr auto BEAM_DENSITY{1.e-5 * g / cm3};
0213     constexpr auto BEAM_MASS_FRACTION{1.};
0214     constexpr auto BEAM_PRESSURE{2.e-2 * bar};
0215     constexpr auto BEAM_TEMPERATURE{STP_Temperature}; 
0216     auto *beam = new G4Material(name = "Beam", BEAM_DENSITY, numberOfComponents = 1, kStateGas, BEAM_TEMPERATURE, BEAM_PRESSURE);
0217     beam->AddMaterial(air, BEAM_MASS_FRACTION);
0218 
0219     G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0220 
0221     
0222 
0223     defaultMaterial = vacuum;
0224 
0225     converterMaterial = tungsten;
0226     acdMaterial = scintillatorMaterial; 
0227     calMaterial = cesiumIodide; 
0228     tkrMaterial = Si; 
0229 }
0230 
0231 
0232 
0233 auto GammaRayTelDetectorConstruction::ConstructPayload() -> G4VPhysicalVolume* {
0234     
0235     ComputePayloadParameters();
0236 
0237     
0238     
0239     
0240 
0241     solidWorld = new G4Box("World", worldSizeXY / 2, worldSizeXY / 2, worldSizeZ / 2);
0242     logicWorld = new G4LogicalVolume(solidWorld, defaultMaterial, "World");
0243     physiWorld = new G4PVPlacement(nullptr, G4ThreeVector(), "World", logicWorld, nullptr, false, 0);
0244 
0245     
0246     
0247     
0248 
0249     solidPayload = new G4Box("Payload", payloadSizeXY / 2, payloadSizeXY / 2, payloadSizeZ / 2);
0250     logicPayload = new G4LogicalVolume(solidPayload, defaultMaterial, "Payload");
0251     physiPayload = new G4PVPlacement(nullptr, G4ThreeVector(), "Payload", logicPayload, physiWorld, false, 0);
0252 
0253     
0254     
0255     
0256 
0257     solidCAL = new G4Box("CAL", calSizeXY / 2, calSizeXY / 2, calSizeZ / 2);
0258     logicCAL = new G4LogicalVolume(solidCAL, defaultMaterial, "CAL");
0259     physiCAL = new G4PVPlacement(nullptr,
0260             G4ThreeVector(0, 0,
0261                     -payloadSizeZ / 2 + calSizeZ / 2),
0262             "CAL", logicCAL, physiPayload, false, 0);
0263 
0264     
0265     
0266     
0267 
0268     solidTKR = new G4Box("TKR", tkrSizeXY / 2, tkrSizeXY / 2, tkrSizeZ / 2);
0269     logicTKR = new G4LogicalVolume(solidTKR, defaultMaterial, "TKR");
0270     physiTKR = new G4PVPlacement(nullptr,
0271             G4ThreeVector(0, 0,
0272                     -payloadSizeZ / 2 + calSizeZ + calTKRDistance
0273                         + tkrSizeZ / 2),
0274             "TKR", logicTKR, physiPayload, false, 0);
0275 
0276     
0277     
0278     
0279 
0280     solidACT = new G4Box("ACT", actSizeXY / 2, actSizeXY / 2, actSizeZ / 2);
0281     logicACT = new G4LogicalVolume(solidACT, acdMaterial, "ACT");
0282     physiACT = new G4PVPlacement(nullptr,
0283             G4ThreeVector(0, 0,
0284                     -payloadSizeZ / 2 + calSizeZ + calTKRDistance + tkrSizeZ
0285                             + acdTKRDistance + actSizeZ / 2),
0286             "ACT", logicACT, physiPayload, false, 0);
0287 
0288     
0289     
0290     
0291 
0292     solidACL1 = new G4Box("ACL1", acl1SizeX / 2, acl1SizeY / 2, acl1SizeZ / 2);
0293     logicACL1 = new G4LogicalVolume(solidACL1, acdMaterial, "ACL");
0294 
0295     physiACL1 = new G4PVPlacement(nullptr,
0296             G4ThreeVector(-payloadSizeXY / 2 + acl1SizeX / 2,
0297                     -payloadSizeXY / 2 + acl1SizeY / 2,
0298                     -payloadSizeZ / 2 + acl1SizeZ / 2),
0299             "ACL1", logicACL1, physiPayload, false, 0);
0300 
0301     physiACL1 = new G4PVPlacement(nullptr,
0302             G4ThreeVector(payloadSizeXY / 2 - acl1SizeX / 2,
0303                     payloadSizeXY / 2 - acl1SizeY / 2,
0304                     -payloadSizeZ / 2 + acl1SizeZ / 2),
0305             "ACL1", logicACL1, physiPayload, false, 1);
0306 
0307     solidACL2 = new G4Box("ACL2", acl2SizeX / 2, acl2SizeY / 2, acl2SizeZ / 2);
0308     logicACL2 = new G4LogicalVolume(solidACL2, acdMaterial, "ACL2");
0309 
0310     physiACL2 = new G4PVPlacement(nullptr,
0311             G4ThreeVector(-payloadSizeXY / 2 + acl2SizeX / 2,
0312                     payloadSizeXY / 2 - acl2SizeY / 2,
0313                     -payloadSizeZ / 2 + acl2SizeZ / 2),
0314             "ACL2", logicACL2, physiPayload, false, 0);
0315 
0316     physiACL2 = new G4PVPlacement(nullptr,
0317             G4ThreeVector(payloadSizeXY / 2 - acl2SizeX / 2,
0318                     -payloadSizeXY / 2 + acl2SizeY / 2,
0319                     -payloadSizeZ / 2 + acl2SizeZ / 2),
0320             "ACL2", logicACL2, physiPayload, false, 1);
0321 
0322     
0323     
0324     
0325 
0326     solidPlane = new G4Box("Plane", tkrSizeXY / 2, tkrSizeXY / 2, tkrSupportThickness / 2);
0327     logicPlane = new G4LogicalVolume(solidPlane, defaultMaterial, "Plane");
0328 
0329     solidTKRDetectorY = new G4Box("TKRDetectorY", tkrSizeXY / 2, tkrSizeXY / 2, tkrSiliconThickness / 2);
0330     logicTKRDetectorY = new G4LogicalVolume(solidTKRDetectorY, tkrMaterial, "TKRDetector Y");
0331 
0332     solidTKRDetectorX = new G4Box("TKRDetectorX", tkrSizeXY / 2, tkrSizeXY / 2, tkrSiliconThickness / 2);
0333     logicTKRDetectorX = new G4LogicalVolume(solidTKRDetectorX, tkrMaterial, "TKRDetector X");
0334 
0335     solidConverter = new G4Box("Converter", tkrSizeXY / 2, tkrSizeXY / 2, converterThickness / 2);
0336     logicConverter = new G4LogicalVolume(solidConverter, converterMaterial, "Converter");
0337 
0338     G4int i = 0;
0339 
0340     for (i = 0; i < numberOfTKRLayers; i++) {
0341         physiTKRDetectorY = new G4PVPlacement(nullptr,
0342             G4ThreeVector(0., 0.,
0343                 -tkrSizeZ / 2 + tkrSiliconThickness / 2
0344                     + (i) * tkrLayerDistance),
0345             "TKRDetectorY", logicTKRDetectorY, physiTKR, false, i);
0346 
0347         physiTKRDetectorX = new G4PVPlacement(nullptr,
0348             G4ThreeVector(0., 0.,
0349                 -tkrSizeZ / 2 + tkrSiliconThickness / 2
0350                     + tkrViewsDistance + tkrSiliconThickness
0351                     + (i) * tkrLayerDistance),
0352             "TKRDetectorX", logicTKRDetectorX, physiTKR, false, i);
0353 
0354         physiConverter = new G4PVPlacement(nullptr,
0355             G4ThreeVector(0., 0.,
0356                 -tkrSizeZ / 2 + 2 * tkrSiliconThickness
0357                     + tkrViewsDistance + converterThickness / 2
0358                     + (i) * tkrLayerDistance),
0359             "Converter", logicConverter, physiTKR, false, i);
0360 
0361         physiPlane = new G4PVPlacement(nullptr,
0362             G4ThreeVector(0., 0.,
0363                 -tkrSizeZ / 2 + 2 * tkrSiliconThickness
0364                     + tkrViewsDistance + converterThickness
0365                     + tkrSupportThickness / 2
0366                     + (i) * tkrLayerDistance),
0367             "Plane", logicPlane, physiTKR, false, i);
0368     }
0369 
0370     auto *solidTKRActiveTileX = new G4Box("Active Tile X", tkrActiveTileXY / 2, tkrActiveTileXY / 2, tkrActiveTileZ / 2);
0371     auto *solidTKRActiveTileY = new G4Box("Active Tile Y", tkrActiveTileXY / 2, tkrActiveTileXY / 2, tkrActiveTileZ / 2);
0372 
0373     auto *logicTKRActiveTileX = new G4LogicalVolume(solidTKRActiveTileX, tkrMaterial, "Active Tile X", nullptr, nullptr, nullptr);
0374     auto *logicTKRActiveTileY = new G4LogicalVolume(solidTKRActiveTileY, tkrMaterial, "Active Tile Y", nullptr, nullptr, nullptr);
0375 
0376     G4int j = 0;
0377     G4int k = 0;
0378 
0379     G4double x = 0.;
0380     G4double y = 0.;
0381     G4double z = 0.;
0382 
0383     for (i = 0; i < numberOfTKRTiles; i++) {
0384         for (j = 0; j < numberOfTKRTiles; j++) {
0385             k = i * numberOfTKRTiles + j;
0386 
0387             x = -tkrSizeXY / 2 + tilesSeparation + siliconGuardRing
0388                     + tkrActiveTileXY / 2
0389                     + (i)
0390                         * ((2 * siliconGuardRing) + tilesSeparation
0391                             + tkrActiveTileXY);
0392 
0393             y = -tkrSizeXY / 2 + tilesSeparation + siliconGuardRing
0394                     + tkrActiveTileXY / 2
0395                     + (j)
0396                         * ((2 * siliconGuardRing) + tilesSeparation
0397                             + tkrActiveTileXY);
0398             z = 0.;
0399 
0400             new G4PVPlacement(nullptr, G4ThreeVector(x, y, z), logicTKRActiveTileY, "Active Tile Y", logicTKRDetectorY, false, k);
0401 
0402             x = -tkrSizeXY / 2 + tilesSeparation + siliconGuardRing
0403                     + tkrActiveTileXY / 2
0404                     + (j)
0405                         * ((2 * siliconGuardRing) + tilesSeparation
0406                             + tkrActiveTileXY);
0407 
0408             y = -tkrSizeXY / 2 + tilesSeparation + siliconGuardRing
0409                     + tkrActiveTileXY / 2
0410                     + (i)
0411                         * ((2 * siliconGuardRing) + tilesSeparation
0412                             + tkrActiveTileXY);
0413             z = 0.;
0414 
0415             new G4PVPlacement(nullptr, G4ThreeVector(x, y, z), logicTKRActiveTileX, "Active Tile X", logicTKRDetectorX, false, k);
0416         }
0417     }
0418 
0419     
0420 
0421     
0422 
0423     
0424 
0425 
0426 
0427 
0428 
0429 
0430     tkrXStripX = tkrYStripY = tkrSiliconPitch;
0431     tkrYStripX = tkrXStripY = tkrActiveTileXY;
0432     tkrZStrip = tkrSiliconThickness;
0433 
0434     auto *solidTKRStripX = new G4Box("Strip X", tkrXStripX / 2, tkrYStripX / 2, tkrZStrip / 2);
0435     logicTKRStripX = new G4LogicalVolume(solidTKRStripX, tkrMaterial, "Strip X", nullptr, nullptr, nullptr);
0436 
0437     auto *solidTKRStripY = new G4Box("Strip Y", tkrXStripY / 2, tkrYStripY / 2, tkrZStrip / 2);
0438     logicTKRStripY = new G4LogicalVolume(solidTKRStripY, tkrMaterial, "Strip Y", nullptr, nullptr, nullptr);
0439 
0440     for (i = 0; i < numberOfTKRStrips; i++) {
0441         new G4PVPlacement(nullptr,
0442             G4ThreeVector(
0443                 -tkrActiveTileXY / 2 + tkrSiliconPitch / 2
0444                     + (i) * tkrSiliconPitch, 0., 0.),
0445             logicTKRStripX, "Strip X", logicTKRActiveTileX, false, i);
0446 
0447         new G4PVPlacement(nullptr,
0448             G4ThreeVector(0.,
0449                 -tkrActiveTileXY / 2 + tkrSiliconPitch / 2
0450                     + (i) * tkrSiliconPitch, 0.),
0451             logicTKRStripY, "Strip Y", logicTKRActiveTileY, false, i);
0452     }
0453 
0454     
0455     
0456     
0457 
0458     solidCALLayerX = new G4Box("CALLayerX", calSizeXY / 2, calSizeXY / 2, calBarThickness / 2);
0459     logicCALLayerX = new G4LogicalVolume(solidCALLayerX, calMaterial, "CALLayerX");
0460 
0461     solidCALLayerY = new G4Box("CALLayerY", calSizeXY / 2, calSizeXY / 2, calBarThickness / 2);
0462     logicCALLayerY = new G4LogicalVolume(solidCALLayerY, calMaterial, "CALLayerY");
0463 
0464     for (i = 0; i < numberOfCALLayers; i++) {
0465         physiCALLayerY = new G4PVPlacement(nullptr,
0466             G4ThreeVector(0, 0,
0467                 -calSizeZ / 2 + calBarThickness / 2
0468                     + (i) * 2 * calBarThickness),
0469             "CALLayerY", logicCALLayerY, physiCAL, false, i);
0470 
0471         physiCALLayerX = new G4PVPlacement(nullptr,
0472             G4ThreeVector(0, 0,
0473                 -calSizeZ / 2 + calBarThickness / 2 + calBarThickness
0474                     + (i) * 2 * calBarThickness),
0475             "CALLayerX", logicCALLayerX, physiCAL, false, i);
0476     }
0477 
0478     
0479     
0480     
0481 
0482     solidCALDetectorX = new G4Box("CALDetectorX", calBarX / 2, calBarY / 2, calBarThickness / 2);
0483     logicCALDetectorX = new G4LogicalVolume(solidCALDetectorX, calMaterial, "CALDetectorX");
0484 
0485     solidCALDetectorY = new G4Box("CALDetectorY", calBarY / 2, calBarX / 2, calBarThickness / 2);
0486     logicCALDetectorY = new G4LogicalVolume(solidCALDetectorY, calMaterial, "CALDetectorY");
0487 
0488     for (i = 0; i < numberOfCALBars; i++) {
0489         physiCALDetectorY = new G4PVPlacement(nullptr,
0490             G4ThreeVector(-calSizeXY / 2 + calBarY / 2 + (i) * calBarY, 0, 0),
0491             logicCALDetectorY, "CALDetectorY", logicCALLayerY, false, i);
0492 
0493         physiCALDetectorX = new G4PVPlacement(nullptr,
0494             G4ThreeVector(0, -calSizeXY / 2 + calBarY / 2 + (i) * calBarY, 0),
0495             logicCALDetectorX, "CALDetectorX", logicCALLayerX, false, i);
0496     }
0497 
0498 
0499 
0500 
0501 
0502 
0503 
0504 
0505 
0506 
0507 
0508 
0509 
0510 
0511 
0512 
0513 
0514 
0515 
0516 
0517 
0518     
0519     
0520     
0521     
0522     logicWorld->SetVisAttributes(G4VisAttributes::GetInvisible());
0523     logicPayload->SetVisAttributes(G4VisAttributes::GetInvisible());
0524     logicTKR->SetVisAttributes(G4VisAttributes::GetInvisible());
0525     logicTKRActiveTileX->SetVisAttributes(G4VisAttributes::GetInvisible());
0526     logicTKRActiveTileY->SetVisAttributes(G4VisAttributes::GetInvisible());
0527     logicPlane->SetVisAttributes(G4VisAttributes::GetInvisible());
0528     logicConverter->SetVisAttributes(G4VisAttributes::GetInvisible());
0529     logicCAL->SetVisAttributes(G4VisAttributes::GetInvisible());
0530     logicCALLayerX->SetVisAttributes(G4VisAttributes::GetInvisible());
0531     logicCALLayerY->SetVisAttributes(G4VisAttributes::GetInvisible());
0532     logicTKRStripX->SetVisAttributes(G4VisAttributes::GetInvisible());
0533     logicTKRStripY->SetVisAttributes(G4VisAttributes::GetInvisible());
0534 
0535     
0536 
0537     auto *visualizationStyle1 = new G4VisAttributes(G4Colour(0.3, 0.8, 0.1));
0538     visualizationStyle1->SetVisibility(true);
0539     visualizationStyle1->SetForceSolid(TRUE);
0540 
0541     auto *visualizationStyle2 = new G4VisAttributes(G4Colour(0.2, 0.3, 0.8));
0542     visualizationStyle2->SetVisibility(true);
0543     visualizationStyle2->SetForceSolid(FALSE);
0544 
0545     auto *visualizationStyle3 = new G4VisAttributes(G4Colour(0.8, 0.2, 0.3));
0546     visualizationStyle3->SetVisibility(true);
0547     visualizationStyle3->SetForceWireframe(TRUE);
0548 
0549     
0550 
0551     logicCALDetectorX->SetVisAttributes(visualizationStyle1);
0552     logicCALDetectorY->SetVisAttributes(visualizationStyle1);
0553     logicTKRDetectorX->SetVisAttributes(visualizationStyle2);
0554     logicTKRDetectorY->SetVisAttributes(visualizationStyle2);
0555     logicACT->SetVisAttributes(visualizationStyle3);
0556     logicACL1->SetVisAttributes(visualizationStyle3);
0557     logicACL2->SetVisAttributes(visualizationStyle3);
0558 
0559     
0560     
0561     
0562     PrintPayloadParameters();
0563 
0564     return physiWorld;
0565 }
0566 
0567 
0568 
0569 void GammaRayTelDetectorConstruction::ConstructSDandField() {
0570     
0571     
0572     
0573     if (trackerSD.Get() == nullptr) {
0574         constexpr auto TRACKER_SENSITIVE_DETECTOR_NAME = "TrackerSD";
0575         auto *sensitiveDetector = new GammaRayTelTrackerSD(TRACKER_SENSITIVE_DETECTOR_NAME);
0576         trackerSD.Put(sensitiveDetector);
0577     }
0578 
0579     G4SDManager::GetSDMpointer()->AddNewDetector(trackerSD.Get());
0580 
0581     
0582     if (logicTKRStripX != nullptr) {
0583         SetSensitiveDetector(logicTKRStripX, trackerSD.Get()); 
0584     }
0585     if (logicTKRStripY != nullptr) {
0586         SetSensitiveDetector(logicTKRStripY, trackerSD.Get()); 
0587     }
0588 
0589     
0590     
0591     
0592     if (calorimeterSD.Get() == nullptr) {
0593         constexpr auto CALORIMETER_SENSITIVE_DETECTOR_NAME = "CalorimeterSD";
0594         auto *sensitiveDetector = new GammaRayTelCalorimeterSD(CALORIMETER_SENSITIVE_DETECTOR_NAME);
0595         calorimeterSD.Put(sensitiveDetector);
0596     }
0597 
0598     G4SDManager::GetSDMpointer()->AddNewDetector(calorimeterSD.Get());
0599     if (logicCALDetectorX != nullptr) {
0600         SetSensitiveDetector(logicCALDetectorX, calorimeterSD.Get()); 
0601     }
0602     if (logicCALDetectorY != nullptr) {
0603         SetSensitiveDetector(logicCALDetectorY, calorimeterSD.Get()); 
0604     }
0605 
0606     
0607     
0608     
0609     if (anticoincidenceSD.Get() == nullptr) {
0610         constexpr auto ANTICOINCIDENCE_SENSITIVE_DETECTOR_NAME = "AnticoincidenceSD";
0611         auto *sensitiveDetector = new GammaRayTelAnticoincidenceSD(ANTICOINCIDENCE_SENSITIVE_DETECTOR_NAME);
0612         anticoincidenceSD.Put(sensitiveDetector);
0613     }
0614 
0615     G4SDManager::GetSDMpointer()->AddNewDetector(anticoincidenceSD.Get());
0616     if (logicACT != nullptr) {
0617         SetSensitiveDetector(logicACT, anticoincidenceSD.Get()); 
0618     }
0619     if (logicACL1 != nullptr) {
0620         SetSensitiveDetector(logicACL1, anticoincidenceSD.Get()); 
0621     }
0622     if (logicACL2 != nullptr) {
0623         SetSensitiveDetector(logicACL2, anticoincidenceSD.Get()); 
0624     }
0625 
0626     
0627     
0628     auto fieldValue = G4ThreeVector();
0629     fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue);
0630     fMagFieldMessenger->SetVerboseLevel(1);
0631 
0632     
0633     G4AutoDelete::Register (fMagFieldMessenger);
0634 }
0635 
0636 
0637 
0638 void GammaRayTelDetectorConstruction::PrintPayloadParameters() {
0639     G4cout
0640         << "\n---------------------------------------------------------------------------------\n"
0641         << "---> The tracker is composed by " << numberOfTKRLayers << " layers"
0642         << ", each made of " << converterMaterial->GetName()
0643         << " and " << converterThickness / mm << " mm long."
0644         << "\n---------------------------------------------------------------------------------\n";
0645 }
0646 
0647 
0648 
0649 void GammaRayTelDetectorConstruction::SetConverterMaterial(G4String materialChoice) {
0650     
0651     G4Material *material = G4Material::GetMaterial(materialChoice);
0652     if (material != nullptr) {
0653         converterMaterial = material;
0654         logicConverter->SetMaterial(material);
0655         PrintPayloadParameters();
0656     }
0657 }
0658 
0659 
0660 
0661 void GammaRayTelDetectorConstruction::SetConverterThickness(G4double value) {
0662     converterThickness = value;
0663 }
0664 
0665 
0666 
0667 void GammaRayTelDetectorConstruction::SetTKRSiliconThickness(G4double value) {
0668     tkrSiliconThickness = value;
0669 }
0670 
0671 
0672 
0673 void GammaRayTelDetectorConstruction::SetTKRSiliconPitch(G4double value) {
0674     tkrSiliconPitch = value;
0675 }
0676 
0677 
0678 
0679 void GammaRayTelDetectorConstruction::SetTKRTileSizeXY(G4double value) {
0680     tkrSiliconTileXY = value;
0681 }
0682 
0683 
0684 
0685 void GammaRayTelDetectorConstruction::SetNbOfTKRLayers(G4int value) {
0686     numberOfTKRLayers = value;
0687 }
0688 
0689 
0690 
0691 void GammaRayTelDetectorConstruction::SetNbOfTKRTiles(G4int value) {
0692     numberOfTKRTiles = value;
0693 }
0694 
0695 
0696 
0697 void GammaRayTelDetectorConstruction::SetTKRLayerDistance(G4double value) {
0698     tkrLayerDistance = value;
0699 }
0700 
0701 
0702 
0703 void GammaRayTelDetectorConstruction::SetTKRViewsDistance(G4double value) {
0704     tkrViewsDistance = value;
0705 }
0706 
0707 
0708 
0709 void GammaRayTelDetectorConstruction::SetNbOfCALLayers(G4int value) {
0710     numberOfCALLayers = value;
0711 }
0712 
0713 
0714 
0715 void GammaRayTelDetectorConstruction::SetNbOfCALBars(G4int value) {
0716     numberOfCALBars = value;
0717 }
0718 
0719 
0720 
0721 void GammaRayTelDetectorConstruction::SetCALBarThickness(G4double value) {
0722     calBarThickness = value;
0723 }
0724 
0725 
0726 
0727 void GammaRayTelDetectorConstruction::SetACDThickness(G4double value) {
0728     acdThickness = value;
0729 }
0730 
0731 
0732 
0733 void GammaRayTelDetectorConstruction::SetMagField(G4double fieldValue) {
0734     
0735     std::stringstream stream;
0736     stream << "/globalField/setValue 0 0 " << fieldValue / tesla << " tesla";
0737 
0738     G4String command = stream.str();
0739     G4cout << "Going to execute: " << command << G4endl;
0740 
0741     auto *uiManager = G4UImanager::GetUIpointer();
0742     uiManager->ApplyCommand(command);
0743 }
0744 
0745 
0746 
0747 void GammaRayTelDetectorConstruction::UpdateGeometry() {
0748     
0749     G4RunManager::GetRunManager()->DefineWorldVolume(ConstructPayload());
0750     G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0751     G4RegionStore::GetInstance()->UpdateMaterialList(physiWorld);
0752     G4RunManager::GetRunManager()->ReinitializeGeometry();
0753 }