Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 09:22:13

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 //
0027 // ------------------------------------------------------------
0028 //      GEANT 4 class implementation file
0029 //      CERN Geneva Switzerland
0030 //
0031 //
0032 //      ------------ GammaRayTelDetectorConstruction  ------
0033 //           by F.Longo, R.Giannitrapani & G.Santin (13 nov 2000)
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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0063 
0064 G4ThreadLocal G4GlobalMagFieldMessenger *GammaRayTelDetectorConstruction::fMagFieldMessenger = nullptr;
0065 
0066 GammaRayTelDetectorConstruction::GammaRayTelDetectorConstruction()
0067 {
0068     // Initialize thread-local sensitive detectors
0069     trackerSD.Put(nullptr);
0070     calorimeterSD.Put(nullptr);
0071     anticoincidenceSD.Put(nullptr);
0072 
0073     ComputePayloadParameters();
0074 
0075     // create commands for interactive definition of the payload
0076     detectorMessenger = new GammaRayTelDetectorMessenger(this);
0077 }
0078 
0079 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0080 
0081 GammaRayTelDetectorConstruction::~GammaRayTelDetectorConstruction() {
0082     delete detectorMessenger;
0083 }
0084 
0085 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0086 
0087 auto GammaRayTelDetectorConstruction::Construct() -> G4VPhysicalVolume* {
0088     DefineMaterials();
0089     return ConstructPayload();
0090 }
0091 
0092 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0093 
0094 void GammaRayTelDetectorConstruction::DefineMaterials() {
0095     G4String name;
0096     G4String symbol;
0097 
0098     G4int numberOfAtoms;
0099     G4int numberOfComponents;
0100 
0101     //
0102     // define Elements
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     // define simple materials
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     // Define a material from elements.
0156     // Case 1: chemical molecule
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     // Define a material from elements.
0171     // Case 2: mixture by fractional mass
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     // examples of vacuum
0204     //
0205     constexpr auto VACUUM_ATOMIC_NUMBER{1.};
0206     constexpr auto VACUUM_DENSITY{universe_mean_density}; // from PhysicalConstants.h
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}; // from PhysicalConstants.h
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     // default materials of the payload
0222 
0223     defaultMaterial = vacuum;
0224 
0225     converterMaterial = tungsten;
0226     acdMaterial = scintillatorMaterial; // anticoincidence (ACD)
0227     calMaterial = cesiumIodide; // calorimeter (CAL)
0228     tkrMaterial = Si; // tracker (TKR)
0229 }
0230 
0231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0232 
0233 auto GammaRayTelDetectorConstruction::ConstructPayload() -> G4VPhysicalVolume* {
0234     // complete the payload parameters definition
0235     ComputePayloadParameters();
0236 
0237     //
0238     // World
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     // Payload
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     // Calorimeter (CAL)
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     // Tracker (TKR)
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     // Anticoincidence, Top Side (ACT)
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     // Anticoincidence, Lateral Side (ACL)
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     // Tracker Structure (Plane + Converter + TKRDetectorX + TKRDetectorY)
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     // Strips
0420 
0421     // Silicon Strips 
0422 
0423     /*
0424     G4double tkrXStripX{0.};
0425     G4double tkrYStripY{0.};
0426     G4double tkrYStripX{0.};
0427     G4double tkrXStripY{0.};
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     // Calorimeter Structure (CALLayerX + CALLayerY)
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     // Calorimeter Structure (CALDetectorX + CALDetectorY)
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      // Cuts by Region
0500 
0501     G4String regionName[] = {"Calorimeter", "Tracker"};
0502 
0503     if (calorimeterCutRegion) {
0504         delete calorimeterCutRegion;
0505     }
0506     calorimeterCutRegion = new G4Region(regionName[0]);
0507     logicCAL->SetRegion(calorimeterCutRegion);
0508     calorimeterCutRegion->AddRootLogicalVolume(logicCAL);
0509 
0510     if (trackerCutRegion != nullptr) {
0511         delete trackerCutRegion;
0512     }
0513     trackerCutRegion = new G4Region(regionName[1]);
0514     logicTKR->SetRegion(trackerCutRegion);
0515     trackerCutRegion->AddRootLogicalVolume(logicTKR);
0516 */
0517 
0518     //                                        
0519     // Visualization attributes
0520     //
0521     // Invisible Volume
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     // Some visualization styles
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     // Visible Volumes
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     // always return the physical World
0561     //
0562     PrintPayloadParameters();
0563 
0564     return physiWorld;
0565 }
0566 
0567 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0568 
0569 void GammaRayTelDetectorConstruction::ConstructSDandField() {
0570     //
0571     // Sensitive detector: Tracker
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     // Flags the strips as sensitive .
0582     if (logicTKRStripX != nullptr) {
0583         SetSensitiveDetector(logicTKRStripX, trackerSD.Get()); // ActiveStripX
0584     }
0585     if (logicTKRStripY != nullptr) {
0586         SetSensitiveDetector(logicTKRStripY, trackerSD.Get()); // ActiveStripY
0587     }
0588 
0589     //
0590     // Sensitive detector: Calorimeter
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()); // CAL BarX
0601     }
0602     if (logicCALDetectorY != nullptr) {
0603         SetSensitiveDetector(logicCALDetectorY, calorimeterSD.Get()); // CAL BarY
0604     }
0605 
0606     //
0607     // Sensitive detector: Anticoincidence
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()); // ACD top
0618     }
0619     if (logicACL1 != nullptr) {
0620         SetSensitiveDetector(logicACL1, anticoincidenceSD.Get()); // ACD lateral side
0621     }
0622     if (logicACL2 != nullptr) {
0623         SetSensitiveDetector(logicACL2, anticoincidenceSD.Get()); // ACD lateral side
0624     }
0625 
0626     // Create global magnetic field messenger.
0627     // Uniform magnetic field is then created automatically if the field value is not zero.
0628     auto fieldValue = G4ThreeVector();
0629     fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue);
0630     fMagFieldMessenger->SetVerboseLevel(1);
0631 
0632     // Register the field messenger for deleting
0633     G4AutoDelete::Register (fMagFieldMessenger);
0634 }
0635 
0636 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0648 
0649 void GammaRayTelDetectorConstruction::SetConverterMaterial(G4String materialChoice) {
0650     // search the material by its name   
0651     G4Material *material = G4Material::GetMaterial(materialChoice);
0652     if (material != nullptr) {
0653         converterMaterial = material;
0654         logicConverter->SetMaterial(material);
0655         PrintPayloadParameters();
0656     }
0657 }
0658 
0659 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0660 
0661 void GammaRayTelDetectorConstruction::SetConverterThickness(G4double value) {
0662     converterThickness = value;
0663 }
0664 
0665 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0666 
0667 void GammaRayTelDetectorConstruction::SetTKRSiliconThickness(G4double value) {
0668     tkrSiliconThickness = value;
0669 }
0670 
0671 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0672 
0673 void GammaRayTelDetectorConstruction::SetTKRSiliconPitch(G4double value) {
0674     tkrSiliconPitch = value;
0675 }
0676 
0677 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0678 
0679 void GammaRayTelDetectorConstruction::SetTKRTileSizeXY(G4double value) {
0680     tkrSiliconTileXY = value;
0681 }
0682 
0683 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0684 
0685 void GammaRayTelDetectorConstruction::SetNbOfTKRLayers(G4int value) {
0686     numberOfTKRLayers = value;
0687 }
0688 
0689 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0690 
0691 void GammaRayTelDetectorConstruction::SetNbOfTKRTiles(G4int value) {
0692     numberOfTKRTiles = value;
0693 }
0694 
0695 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0696 
0697 void GammaRayTelDetectorConstruction::SetTKRLayerDistance(G4double value) {
0698     tkrLayerDistance = value;
0699 }
0700 
0701 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0702 
0703 void GammaRayTelDetectorConstruction::SetTKRViewsDistance(G4double value) {
0704     tkrViewsDistance = value;
0705 }
0706 
0707 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0708 
0709 void GammaRayTelDetectorConstruction::SetNbOfCALLayers(G4int value) {
0710     numberOfCALLayers = value;
0711 }
0712 
0713 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0714 
0715 void GammaRayTelDetectorConstruction::SetNbOfCALBars(G4int value) {
0716     numberOfCALBars = value;
0717 }
0718 
0719 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0720 
0721 void GammaRayTelDetectorConstruction::SetCALBarThickness(G4double value) {
0722     calBarThickness = value;
0723 }
0724 
0725 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0726 
0727 void GammaRayTelDetectorConstruction::SetACDThickness(G4double value) {
0728     acdThickness = value;
0729 }
0730 
0731 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0732 
0733 void GammaRayTelDetectorConstruction::SetMagField(G4double fieldValue) {
0734     // Just invoke manually the MT-safe command /globalField/setValue instantiated by the GlobalFieldMessenger
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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0746 
0747 void GammaRayTelDetectorConstruction::UpdateGeometry() {
0748     // delete payloadSD;
0749     G4RunManager::GetRunManager()->DefineWorldVolume(ConstructPayload());
0750     G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0751     G4RegionStore::GetInstance()->UpdateMaterialList(physiWorld);
0752     G4RunManager::GetRunManager()->ReinitializeGeometry();
0753 }