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