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 // Last modified: G.A.P.Cirrone April 2008; >> 28 // >> 29 // See more at: http://geant4infn.wikispaces.com/HadrontherapyExample >> 30 // >> 31 // ---------------------------------------------------------------------------- >> 32 // GEANT 4 - Hadrontherapy example >> 33 // ---------------------------------------------------------------------------- >> 34 // Code developed by: >> 35 // >> 36 // G.A.P. Cirrone(a)*, F. Di Rosa(a), S. Guatelli(b), G. Russo(a) >> 37 // >> 38 // (a) Laboratori Nazionali del Sud >> 39 // of the National Institute for Nuclear Physics, Catania, Italy >> 40 // (b) National Institute for Nuclear Physics Section of Genova, genova, Italy >> 41 // >> 42 // * cirrone@lns.infn.it >> 43 // ---------------------------------------------------------------------------- 28 44 29 #include "G4UnitsTable.hh" << 45 #include "HadrontherapyDetectorROGeometry.hh" 30 #include "G4SystemOfUnits.hh" << 46 #include "HadrontherapyDummySD.hh" 31 #include "G4LogicalVolume.hh" 47 #include "G4LogicalVolume.hh" 32 #include "G4VPhysicalVolume.hh" 48 #include "G4VPhysicalVolume.hh" 33 #include "G4PVPlacement.hh" 49 #include "G4PVPlacement.hh" 34 #include "G4PVReplica.hh" 50 #include "G4PVReplica.hh" 35 #include "G4Box.hh" 51 #include "G4Box.hh" 36 #include "G4ThreeVector.hh" 52 #include "G4ThreeVector.hh" 37 #include "G4Material.hh" 53 #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 54 64 ////////////////////////////////////////////// 55 ///////////////////////////////////////////////////////////////////////////// 65 HadrontherapyDetectorROGeometry::Hadrontherapy << 56 HadrontherapyDetectorROGeometry::HadrontherapyDetectorROGeometry(G4String aString, 66 : G4VUserParallelWorld(aString),RODetector(0 << 57 G4double detectorDimX, 67 RODetectorYDivision(0),RODetectorZDivision << 58 G4double detectorDimY, 68 RODetectorXDivisionLog(0),RODetectorYDivis << 59 G4double detectorDimZ, 69 sensitiveLogicalVolume(0) << 60 G4int numberOfVoxelsX, >> 61 G4int numberOfVoxelsY, >> 62 G4int numberOfVoxelsZ): >> 63 G4VReadOutGeometry(aString), >> 64 detectorSizeX(detectorDimX), >> 65 detectorSizeY(detectorDimY), >> 66 detectorSizeZ(detectorDimZ), >> 67 numberOfVoxelsAlongX(numberOfVoxelsX), >> 68 numberOfVoxelsAlongY(numberOfVoxelsY), >> 69 numberOfVoxelsAlongZ(numberOfVoxelsZ) 70 { 70 { 71 isBuilt = false; << 72 isInitialized = false; << 73 } 71 } 74 72 75 ////////////////////////////////////////////// 73 ///////////////////////////////////////////////////////////////////////////// 76 << 74 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 { 75 { 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 } 76 } 189 77 190 ////////////////////////////////////////////// 78 ///////////////////////////////////////////////////////////////////////////// 191 HadrontherapyDetectorROGeometry::~Hadrontherap << 79 G4VPhysicalVolume* HadrontherapyDetectorROGeometry::Build() 192 {;} << 193 << 194 ////////////////////////////////////////////// << 195 void HadrontherapyDetectorROGeometry::Construc << 196 { 80 { 197 // A dummy material is used to fill the volu 81 // A dummy material is used to fill the volumes of the readout geometry. 198 // (It will be allowed to set a NULL pointer 82 // (It will be allowed to set a NULL pointer in volumes of such virtual 199 // division in future, since this material i 83 // division in future, since this material is irrelevant for tracking.) 200 << 201 84 202 // << 85 G4Material* dummyMat = new G4Material(name="dummyMat", 1., 1.*g/mole, 1.*g/cm3); 203 // World << 86 204 // << 87 G4double worldSizeX = 200.0 *cm; 205 G4VPhysicalVolume* ghostWorld = GetWorld(); << 88 G4double worldSizeY = 200.0 *cm; 206 worldLogical = ghostWorld->GetLogicalVolume( << 89 G4double worldSizeZ = 200.0 *cm; 207 << 208 if (!isInitialized) << 209 { << 210 G4Exception("HadrontherapyDetectorROGeom << 211 FatalException,"Parameters of the RO geo << 212 return; << 213 } << 214 90 215 << 216 G4double halfDetectorSizeX = detectorSizeX; 91 G4double halfDetectorSizeX = detectorSizeX; 217 G4double halfDetectorSizeY = detectorSizeY; 92 G4double halfDetectorSizeY = detectorSizeY; 218 G4double halfDetectorSizeZ = detectorSizeZ; 93 G4double halfDetectorSizeZ = detectorSizeZ; 219 << 94 220 // World volume of ROGeometry ... SERVE SO << 95 // World volume of ROGeometry ... >> 96 G4Box* ROWorld = new G4Box("ROWorld", >> 97 worldSizeX, >> 98 worldSizeY, >> 99 worldSizeZ); >> 100 >> 101 G4LogicalVolume* ROWorldLog = new G4LogicalVolume(ROWorld, dummyMat, >> 102 "ROWorldLog", 0,0,0); >> 103 >> 104 G4VPhysicalVolume* ROWorldPhys = new G4PVPlacement(0,G4ThreeVector(), >> 105 "ROWorldPhys", >> 106 ROWorldLog, >> 107 0,false,0); 221 108 222 // Detector ROGeometry 109 // Detector ROGeometry 223 RODetector = new G4Box("RODetector", << 110 G4Box *RODetector = new G4Box("RODetector", 224 halfDetectorSizeX, << 111 halfDetectorSizeX, 225 halfDetectorSizeY, << 112 halfDetectorSizeY, 226 halfDetectorSizeZ); << 113 halfDetectorSizeZ); 227 << 114 228 RODetectorLog = new G4LogicalVolume(RODetect << 115 G4LogicalVolume *RODetectorLog = new G4LogicalVolume(RODetector, 229 0, << 116 dummyMat, 230 "RODetectorLog", << 117 "RODetectorLog", 231 0,0,0); << 118 0,0,0); 232 << 233 << 234 119 235 G4VPhysicalVolume *RODetectorPhys = new G4PV 120 G4VPhysicalVolume *RODetectorPhys = new G4PVPlacement(0, 236 detectorToWorldPosition,RODetect << 121 G4ThreeVector(20.0 *mm, 237 "RODetectorPhys", << 122 0.0 *mm, 238 worldLogical, << 123 0.0 *mm), >> 124 "DetectorPhys", >> 125 RODetectorLog, >> 126 ROWorldPhys, 239 false,0); 127 false,0); 240 << 241 << 242 << 243 128 244 // Division along X axis: the detector is di << 129 >> 130 // Division along X axis: the detector is devided in slices along the X axis 245 131 246 G4double halfXVoxelSizeX = halfDetectorSizeX 132 G4double halfXVoxelSizeX = halfDetectorSizeX/numberOfVoxelsAlongX; 247 G4double halfXVoxelSizeY = halfDetectorSizeY 133 G4double halfXVoxelSizeY = halfDetectorSizeY; 248 G4double halfXVoxelSizeZ = halfDetectorSizeZ 134 G4double halfXVoxelSizeZ = halfDetectorSizeZ; 249 G4double voxelXThickness = 2*halfXVoxelSizeX 135 G4double voxelXThickness = 2*halfXVoxelSizeX; 250 << 251 136 252 RODetectorXDivision = new G4Box("RODetectorX << 137 G4Box *RODetectorXDivision = new G4Box("RODetectorXDivision", 253 halfXVoxelSizeX, << 138 halfXVoxelSizeX, 254 halfXVoxelSizeY, << 139 halfXVoxelSizeY, 255 halfXVoxelSizeZ); << 140 halfXVoxelSizeZ); 256 << 141 257 RODetectorXDivisionLog = new G4LogicalVolume << 142 G4LogicalVolume *RODetectorXDivisionLog = new G4LogicalVolume(RODetectorXDivision, 258 0, << 143 dummyMat, 259 "RODetectorXDivisionLog", << 144 "RODetectorXDivisionLog", 260 0,0,0); << 145 0,0,0); 261 146 262 G4VPhysicalVolume *RODetectorXDivisionPhys = 147 G4VPhysicalVolume *RODetectorXDivisionPhys = new G4PVReplica("RODetectorXDivisionPhys", 263 148 RODetectorXDivisionLog, 264 149 RODetectorPhys, 265 150 kXAxis, 266 151 numberOfVoxelsAlongX, 267 152 voxelXThickness); 268 153 269 // Division along Y axis: the slices along t << 154 // Division along Y axis: the slices along the X axis are devided along the Y axis 270 155 271 G4double halfYVoxelSizeX = halfXVoxelSizeX; << 156 G4double halfYVoxelSizeX = halfXVoxelSizeX; 272 G4double halfYVoxelSizeY = halfDetectorSizeY 157 G4double halfYVoxelSizeY = halfDetectorSizeY/numberOfVoxelsAlongY; 273 G4double halfYVoxelSizeZ = halfDetectorSizeZ 158 G4double halfYVoxelSizeZ = halfDetectorSizeZ; 274 G4double voxelYThickness = 2*halfYVoxelSizeY 159 G4double voxelYThickness = 2*halfYVoxelSizeY; 275 160 276 RODetectorYDivision = new G4Box("RODetectorY << 161 G4Box *RODetectorYDivision = new G4Box("RODetectorYDivision", 277 halfYVoxelSizeX, << 162 halfYVoxelSizeX, 278 halfYVoxelSizeY, << 163 halfYVoxelSizeY, 279 halfYVoxelSizeZ); << 164 halfYVoxelSizeZ); 280 << 165 281 RODetectorYDivisionLog = new G4LogicalVolume << 166 G4LogicalVolume *RODetectorYDivisionLog = new G4LogicalVolume(RODetectorYDivision, 282 0, << 167 dummyMat, 283 "RODetectorYDivisionLog", << 168 "RODetectorYDivisionLog", 284 0,0,0); << 169 0,0,0); 285 170 286 G4VPhysicalVolume *RODetectorYDivisionPhys = 171 G4VPhysicalVolume *RODetectorYDivisionPhys = new G4PVReplica("RODetectorYDivisionPhys", 287 RODetectorYDivisionLog, 172 RODetectorYDivisionLog, 288 RODetectorXDivisionPhys, 173 RODetectorXDivisionPhys, 289 kYAxis, 174 kYAxis, 290 numberOfVoxelsAlongY, 175 numberOfVoxelsAlongY, 291 voxelYThickness); 176 voxelYThickness); 292 177 293 // Division along Z axis: the slices along t << 178 // Division along Z axis: the slices along the Y axis are devided along the Z axis 294 179 295 G4double halfZVoxelSizeX = halfXVoxelSizeX; 180 G4double halfZVoxelSizeX = halfXVoxelSizeX; 296 G4double halfZVoxelSizeY = halfYVoxelSizeY; 181 G4double halfZVoxelSizeY = halfYVoxelSizeY; 297 G4double halfZVoxelSizeZ = halfDetectorSizeZ 182 G4double halfZVoxelSizeZ = halfDetectorSizeZ/numberOfVoxelsAlongZ; 298 G4double voxelZThickness = 2*halfZVoxelSizeZ 183 G4double voxelZThickness = 2*halfZVoxelSizeZ; 299 184 300 RODetectorZDivision = new G4Box("RODetectorZ << 185 G4Box *RODetectorZDivision = new G4Box("RODetectorZDivision", 301 halfZVoxelSizeX, << 186 halfZVoxelSizeX, 302 halfZVoxelSizeY, << 187 halfZVoxelSizeY, 303 halfZVoxelSizeZ); << 188 halfZVoxelSizeZ); 304 << 189 305 RODetectorZDivisionLog = new G4LogicalVolume << 190 G4LogicalVolume *RODetectorZDivisionLog = new G4LogicalVolume(RODetectorZDivision, 306 0, << 191 dummyMat, 307 "RODetectorZDivisionLog", << 192 "RODetectorZDivisionLog", 308 0,0,0); << 193 0,0,0); 309 << 194 310 new G4PVReplica("RODetectorZDivisionPhys", << 195 RODetectorZDivisionPhys = new G4PVReplica("RODetectorZDivisionPhys", 311 RODetectorZDivisionLog, << 196 RODetectorZDivisionLog, 312 RODetectorYDivisionPhys, << 197 RODetectorYDivisionPhys, 313 kZAxis, << 198 kZAxis, 314 numberOfVoxelsAlongZ, << 199 numberOfVoxelsAlongZ, 315 voxelZThickness); << 200 voxelZThickness); 316 201 317 sensitiveLogicalVolume = RODetectorZDivision << 202 HadrontherapyDummySD *dummySD = new HadrontherapyDummySD; 318 isBuilt = true; << 203 RODetectorZDivisionLog -> SetSensitiveDetector(dummySD); 319 } << 320 204 321 void HadrontherapyDetectorROGeometry::Construc << 205 return ROWorldPhys; 322 { << 206 } 323 G4String sensitiveDetectorName = "RODetector" << 324 << 325 HadrontherapyDetectorSD* detectorSD = new Had << 326 G4SDManager::GetSDMpointer()->AddNewDetector( << 327 sensitiveLogicalVolume->SetSensitiveDetector( << 328 << 329 // SetSensitiveDetector(sensitiveLogicalVolum << 330 207 331 208 332 } << 333 209 334 210