File indexing completed on 2025-02-23 09:22:20
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 "VoxelizedSensitiveDetector.hh"
0031
0032 #include "G4Box.hh"
0033 #include "G4LogicalVolume.hh"
0034 #include "G4PVReplica.hh"
0035 #include "G4PhysicalVolumeStore.hh"
0036 #include "G4RunManager.hh"
0037 #include "G4SDManager.hh"
0038 #include "G4SystemOfUnits.hh"
0039 #include "G4TransportationManager.hh"
0040 #include "G4VPhysicalVolume.hh"
0041
0042 #include "DetectorConstruction.hh"
0043 #include "SD.hh"
0044 #include "VoxelizedSensitiveDetectorMessenger.hh"
0045
0046 namespace RadioBio
0047 {
0048
0049
0050
0051 VoxelizedSensitiveDetector* VoxelizedSensitiveDetector::fInstance = nullptr;
0052
0053
0054
0055 VoxelizedSensitiveDetector* VoxelizedSensitiveDetector::CreateInstance(DetectorConstruction* det,
0056 double xWidth, double yWidth,
0057 double zWidth)
0058 {
0059 if (fInstance) {
0060 delete fInstance;
0061 G4Exception("VoxelizedSensitiveDetector::createInstance", "RecreatingVoxelization",
0062 FatalException, "Creating another, new, instance of VoxelizedSensitiveDetector");
0063 }
0064 fInstance = new VoxelizedSensitiveDetector(det, xWidth, yWidth, zWidth);
0065 return fInstance;
0066 }
0067
0068
0069
0070 VoxelizedSensitiveDetector* VoxelizedSensitiveDetector::GetInstance()
0071 {
0072 return fInstance;
0073 }
0074
0075
0076
0077 VoxelizedSensitiveDetector::VoxelizedSensitiveDetector(DetectorConstruction* det, double xWidth,
0078 double yWidth, double zWidth)
0079 : fDetector(det), fVoxelWidthX(xWidth), fVoxelWidthY(yWidth), fVoxelWidthZ(zWidth)
0080 {
0081 fVoxelizedSensitiveDetectorMessenger = new VoxelizedSensitiveDetectorMessenger(this);
0082 UpdateVoxelVolume();
0083 CalculateVoxelNumber();
0084 }
0085
0086
0087
0088 VoxelizedSensitiveDetector::~VoxelizedSensitiveDetector()
0089 {
0090 delete fVoxelizedSensitiveDetectorMessenger;
0091 }
0092
0093
0094
0095 void VoxelizedSensitiveDetector::UpdateVoxelVolume()
0096 {
0097 fVoxelVolume = fVoxelWidthX * fVoxelWidthY * fVoxelWidthZ;
0098 fVoxelDensity = fDetector->GetMaterial()->GetDensity();
0099 fVoxelMass = fVoxelVolume * fVoxelDensity;
0100 }
0101
0102
0103
0104 void VoxelizedSensitiveDetector::SetVoxelWidth(G4ThreeVector voxWidth)
0105 {
0106 fVoxelWidthX = voxWidth.getX();
0107 fVoxelWidthY = voxWidth.getY();
0108 fVoxelWidthZ = voxWidth.getZ();
0109 CalculateVoxelNumber();
0110 }
0111
0112
0113
0114 void VoxelizedSensitiveDetector::SetVoxelWidthX(G4double voxWidthX)
0115 {
0116 if (fVoxelWidthX == voxWidthX) return;
0117 fVoxelWidthX = voxWidthX;
0118 CalculateVoxelNumber();
0119 }
0120
0121
0122
0123 void VoxelizedSensitiveDetector::SetVoxelWidthY(G4double voxWidthY)
0124 {
0125 if (fVoxelWidthY == voxWidthY) return;
0126 fVoxelWidthY = voxWidthY;
0127 CalculateVoxelNumber();
0128 }
0129
0130
0131
0132 void VoxelizedSensitiveDetector::SetVoxelWidthZ(G4double voxWidthZ)
0133 {
0134 if (fVoxelWidthZ == voxWidthZ) return;
0135 fVoxelWidthZ = voxWidthZ;
0136 CalculateVoxelNumber();
0137 }
0138
0139
0140
0141
0142
0143 void VoxelizedSensitiveDetector::CalculateVoxelNumber()
0144 {
0145 fVoxelNumberAlongX = G4int(fDetector->GetSizeX() / fVoxelWidthX);
0146 fVoxelWidthX = fDetector->GetSizeX() / G4double(fVoxelNumberAlongX);
0147
0148 fVoxelNumberAlongY = G4int(fDetector->GetSizeY() / fVoxelWidthY);
0149 fVoxelWidthY = fDetector->GetSizeY() / G4double(fVoxelNumberAlongY);
0150
0151 fVoxelNumberAlongZ = G4int(fDetector->GetSizeZ() / fVoxelWidthZ);
0152 fVoxelWidthZ = fDetector->GetSizeZ() / G4double(fVoxelNumberAlongZ);
0153
0154 if (fVoxelNumberAlongY % 2 == 0)
0155 G4Exception("VoxelizedSensitiveDetector::CalculateVoxelNumber", "VoxelNumberYEven", JustWarning,
0156 "Trying to voxelize with an even number of voxels along the Y axis."
0157 "Please select an odd number to prevent from warnings due to tracking");
0158
0159 if (fVoxelNumberAlongZ % 2 == 0)
0160 G4Exception("VoxelizedSensitiveDetector::CalculateVoxelNumber", "VoxelNumberZEven", JustWarning,
0161 "Trying to voxelize with an even number of voxels along the Z axis."
0162 "Please select an odd number to prevent from warnings due to tracking");
0163
0164 fTotalVoxelNumber = fVoxelNumberAlongX * fVoxelNumberAlongY * fVoxelNumberAlongZ;
0165
0166 UpdateVoxelVolume();
0167 }
0168
0169
0170
0171 void VoxelizedSensitiveDetector::ConstructXDivision()
0172 {
0173 if (fWorldLogical == nullptr)
0174 G4Exception("VoxelizedSensitiveDetector::ConstructXDivision", "WorldNotInit", FatalException,
0175 "Voxelizing without having a pointer to world logical volume!");
0176
0177 if (!fDetector)
0178 G4Exception("VoxelizedSensitiveDetector::ConstructXDivision", "DetConstInit", FatalException,
0179 "Voxelizing without having a pointer to DetectorConstruction!");
0180
0181 fVoxelizedDetectorXDivision = new G4Box("VoxelizedDetectorXDivision", fVoxelWidthX / 2,
0182 fDetector->GetSizeY() / 2, fDetector->GetSizeZ() / 2);
0183
0184 fVoxelizedDetectorXDivisionLog =
0185 new G4LogicalVolume(fVoxelizedDetectorXDivision, fWorldLogical->GetMaterial(),
0186 "VoxelizedDetectorXDivisionLog", 0, 0, 0);
0187
0188 fVoxelizedDetectorXDivisionPhys =
0189 new G4PVReplica("VoxelizedDetectorXDivisionPhys", fVoxelizedDetectorXDivisionLog, fWorldLogical,
0190 kXAxis, fVoxelNumberAlongX, fVoxelWidthX);
0191 }
0192
0193
0194
0195 void VoxelizedSensitiveDetector::ConstructYDivision()
0196 {
0197 fVoxelizedDetectorYDivision = new G4Box("VoxelizedDetectorYDivision", fVoxelWidthX / 2,
0198 fVoxelWidthY / 2, fDetector->GetSizeZ() / 2);
0199
0200 fVoxelizedDetectorYDivisionLog =
0201 new G4LogicalVolume(fVoxelizedDetectorYDivision, fWorldLogical->GetMaterial(),
0202 "VoxelizedDetectorYDivisionLog", 0, 0, 0);
0203
0204 fVoxelizedDetectorYDivisionPhys =
0205 new G4PVReplica("VoxelizedDetectorYDivisionPhys", fVoxelizedDetectorYDivisionLog,
0206 fVoxelizedDetectorXDivisionLog, kYAxis, fVoxelNumberAlongY, fVoxelWidthY);
0207 }
0208
0209
0210
0211 void VoxelizedSensitiveDetector::ConstructZDivision()
0212 {
0213 fVoxelizedDetectorZDivision =
0214 new G4Box("VoxelizedDetectorZDivision", fVoxelWidthX / 2, fVoxelWidthY / 2, fVoxelWidthZ / 2);
0215
0216 fVoxelizedDetectorZDivisionLog =
0217 new G4LogicalVolume(fVoxelizedDetectorZDivision, fWorldLogical->GetMaterial(),
0218 "VoxelizedDetectorZDivisionLog", 0, 0, 0);
0219
0220 fVoxelizedDetectorZDivisionPhys =
0221 new G4PVReplica("VoxelizedDetectorZDivisionPhys", fVoxelizedDetectorZDivisionLog,
0222 fVoxelizedDetectorYDivisionPhys, kZAxis, fVoxelNumberAlongZ, fVoxelWidthZ);
0223
0224 fSensitiveLogicalVolume = fVoxelizedDetectorZDivisionLog;
0225 }
0226
0227
0228
0229
0230 G4bool VoxelizedSensitiveDetector::ConstructVoxelizedDetector()
0231 {
0232
0233 ConstructXDivision();
0234
0235
0236 ConstructYDivision();
0237
0238
0239 ConstructZDivision();
0240
0241
0242 fSensitiveLogicalVolume = fVoxelizedDetectorZDivisionLog;
0243 fIsBuilt = true;
0244
0245 return true;
0246 }
0247
0248
0249
0250 void VoxelizedSensitiveDetector::UpdateVoxelizedGeometry()
0251 {
0252
0253 if (!fIsBuilt) {
0254 return;
0255 }
0256
0257 CalculateVoxelNumber();
0258
0259
0260 G4VPhysicalVolume* myVol;
0261
0262 G4PhysicalVolumeStore* store = G4PhysicalVolumeStore::GetInstance();
0263
0264 myVol = store->GetVolume("VoxelizedDetectorXDivisionPhys");
0265 store->DeRegister(myVol);
0266 myVol = store->GetVolume("VoxelizedDetectorYDivisionPhys");
0267 store->DeRegister(myVol);
0268 myVol = store->GetVolume("VoxelizedDetectorZDivisionPhys");
0269 store->DeRegister(myVol);
0270 fVoxelizedDetectorXDivisionPhys =
0271 new G4PVReplica("VoxelizedDetectorXDivisionPhys", fVoxelizedDetectorXDivisionLog, fWorldLogical,
0272 kXAxis, fVoxelNumberAlongX, fVoxelWidthX);
0273
0274 fVoxelizedDetectorYDivisionPhys =
0275 new G4PVReplica("VoxelizedDetectorYDivisionPhys", fVoxelizedDetectorYDivisionLog,
0276 fVoxelizedDetectorXDivisionPhys, kYAxis, fVoxelNumberAlongY, fVoxelWidthY);
0277
0278 fVoxelizedDetectorZDivisionPhys =
0279 new G4PVReplica("VoxelizedDetectorZDivisionPhys", fVoxelizedDetectorZDivisionLog,
0280 fVoxelizedDetectorYDivisionPhys, kZAxis, fVoxelNumberAlongZ, fVoxelWidthZ);
0281
0282 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0283 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0284 }
0285
0286
0287
0288 void VoxelizedSensitiveDetector::ConstructSD()
0289 {
0290 G4String sensitiveDetectorName = "VoxelizedDetector";
0291 G4String HCname = "LETdata";
0292
0293 SD* detectorSD = new SD(sensitiveDetectorName, HCname);
0294 G4SDManager::GetSDMpointer()->AddNewDetector(detectorSD);
0295 fSensitiveLogicalVolume->SetSensitiveDetector(detectorSD);
0296 }
0297
0298
0299
0300 void VoxelizedSensitiveDetector::Construct()
0301 {
0302 ConstructVoxelizedDetector();
0303 }
0304
0305
0306
0307 void VoxelizedSensitiveDetector::InitializeWorldPtr(G4VPhysicalVolume* pWorld)
0308 {
0309 if (pWorld == nullptr)
0310 G4Exception("VoxelizedSensitiveDetector::InitializeWorldPtr", "WorldinitNull", FatalException,
0311 "Initializing Voxelization Class with a Null Pointer to World!");
0312 fWorldLogical = pWorld->GetLogicalVolume();
0313 }
0314
0315
0316
0317
0318 G4int VoxelizedSensitiveDetector::GetThisVoxelNumber(G4int x, G4int y, G4int z) const
0319 {
0320 G4int nz = GetVoxelNumberAlongZ();
0321 G4int ny = GetVoxelNumberAlongY();
0322
0323 return z + nz * (y + ny * (x));
0324 }
0325
0326
0327
0328 }