File indexing completed on 2026-09-10 08:29:52
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 #include "Par04ParallelFastWorld.hh"
0031
0032 #include "Par04ParallelFastSensitiveDetector.hh"
0033 #include "Par04ParallelFullWorld.hh"
0034
0035
0036 #include "G4AutoDelete.hh"
0037 #include "G4Colour.hh"
0038 #include "G4LogicalVolume.hh"
0039 #include "G4Material.hh"
0040 #include "G4NistManager.hh"
0041 #include "G4PVPlacement.hh"
0042 #include "G4PVReplica.hh"
0043 #include "G4SDManager.hh"
0044 #include "G4SystemOfUnits.hh"
0045 #include "G4ThreeVector.hh"
0046 #include "G4Tubs.hh"
0047 #include "G4UnitsTable.hh"
0048 #include "G4VPhysicalVolume.hh"
0049 #include "G4VisAttributes.hh"
0050 #include "globals.hh"
0051
0052
0053
0054 Par04ParallelFastWorld::Par04ParallelFastWorld(G4String aWorldName,
0055 const Par04DetectorConstruction* aMassDetector,
0056 const Par04ParallelFullWorld* aParallelFull)
0057 : G4VUserParallelWorld(aWorldName), fMassDetector(aMassDetector), fParallelFull(aParallelFull)
0058 {
0059 fNbOfLayers = fMassDetector->GetNbOfLayers();
0060 }
0061
0062
0063
0064 Par04ParallelFastWorld::~Par04ParallelFastWorld() = default;
0065
0066
0067
0068 void Par04ParallelFastWorld::Construct()
0069 {
0070
0071 G4Material* dummy = nullptr;
0072
0073
0074 auto parallelLogicalVolume = GetWorld()->GetLogicalVolume();
0075
0076 G4double detectorInnerRadius = fMassDetector->GetInnerRadius();
0077 G4double detectorLength = fMassDetector->GetLength();
0078 G4double fullLayerThickness =
0079 fMassDetector->GetAbsorberThickness(0) + fMassDetector->GetAbsorberThickness(1);
0080 fLayerThickness = fullLayerThickness;
0081
0082 fNbOfLayers = fMassDetector->GetNbOfLayers();
0083 fNbOfSlices = fParallelFull->GetNbOfSlices();
0084 fNbOfRows = fParallelFull->GetNbOfRows();
0085 G4double detectorRadius = fNbOfLayers * fullLayerThickness;
0086 G4double detectorOuterRadius = detectorInnerRadius + detectorRadius;
0087 G4double rowThickness = detectorLength / fNbOfRows;
0088 G4double full2Pi = 2. * CLHEP::pi * rad;
0089 Print();
0090
0091
0092
0093 auto solidDetector = new G4Tubs("Detector",
0094 detectorInnerRadius,
0095 detectorOuterRadius,
0096 detectorLength / 2.,
0097 0,
0098 full2Pi);
0099 auto logicDetector = new G4LogicalVolume(solidDetector,
0100 dummy,
0101 "Detector");
0102 new G4PVPlacement(0,
0103 G4ThreeVector(0, 0, 0),
0104 logicDetector,
0105 "Detector",
0106 parallelLogicalVolume,
0107 false,
0108 9999,
0109 true);
0110
0111
0112 auto solidRow =
0113 new G4Tubs("Row", detectorInnerRadius, detectorOuterRadius, rowThickness / 2., 0, full2Pi);
0114
0115 auto logicRow = new G4LogicalVolume(solidRow, dummy, "Row");
0116 if (fNbOfRows > 1)
0117 new G4PVReplica("Row", logicRow, logicDetector, kZAxis, fNbOfRows, rowThickness);
0118 else
0119 new G4PVPlacement(0, G4ThreeVector(), logicRow, "Row", logicDetector, false, 0);
0120
0121
0122 G4double cellPhi = full2Pi / fNbOfSlices;
0123 auto solidSlice =
0124 new G4Tubs("Slice", detectorInnerRadius, detectorOuterRadius, rowThickness / 2, 0, cellPhi);
0125 auto logicSlice = new G4LogicalVolume(solidSlice, dummy, "Slice");
0126 if (fNbOfSlices > 1) {
0127 new G4PVReplica("Slice", logicSlice, logicRow, kPhi, fNbOfSlices, cellPhi, -cellPhi);
0128 }
0129 else {
0130 new G4PVPlacement(0, G4ThreeVector(), logicSlice, "Slice", logicRow, false, 0);
0131 }
0132
0133
0134 G4VisAttributes attribs;
0135 attribs.SetColour(G4Colour(0, 1, 0, 0.1));
0136 attribs.SetForceSolid(true);
0137 if (fNbOfLayers > 1) {
0138 auto solidCell = new G4Tubs("Cell", detectorInnerRadius, detectorInnerRadius + fLayerThickness,
0139 rowThickness / 2, 0, cellPhi);
0140 fLogicalCell.push_back(new G4LogicalVolume(solidCell, dummy, "Cell_0"));
0141 new G4PVReplica("Cell", fLogicalCell.back(), logicSlice, kRho, fNbOfLayers, fLayerThickness,
0142 detectorInnerRadius);
0143 }
0144 else {
0145 auto solidCell = new G4Tubs("Cell", detectorInnerRadius, detectorInnerRadius + fLayerThickness,
0146 rowThickness / 2, 0, cellPhi);
0147 fLogicalCell.push_back(new G4LogicalVolume(solidCell, dummy, "Cell"));
0148 fLogicalCell.back()->SetVisAttributes(attribs);
0149 new G4PVPlacement(0, G4ThreeVector(), fLogicalCell.back(), "Cell", logicSlice, false, 0);
0150 }
0151 Print();
0152 }
0153
0154
0155
0156 void Par04ParallelFastWorld::ConstructSD()
0157 {
0158
0159 G4SDManager* SDman = G4SDManager::GetSDMpointer();
0160 Par04ParallelFastSensitiveDetector* caloSD =
0161 new Par04ParallelFastSensitiveDetector("parallelFastSD", fNbOfLayers, fNbOfSlices);
0162 SDman->AddNewDetector(caloSD);
0163 for (const auto& logicalCell : fLogicalCell)
0164 logicalCell->SetSensitiveDetector(caloSD);
0165 }
0166
0167
0168
0169 void Par04ParallelFastWorld::Print()
0170 {
0171 G4cout << "\n------------------------------------------------------"
0172 << "\n Readout geometry with physics layout is set in parallel geometry:\t"
0173 << "\n Cylindrical detector is divided along radius (layers), phi (slices), and z (rows)."
0174 << "\n Number of layers is determined by number of layers set in detector construction. "
0175 << "\n- Number of layers: " << fNbOfLayers << "\n------- Number of slices: " << fNbOfSlices
0176 << "\n- Number of rows: " << fNbOfRows;
0177 G4cout << "\n Readout will collect energy from fast simulation.\n------- Thickness is "
0178 << "a sum of all absorbers"
0179 << " = " << G4BestUnit(fLayerThickness, "Length")
0180 << "\n-----------------------------------------------------" << G4endl;
0181 }