File indexing completed on 2025-02-23 09:22:33
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 #include "Par03DetectorConstruction.hh"
0027
0028 #include "Par03DetectorMessenger.hh"
0029 #include "Par03EMShowerModel.hh"
0030 #include "Par03SensitiveDetector.hh"
0031
0032 #include "G4Box.hh"
0033 #include "G4LogicalVolume.hh"
0034 #include "G4Material.hh"
0035 #include "G4NistManager.hh"
0036 #include "G4PVPlacement.hh"
0037 #include "G4PVReplica.hh"
0038 #include "G4Region.hh"
0039 #include "G4RegionStore.hh"
0040 #include "G4RunManager.hh"
0041 #include "G4SDManager.hh"
0042 #include "G4Tubs.hh"
0043 #include "G4UnitsTable.hh"
0044 #include "G4VisAttributes.hh"
0045
0046
0047
0048 Par03DetectorConstruction::Par03DetectorConstruction() : G4VUserDetectorConstruction()
0049 {
0050 fDetectorMessenger = new Par03DetectorMessenger(this);
0051
0052 G4NistManager* nistManager = G4NistManager::Instance();
0053 fDetectorMaterial = nistManager->FindOrBuildMaterial("G4_Fe");
0054 }
0055
0056
0057
0058 Par03DetectorConstruction::~Par03DetectorConstruction() = default;
0059
0060
0061
0062 G4VPhysicalVolume* Par03DetectorConstruction::Construct()
0063 {
0064
0065 G4NistManager* nistManager = G4NistManager::Instance();
0066 G4Material* air = nistManager->FindOrBuildMaterial("G4_AIR");
0067
0068
0069 G4double full2Pi = 2. * CLHEP::pi * rad;
0070 G4double layerThickness = fDetectorLength / fNbOfLayers;
0071 G4double cellPhi = full2Pi / fNbOfPhiCells;
0072 G4double cellDR = fDetectorRadius / fNbOfRhoCells;
0073
0074
0075 auto fSolidWorld = new G4Box("World",
0076 fWorldSize / 2.,
0077 fWorldSize / 2.,
0078 fWorldSize / 2.);
0079 auto fLogicWorld = new G4LogicalVolume(fSolidWorld,
0080 air,
0081 "World");
0082 auto fPhysicWorld = new G4PVPlacement(0,
0083 G4ThreeVector(),
0084 fLogicWorld,
0085 "World",
0086 0,
0087 false,
0088 999,
0089 true);
0090
0091
0092 auto fSolidDetector = new G4Tubs("Detector",
0093 0,
0094 fDetectorRadius,
0095 fDetectorLength / 2.,
0096 0,
0097 full2Pi);
0098 auto fLogicDetector = new G4LogicalVolume(fSolidDetector,
0099 fDetectorMaterial,
0100 "Detector");
0101 new G4PVPlacement(0,
0102 G4ThreeVector(0, 0,
0103 fDetectorLength / 2),
0104 fLogicDetector,
0105 "Detector",
0106 fLogicWorld,
0107 false,
0108 99,
0109 true);
0110
0111
0112 auto detectorRegion = new G4Region("DetectorRegion");
0113 detectorRegion->AddRootLogicalVolume(fLogicDetector);
0114
0115
0116
0117 auto fSolidLayer = new G4Tubs("Layer",
0118 0,
0119 fDetectorRadius,
0120 layerThickness / 2.,
0121 0,
0122 full2Pi);
0123 auto fLogicLayer = new G4LogicalVolume(fSolidLayer,
0124 air,
0125 "Layer");
0126 if (fNbOfLayers > 1)
0127 new G4PVReplica("Layer",
0128 fLogicLayer,
0129 fLogicDetector,
0130 kZAxis,
0131 fNbOfLayers,
0132 layerThickness);
0133 else
0134 new G4PVPlacement(0,
0135 G4ThreeVector(),
0136 fLogicLayer,
0137 "Layer",
0138 fLogicDetector,
0139 false,
0140 0,
0141 true);
0142
0143
0144 auto fSolidRow = new G4Tubs("Row",
0145 0,
0146 fDetectorRadius,
0147 layerThickness / 2.,
0148 0,
0149 cellPhi);
0150
0151 auto fLogicRow = new G4LogicalVolume(fSolidRow,
0152 air,
0153 "Segment");
0154 if (fNbOfPhiCells > 1)
0155 new G4PVReplica("Segment",
0156 fLogicRow,
0157 fLogicLayer,
0158 kPhi,
0159 fNbOfPhiCells,
0160 cellPhi);
0161 else
0162 new G4PVPlacement(0,
0163 G4ThreeVector(),
0164 fLogicRow,
0165 "Row",
0166 fLogicLayer,
0167 false,
0168 0,
0169 true);
0170
0171
0172
0173 auto fSolidCell = new G4Tubs("Cell",
0174 0,
0175 cellDR,
0176 layerThickness / 2.,
0177 0,
0178 cellPhi);
0179
0180 fLogicCell = new G4LogicalVolume(fSolidCell,
0181 fDetectorMaterial,
0182 "Cell");
0183 if (fNbOfRhoCells > 1)
0184 new G4PVReplica("Cell",
0185 fLogicCell,
0186 fLogicRow,
0187 kRho,
0188 fNbOfRhoCells,
0189 cellDR);
0190 else
0191 new G4PVPlacement(0,
0192 G4ThreeVector(),
0193 fLogicCell,
0194 "Cell",
0195 fLogicRow,
0196 false,
0197 0,
0198 true);
0199
0200
0201 fLogicWorld->SetVisAttributes(G4VisAttributes::GetInvisible());
0202 fLogicLayer->SetVisAttributes(G4VisAttributes::GetInvisible());
0203 fLogicRow->SetVisAttributes(G4VisAttributes::GetInvisible());
0204 G4VisAttributes attribs;
0205 attribs.SetColour(G4Colour(0, 0, 1, 0.3));
0206 attribs.SetForceSolid(true);
0207 fLogicCell->SetVisAttributes(attribs);
0208
0209 Print();
0210 return fPhysicWorld;
0211 }
0212
0213
0214
0215 void Par03DetectorConstruction::ConstructSDandField()
0216 {
0217 Par03SensitiveDetector* caloSD =
0218 new Par03SensitiveDetector("sensitiveDetector", fNbOfLayers, fNbOfPhiCells, fNbOfRhoCells);
0219 G4SDManager::GetSDMpointer()->AddNewDetector(caloSD);
0220 SetSensitiveDetector(fLogicCell, caloSD);
0221
0222 auto detectorRegion = G4RegionStore::GetInstance()->GetRegion("DetectorRegion");
0223 new Par03EMShowerModel("model", detectorRegion);
0224 }
0225
0226
0227
0228 void Par03DetectorConstruction::Print() const
0229 {
0230 G4cout << "\n------------------------------------------------------"
0231 << "\n--- Detector material:\t" << fDetectorMaterial->GetName()
0232 << "\n--- Detector length:\t" << G4BestUnit(fDetectorLength, "Length")
0233 << "\n--- Detector radius:\t" << G4BestUnit(fDetectorRadius, "Length")
0234 << "\n--- Number of layers:\t" << fNbOfLayers << "\n--- Number of R-cells:\t"
0235 << fNbOfRhoCells << "\n--- Number of phi-cells:\t" << fNbOfPhiCells << G4endl;
0236 G4cout << "-----------------------------------------------------" << G4endl;
0237 }
0238
0239
0240
0241 void Par03DetectorConstruction::SetMaterial(const G4String& aName)
0242 {
0243
0244 G4Material* material = G4NistManager::Instance()->FindOrBuildMaterial(aName);
0245 if (material)
0246 fDetectorMaterial = material;
0247 else
0248 G4Exception("Par03DetectorConstruction::SetMaterial()", "InvalidSetup", FatalException,
0249 ("Unknown material name: " + aName).c_str());
0250 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0251 }
0252
0253
0254
0255 void Par03DetectorConstruction::SetRadius(G4double aRadius)
0256 {
0257
0258 if (aRadius >= fWorldSize / 2.)
0259 G4Exception("Par03DetectorConstruction::SetRadius()", "InvalidSetup", FatalException,
0260 ("Detector radius cannot be larger than the world size ("
0261 + G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
0262 .c_str());
0263 fDetectorRadius = aRadius;
0264 }
0265
0266
0267 void Par03DetectorConstruction::SetLength(G4double aLength)
0268 {
0269
0270 if (aLength >= fWorldSize / 2.)
0271 G4Exception("Par03DetectorConstruction::SetLength()", "InvalidSetup", FatalException,
0272 ("Detector length cannot be larger than the world size ("
0273 + G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
0274 .c_str());
0275 fDetectorLength = aLength;
0276 }