Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // Hadrontherapy advanced example for Geant4 27 // See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy 28 29 #include "G4UnitsTable.hh" 30 #include "G4SystemOfUnits.hh" 31 #include "G4LogicalVolume.hh" 32 #include "G4VPhysicalVolume.hh" 33 #include "G4PVPlacement.hh" 34 #include "G4PVReplica.hh" 35 #include "G4Box.hh" 36 #include "G4ThreeVector.hh" 37 #include "G4Material.hh" 38 #include "G4NistManager.hh" 39 #include "G4GeometryManager.hh" 40 #include "G4SolidStore.hh" 41 #include "G4LogicalVolumeStore.hh" 42 43 44 45 #include "G4SDManager.hh" 46 #include "G4RunManager.hh" 47 48 #include "G4PhysicalVolumeStore.hh" 49 50 #include "G4ThreeVector.hh" 51 52 #include "globals.hh" 53 #include "G4Transform3D.hh" 54 #include "G4RotationMatrix.hh" 55 #include "G4Colour.hh" 56 #include "G4UserLimits.hh" 57 58 #include "G4VisAttributes.hh" 59 60 #include "HadrontherapyDetectorROGeometry.hh" 61 #include "HadrontherapyDummySD.hh" 62 #include "HadrontherapyDetectorSD.hh" 63 64 ///////////////////////////////////////////////////////////////////////////// 65 HadrontherapyDetectorROGeometry::HadrontherapyDetectorROGeometry(G4String aString) 66 : G4VUserParallelWorld(aString),RODetector(0),RODetectorXDivision(0), 67 RODetectorYDivision(0),RODetectorZDivision(0),worldLogical(0),RODetectorLog(0), 68 RODetectorXDivisionLog(0),RODetectorYDivisionLog(0),RODetectorZDivisionLog(0), 69 sensitiveLogicalVolume(0) 70 { 71 isBuilt = false; 72 isInitialized = false; 73 } 74 75 ///////////////////////////////////////////////////////////////////////////// 76 77 void HadrontherapyDetectorROGeometry::Initialize(G4ThreeVector pos, 78 G4double detectorDimX, 79 G4double detectorDimY, 80 G4double detectorDimZ, 81 G4int numberOfVoxelsX, 82 G4int numberOfVoxelsY, 83 G4int numberOfVoxelsZ) 84 { 85 detectorToWorldPosition = pos; 86 detectorSizeX = detectorDimX; 87 detectorSizeY= detectorDimY; 88 detectorSizeZ=detectorDimZ; 89 numberOfVoxelsAlongX=numberOfVoxelsX; 90 numberOfVoxelsAlongY=numberOfVoxelsY; 91 numberOfVoxelsAlongZ=numberOfVoxelsZ; 92 93 isInitialized = true; 94 95 96 97 } 98 99 void HadrontherapyDetectorROGeometry::UpdateROGeometry() 100 { 101 //Nothing happens if the RO geometry is not built. But parameters are properly set. 102 if (!isBuilt) 103 { 104 //G4Exception("HadrontherapyDetectorROGeometry::UpdateROGeometry","had001", 105 // JustWarning,"Cannot update geometry before it is built"); 106 return; 107 } 108 109 //1) Update the dimensions of the G4Boxes 110 G4double halfDetectorSizeX = detectorSizeX; 111 G4double halfDetectorSizeY = detectorSizeY; 112 G4double halfDetectorSizeZ = detectorSizeZ; 113 114 RODetector->SetXHalfLength(halfDetectorSizeX); 115 RODetector->SetYHalfLength(halfDetectorSizeY); 116 RODetector->SetZHalfLength(halfDetectorSizeZ); 117 118 G4double halfXVoxelSizeX = halfDetectorSizeX/numberOfVoxelsAlongX; 119 G4double halfXVoxelSizeY = halfDetectorSizeY; 120 G4double halfXVoxelSizeZ = halfDetectorSizeZ; 121 G4double voxelXThickness = 2*halfXVoxelSizeX; 122 123 RODetectorXDivision->SetXHalfLength(halfXVoxelSizeX); 124 RODetectorXDivision->SetYHalfLength(halfXVoxelSizeY); 125 RODetectorXDivision->SetZHalfLength(halfXVoxelSizeZ); 126 127 G4double halfYVoxelSizeX = halfXVoxelSizeX; 128 G4double halfYVoxelSizeY = halfDetectorSizeY/numberOfVoxelsAlongY; 129 G4double halfYVoxelSizeZ = halfDetectorSizeZ; 130 G4double voxelYThickness = 2*halfYVoxelSizeY; 131 132 RODetectorYDivision->SetXHalfLength(halfYVoxelSizeX); 133 RODetectorYDivision->SetYHalfLength(halfYVoxelSizeY); 134 RODetectorYDivision->SetZHalfLength(halfYVoxelSizeZ); 135 136 G4double halfZVoxelSizeX = halfXVoxelSizeX; 137 G4double halfZVoxelSizeY = halfYVoxelSizeY; 138 G4double halfZVoxelSizeZ = halfDetectorSizeZ/numberOfVoxelsAlongZ; 139 G4double voxelZThickness = 2*halfZVoxelSizeZ; 140 141 RODetectorZDivision->SetXHalfLength(halfZVoxelSizeX); 142 RODetectorZDivision->SetYHalfLength(halfZVoxelSizeY); 143 RODetectorZDivision->SetZHalfLength(halfZVoxelSizeZ); 144 145 //Delete and re-build the relevant physical volumes 146 G4PhysicalVolumeStore* store = 147 G4PhysicalVolumeStore::GetInstance(); 148 149 //Delete... 150 G4VPhysicalVolume* myVol = store->GetVolume("RODetectorPhys"); 151 store->DeRegister(myVol); 152 //..and rebuild 153 G4VPhysicalVolume *RODetectorPhys = new G4PVPlacement(0, 154 detectorToWorldPosition, 155 RODetectorLog, 156 "RODetectorPhys", 157 worldLogical, 158 false,0); 159 160 myVol = store->GetVolume("RODetectorXDivisionPhys"); 161 store->DeRegister(myVol); 162 G4VPhysicalVolume *RODetectorXDivisionPhys = new G4PVReplica("RODetectorXDivisionPhys", 163 RODetectorXDivisionLog, 164 RODetectorPhys, 165 kXAxis, 166 numberOfVoxelsAlongX, 167 voxelXThickness); 168 myVol = store->GetVolume("RODetectorYDivisionPhys"); 169 store->DeRegister(myVol); 170 G4VPhysicalVolume *RODetectorYDivisionPhys = new G4PVReplica("RODetectorYDivisionPhys", 171 RODetectorYDivisionLog, 172 RODetectorXDivisionPhys, 173 kYAxis, 174 numberOfVoxelsAlongY, 175 voxelYThickness); 176 177 myVol = store->GetVolume("RODetectorZDivisionPhys"); 178 store->DeRegister(myVol); 179 new G4PVReplica("RODetectorZDivisionPhys", 180 RODetectorZDivisionLog, 181 RODetectorYDivisionPhys, 182 kZAxis, 183 numberOfVoxelsAlongZ, 184 voxelZThickness); 185 186 return; 187 188 } 189 190 ///////////////////////////////////////////////////////////////////////////// 191 HadrontherapyDetectorROGeometry::~HadrontherapyDetectorROGeometry() 192 {;} 193 194 ///////////////////////////////////////////////////////////////////////////// 195 void HadrontherapyDetectorROGeometry::Construct() 196 { 197 // A dummy material is used to fill the volumes of the readout geometry. 198 // (It will be allowed to set a NULL pointer in volumes of such virtual 199 // division in future, since this material is irrelevant for tracking.) 200 201 202 // 203 // World 204 // 205 G4VPhysicalVolume* ghostWorld = GetWorld(); 206 worldLogical = ghostWorld->GetLogicalVolume(); 207 208 if (!isInitialized) 209 { 210 G4Exception("HadrontherapyDetectorROGeometry::Construct","had001", 211 FatalException,"Parameters of the RO geometry are not initialized"); 212 return; 213 } 214 215 216 G4double halfDetectorSizeX = detectorSizeX; 217 G4double halfDetectorSizeY = detectorSizeY; 218 G4double halfDetectorSizeZ = detectorSizeZ; 219 220 // World volume of ROGeometry ... SERVE SOLO PER LA ROG 221 222 // Detector ROGeometry 223 RODetector = new G4Box("RODetector", 224 halfDetectorSizeX, 225 halfDetectorSizeY, 226 halfDetectorSizeZ); 227 228 RODetectorLog = new G4LogicalVolume(RODetector, 229 0, 230 "RODetectorLog", 231 0,0,0); 232 233 234 235 G4VPhysicalVolume *RODetectorPhys = new G4PVPlacement(0, 236 detectorToWorldPosition,RODetectorLog, 237 "RODetectorPhys", 238 worldLogical, 239 false,0); 240 241 242 243 244 // Division along X axis: the detector is divided in slices along the X axis 245 246 G4double halfXVoxelSizeX = halfDetectorSizeX/numberOfVoxelsAlongX; 247 G4double halfXVoxelSizeY = halfDetectorSizeY; 248 G4double halfXVoxelSizeZ = halfDetectorSizeZ; 249 G4double voxelXThickness = 2*halfXVoxelSizeX; 250 251 252 RODetectorXDivision = new G4Box("RODetectorXDivision", 253 halfXVoxelSizeX, 254 halfXVoxelSizeY, 255 halfXVoxelSizeZ); 256 257 RODetectorXDivisionLog = new G4LogicalVolume(RODetectorXDivision, 258 0, 259 "RODetectorXDivisionLog", 260 0,0,0); 261 262 G4VPhysicalVolume *RODetectorXDivisionPhys = new G4PVReplica("RODetectorXDivisionPhys", 263 RODetectorXDivisionLog, 264 RODetectorPhys, 265 kXAxis, 266 numberOfVoxelsAlongX, 267 voxelXThickness); 268 269 // Division along Y axis: the slices along the X axis are divided along the Y axis 270 271 G4double halfYVoxelSizeX = halfXVoxelSizeX; 272 G4double halfYVoxelSizeY = halfDetectorSizeY/numberOfVoxelsAlongY; 273 G4double halfYVoxelSizeZ = halfDetectorSizeZ; 274 G4double voxelYThickness = 2*halfYVoxelSizeY; 275 276 RODetectorYDivision = new G4Box("RODetectorYDivision", 277 halfYVoxelSizeX, 278 halfYVoxelSizeY, 279 halfYVoxelSizeZ); 280 281 RODetectorYDivisionLog = new G4LogicalVolume(RODetectorYDivision, 282 0, 283 "RODetectorYDivisionLog", 284 0,0,0); 285 286 G4VPhysicalVolume *RODetectorYDivisionPhys = new G4PVReplica("RODetectorYDivisionPhys", 287 RODetectorYDivisionLog, 288 RODetectorXDivisionPhys, 289 kYAxis, 290 numberOfVoxelsAlongY, 291 voxelYThickness); 292 293 // Division along Z axis: the slices along the Y axis are divided along the Z axis 294 295 G4double halfZVoxelSizeX = halfXVoxelSizeX; 296 G4double halfZVoxelSizeY = halfYVoxelSizeY; 297 G4double halfZVoxelSizeZ = halfDetectorSizeZ/numberOfVoxelsAlongZ; 298 G4double voxelZThickness = 2*halfZVoxelSizeZ; 299 300 RODetectorZDivision = new G4Box("RODetectorZDivision", 301 halfZVoxelSizeX, 302 halfZVoxelSizeY, 303 halfZVoxelSizeZ); 304 305 RODetectorZDivisionLog = new G4LogicalVolume(RODetectorZDivision, 306 0, 307 "RODetectorZDivisionLog", 308 0,0,0); 309 310 new G4PVReplica("RODetectorZDivisionPhys", 311 RODetectorZDivisionLog, 312 RODetectorYDivisionPhys, 313 kZAxis, 314 numberOfVoxelsAlongZ, 315 voxelZThickness); 316 317 sensitiveLogicalVolume = RODetectorZDivisionLog; 318 isBuilt = true; 319 } 320 321 void HadrontherapyDetectorROGeometry::ConstructSD() 322 { 323 G4String sensitiveDetectorName = "RODetector"; 324 325 HadrontherapyDetectorSD* detectorSD = new HadrontherapyDetectorSD(sensitiveDetectorName); 326 G4SDManager::GetSDMpointer()->AddNewDetector(detectorSD); 327 sensitiveLogicalVolume->SetSensitiveDetector(detectorSD); 328 329 // SetSensitiveDetector(sensitiveLogicalVolume,detectorSD); 330 331 332 } 333 334