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