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