├── .gitignore ├── README.md ├── example ├── example.py ├── machine │ ├── cone.stl │ ├── example.yaml │ └── target.ply └── macros │ └── vis.mac ├── linac ├── __init__.py ├── g4 │ ├── CMakeLists.txt │ ├── __init__.py │ ├── include │ │ ├── BremSplittingProcess.hh │ │ ├── DetectorConstruction.hh │ │ ├── EventAction.hh │ │ ├── ParallelDetectorConstruction.hh │ │ ├── Phasespace.hh │ │ ├── PhasespaceRecord.hh │ │ ├── PhysicsList.hh │ │ ├── PrimaryGeneratorAction.hh │ │ ├── SensitiveDetector.hh │ │ ├── SteppingAction.hh │ │ └── StopKillShield.hh │ ├── libg4.cc │ └── src │ │ ├── BremSplittingProcess.cc │ │ ├── DetectorConstruction.cc │ │ ├── EventAction.cc │ │ ├── ParallelDetectorConstruction.cc │ │ ├── Phasespace.cc │ │ ├── PhasespaceRecord.cc │ │ ├── PhysicsList.cc │ │ ├── PrimaryGeneratorAction.cc │ │ ├── SensitiveDetector.cc │ │ ├── SteppingAction.cc │ │ └── StopKillShield.cc ├── geometry.py └── simulation.py └── utils └── phsp_inspector ├── CMakeLists.txt ├── lib_phsp_inspector.cc ├── phsp ├── test1.phsp └── test2.phsp ├── phsp_inspector └── __init__.py └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.swp 3 | *.so 4 | *.phsp 5 | 6 | linac/g4/build/* 7 | utils/phsp_inspector/build/* 8 | machines/* 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GEANT4 Clinical Linear Accelerator Simulation 2 | 3 | A generic platform for clinical linear accelerator simulation using GEANT4. 4 | 5 | # Dependencies 6 | * GEANT4 7 | * CADMesh 8 | * G4VoxelData 9 | * Python, numpy 10 | * PyUblas 11 | 12 | # Installation 13 | To compile the Python module: 14 | 15 | $> cd g4/ 16 | $> mkdir build 17 | $> cd build/ 18 | $> cmake .. 19 | $> make 20 | 21 | -------------------------------------------------------------------------------- /example/example.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | from linac import Linac, Simulation 5 | 6 | 7 | linac = Linac("machine/example.yaml") 8 | 9 | sim = Simulation("example", linac, run_id=os.getpid()) 10 | sim.show() 11 | 12 | # Control flow 13 | sim.enable_phasespace("exitwindow1") 14 | sim.enable_phasespace("exitwindow2") 15 | sim.beam_on(int(1e4)) 16 | 17 | sim.disable_phasespace("exitwindow1") 18 | #sim.disable_phasespace("exitwindow2") 19 | 20 | sim.enable_phasespace_source("exitwindow2") # Automatically disables a phasespace, if enabled 21 | 22 | for angle in range(0, 360, 5): 23 | linac.rotate_gantry(angle) 24 | sim.beam_on(int(1e9)) 25 | 26 | #sim.start_session() 27 | 28 | -------------------------------------------------------------------------------- /example/machine/cone.stl: -------------------------------------------------------------------------------- 1 | solid vcg 2 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 3 | outer loop 4 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 5 | vertex 1.000000e+02 -5.000000e+01 0.000000e+00 6 | vertex 9.659258e+01 -5.000000e+01 2.588190e+01 7 | endloop 8 | endfacet 9 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 10 | outer loop 11 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 12 | vertex 9.659258e+01 -5.000000e+01 2.588190e+01 13 | vertex 8.660254e+01 -5.000000e+01 5.000000e+01 14 | endloop 15 | endfacet 16 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 17 | outer loop 18 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 19 | vertex 8.660254e+01 -5.000000e+01 5.000000e+01 20 | vertex 7.071068e+01 -5.000000e+01 7.071068e+01 21 | endloop 22 | endfacet 23 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 24 | outer loop 25 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 26 | vertex 7.071068e+01 -5.000000e+01 7.071068e+01 27 | vertex 5.000000e+01 -5.000000e+01 8.660254e+01 28 | endloop 29 | endfacet 30 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 31 | outer loop 32 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 33 | vertex 5.000000e+01 -5.000000e+01 8.660254e+01 34 | vertex 2.588190e+01 -5.000000e+01 9.659258e+01 35 | endloop 36 | endfacet 37 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 38 | outer loop 39 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 40 | vertex 2.588190e+01 -5.000000e+01 9.659258e+01 41 | vertex 6.123032e-15 -5.000000e+01 1.000000e+02 42 | endloop 43 | endfacet 44 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 45 | outer loop 46 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 47 | vertex 6.123032e-15 -5.000000e+01 1.000000e+02 48 | vertex -2.588190e+01 -5.000000e+01 9.659258e+01 49 | endloop 50 | endfacet 51 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 52 | outer loop 53 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 54 | vertex -2.588190e+01 -5.000000e+01 9.659258e+01 55 | vertex -5.000000e+01 -5.000000e+01 8.660254e+01 56 | endloop 57 | endfacet 58 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 59 | outer loop 60 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 61 | vertex -5.000000e+01 -5.000000e+01 8.660254e+01 62 | vertex -7.071068e+01 -5.000000e+01 7.071068e+01 63 | endloop 64 | endfacet 65 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 66 | outer loop 67 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 68 | vertex -7.071068e+01 -5.000000e+01 7.071068e+01 69 | vertex -8.660254e+01 -5.000000e+01 5.000000e+01 70 | endloop 71 | endfacet 72 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 73 | outer loop 74 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 75 | vertex -8.660254e+01 -5.000000e+01 5.000000e+01 76 | vertex -9.659258e+01 -5.000000e+01 2.588190e+01 77 | endloop 78 | endfacet 79 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 80 | outer loop 81 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 82 | vertex -9.659258e+01 -5.000000e+01 2.588190e+01 83 | vertex -1.000000e+02 -5.000000e+01 1.224606e-14 84 | endloop 85 | endfacet 86 | facet normal -0.000000e+00 -1.000000e+00 0.000000e+00 87 | outer loop 88 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 89 | vertex -1.000000e+02 -5.000000e+01 1.224606e-14 90 | vertex -9.659258e+01 -5.000000e+01 -2.588190e+01 91 | endloop 92 | endfacet 93 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 94 | outer loop 95 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 96 | vertex -9.659258e+01 -5.000000e+01 -2.588190e+01 97 | vertex -8.660254e+01 -5.000000e+01 -5.000000e+01 98 | endloop 99 | endfacet 100 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 101 | outer loop 102 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 103 | vertex -8.660254e+01 -5.000000e+01 -5.000000e+01 104 | vertex -7.071068e+01 -5.000000e+01 -7.071068e+01 105 | endloop 106 | endfacet 107 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 108 | outer loop 109 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 110 | vertex -7.071068e+01 -5.000000e+01 -7.071068e+01 111 | vertex -5.000000e+01 -5.000000e+01 -8.660254e+01 112 | endloop 113 | endfacet 114 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 115 | outer loop 116 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 117 | vertex -5.000000e+01 -5.000000e+01 -8.660254e+01 118 | vertex -2.588190e+01 -5.000000e+01 -9.659258e+01 119 | endloop 120 | endfacet 121 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 122 | outer loop 123 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 124 | vertex -2.588190e+01 -5.000000e+01 -9.659258e+01 125 | vertex -1.836910e-14 -5.000000e+01 -1.000000e+02 126 | endloop 127 | endfacet 128 | facet normal 0.000000e+00 -1.000000e+00 -0.000000e+00 129 | outer loop 130 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 131 | vertex -1.836910e-14 -5.000000e+01 -1.000000e+02 132 | vertex 2.588190e+01 -5.000000e+01 -9.659258e+01 133 | endloop 134 | endfacet 135 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 136 | outer loop 137 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 138 | vertex 2.588190e+01 -5.000000e+01 -9.659258e+01 139 | vertex 5.000000e+01 -5.000000e+01 -8.660254e+01 140 | endloop 141 | endfacet 142 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 143 | outer loop 144 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 145 | vertex 5.000000e+01 -5.000000e+01 -8.660254e+01 146 | vertex 7.071068e+01 -5.000000e+01 -7.071068e+01 147 | endloop 148 | endfacet 149 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 150 | outer loop 151 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 152 | vertex 7.071068e+01 -5.000000e+01 -7.071068e+01 153 | vertex 8.660254e+01 -5.000000e+01 -5.000000e+01 154 | endloop 155 | endfacet 156 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 157 | outer loop 158 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 159 | vertex 8.660254e+01 -5.000000e+01 -5.000000e+01 160 | vertex 9.659258e+01 -5.000000e+01 -2.588190e+01 161 | endloop 162 | endfacet 163 | facet normal 0.000000e+00 -1.000000e+00 0.000000e+00 164 | outer loop 165 | vertex 0.000000e+00 -5.000000e+01 0.000000e+00 166 | vertex 9.659258e+01 -5.000000e+01 -2.588190e+01 167 | vertex 1.000000e+02 -5.000000e+01 0.000000e+00 168 | endloop 169 | endfacet 170 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 171 | outer loop 172 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 173 | vertex 1.931852e+02 5.000000e+01 5.176381e+01 174 | vertex 2.000000e+02 5.000000e+01 0.000000e+00 175 | endloop 176 | endfacet 177 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 178 | outer loop 179 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 180 | vertex 1.732051e+02 5.000000e+01 1.000000e+02 181 | vertex 1.931852e+02 5.000000e+01 5.176381e+01 182 | endloop 183 | endfacet 184 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 185 | outer loop 186 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 187 | vertex 1.414214e+02 5.000000e+01 1.414214e+02 188 | vertex 1.732051e+02 5.000000e+01 1.000000e+02 189 | endloop 190 | endfacet 191 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 192 | outer loop 193 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 194 | vertex 1.000000e+02 5.000000e+01 1.732051e+02 195 | vertex 1.414214e+02 5.000000e+01 1.414214e+02 196 | endloop 197 | endfacet 198 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 199 | outer loop 200 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 201 | vertex 5.176381e+01 5.000000e+01 1.931852e+02 202 | vertex 1.000000e+02 5.000000e+01 1.732051e+02 203 | endloop 204 | endfacet 205 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 206 | outer loop 207 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 208 | vertex 1.224606e-14 5.000000e+01 2.000000e+02 209 | vertex 5.176381e+01 5.000000e+01 1.931852e+02 210 | endloop 211 | endfacet 212 | facet normal 0.000000e+00 1.000000e+00 -0.000000e+00 213 | outer loop 214 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 215 | vertex -5.176381e+01 5.000000e+01 1.931852e+02 216 | vertex 1.224606e-14 5.000000e+01 2.000000e+02 217 | endloop 218 | endfacet 219 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 220 | outer loop 221 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 222 | vertex -1.000000e+02 5.000000e+01 1.732051e+02 223 | vertex -5.176381e+01 5.000000e+01 1.931852e+02 224 | endloop 225 | endfacet 226 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 227 | outer loop 228 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 229 | vertex -1.414214e+02 5.000000e+01 1.414214e+02 230 | vertex -1.000000e+02 5.000000e+01 1.732051e+02 231 | endloop 232 | endfacet 233 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 234 | outer loop 235 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 236 | vertex -1.732051e+02 5.000000e+01 1.000000e+02 237 | vertex -1.414214e+02 5.000000e+01 1.414214e+02 238 | endloop 239 | endfacet 240 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 241 | outer loop 242 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 243 | vertex -1.931852e+02 5.000000e+01 5.176381e+01 244 | vertex -1.732051e+02 5.000000e+01 1.000000e+02 245 | endloop 246 | endfacet 247 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 248 | outer loop 249 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 250 | vertex -2.000000e+02 5.000000e+01 2.449213e-14 251 | vertex -1.931852e+02 5.000000e+01 5.176381e+01 252 | endloop 253 | endfacet 254 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 255 | outer loop 256 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 257 | vertex -1.931852e+02 5.000000e+01 -5.176381e+01 258 | vertex -2.000000e+02 5.000000e+01 2.449213e-14 259 | endloop 260 | endfacet 261 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 262 | outer loop 263 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 264 | vertex -1.732051e+02 5.000000e+01 -1.000000e+02 265 | vertex -1.931852e+02 5.000000e+01 -5.176381e+01 266 | endloop 267 | endfacet 268 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 269 | outer loop 270 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 271 | vertex -1.414214e+02 5.000000e+01 -1.414214e+02 272 | vertex -1.732051e+02 5.000000e+01 -1.000000e+02 273 | endloop 274 | endfacet 275 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 276 | outer loop 277 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 278 | vertex -1.000000e+02 5.000000e+01 -1.732051e+02 279 | vertex -1.414214e+02 5.000000e+01 -1.414214e+02 280 | endloop 281 | endfacet 282 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 283 | outer loop 284 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 285 | vertex -5.176381e+01 5.000000e+01 -1.931852e+02 286 | vertex -1.000000e+02 5.000000e+01 -1.732051e+02 287 | endloop 288 | endfacet 289 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 290 | outer loop 291 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 292 | vertex -3.673819e-14 5.000000e+01 -2.000000e+02 293 | vertex -5.176381e+01 5.000000e+01 -1.931852e+02 294 | endloop 295 | endfacet 296 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 297 | outer loop 298 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 299 | vertex 5.176381e+01 5.000000e+01 -1.931852e+02 300 | vertex -3.673819e-14 5.000000e+01 -2.000000e+02 301 | endloop 302 | endfacet 303 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 304 | outer loop 305 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 306 | vertex 1.000000e+02 5.000000e+01 -1.732051e+02 307 | vertex 5.176381e+01 5.000000e+01 -1.931852e+02 308 | endloop 309 | endfacet 310 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 311 | outer loop 312 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 313 | vertex 1.414214e+02 5.000000e+01 -1.414214e+02 314 | vertex 1.000000e+02 5.000000e+01 -1.732051e+02 315 | endloop 316 | endfacet 317 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 318 | outer loop 319 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 320 | vertex 1.732051e+02 5.000000e+01 -1.000000e+02 321 | vertex 1.414214e+02 5.000000e+01 -1.414214e+02 322 | endloop 323 | endfacet 324 | facet normal 0.000000e+00 1.000000e+00 0.000000e+00 325 | outer loop 326 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 327 | vertex 1.931852e+02 5.000000e+01 -5.176381e+01 328 | vertex 1.732051e+02 5.000000e+01 -1.000000e+02 329 | endloop 330 | endfacet 331 | facet normal -0.000000e+00 1.000000e+00 0.000000e+00 332 | outer loop 333 | vertex 0.000000e+00 5.000000e+01 0.000000e+00 334 | vertex 2.000000e+02 5.000000e+01 0.000000e+00 335 | vertex 1.931852e+02 5.000000e+01 -5.176381e+01 336 | endloop 337 | endfacet 338 | facet normal 7.040626e-01 -7.040626e-01 9.269159e-02 339 | outer loop 340 | vertex 1.000000e+02 -5.000000e+01 0.000000e+00 341 | vertex 2.000000e+02 5.000000e+01 0.000000e+00 342 | vertex 1.931852e+02 5.000000e+01 5.176381e+01 343 | endloop 344 | endfacet 345 | facet normal 7.040626e-01 -7.040626e-01 9.269159e-02 346 | outer loop 347 | vertex 1.000000e+02 -5.000000e+01 0.000000e+00 348 | vertex 1.931852e+02 5.000000e+01 5.176381e+01 349 | vertex 9.659258e+01 -5.000000e+01 2.588190e+01 350 | endloop 351 | endfacet 352 | facet normal 6.560819e-01 -7.040626e-01 2.717580e-01 353 | outer loop 354 | vertex 9.659258e+01 -5.000000e+01 2.588190e+01 355 | vertex 1.931852e+02 5.000000e+01 5.176381e+01 356 | vertex 1.732051e+02 5.000000e+01 1.000000e+02 357 | endloop 358 | endfacet 359 | facet normal 6.560819e-01 -7.040626e-01 2.717580e-01 360 | outer loop 361 | vertex 9.659258e+01 -5.000000e+01 2.588190e+01 362 | vertex 1.732051e+02 5.000000e+01 1.000000e+02 363 | vertex 8.660254e+01 -5.000000e+01 5.000000e+01 364 | endloop 365 | endfacet 366 | facet normal 5.633903e-01 -7.040626e-01 4.323045e-01 367 | outer loop 368 | vertex 8.660254e+01 -5.000000e+01 5.000000e+01 369 | vertex 1.732051e+02 5.000000e+01 1.000000e+02 370 | vertex 1.414214e+02 5.000000e+01 1.414214e+02 371 | endloop 372 | endfacet 373 | facet normal 5.633903e-01 -7.040626e-01 4.323045e-01 374 | outer loop 375 | vertex 8.660254e+01 -5.000000e+01 5.000000e+01 376 | vertex 1.414214e+02 5.000000e+01 1.414214e+02 377 | vertex 7.071068e+01 -5.000000e+01 7.071068e+01 378 | endloop 379 | endfacet 380 | facet normal 4.323046e-01 -7.040626e-01 5.633903e-01 381 | outer loop 382 | vertex 7.071068e+01 -5.000000e+01 7.071068e+01 383 | vertex 1.414214e+02 5.000000e+01 1.414214e+02 384 | vertex 1.000000e+02 5.000000e+01 1.732051e+02 385 | endloop 386 | endfacet 387 | facet normal 4.323045e-01 -7.040626e-01 5.633903e-01 388 | outer loop 389 | vertex 7.071068e+01 -5.000000e+01 7.071068e+01 390 | vertex 1.000000e+02 5.000000e+01 1.732051e+02 391 | vertex 5.000000e+01 -5.000000e+01 8.660254e+01 392 | endloop 393 | endfacet 394 | facet normal 2.717580e-01 -7.040626e-01 6.560819e-01 395 | outer loop 396 | vertex 5.000000e+01 -5.000000e+01 8.660254e+01 397 | vertex 1.000000e+02 5.000000e+01 1.732051e+02 398 | vertex 5.176381e+01 5.000000e+01 1.931852e+02 399 | endloop 400 | endfacet 401 | facet normal 2.717580e-01 -7.040626e-01 6.560819e-01 402 | outer loop 403 | vertex 5.000000e+01 -5.000000e+01 8.660254e+01 404 | vertex 5.176381e+01 5.000000e+01 1.931852e+02 405 | vertex 2.588190e+01 -5.000000e+01 9.659258e+01 406 | endloop 407 | endfacet 408 | facet normal 9.269172e-02 -7.040626e-01 7.040626e-01 409 | outer loop 410 | vertex 2.588190e+01 -5.000000e+01 9.659258e+01 411 | vertex 5.176381e+01 5.000000e+01 1.931852e+02 412 | vertex 1.224606e-14 5.000000e+01 2.000000e+02 413 | endloop 414 | endfacet 415 | facet normal 9.269159e-02 -7.040626e-01 7.040626e-01 416 | outer loop 417 | vertex 2.588190e+01 -5.000000e+01 9.659258e+01 418 | vertex 1.224606e-14 5.000000e+01 2.000000e+02 419 | vertex 6.123032e-15 -5.000000e+01 1.000000e+02 420 | endloop 421 | endfacet 422 | facet normal -9.269159e-02 -7.040626e-01 7.040626e-01 423 | outer loop 424 | vertex 6.123032e-15 -5.000000e+01 1.000000e+02 425 | vertex 1.224606e-14 5.000000e+01 2.000000e+02 426 | vertex -5.176381e+01 5.000000e+01 1.931852e+02 427 | endloop 428 | endfacet 429 | facet normal -9.269159e-02 -7.040626e-01 7.040626e-01 430 | outer loop 431 | vertex 6.123032e-15 -5.000000e+01 1.000000e+02 432 | vertex -5.176381e+01 5.000000e+01 1.931852e+02 433 | vertex -2.588190e+01 -5.000000e+01 9.659258e+01 434 | endloop 435 | endfacet 436 | facet normal -2.717580e-01 -7.040626e-01 6.560819e-01 437 | outer loop 438 | vertex -2.588190e+01 -5.000000e+01 9.659258e+01 439 | vertex -5.176381e+01 5.000000e+01 1.931852e+02 440 | vertex -1.000000e+02 5.000000e+01 1.732051e+02 441 | endloop 442 | endfacet 443 | facet normal -2.717580e-01 -7.040626e-01 6.560819e-01 444 | outer loop 445 | vertex -2.588190e+01 -5.000000e+01 9.659258e+01 446 | vertex -1.000000e+02 5.000000e+01 1.732051e+02 447 | vertex -5.000000e+01 -5.000000e+01 8.660254e+01 448 | endloop 449 | endfacet 450 | facet normal -4.323045e-01 -7.040626e-01 5.633903e-01 451 | outer loop 452 | vertex -5.000000e+01 -5.000000e+01 8.660254e+01 453 | vertex -1.000000e+02 5.000000e+01 1.732051e+02 454 | vertex -1.414214e+02 5.000000e+01 1.414214e+02 455 | endloop 456 | endfacet 457 | facet normal -4.323045e-01 -7.040626e-01 5.633903e-01 458 | outer loop 459 | vertex -5.000000e+01 -5.000000e+01 8.660254e+01 460 | vertex -1.414214e+02 5.000000e+01 1.414214e+02 461 | vertex -7.071068e+01 -5.000000e+01 7.071068e+01 462 | endloop 463 | endfacet 464 | facet normal -5.633903e-01 -7.040626e-01 4.323046e-01 465 | outer loop 466 | vertex -7.071068e+01 -5.000000e+01 7.071068e+01 467 | vertex -1.414214e+02 5.000000e+01 1.414214e+02 468 | vertex -1.732051e+02 5.000000e+01 1.000000e+02 469 | endloop 470 | endfacet 471 | facet normal -5.633903e-01 -7.040626e-01 4.323045e-01 472 | outer loop 473 | vertex -7.071068e+01 -5.000000e+01 7.071068e+01 474 | vertex -1.732051e+02 5.000000e+01 1.000000e+02 475 | vertex -8.660254e+01 -5.000000e+01 5.000000e+01 476 | endloop 477 | endfacet 478 | facet normal -6.560819e-01 -7.040626e-01 2.717580e-01 479 | outer loop 480 | vertex -8.660254e+01 -5.000000e+01 5.000000e+01 481 | vertex -1.732051e+02 5.000000e+01 1.000000e+02 482 | vertex -1.931852e+02 5.000000e+01 5.176381e+01 483 | endloop 484 | endfacet 485 | facet normal -6.560819e-01 -7.040626e-01 2.717580e-01 486 | outer loop 487 | vertex -8.660254e+01 -5.000000e+01 5.000000e+01 488 | vertex -1.931852e+02 5.000000e+01 5.176381e+01 489 | vertex -9.659258e+01 -5.000000e+01 2.588190e+01 490 | endloop 491 | endfacet 492 | facet normal -7.040626e-01 -7.040626e-01 9.269172e-02 493 | outer loop 494 | vertex -9.659258e+01 -5.000000e+01 2.588190e+01 495 | vertex -1.931852e+02 5.000000e+01 5.176381e+01 496 | vertex -2.000000e+02 5.000000e+01 2.449213e-14 497 | endloop 498 | endfacet 499 | facet normal -7.040626e-01 -7.040626e-01 9.269159e-02 500 | outer loop 501 | vertex -9.659258e+01 -5.000000e+01 2.588190e+01 502 | vertex -2.000000e+02 5.000000e+01 2.449213e-14 503 | vertex -1.000000e+02 -5.000000e+01 1.224606e-14 504 | endloop 505 | endfacet 506 | facet normal -7.040626e-01 -7.040626e-01 -9.269159e-02 507 | outer loop 508 | vertex -1.000000e+02 -5.000000e+01 1.224606e-14 509 | vertex -2.000000e+02 5.000000e+01 2.449213e-14 510 | vertex -1.931852e+02 5.000000e+01 -5.176381e+01 511 | endloop 512 | endfacet 513 | facet normal -7.040626e-01 -7.040626e-01 -9.269159e-02 514 | outer loop 515 | vertex -1.000000e+02 -5.000000e+01 1.224606e-14 516 | vertex -1.931852e+02 5.000000e+01 -5.176381e+01 517 | vertex -9.659258e+01 -5.000000e+01 -2.588190e+01 518 | endloop 519 | endfacet 520 | facet normal -6.560819e-01 -7.040626e-01 -2.717580e-01 521 | outer loop 522 | vertex -9.659258e+01 -5.000000e+01 -2.588190e+01 523 | vertex -1.931852e+02 5.000000e+01 -5.176381e+01 524 | vertex -1.732051e+02 5.000000e+01 -1.000000e+02 525 | endloop 526 | endfacet 527 | facet normal -6.560819e-01 -7.040626e-01 -2.717580e-01 528 | outer loop 529 | vertex -9.659258e+01 -5.000000e+01 -2.588190e+01 530 | vertex -1.732051e+02 5.000000e+01 -1.000000e+02 531 | vertex -8.660254e+01 -5.000000e+01 -5.000000e+01 532 | endloop 533 | endfacet 534 | facet normal -5.633903e-01 -7.040626e-01 -4.323045e-01 535 | outer loop 536 | vertex -8.660254e+01 -5.000000e+01 -5.000000e+01 537 | vertex -1.732051e+02 5.000000e+01 -1.000000e+02 538 | vertex -1.414214e+02 5.000000e+01 -1.414214e+02 539 | endloop 540 | endfacet 541 | facet normal -5.633903e-01 -7.040626e-01 -4.323045e-01 542 | outer loop 543 | vertex -8.660254e+01 -5.000000e+01 -5.000000e+01 544 | vertex -1.414214e+02 5.000000e+01 -1.414214e+02 545 | vertex -7.071068e+01 -5.000000e+01 -7.071068e+01 546 | endloop 547 | endfacet 548 | facet normal -4.323046e-01 -7.040626e-01 -5.633903e-01 549 | outer loop 550 | vertex -7.071068e+01 -5.000000e+01 -7.071068e+01 551 | vertex -1.414214e+02 5.000000e+01 -1.414214e+02 552 | vertex -1.000000e+02 5.000000e+01 -1.732051e+02 553 | endloop 554 | endfacet 555 | facet normal -4.323045e-01 -7.040626e-01 -5.633903e-01 556 | outer loop 557 | vertex -7.071068e+01 -5.000000e+01 -7.071068e+01 558 | vertex -1.000000e+02 5.000000e+01 -1.732051e+02 559 | vertex -5.000000e+01 -5.000000e+01 -8.660254e+01 560 | endloop 561 | endfacet 562 | facet normal -2.717580e-01 -7.040626e-01 -6.560819e-01 563 | outer loop 564 | vertex -5.000000e+01 -5.000000e+01 -8.660254e+01 565 | vertex -1.000000e+02 5.000000e+01 -1.732051e+02 566 | vertex -5.176381e+01 5.000000e+01 -1.931852e+02 567 | endloop 568 | endfacet 569 | facet normal -2.717580e-01 -7.040626e-01 -6.560819e-01 570 | outer loop 571 | vertex -5.000000e+01 -5.000000e+01 -8.660254e+01 572 | vertex -5.176381e+01 5.000000e+01 -1.931852e+02 573 | vertex -2.588190e+01 -5.000000e+01 -9.659258e+01 574 | endloop 575 | endfacet 576 | facet normal -9.269172e-02 -7.040626e-01 -7.040626e-01 577 | outer loop 578 | vertex -2.588190e+01 -5.000000e+01 -9.659258e+01 579 | vertex -5.176381e+01 5.000000e+01 -1.931852e+02 580 | vertex -3.673819e-14 5.000000e+01 -2.000000e+02 581 | endloop 582 | endfacet 583 | facet normal -9.269159e-02 -7.040626e-01 -7.040626e-01 584 | outer loop 585 | vertex -2.588190e+01 -5.000000e+01 -9.659258e+01 586 | vertex -3.673819e-14 5.000000e+01 -2.000000e+02 587 | vertex -1.836910e-14 -5.000000e+01 -1.000000e+02 588 | endloop 589 | endfacet 590 | facet normal 9.269159e-02 -7.040626e-01 -7.040626e-01 591 | outer loop 592 | vertex -1.836910e-14 -5.000000e+01 -1.000000e+02 593 | vertex -3.673819e-14 5.000000e+01 -2.000000e+02 594 | vertex 5.176381e+01 5.000000e+01 -1.931852e+02 595 | endloop 596 | endfacet 597 | facet normal 9.269159e-02 -7.040626e-01 -7.040626e-01 598 | outer loop 599 | vertex -1.836910e-14 -5.000000e+01 -1.000000e+02 600 | vertex 5.176381e+01 5.000000e+01 -1.931852e+02 601 | vertex 2.588190e+01 -5.000000e+01 -9.659258e+01 602 | endloop 603 | endfacet 604 | facet normal 2.717580e-01 -7.040626e-01 -6.560819e-01 605 | outer loop 606 | vertex 2.588190e+01 -5.000000e+01 -9.659258e+01 607 | vertex 5.176381e+01 5.000000e+01 -1.931852e+02 608 | vertex 1.000000e+02 5.000000e+01 -1.732051e+02 609 | endloop 610 | endfacet 611 | facet normal 2.717580e-01 -7.040626e-01 -6.560819e-01 612 | outer loop 613 | vertex 2.588190e+01 -5.000000e+01 -9.659258e+01 614 | vertex 1.000000e+02 5.000000e+01 -1.732051e+02 615 | vertex 5.000000e+01 -5.000000e+01 -8.660254e+01 616 | endloop 617 | endfacet 618 | facet normal 4.323045e-01 -7.040626e-01 -5.633903e-01 619 | outer loop 620 | vertex 5.000000e+01 -5.000000e+01 -8.660254e+01 621 | vertex 1.000000e+02 5.000000e+01 -1.732051e+02 622 | vertex 1.414214e+02 5.000000e+01 -1.414214e+02 623 | endloop 624 | endfacet 625 | facet normal 4.323045e-01 -7.040626e-01 -5.633903e-01 626 | outer loop 627 | vertex 5.000000e+01 -5.000000e+01 -8.660254e+01 628 | vertex 1.414214e+02 5.000000e+01 -1.414214e+02 629 | vertex 7.071068e+01 -5.000000e+01 -7.071068e+01 630 | endloop 631 | endfacet 632 | facet normal 5.633903e-01 -7.040626e-01 -4.323046e-01 633 | outer loop 634 | vertex 7.071068e+01 -5.000000e+01 -7.071068e+01 635 | vertex 1.414214e+02 5.000000e+01 -1.414214e+02 636 | vertex 1.732051e+02 5.000000e+01 -1.000000e+02 637 | endloop 638 | endfacet 639 | facet normal 5.633903e-01 -7.040626e-01 -4.323045e-01 640 | outer loop 641 | vertex 7.071068e+01 -5.000000e+01 -7.071068e+01 642 | vertex 1.732051e+02 5.000000e+01 -1.000000e+02 643 | vertex 8.660254e+01 -5.000000e+01 -5.000000e+01 644 | endloop 645 | endfacet 646 | facet normal 6.560819e-01 -7.040626e-01 -2.717580e-01 647 | outer loop 648 | vertex 8.660254e+01 -5.000000e+01 -5.000000e+01 649 | vertex 1.732051e+02 5.000000e+01 -1.000000e+02 650 | vertex 1.931852e+02 5.000000e+01 -5.176381e+01 651 | endloop 652 | endfacet 653 | facet normal 6.560819e-01 -7.040626e-01 -2.717580e-01 654 | outer loop 655 | vertex 8.660254e+01 -5.000000e+01 -5.000000e+01 656 | vertex 1.931852e+02 5.000000e+01 -5.176381e+01 657 | vertex 9.659258e+01 -5.000000e+01 -2.588190e+01 658 | endloop 659 | endfacet 660 | facet normal 7.040626e-01 -7.040626e-01 -9.269172e-02 661 | outer loop 662 | vertex 9.659258e+01 -5.000000e+01 -2.588190e+01 663 | vertex 1.931852e+02 5.000000e+01 -5.176381e+01 664 | vertex 2.000000e+02 5.000000e+01 0.000000e+00 665 | endloop 666 | endfacet 667 | facet normal 7.040626e-01 -7.040626e-01 -9.269159e-02 668 | outer loop 669 | vertex 9.659258e+01 -5.000000e+01 -2.588190e+01 670 | vertex 2.000000e+02 5.000000e+01 0.000000e+00 671 | vertex 1.000000e+02 -5.000000e+01 0.000000e+00 672 | endloop 673 | endfacet 674 | endsolid vcg 675 | -------------------------------------------------------------------------------- /example/machine/example.yaml: -------------------------------------------------------------------------------- 1 | world: 2 | cube: 3 | side: 4000 4 | material: G4_AIR 5 | colour: [0, 0, 0, 0] 6 | daughters: 7 | head: 8 | cylinder: 9 | radius: 500 10 | length: 800 11 | translation: [0, 0, 800] 12 | rotation: [0, 0, 0] 13 | colour: [0, 1, 0, 0.25] 14 | daughters: 15 | filter: 16 | filename: machine/cone.stl 17 | translation: [0, 0, -200] 18 | rotation: [90, 0, 0] 19 | material: G4_WATER 20 | colour: [0, 0, 1] 21 | 22 | vacuum: 23 | cylinder: 24 | radius: 250 25 | length: 250 26 | translation: [0, 0, 100] 27 | material: G4_Galactic 28 | colour: [1, 1, 0, 0.25] 29 | daughters: 30 | target: 31 | filename: machine/target.ply 32 | translation: [0, 0, 0] 33 | rotation: [90, 0, 0] 34 | material: G4_WATER 35 | colour: [0, 1, 1] 36 | 37 | zslab: 38 | slab: 39 | side: 50 40 | thickness: 5 41 | material: G4_Pb 42 | repeat: 4 43 | interval: -100 44 | origin: [0, 0, 150] 45 | translation: 46 | function: repeat_z 47 | yslab: 48 | inherit: zslab 49 | rotation: [90, 0, 0] 50 | origin: [0, 150, 0] 51 | translation: 52 | function: repeat_y 53 | xslab: 54 | inherit: zslab 55 | rotation: [0, 90, 0] 56 | origin: [150, 0, 0] 57 | translation: 58 | function: repeat_x 59 | 60 | 61 | gun: 62 | spot_size: 1 63 | fwhm: 2 64 | recycling_number: 10 65 | 66 | phasespaces: 67 | exitwindow1: 68 | z_position: 0 69 | radius: 1000 70 | material: G4_AIR 71 | redistribute: false 72 | kill: false 73 | 74 | exitwindow2: 75 | z_position: -100 76 | radius: 1000 77 | material: G4_AIR 78 | redistribute: false 79 | kill: true 80 | 81 | iso: 82 | z_position: -500 83 | radius: 1000 84 | material: G4_AIR 85 | redistribute: false 86 | kill: true 87 | 88 | -------------------------------------------------------------------------------- /example/machine/target.ply: -------------------------------------------------------------------------------- 1 | ply 2 | format ascii 1.0 3 | comment VCGLIB generated 4 | element vertex 74 5 | property float x 6 | property float y 7 | property float z 8 | element face 144 9 | property list uchar int vertex_indices 10 | end_header 11 | 0 -5 0 12 | 0 5 0 13 | 50 -5 0 14 | 49.2404 -5 8.68241 15 | 46.9846 -5 17.101 16 | 43.3013 -5 25 17 | 38.3022 -5 32.1394 18 | 32.1394 -5 38.3022 19 | 25 -5 43.3013 20 | 17.101 -5 46.9846 21 | 8.68241 -5 49.2404 22 | 3.06152e-15 -5 50 23 | -8.68241 -5 49.2404 24 | -17.101 -5 46.9846 25 | -25 -5 43.3013 26 | -32.1394 -5 38.3022 27 | -38.3022 -5 32.1394 28 | -43.3013 -5 25 29 | -46.9846 -5 17.101 30 | -49.2404 -5 8.68241 31 | -50 -5 6.12303e-15 32 | -49.2404 -5 -8.68241 33 | -46.9846 -5 -17.101 34 | -43.3013 -5 -25 35 | -38.3022 -5 -32.1394 36 | -32.1394 -5 -38.3022 37 | -25 -5 -43.3013 38 | -17.101 -5 -46.9846 39 | -8.68241 -5 -49.2404 40 | -9.18455e-15 -5 -50 41 | 8.68241 -5 -49.2404 42 | 17.101 -5 -46.9846 43 | 25 -5 -43.3013 44 | 32.1394 -5 -38.3022 45 | 38.3022 -5 -32.1394 46 | 43.3013 -5 -25 47 | 46.9846 -5 -17.101 48 | 49.2404 -5 -8.68241 49 | 50 5 0 50 | 49.2404 5 8.68241 51 | 46.9846 5 17.101 52 | 43.3013 5 25 53 | 38.3022 5 32.1394 54 | 32.1394 5 38.3022 55 | 25 5 43.3013 56 | 17.101 5 46.9846 57 | 8.68241 5 49.2404 58 | 3.06152e-15 5 50 59 | -8.68241 5 49.2404 60 | -17.101 5 46.9846 61 | -25 5 43.3013 62 | -32.1394 5 38.3022 63 | -38.3022 5 32.1394 64 | -43.3013 5 25 65 | -46.9846 5 17.101 66 | -49.2404 5 8.68241 67 | -50 5 6.12303e-15 68 | -49.2404 5 -8.68241 69 | -46.9846 5 -17.101 70 | -43.3013 5 -25 71 | -38.3022 5 -32.1394 72 | -32.1394 5 -38.3022 73 | -25 5 -43.3013 74 | -17.101 5 -46.9846 75 | -8.68241 5 -49.2404 76 | -9.18455e-15 5 -50 77 | 8.68241 5 -49.2404 78 | 17.101 5 -46.9846 79 | 25 5 -43.3013 80 | 32.1394 5 -38.3022 81 | 38.3022 5 -32.1394 82 | 43.3013 5 -25 83 | 46.9846 5 -17.101 84 | 49.2404 5 -8.68241 85 | 3 0 2 3 86 | 3 0 3 4 87 | 3 0 4 5 88 | 3 0 5 6 89 | 3 0 6 7 90 | 3 0 7 8 91 | 3 0 8 9 92 | 3 0 9 10 93 | 3 0 10 11 94 | 3 0 11 12 95 | 3 0 12 13 96 | 3 0 13 14 97 | 3 0 14 15 98 | 3 0 15 16 99 | 3 0 16 17 100 | 3 0 17 18 101 | 3 0 18 19 102 | 3 0 19 20 103 | 3 0 20 21 104 | 3 0 21 22 105 | 3 0 22 23 106 | 3 0 23 24 107 | 3 0 24 25 108 | 3 0 25 26 109 | 3 0 26 27 110 | 3 0 27 28 111 | 3 0 28 29 112 | 3 0 29 30 113 | 3 0 30 31 114 | 3 0 31 32 115 | 3 0 32 33 116 | 3 0 33 34 117 | 3 0 34 35 118 | 3 0 35 36 119 | 3 0 36 37 120 | 3 0 37 2 121 | 3 1 39 38 122 | 3 1 40 39 123 | 3 1 41 40 124 | 3 1 42 41 125 | 3 1 43 42 126 | 3 1 44 43 127 | 3 1 45 44 128 | 3 1 46 45 129 | 3 1 47 46 130 | 3 1 48 47 131 | 3 1 49 48 132 | 3 1 50 49 133 | 3 1 51 50 134 | 3 1 52 51 135 | 3 1 53 52 136 | 3 1 54 53 137 | 3 1 55 54 138 | 3 1 56 55 139 | 3 1 57 56 140 | 3 1 58 57 141 | 3 1 59 58 142 | 3 1 60 59 143 | 3 1 61 60 144 | 3 1 62 61 145 | 3 1 63 62 146 | 3 1 64 63 147 | 3 1 65 64 148 | 3 1 66 65 149 | 3 1 67 66 150 | 3 1 68 67 151 | 3 1 69 68 152 | 3 1 70 69 153 | 3 1 71 70 154 | 3 1 72 71 155 | 3 1 73 72 156 | 3 1 38 73 157 | 3 2 38 39 158 | 3 2 39 3 159 | 3 3 39 40 160 | 3 3 40 4 161 | 3 4 40 41 162 | 3 4 41 5 163 | 3 5 41 42 164 | 3 5 42 6 165 | 3 6 42 43 166 | 3 6 43 7 167 | 3 7 43 44 168 | 3 7 44 8 169 | 3 8 44 45 170 | 3 8 45 9 171 | 3 9 45 46 172 | 3 9 46 10 173 | 3 10 46 47 174 | 3 10 47 11 175 | 3 11 47 48 176 | 3 11 48 12 177 | 3 12 48 49 178 | 3 12 49 13 179 | 3 13 49 50 180 | 3 13 50 14 181 | 3 14 50 51 182 | 3 14 51 15 183 | 3 15 51 52 184 | 3 15 52 16 185 | 3 16 52 53 186 | 3 16 53 17 187 | 3 17 53 54 188 | 3 17 54 18 189 | 3 18 54 55 190 | 3 18 55 19 191 | 3 19 55 56 192 | 3 19 56 20 193 | 3 20 56 57 194 | 3 20 57 21 195 | 3 21 57 58 196 | 3 21 58 22 197 | 3 22 58 59 198 | 3 22 59 23 199 | 3 23 59 60 200 | 3 23 60 24 201 | 3 24 60 61 202 | 3 24 61 25 203 | 3 25 61 62 204 | 3 25 62 26 205 | 3 26 62 63 206 | 3 26 63 27 207 | 3 27 63 64 208 | 3 27 64 28 209 | 3 28 64 65 210 | 3 28 65 29 211 | 3 29 65 66 212 | 3 29 66 30 213 | 3 30 66 67 214 | 3 30 67 31 215 | 3 31 67 68 216 | 3 31 68 32 217 | 3 32 68 69 218 | 3 32 69 33 219 | 3 33 69 70 220 | 3 33 70 34 221 | 3 34 70 71 222 | 3 34 71 35 223 | 3 35 71 72 224 | 3 35 72 36 225 | 3 36 72 73 226 | 3 36 73 37 227 | 3 37 73 38 228 | 3 37 38 2 229 | -------------------------------------------------------------------------------- /example/macros/vis.mac: -------------------------------------------------------------------------------- 1 | /tracking/verbose 0 2 | 3 | /vis/verbose 0 4 | /vis/open OGLIX 800x800-0+50 5 | /vis/drawVolume 6 | 7 | /vis/scene/add/axes 0 0 0 900 mm 8 | 9 | /vis/viewer/set/viewpointThetaPhi 90 0 10 | /vis/viewer/zoom 1 11 | /vis/viewer/set/style solid 12 | /vis/viewer/set/hiddenEdge 1 13 | 14 | /vis/scene/add/trajectories 15 | /vis/scene/endOfEventAction accumulate 16 | 17 | #/run/beamOn 100 18 | 19 | -------------------------------------------------------------------------------- /linac/__init__.py: -------------------------------------------------------------------------------- 1 | from geometry import Volume, Linac 2 | from simulation import Simulation 3 | 4 | from g4 import ShowGUI 5 | 6 | -------------------------------------------------------------------------------- /linac/g4/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # License & Copyright 2 | # =================== 3 | # 4 | # Copyright 2012 Christopher M Poole 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | cmake_minimum_required(VERSION 2.6 FATAL_ERROR) 21 | project(g4) 22 | 23 | find_package(Geant4 REQUIRED ui_all vis_all) 24 | find_package(PythonLibs REQUIRED) 25 | find_package(Boost REQUIRED COMPONENTS python serialization iostreams) 26 | 27 | include(${Geant4_USE_FILE}) 28 | include_directories(${PYTHON_INCLUDE_DIRS}) 29 | include_directories(${PROJECT_SOURCE_DIR}/include) 30 | include_directories(/usr/local/include) 31 | 32 | # CADMesh 33 | find_package(cadmesh) 34 | 35 | # G4VoxelData with DICIOM 36 | find_package(G4VoxelData) 37 | 38 | # User code 39 | file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc) 40 | file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh) 41 | 42 | SET(LIBRARY_OUTPUT_PATH "..") 43 | add_library(g4 "SHARED" libg4.cc ${sources} ${headers}) 44 | 45 | target_link_libraries(g4 ${cadmesh_LIBRARIES}) 46 | target_link_libraries(g4 ${Geant4_LIBRARIES}) 47 | target_link_libraries(g4 ${Boost_LIBRARIES}) 48 | target_link_libraries(g4 ${Python_LIBRARIES}) 49 | target_link_libraries(g4 cnpy) 50 | target_link_libraries(g4 ${G4VOXELDATA_DICOM_LIBRARIES}) 51 | 52 | -------------------------------------------------------------------------------- /linac/g4/__init__.py: -------------------------------------------------------------------------------- 1 | # License & Copyright 2 | # =================== 3 | # 4 | # Copyright 2012 Christopher M Poole 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | from libg4 import DetectorConstruction, PhysicsList, \ 21 | PrimaryGeneratorAction, EventAction, SteppingAction, ShowGUI 22 | 23 | -------------------------------------------------------------------------------- /linac/g4/include/BremSplittingProcess.hh: -------------------------------------------------------------------------------- 1 | // 2 | // ******************************************************************** 3 | // * DISCLAIMER * 4 | // * * 5 | // * The following disclaimer summarizes all the specific disclaimers * 6 | // * of contributors to this software. The specific disclaimers,which * 7 | // * govern, are listed with their locations in: * 8 | // * http://cern.ch/geant4/license * 9 | // * * 10 | // * Neither the authors of this software system, nor their employing * 11 | // * institutes,nor the agencies providing financial support for this * 12 | // * work make any representation or warranty, express or implied, * 13 | // * regarding this software system or assume any liability for its * 14 | // * use. * 15 | // * * 16 | // * This code implementation is the intellectual property of the * 17 | // * GEANT4 collaboration. * 18 | // * By copying, distributing or modifying the Program (or any work * 19 | // * based on the Program) you indicate your acceptance of this * 20 | // * statement, and all its terms. * 21 | // ******************************************************************** 22 | // 23 | // 24 | // Jane Tinslay, March 2006 25 | // 26 | #ifndef BREMSPLITTINGPROCESS_HH 27 | #define BREMSPLITTINGPROCESS_HH 1 28 | 29 | #include "G4WrapperProcess.hh" 30 | 31 | class BremSplittingProcessMessenger; 32 | 33 | class BremSplittingProcess : public G4WrapperProcess { 34 | 35 | public: 36 | 37 | BremSplittingProcess(); 38 | 39 | virtual ~BremSplittingProcess(); 40 | 41 | // Override PostStepDoIt method 42 | G4VParticleChange* PostStepDoIt(const G4Track& track, const G4Step& step); 43 | 44 | // Modifiers 45 | void SetNSplit(G4int); 46 | static void SetIsActive(G4bool); 47 | 48 | // Accessors 49 | static G4bool GetIsActive(); 50 | G4int GetNSplit(); 51 | static G4int GetNSecondaries(); 52 | 53 | 54 | private: 55 | 56 | // Data members 57 | // static G4int fNSplit; 58 | G4int fNSplit; 59 | static G4int fNSecondaries; 60 | static G4bool fActive; 61 | 62 | BremSplittingProcessMessenger* bremMessenger; 63 | 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /linac/g4/include/DetectorConstruction.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef DetectorConstruction_H 23 | #define DetectorConstruction_H 1 24 | 25 | // USER // 26 | #include "ParallelDetectorConstruction.hh" 27 | #include "StopKillShield.hh" 28 | #include "SensitiveDetector.hh" 29 | #include "Phasespace.hh" 30 | 31 | // GEANT4 // 32 | #include "G4VUserDetectorConstruction.hh" 33 | 34 | #include "G4Region.hh" 35 | #include "G4ProductionCuts.hh" 36 | 37 | #include "G4Box.hh" 38 | #include "G4Tubs.hh" 39 | #include "G4LogicalVolume.hh" 40 | #include "G4PVPlacement.hh" 41 | #include "G4AssemblyVolume.hh" 42 | #include "G4Material.hh" 43 | #include "G4NistManager.hh" 44 | #include "G4Colour.hh" 45 | #include "G4SDManager.hh" 46 | 47 | #include "G4RotationMatrix.hh" 48 | 49 | // G4VoxelData// 50 | #include "G4VoxelData.hh" 51 | #include "G4VoxelArray.hh" 52 | #include "G4VoxelDataParameterisation.hh" 53 | #include "DicomDataIO.hh" 54 | #include "NumpyDataIO.hh" 55 | 56 | // BOOST/PYTHON // 57 | #include "boost/python.hpp" 58 | //#include "pyublas/numpy.hpp" 59 | 60 | 61 | // Simple data structure for setpoints in hounsfiled -> G4Material ramp 62 | class Hounsfield{ 63 | public: 64 | Hounsfield(int value, G4String material_name, G4double density) { 65 | this->value = value; 66 | this->material_name = material_name; 67 | this->density = density; 68 | }; 69 | 70 | public: 71 | G4int value; 72 | G4String material_name; 73 | G4double density; 74 | }; 75 | 76 | 77 | class DetectorConstruction : public G4VUserDetectorConstruction 78 | { 79 | public: 80 | DetectorConstruction(); 81 | ~DetectorConstruction(); 82 | 83 | G4VPhysicalVolume* Construct(); 84 | 85 | public: 86 | G4VPhysicalVolume* FindVolume(G4String name, G4VPhysicalVolume * mother); 87 | 88 | void AddMaterial(G4String name, G4double density, boost::python::object move); 89 | 90 | void SetupPhantom(); 91 | void SetupCADPhantom(char* filename, G4ThreeVector offset); 92 | 93 | G4VPhysicalVolume* AddTube(char* name, 94 | double inner_radius, double outer_radius, double length, 95 | G4ThreeVector translation, G4ThreeVector rotation, 96 | char* material_name, G4Colour colour, 97 | G4LogicalVolume* mother_logical); 98 | 99 | G4VPhysicalVolume* AddSlab(char* name, 100 | double side, double thickness, 101 | char* material, 102 | G4ThreeVector translation, 103 | G4ThreeVector rotation, 104 | G4Colour colour, 105 | G4LogicalVolume* mother_logical); 106 | 107 | G4VPhysicalVolume* AddCADComponent(char* name, char* filename, char* material, 108 | double scale, 109 | G4ThreeVector translation, 110 | G4ThreeVector rotation, 111 | G4Colour colour, G4bool tessellated, 112 | G4LogicalVolume* mother_logical); 113 | 114 | void SetupCT(); 115 | 116 | std::map MakeMaterialsMap(G4int increment); 117 | G4Material* MakeNewMaterial(G4String base_material_name, G4double density); 118 | 119 | public: 120 | void SetWorldSize(G4ThreeVector size) { 121 | this->world_size = size; 122 | }; 123 | 124 | void SetWorldMaterial(G4String name) { 125 | this->world_material = nist_manager->FindOrBuildMaterial(name); 126 | }; 127 | 128 | void SetWorldColour(G4Color colour) { 129 | this->world_colour = colour; 130 | }; 131 | 132 | void RemoveHead() { 133 | if (head_physical) 134 | delete head_physical; 135 | if (sheild_physical) 136 | delete sheild_physical; 137 | if (lid_physical) 138 | delete lid_physical; 139 | 140 | headless = true; 141 | }; 142 | 143 | void ClosePhasespace() { 144 | // phasespace_sensitive_detector->Close(); 145 | for(int i=0; iClose(); 147 | } 148 | 149 | phasespaces.clear(); 150 | }; 151 | 152 | void UsePhantom(G4bool use) { 153 | use_phantom = use; 154 | } 155 | 156 | void UseCADPhantom(char* filename, G4ThreeVector offset) { 157 | phantom_filename = filename; 158 | phantom_offset = offset; 159 | use_cad_phantom = true; 160 | 161 | SetupCADPhantom(filename, offset); 162 | } 163 | 164 | G4ThreeVector GetCTOrigin() { 165 | return G4ThreeVector(this->data->origin[0], 166 | this->data->origin[1], 167 | this->data->origin[2]); 168 | } 169 | 170 | void SetCTPosition(G4ThreeVector ct_position) { 171 | this->ct_position = ct_position; 172 | } 173 | 174 | void UseCT(G4String ct_directory, G4int acquisition_number) { 175 | this->use_ct = true; 176 | this->ct_directory = ct_directory; 177 | 178 | DicomDataIO* reader = new DicomDataIO(); 179 | reader->SetAcquisitionNumber(acquisition_number); 180 | 181 | this->data = reader->ReadDirectory(this->ct_directory); 182 | this->array = new G4VoxelArray(this->data); 183 | this->array->Merge(2, 2, 2); 184 | 185 | G4int increment = 25; 186 | materials = MakeMaterialsMap(increment); 187 | } 188 | 189 | void UseArray(G4String filename, G4double x, G4double y, G4double z) { 190 | this->use_ct = true; 191 | 192 | NumpyDataIO* reader = new NumpyDataIO(); 193 | 194 | this->data = reader->Read(filename); 195 | this->array = new G4VoxelArray(this->data); 196 | 197 | std::vector spacing; 198 | spacing.push_back(x); spacing.push_back(y); spacing.push_back(z); 199 | //this->array->SetSpacing(spacing); 200 | 201 | G4int increment = 25; 202 | materials = MakeMaterialsMap(increment); 203 | }; 204 | 205 | void HideCT(G4bool hide) { 206 | this->use_ct = !hide; 207 | }; 208 | 209 | void CropX(G4int xmin, G4int xmax) { 210 | this->array->CropX(xmin, xmax); 211 | }; 212 | 213 | void CropY(G4int ymin, G4int ymax) { 214 | this->array->CropY(ymin, ymax); 215 | }; 216 | 217 | void CropZ(G4int zmin, G4int zmax) { 218 | this->array->CropZ(zmin, zmax); 219 | }; 220 | 221 | void CropCT(G4int xmin, G4int xmax, G4int ymin, G4int ymax, G4int zmin, G4int zmax) { 222 | this->array->Crop(xmin, xmax, ymin, ymax, zmin, zmax); 223 | } 224 | 225 | pyublas::numpy_vector GetEnergyHistogram() { 226 | return detector->GetEnergyHistogram(); 227 | } 228 | 229 | pyublas::numpy_vector GetEnergySqHistogram() { 230 | return detector->GetEnergySqHistogram(); 231 | } 232 | 233 | pyublas::numpy_vector GetCountsHistogram() { 234 | return detector->GetCountsHistogram(); 235 | } 236 | 237 | void ZeroHistograms() { 238 | std::fill(detector->energy_histogram.begin(), detector->energy_histogram.end(), 0.0); 239 | std::fill(detector->energysq_histogram.begin(), detector->energysq_histogram.end(), 0.0); 240 | std::fill(detector->counts_histogram.begin(), detector->counts_histogram.end(), 0.0); 241 | } 242 | 243 | void SetVerbosity(G4int verbose) { 244 | this->verbose = verbose; 245 | } 246 | 247 | G4LogicalVolume* GetWorld() { 248 | return world_logical; 249 | } 250 | 251 | void SetAsStopKillSheild(G4VPhysicalVolume* physical) { 252 | StopKillSheild* sheild = new StopKillSheild(physical->GetName()); 253 | 254 | G4SDManager* sd_manager = G4SDManager::GetSDMpointer(); 255 | sd_manager->AddNewDetector(sheild); 256 | physical->GetLogicalVolume()->SetSensitiveDetector(sheild); 257 | } 258 | 259 | G4VPhysicalVolume* AddPhasespace(char* name, double radius, double z_position, bool kill) { 260 | if (GetNumberOfParallelWorld() == 1) { 261 | ParallelDetectorConstruction* pw = (ParallelDetectorConstruction*) GetParallelWorld(0); 262 | return pw->AddPhasespace(name, radius, z_position, kill); 263 | } 264 | 265 | return 0; 266 | } 267 | 268 | void RemovePhasespace(char* name) { 269 | if (GetNumberOfParallelWorld() == 1) { 270 | ParallelDetectorConstruction* pw = (ParallelDetectorConstruction*) GetParallelWorld(0); 271 | pw->RemovePhasespace(name); 272 | } 273 | } 274 | 275 | private: 276 | G4Region* region; 277 | G4ProductionCuts* cuts; 278 | 279 | G4Box* world_solid; 280 | G4LogicalVolume* world_logical; 281 | G4VPhysicalVolume* world_physical; 282 | 283 | G4ThreeVector world_size; 284 | G4Material* world_material; 285 | G4Color world_colour; 286 | 287 | G4Box* phantom_solid; 288 | G4LogicalVolume* phantom_logical; 289 | G4VPhysicalVolume* phantom_physical; 290 | 291 | SensitiveDetector* detector; 292 | //Phasespace* phasespace_sensitive_detector; 293 | std::vector phasespaces; 294 | 295 | G4Tubs* head_solid; 296 | G4LogicalVolume* head_logical; 297 | G4VPhysicalVolume* head_physical; 298 | 299 | G4Tubs* vacuum_solid; 300 | G4LogicalVolume* vacuum_logical; 301 | G4VPhysicalVolume* vacuum_physical; 302 | 303 | G4Tubs* sheild_solid; 304 | G4LogicalVolume* sheild_logical; 305 | G4VPhysicalVolume* sheild_physical; 306 | 307 | G4Tubs* lid_solid; 308 | G4LogicalVolume* lid_logical; 309 | G4VPhysicalVolume* lid_physical; 310 | 311 | G4NistManager* nist_manager; 312 | G4Material* StainlessSteel; 313 | 314 | G4ThreeVector head_position; 315 | G4RotationMatrix* head_rotation; 316 | G4double head_length; 317 | G4ThreeVector vacuum_position; 318 | G4double vacuum_length; 319 | 320 | G4bool use_phantom; 321 | G4bool use_ct; 322 | G4bool ct_built; 323 | 324 | G4bool use_cad_phantom; 325 | char* phantom_filename; 326 | G4ThreeVector phantom_offset; 327 | 328 | G4String ct_directory; 329 | G4ThreeVector ct_position; 330 | 331 | G4bool headless; 332 | 333 | G4VoxelData* data; 334 | G4VoxelArray* array; 335 | G4VoxelDataParameterisation* voxeldata_param; 336 | std::map materials; 337 | std::vector hounsfield; 338 | 339 | G4int verbose; 340 | }; 341 | 342 | #endif 343 | 344 | -------------------------------------------------------------------------------- /linac/g4/include/EventAction.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef EventAction_h 23 | #define EventAction_h 1 24 | 25 | #include "G4UserEventAction.hh" 26 | #include "globals.hh" 27 | 28 | #include "G4Event.hh" 29 | 30 | class EventAction : public G4UserEventAction 31 | { 32 | public: 33 | EventAction(); 34 | virtual ~EventAction(); 35 | 36 | public: 37 | virtual void BeginOfEventAction(const G4Event*); 38 | virtual void EndOfEventAction(const G4Event*); 39 | 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /linac/g4/include/ParallelDetectorConstruction.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef ParallelDetectorConstruction_H 23 | #define ParallelDetectorConstruction_H 1 24 | 25 | // USER // 26 | #include "Phasespace.hh" 27 | 28 | // GEANT4 // 29 | #include "G4VUserParallelWorld.hh" 30 | #include "G4LogicalVolume.hh" 31 | 32 | 33 | class ParallelDetectorConstruction : public G4VUserParallelWorld 34 | { 35 | public: 36 | ParallelDetectorConstruction(G4String name); 37 | ~ParallelDetectorConstruction(); 38 | 39 | void Construct(); 40 | G4VPhysicalVolume* AddPhasespace(char* name, double radius, double z_position, bool kill); 41 | void RemovePhasespace(char* name); 42 | 43 | private: 44 | G4LogicalVolume* world_logical; 45 | G4VPhysicalVolume* world_physical; 46 | 47 | std::map phasespaces; 48 | 49 | G4int verbose; 50 | }; 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /linac/g4/include/Phasespace.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef _PHASESPACE_HH 23 | #define _PHASESPACE_HH 24 | 25 | #include "PhasespaceRecord.hh" 26 | 27 | #include "G4VSensitiveDetector.hh" 28 | #include "G4VUserDetectorConstruction.hh" 29 | #include "globals.hh" 30 | 31 | //#include "boost/python.hpp" 32 | //#include "pyublas/numpy.hpp" 33 | 34 | #include "boost/archive/binary_iarchive.hpp" 35 | #include "boost/archive/binary_oarchive.hpp" 36 | 37 | #include 38 | 39 | 40 | class G4Step; 41 | class G4TouchableHistory; 42 | class G4HCofThisEvent; 43 | class DetectorConstruction; 44 | 45 | class Phasespace : public G4VSensitiveDetector { 46 | public: 47 | Phasespace(const G4String& name, G4double radius); 48 | virtual ~Phasespace(); 49 | 50 | void Initialize(G4HCofThisEvent*); 51 | G4bool ProcessHits(G4Step*, G4TouchableHistory*); 52 | void EndOfEvent(G4HCofThisEvent*); 53 | void clear(); 54 | void PrintAll(); 55 | 56 | public: 57 | void Close(); 58 | 59 | void SetKillAtPlane(G4bool kill) { 60 | this->kill = kill; 61 | }; 62 | 63 | G4bool GetKillAtPlane() { 64 | return this->kill; 65 | }; 66 | 67 | G4String GetName() { 68 | return this->name; 69 | }; 70 | 71 | private: 72 | DetectorConstruction* detector_construction; 73 | 74 | std::ofstream* output_file_stream; 75 | boost::archive::binary_oarchive* phasespace_archive; 76 | 77 | G4String name; 78 | G4double radius; 79 | G4int record_count; 80 | G4bool kill; 81 | }; 82 | 83 | 84 | #endif /* _PHASESPACE_HH */ 85 | 86 | -------------------------------------------------------------------------------- /linac/g4/include/PhasespaceRecord.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef PHASESPACERECORD_HH 23 | #define PHASESPACERECORD_HH 24 | 25 | #include "globals.hh" 26 | 27 | #include "G4Step.hh" 28 | #include "G4ThreeVector.hh" 29 | 30 | #include "boost/archive/binary_iarchive.hpp" 31 | #include "boost/archive/binary_oarchive.hpp" 32 | 33 | 34 | class PhasespaceRecord { 35 | public: 36 | PhasespaceRecord(); 37 | PhasespaceRecord(G4Step* step); 38 | virtual ~PhasespaceRecord(); 39 | 40 | private: 41 | friend class boost::serialization::access; 42 | template 43 | void serialize(Archive & ar, const unsigned int) { 44 | ar & position_x; 45 | ar & position_y; 46 | ar & position_z; 47 | 48 | ar & momentum_x; 49 | ar & momentum_y; 50 | ar & momentum_z; 51 | 52 | ar & kinetic_energy; 53 | 54 | ar & weight; 55 | 56 | ar & particle_type; 57 | 58 | } 59 | 60 | public: 61 | G4bool CheckIt(G4double xlow, G4double xhigh, G4double ylow, 62 | G4double yhigh, G4double zlow, G4double zhigh); 63 | G4ThreeVector GetPosition(); 64 | G4ThreeVector GetMomentum(); 65 | G4double GetKineticEnergy(); 66 | G4int GetParticleType(); 67 | G4double GetWeight(); 68 | 69 | public: 70 | double position_x; 71 | double position_y; 72 | double position_z; 73 | 74 | double momentum_x; 75 | double momentum_y; 76 | double momentum_z; 77 | 78 | double kinetic_energy; 79 | 80 | double weight; 81 | 82 | int particle_type; 83 | 84 | }; 85 | 86 | #endif /* PHASESPACERECORD_HH */ 87 | -------------------------------------------------------------------------------- /linac/g4/include/PhysicsList.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef PhysicsList_h 23 | #define PhysicsList_h 1 24 | 25 | // GEANT4 // 26 | #include "globals.hh" 27 | #include "G4VModularPhysicsList.hh" 28 | #include "G4VUserPhysicsList.hh" 29 | #include "G4RunManager.hh" 30 | #include "G4ProductionCutsTable.hh" 31 | 32 | 33 | //class PhysicsList: public G4VUserPhysicsList 34 | class PhysicsList: public G4VModularPhysicsList 35 | { 36 | public: 37 | PhysicsList(); 38 | ~PhysicsList(); 39 | 40 | protected: 41 | void ConstructParticle(); 42 | void ConstructProcess(); 43 | void SetCuts(); 44 | void AddParallelWorldProcess(); 45 | 46 | public: 47 | void OverrideCuts(double gamma_cuts, double e_cuts){ 48 | this->gamma_cuts = gamma_cuts; 49 | this->e_cuts = e_cuts; 50 | 51 | SetCuts(); 52 | }; 53 | 54 | private: 55 | double gamma_cuts; 56 | double e_cuts; 57 | }; 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /linac/g4/include/PrimaryGeneratorAction.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef PrimaryGeneratorAction_h 23 | #define PrimaryGeneratorAction_h 1 24 | 25 | #include "PhasespaceRecord.hh" 26 | 27 | #include "G4VUserPrimaryGeneratorAction.hh" 28 | #include "G4GeneralParticleSource.hh" 29 | #include "G4ParticleGun.hh" 30 | 31 | #include "boost/archive/binary_iarchive.hpp" 32 | #include "boost/archive/binary_oarchive.hpp" 33 | 34 | class G4GeneralParticleSource; 35 | class G4Event; 36 | 37 | /* 38 | class PhasespaceRecordStream { 39 | public: 40 | PhasespaceRecordStream(char* filename) {//: input_file_stream(filename) , phasespace_archive(input_file_stream) { 41 | input_file_stream = new std::ifstream(filename); 42 | phasespace_archive = new boost::archive::binary_iarchive(*input_file_stream); 43 | 44 | current_record = new PhasespaceRecord(); 45 | }; 46 | 47 | ~PhasespaceRecordStream() { 48 | delete input_file_stream; 49 | delete phasespace_archive; 50 | delete current_record; 51 | }; 52 | 53 | PhasespaceRecord* GetNextRecord() { 54 | G4cout << "reading record... "; 55 | *phasespace_archive >> current_record; 56 | G4cout << "done." << G4endl; 57 | 58 | return current_record; 59 | } 60 | 61 | public: 62 | PhasespaceRecord* current_record; 63 | 64 | private: 65 | std::ifstream* input_file_stream; 66 | boost::archive::binary_iarchive* phasespace_archive; 67 | }; 68 | */ 69 | 70 | class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction 71 | { 72 | public: 73 | PrimaryGeneratorAction(); 74 | ~PrimaryGeneratorAction(); 75 | 76 | void Reset(); 77 | 78 | void SetPosition(G4ThreeVector position) { 79 | particle_gun->GetCurrentSource()->GetPosDist()->SetCentreCoords(position); 80 | }; 81 | 82 | void SetDirection(G4ThreeVector direction) { 83 | particle_gun->GetCurrentSource()->GetAngDist()-> 84 | SetParticleMomentumDirection(direction); 85 | }; 86 | 87 | void SetEnergy(G4double energy) { 88 | particle_gun->GetCurrentSource()->GetEneDist()->SetMonoEnergy(energy*MeV); 89 | }; 90 | 91 | void SetFWHM(G4double fwhm) { 92 | particle_gun->GetCurrentSource()->GetPosDist()->SetBeamSigmaInR(fwhm*mm); 93 | }; 94 | 95 | void SetRecyclingNumber(G4int number) { 96 | recycling_number = number; 97 | } 98 | 99 | void SetRedistribute(G4bool flag) { 100 | redistribute = flag; 101 | G4cout << "setting redistribute flag to " << redistribute << G4endl; 102 | } 103 | 104 | void SetGantryRotation(G4ThreeVector rotation) { 105 | G4cout << "Setting gantry rotation: " << rotation << G4endl; 106 | this->rotation = rotation; 107 | }; 108 | 109 | void SetSource(char* phasespace) { 110 | if (phasespace == NULL) { 111 | G4cout << "Not using phasespace file as particle source, running from GPS" << G4endl; 112 | from_phasespace = false; 113 | } else { 114 | from_phasespace = true; 115 | G4cout << "Using phasespace file as particle source: " << phasespace << G4endl; 116 | 117 | input_file_stream = new std::ifstream(phasespace, std::ios::binary); 118 | phasespace_archive = new boost::archive::binary_iarchive(*input_file_stream); 119 | 120 | particle_gun->GetCurrentSource()->GetPosDist()->SetPosDisType("Point"); 121 | phasespace_record_repeat = -1; 122 | } 123 | } 124 | 125 | void SetPhasespaceLimits(G4double xlow, G4double xhigh, 126 | G4double ylow, G4double yhigh, G4double zlow, G4double zhigh) { 127 | this->xlow = xlow; 128 | this->xhigh = xhigh; 129 | this->ylow = ylow; 130 | this->yhigh = yhigh; 131 | this->zlow = zlow; 132 | this->zhigh = zhigh; 133 | } 134 | 135 | public: 136 | void GeneratePrimaries(G4Event* event); 137 | void GeneratePhasespacePrimaries(G4Event* event); 138 | 139 | private: 140 | G4ParticleGun* phasespace_particle_gun; 141 | G4GeneralParticleSource* particle_gun; 142 | 143 | G4ThreeVector rotation; 144 | 145 | G4bool from_phasespace; 146 | 147 | // Not in the constructor, so we need pointers. 148 | std::ifstream* input_file_stream; 149 | boost::archive::binary_iarchive* phasespace_archive; 150 | 151 | G4ParticleDefinition* electron; 152 | G4ParticleDefinition* gamma; 153 | G4ParticleDefinition* positron; 154 | 155 | G4int recycling_number; 156 | G4bool redistribute; 157 | 158 | PhasespaceRecord phasespace_record; 159 | G4int phasespace_record_repeat; 160 | 161 | G4int count; 162 | 163 | G4double xlow; 164 | G4double xhigh; 165 | G4double ylow; 166 | G4double yhigh; 167 | G4double zlow; 168 | G4double zhigh; 169 | }; 170 | 171 | #endif 172 | 173 | -------------------------------------------------------------------------------- /linac/g4/include/SensitiveDetector.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef _SensitiveDETECTOR_HH 23 | #define _SensitiveDETECTOR_HH 24 | 25 | 26 | #include "G4VSensitiveDetector.hh" 27 | #include "G4VUserDetectorConstruction.hh" 28 | #include "globals.hh" 29 | 30 | #include "boost/python.hpp" 31 | #include "pyublas/numpy.hpp" 32 | 33 | #include 34 | 35 | class G4Step; 36 | class G4TouchableHistory; 37 | class G4HCofThisEvent; 38 | class DetectorConstruction; 39 | 40 | class SensitiveDetector : public G4VSensitiveDetector { 41 | public: 42 | SensitiveDetector(const G4String& name); 43 | virtual ~SensitiveDetector(); 44 | 45 | void Initialize(G4HCofThisEvent*); 46 | G4bool ProcessHits(G4Step*, G4TouchableHistory*); 47 | void EndOfEvent(G4HCofThisEvent*); 48 | void clear(); 49 | void PrintAll(); 50 | 51 | DetectorConstruction* detector_construction; 52 | 53 | void SetDimensions(G4int x, G4int y, G4int z) { 54 | x_dim = x; 55 | y_dim = y; 56 | z_dim = z; 57 | }; 58 | 59 | void SetMinimumCutoff(G4int x, G4int y, G4int z) { 60 | x_min = x; 61 | y_min = y; 62 | z_min = z; 63 | }; 64 | 65 | void SetMaximumCutoff(G4int x, G4int y, G4int z) { 66 | x_max = x; 67 | y_max = y; 68 | z_max = z; 69 | }; 70 | 71 | void SetResolution(G4float x, G4float y, G4float z) { 72 | x_res = x; 73 | y_res = y; 74 | z_res = z; 75 | 76 | volume = x * y * z; 77 | }; 78 | 79 | pyublas::numpy_vector GetEnergyHistogram() { 80 | return this->energy_histogram; 81 | } 82 | 83 | pyublas::numpy_vector GetEnergySqHistogram() { 84 | return this->energysq_histogram; 85 | } 86 | 87 | pyublas::numpy_vector GetCountsHistogram() { 88 | return this->counts_histogram; 89 | } 90 | 91 | public: 92 | 93 | pyublas::numpy_vector energy_histogram; 94 | pyublas::numpy_vector energysq_histogram; 95 | pyublas::numpy_vector counts_histogram; 96 | 97 | //G4double voxel_mass; 98 | G4double volume; 99 | G4bool debug; 100 | 101 | G4int x_dim; 102 | G4int y_dim; 103 | G4int z_dim; 104 | G4int x_min; 105 | G4int y_min; 106 | G4int z_min; 107 | G4int x_max; 108 | G4int y_max; 109 | G4int z_max; 110 | 111 | G4float x_res; 112 | G4float y_res; 113 | G4float z_res; 114 | 115 | }; 116 | 117 | 118 | #endif /* _SensitiveDETECTOR_HH */ 119 | 120 | -------------------------------------------------------------------------------- /linac/g4/include/SteppingAction.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef STEPPINGACTION_HH 23 | #define STEPPINGACTION_HH 24 | 25 | #include "globals.hh" 26 | #include "G4UserSteppingAction.hh" 27 | #include "G4Step.hh" 28 | 29 | 30 | class SteppingAction : public G4UserSteppingAction 31 | { 32 | public: 33 | SteppingAction(); 34 | virtual ~SteppingAction(); 35 | 36 | virtual void UserSteppingAction(const G4Step* step); 37 | }; 38 | 39 | 40 | #endif // STEPPINGACTION_HH 41 | -------------------------------------------------------------------------------- /linac/g4/include/StopKillShield.hh: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #ifndef StopKillSheild_H 23 | #define StopKillSheild_H 1 24 | 25 | #include "G4VSensitiveDetector.hh" 26 | #include "G4HCofThisEvent.hh" 27 | #include "G4Step.hh" 28 | 29 | 30 | class StopKillSheild : public G4VSensitiveDetector 31 | { 32 | public: 33 | StopKillSheild(G4String); 34 | ~StopKillSheild(); 35 | 36 | public: 37 | void Initialize(G4HCofThisEvent*); 38 | G4bool ProcessHits(G4Step*, G4TouchableHistory*); 39 | void EndOfEvent(G4HCofThisEvent*); 40 | 41 | }; 42 | 43 | #endif 44 | 45 | -------------------------------------------------------------------------------- /linac/g4/libg4.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #include "DetectorConstruction.hh" 23 | #include "PhysicsList.hh" 24 | #include "SteppingAction.hh" 25 | #include "EventAction.hh" 26 | #include "PrimaryGeneratorAction.hh" 27 | 28 | #include "Phasespace.hh" 29 | #include "PhasespaceRecord.hh" 30 | 31 | // GEANT4 // 32 | #include "G4LogicalVolume.hh" 33 | #include "G4UImanager.hh" 34 | #include "G4VisManager.hh" 35 | #include "G4UIExecutive.hh" 36 | #include "G4VisExecutive.hh" 37 | 38 | // BOOST/PYTHON // 39 | #include "boost/python.hpp" 40 | #include "pyublas/numpy.hpp" 41 | 42 | 43 | void ShowGUI(char* macro) 44 | { 45 | int argc = 1; 46 | char* argv[1] = {""}; 47 | 48 | G4VisManager* visManager = new G4VisExecutive; 49 | visManager->Initialize(); 50 | 51 | G4UImanager* ui_manager = G4UImanager::GetUIpointer(); 52 | G4UIExecutive* ui = new G4UIExecutive(argc, argv); 53 | 54 | ui_manager->ApplyCommand(G4String("/control/execute ") + G4String(macro)); 55 | 56 | ui->SessionStart(); 57 | delete ui; 58 | }; 59 | 60 | 61 | using namespace boost::python; 62 | 63 | 64 | // Members with default kwargs .. 65 | BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(_AddCADComponent, 66 | DetectorConstruction::AddCADComponent, 3, 8) 67 | BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(_SetupHead, 68 | DetectorConstruction::SetupHead, 6, 6) 69 | 70 | 71 | BOOST_PYTHON_MODULE(libg4) { 72 | def("ShowGUI", ShowGUI); 73 | 74 | class_, boost::noncopyable> 76 | ("DetectorConstruction", "detector") 77 | .def("AddMaterial", &DetectorConstruction::AddMaterial) 78 | .def("AddPhasespace", &DetectorConstruction::AddPhasespace, 79 | return_internal_reference<>()) 80 | .def("RemovePhasespace", &DetectorConstruction::RemovePhasespace) 81 | .def("AddCADComponent", &DetectorConstruction::AddCADComponent, 82 | return_internal_reference<>()) 83 | .def("AddTube", &DetectorConstruction::AddTube, 84 | return_internal_reference<>()) 85 | .def("AddSlab", &DetectorConstruction::AddSlab, 86 | return_internal_reference<>()) 87 | .def("ClosePhasespace", &DetectorConstruction::ClosePhasespace) 88 | .def("UsePhantom", &DetectorConstruction::UsePhantom) 89 | .def("UseCADPhantom", &DetectorConstruction::UseCADPhantom) 90 | .def("GetEnergyHistogram", &DetectorConstruction::GetEnergyHistogram) 91 | .def("GetEnergySqHistogram", &DetectorConstruction::GetEnergySqHistogram) 92 | .def("GetCountsHistogram", &DetectorConstruction::GetCountsHistogram) 93 | .def("GetCTOrigin", &DetectorConstruction::GetCTOrigin) 94 | .def("ZeroHistograms", &DetectorConstruction::ZeroHistograms) 95 | .def("UseCT", &DetectorConstruction::UseCT) 96 | .def("SetupCT", &DetectorConstruction::SetupCT) 97 | .def("UseArray", &DetectorConstruction::UseArray) 98 | .def("HideCT", &DetectorConstruction::HideCT) 99 | .def("CropCT", &DetectorConstruction::CropCT) 100 | .def("CropX", &DetectorConstruction::CropX) 101 | .def("CropY", &DetectorConstruction::CropY) 102 | .def("CropZ", &DetectorConstruction::CropZ) 103 | .def("SetCTPosition", &DetectorConstruction::SetCTPosition) 104 | .def("GetWorld", &DetectorConstruction::GetWorld, 105 | return_internal_reference<>()) 106 | .def("SetWorldMaterial", &DetectorConstruction::SetWorldMaterial) 107 | .def("SetWorldSize", &DetectorConstruction::SetWorldSize) 108 | .def("SetWorldColour", &DetectorConstruction::SetWorldColour) 109 | .def("SetAsStopKillSheild", &DetectorConstruction::SetAsStopKillSheild) 110 | ; // End DetectorConstruction 111 | 112 | class_ > 114 | bases > 115 | ("PhysicsList", "physics list") 116 | .def("OverrideCuts", &PhysicsList::OverrideCuts) 117 | ; // End PhysicsList 118 | 119 | class_, boost::noncopyable> 121 | ("SteppingAction", "SteppingAction") 122 | ; // End SteppingAction 123 | 124 | class_ > 126 | ("EventAction", "EventAction") 127 | ; // End EventAction 128 | 129 | class_, boost::noncopyable> 131 | ("PrimaryGeneratorAction", "PrimaryGeneratorAction") 132 | .def("Reset", &PrimaryGeneratorAction::Reset) 133 | .def("SetPosition", &PrimaryGeneratorAction::SetPosition) 134 | .def("SetDirection", &PrimaryGeneratorAction::SetDirection) 135 | .def("SetEnergy", &PrimaryGeneratorAction::SetEnergy) 136 | .def("SetFWHM", &PrimaryGeneratorAction::SetFWHM) 137 | .def("SetSource", &PrimaryGeneratorAction::SetSource) 138 | .def("SetRecyclingNumber", &PrimaryGeneratorAction::SetRecyclingNumber) 139 | .def("SetRedistribute", &PrimaryGeneratorAction::SetRedistribute) 140 | .def("SetGantryRotation", &PrimaryGeneratorAction::SetGantryRotation) 141 | .def("SetPhasespaceLimits", &PrimaryGeneratorAction::SetPhasespaceLimits) 142 | ; // End PrimaryGeneratorAction 143 | } 144 | 145 | -------------------------------------------------------------------------------- /linac/g4/src/BremSplittingProcess.cc: -------------------------------------------------------------------------------- 1 | // 2 | // ******************************************************************** 3 | // * DISCLAIMER * 4 | // * * 5 | // * The following disclaimer summarizes all the specific disclaimers * 6 | // * of contributors to this software. The specific disclaimers,which * 7 | // * govern, are listed with their locations in: * 8 | // * http://cern.ch/geant4/license * 9 | // * * 10 | // * Neither the authors of this software system, nor their employing * 11 | // * institutes,nor the agencies providing financial support for this * 12 | // * work make any representation or warranty, express or implied, * 13 | // * regarding this software system or assume any liability for its * 14 | // * use. * 15 | // * * 16 | // * This code implementation is the intellectual property of the * 17 | // * GEANT4 collaboration. * 18 | // * By copying, distributing or modifying the Program (or any work * 19 | // * based on the Program) you indicate your acceptance of this * 20 | // * statement, and all its terms. * 21 | // ******************************************************************** 22 | // 23 | // 24 | // Jane Tinslay, March 2006 25 | // 26 | #include "BremSplittingProcess.hh" 27 | //#include "BremSplittingProcessMessenger.hh"//used for UI command to change splitting number 28 | 29 | #include "G4Track.hh" 30 | #include "G4VParticleChange.hh" 31 | #include 32 | #include 33 | 34 | //#include "BremSplittingProcessMessenger.hh" 35 | 36 | // Initialise static data 37 | //G4int BremSplittingProcess::fNSplit = 10; 38 | G4int BremSplittingProcess::fNSecondaries = 10; 39 | 40 | G4bool BremSplittingProcess::fActive = true; 41 | 42 | BremSplittingProcess::BremSplittingProcess() { 43 | 44 | fNSplit = 10;//unless specified by UI command, will be 10 (ie no splitting 45 | 46 | // bremMessenger = new BremSplittingProcessMessenger(this);//instantiate messenger class for UI commands 47 | 48 | } 49 | 50 | BremSplittingProcess::~BremSplittingProcess() { 51 | 52 | if(bremMessenger) 53 | delete bremMessenger; 54 | 55 | } 56 | 57 | G4VParticleChange* BremSplittingProcess::PostStepDoIt(const G4Track& track, const G4Step& step) 58 | { 59 | // Just do regular processing if brem splitting is not activated 60 | G4VParticleChange* particleChange(0); 61 | 62 | if (!fActive) { 63 | particleChange = pRegProcess->PostStepDoIt(track, step); 64 | assert (0 != particleChange); 65 | 66 | fNSecondaries += particleChange->GetNumberOfSecondaries(); 67 | 68 | return particleChange; 69 | } 70 | 71 | // Do brem splitting 72 | assert (fNSplit > 0); 73 | 74 | G4int i(0); 75 | G4double weight = track.GetWeight()/fNSplit; 76 | 77 | // Secondary store 78 | std::vector secondaries; 79 | secondaries.reserve(fNSplit); 80 | 81 | // Loop over PostStepDoIt method to generate multiple secondaries. 82 | for (i=0; iPostStepDoIt(track, step); 84 | 85 | assert (0 != particleChange); 86 | particleChange->SetVerboseLevel(0); 87 | 88 | G4int j(0); 89 | 90 | for (j=0; jGetNumberOfSecondaries(); j++) { 91 | secondaries.push_back(new G4Track(*(particleChange->GetSecondary(j)))); 92 | } 93 | } 94 | 95 | // Configure particleChange to handle multiple secondaries. Other 96 | // data is unchanged 97 | particleChange->SetNumberOfSecondaries(secondaries.size()); 98 | particleChange->SetSecondaryWeightByProcess(true); 99 | 100 | // Add all secondaries 101 | std::vector::iterator iter = secondaries.begin(); 102 | 103 | while (iter != secondaries.end()) { 104 | G4Track* myTrack = *iter; 105 | myTrack->SetWeight(weight); 106 | 107 | // particleChange takes ownership 108 | particleChange->AddSecondary(myTrack); 109 | 110 | iter++; 111 | } 112 | 113 | fNSecondaries += secondaries.size(); 114 | 115 | return particleChange; 116 | } 117 | 118 | void BremSplittingProcess::SetNSplit(G4int nSplit) 119 | { 120 | fNSplit = nSplit; 121 | } 122 | 123 | void BremSplittingProcess::SetIsActive(G4bool active) 124 | { 125 | fActive = active; 126 | } 127 | 128 | G4bool BremSplittingProcess::GetIsActive() 129 | { 130 | return fActive; 131 | } 132 | 133 | G4int BremSplittingProcess::GetNSplit() 134 | { 135 | return fNSplit; 136 | } 137 | 138 | G4int BremSplittingProcess::GetNSecondaries() 139 | { 140 | return fNSecondaries; 141 | } 142 | -------------------------------------------------------------------------------- /linac/g4/src/DetectorConstruction.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | // USER // 23 | #include "DetectorConstruction.hh" 24 | 25 | // CADMesh // 26 | #include "CADMesh.hh" 27 | 28 | // GEANT4 // 29 | #include "globals.hh" 30 | #include "G4Material.hh" 31 | #include "G4NistManager.hh" 32 | #include "G4UserLimits.hh" 33 | #include "G4VisAttributes.hh" 34 | #include "G4PhysicalVolumeStore.hh" 35 | #include "G4LogicalVolumeStore.hh" 36 | #include "G4SolidStore.hh" 37 | #include "G4RunManager.hh" 38 | 39 | 40 | DetectorConstruction::DetectorConstruction() 41 | { 42 | verbose = 4; 43 | 44 | if (verbose >= 4) 45 | G4cout << "DetectorConstruction::DetectorConstruction" << G4endl; 46 | 47 | // Setpoints we will interpolate between for 48 | // our materials ramp. 49 | hounsfield.push_back(Hounsfield(-1050, "G4_AIR", 0.001 )); 50 | hounsfield.push_back(Hounsfield(-950,"G4_AIR", 0.044)); 51 | hounsfield.push_back(Hounsfield(-700,"G4_LUNG_ICRP", 0.302)); 52 | hounsfield.push_back(Hounsfield(125,"G4_TISSUE_SOFT_ICRP", 1.101)); 53 | hounsfield.push_back(Hounsfield(2500,"G4_BONE_CORTICAL_ICRP", 2.088)); 54 | 55 | world_size = G4ThreeVector(3*m, 3*m, 3*m); 56 | 57 | nist_manager = G4NistManager::Instance(); 58 | world_material = nist_manager->FindOrBuildMaterial("G4_AIR"); 59 | 60 | use_phantom = false; 61 | use_cad_phantom = false; 62 | region = NULL; 63 | use_ct = false; 64 | ct_built = false; 65 | 66 | headless = false; 67 | 68 | detector = NULL; 69 | voxeldata_param = NULL; 70 | 71 | RegisterParallelWorld(new ParallelDetectorConstruction("parallel_world")); 72 | } 73 | 74 | DetectorConstruction::~DetectorConstruction() 75 | { 76 | } 77 | 78 | G4VPhysicalVolume* DetectorConstruction::Construct() 79 | { 80 | if (verbose >= 4) 81 | G4cout << "DetectorConstruction::Construct" << G4endl; 82 | 83 | G4SolidStore::GetInstance()->Clean(); 84 | G4LogicalVolumeStore::GetInstance()->Clean(); 85 | G4PhysicalVolumeStore::GetInstance()->Clean(); 86 | 87 | G4NistManager* man = G4NistManager::Instance(); 88 | man->SetVerbose(1); 89 | // Define elements from NIST 90 | man->FindOrBuildElement("H"); 91 | G4Element* C = man->FindOrBuildElement("C"); 92 | G4Element* Si = man->FindOrBuildElement("Si"); 93 | G4Element* Cr = man->FindOrBuildElement("Cr"); 94 | G4Element* Mn = man->FindOrBuildElement("Mn"); 95 | G4Element* Fe = man->FindOrBuildElement("Fe"); 96 | G4Element* Ni = man->FindOrBuildElement("Ni"); 97 | // Define materials not in NIST 98 | G4double density; 99 | G4int ncomponents; 100 | G4double fractionmass; 101 | StainlessSteel = new G4Material("StainlessSteel", density= 8.06*g/cm3, ncomponents=6); 102 | StainlessSteel->AddElement(C, fractionmass=0.001); 103 | StainlessSteel->AddElement(Si, fractionmass=0.007); 104 | StainlessSteel->AddElement(Cr, fractionmass=0.18); 105 | StainlessSteel->AddElement(Mn, fractionmass=0.01); 106 | StainlessSteel->AddElement(Fe, fractionmass=0.712); 107 | StainlessSteel->AddElement(Ni, fractionmass=0.09); 108 | 109 | 110 | world_solid = new G4Box("world_solid", world_size.x()/2., world_size.y()/2., world_size.z()/2.); 111 | world_logical = new G4LogicalVolume(world_solid, world_material, "world_logical", 0, 0, 0); 112 | world_physical = new G4PVPlacement(0, G4ThreeVector(), world_logical, 113 | "world_physical", 0, false, 0); 114 | if (world_colour.GetAlpha() == 0) { 115 | world_logical->SetVisAttributes(G4VisAttributes::Invisible); 116 | } else { 117 | world_logical->SetVisAttributes(new G4VisAttributes(world_colour)); 118 | } 119 | /* 120 | if (region) { 121 | G4cout << "Deleting region." << G4endl; 122 | cuts = region->GetProductionCuts(); 123 | delete region; 124 | } 125 | G4cout << "Added region." << G4endl; 126 | region = new G4Region("ShortCuts"); 127 | region->SetProductionCuts(cuts); 128 | 129 | phantom_logical->SetRegion(region); 130 | region->AddRootLogicalVolume(phantom_logical); 131 | */ 132 | return world_physical; 133 | } 134 | 135 | 136 | G4VPhysicalVolume* DetectorConstruction::FindVolume(G4String name, G4VPhysicalVolume * mother) 137 | { 138 | if (verbose >= 4) 139 | G4cout << "DetectorConstruction::FindVolume" << G4endl; 140 | 141 | if(mother->GetName() == name) { 142 | return mother; 143 | } 144 | 145 | int count = mother->GetLogicalVolume()->GetNoDaughters(); 146 | for(int i=0; iGetLogicalVolume()->GetDaughter(i); 148 | if(daughter->GetName() == name) { 149 | return daughter; 150 | } else { 151 | G4VPhysicalVolume * volume = FindVolume(name, daughter); 152 | 153 | if(volume){ 154 | return volume; 155 | } 156 | } 157 | } 158 | return NULL; 159 | } 160 | 161 | 162 | void DetectorConstruction::SetupPhantom() 163 | { 164 | if (verbose >= 4) 165 | G4cout << "DetectorConstruction::SetupPhantom" << G4endl; 166 | 167 | G4Material* water = nist_manager->FindOrBuildMaterial("G4_WATER"); 168 | 169 | phantom_solid = new G4Box("phantom_solid", 200*mm, 200*mm, 200*mm); 170 | phantom_logical = new G4LogicalVolume(phantom_solid, water, "phantom_logical", 0, 0, 0); 171 | phantom_physical = new G4PVPlacement(0, G4ThreeVector(0, 0, -150*mm), phantom_logical, 172 | "phantom_physical", world_logical, false, 0); 173 | // phantom_logical->SetVisAttributes(new G4VisAttributes(G4Colour(0, 0.6, 0.9, 1))); 174 | 175 | if (!this->detector) 176 | detector = new SensitiveDetector("phantom_detector"); 177 | 178 | G4SDManager* sd_manager = G4SDManager::GetSDMpointer(); 179 | sd_manager->AddNewDetector(detector); 180 | phantom_logical->SetSensitiveDetector(detector); 181 | } 182 | 183 | void DetectorConstruction::SetupCADPhantom(char* filename, G4ThreeVector offset) 184 | { 185 | if (verbose >= 4) 186 | G4cout << "DetectorConstruction::SetupCADPhantom" << G4endl; 187 | 188 | G4Material* water = nist_manager->FindOrBuildMaterial("G4_WATER"); 189 | 190 | G4RotationMatrix* rot = new G4RotationMatrix(); 191 | rot->rotateZ(90*deg); 192 | rot->rotateY(-90*deg); 193 | 194 | CADMesh* mesh = new CADMesh(filename, (char*) "STL", 1, offset, false); 195 | G4VSolid* solid = mesh->TessellatedMesh(); 196 | G4LogicalVolume* logical = new G4LogicalVolume(solid, water, filename, 0, 0, 0); 197 | 198 | G4VPhysicalVolume* physical = new G4PVPlacement(rot, G4ThreeVector(), 199 | logical, filename, world_logical, 200 | false, 0); 201 | 202 | if (!this->detector) 203 | detector = new SensitiveDetector("phantom_detector"); 204 | 205 | G4SDManager* sd_manager = G4SDManager::GetSDMpointer(); 206 | sd_manager->AddNewDetector(detector); 207 | logical->SetSensitiveDetector(detector); 208 | 209 | G4RunManager::GetRunManager()->GeometryHasBeenModified(); 210 | } 211 | 212 | 213 | void DetectorConstruction::AddMaterial(G4String name, G4double density, 214 | boost::python::object move) 215 | { 216 | if (verbose >= 4) 217 | G4cout << "DetectorConstruction::AddMaterial" << G4endl; 218 | 219 | G4cout << "adding material " << name << " with density : " << density << G4endl; 220 | boost::python::object a = move(); 221 | int b = boost::python::extract(a); 222 | G4cout << b << G4endl; 223 | } 224 | 225 | 226 | G4VPhysicalVolume* DetectorConstruction::AddTube(char* name, 227 | double inner_radius, double outer_radius, double length, 228 | G4ThreeVector translation, G4ThreeVector rotation, 229 | char* material_name, G4Colour colour, 230 | G4LogicalVolume* mother_logical) 231 | { 232 | if (verbose >= 4) 233 | G4cout << "DetectorConstruction::AddTube" << G4endl; 234 | 235 | G4Material* material = nist_manager->FindOrBuildMaterial(material_name); 236 | 237 | G4RotationMatrix* rot = new G4RotationMatrix(); 238 | rot->rotateX(rotation.x()*deg); 239 | rot->rotateY(rotation.y()*deg); 240 | rot->rotateZ(rotation.z()*deg); 241 | 242 | G4Tubs* solid = new G4Tubs(name, inner_radius, outer_radius, length/2., 0, 360*deg); 243 | G4LogicalVolume* logical = new G4LogicalVolume(solid, material, name, 0, 0, 0); 244 | logical->SetVisAttributes(new G4VisAttributes(colour)); 245 | 246 | G4VPhysicalVolume* physical = new G4PVPlacement(rot, translation, 247 | logical, name, mother_logical, false, 0); 248 | 249 | return physical; 250 | } 251 | 252 | 253 | G4VPhysicalVolume* DetectorConstruction::AddSlab(char* name, 254 | double side, double thickness, 255 | char* material, 256 | G4ThreeVector translation, 257 | G4ThreeVector rotation, 258 | G4Colour colour, 259 | G4LogicalVolume* mother_logical) 260 | { 261 | if (verbose >= 4) 262 | G4cout << "DetectorConstruction::AddSlab" << G4endl; 263 | 264 | G4Material* mat = nist_manager->FindOrBuildMaterial(material); 265 | 266 | G4RotationMatrix* rot = new G4RotationMatrix(); 267 | rot->rotateX(rotation.x()*deg); 268 | rot->rotateY(rotation.y()*deg); 269 | rot->rotateZ(rotation.z()*deg); 270 | 271 | G4Box* solid = new G4Box(name, side/2., side/2., thickness/2.); 272 | G4LogicalVolume* logical = new G4LogicalVolume(solid, mat, name, 0, 0, 0); 273 | logical->SetVisAttributes(new G4VisAttributes(colour)); 274 | 275 | G4VPhysicalVolume* physical = new G4PVPlacement(rot, translation, 276 | logical, name, mother_logical, 277 | false, 0); 278 | 279 | return physical; 280 | } 281 | 282 | 283 | G4VPhysicalVolume* DetectorConstruction::AddCADComponent(char* name, 284 | char* filename, 285 | char* material, 286 | double scale, 287 | G4ThreeVector translation, 288 | G4ThreeVector rotation, 289 | G4Colour colour, 290 | G4bool tessellated, 291 | G4LogicalVolume* mother_logical) 292 | { 293 | if (verbose >= 4) 294 | G4cout << "DetectorConstruction::AddCADComponent" << G4endl; 295 | 296 | G4Material* mat = nist_manager->FindOrBuildMaterial(material); 297 | 298 | G4RotationMatrix* rot = new G4RotationMatrix(); 299 | rot->rotateX(rotation.x()*deg); 300 | rot->rotateY(rotation.y()*deg); 301 | rot->rotateZ(rotation.z()*deg); 302 | 303 | if (tessellated) { 304 | CADMesh* mesh = new CADMesh(filename, (char*) "STL", scale, G4ThreeVector(), false); 305 | G4VSolid* solid = mesh->TessellatedMesh(); 306 | G4LogicalVolume* logical = new G4LogicalVolume(solid, mat, name, 0, 0, 0); 307 | logical->SetVisAttributes(new G4VisAttributes(colour)); 308 | 309 | G4VPhysicalVolume* physical = new G4PVPlacement(rot, translation, 310 | logical, name, mother_logical, 311 | false, 0); 312 | return physical; 313 | 314 | } else { 315 | CADMesh * mesh = new CADMesh(filename, (char*) "PLY", mat); 316 | G4AssemblyVolume* assembly = mesh->TetrahedralMesh(); 317 | G4Translate3D trans(translation.x(), translation.y(), translation.z()); 318 | G4Transform3D rotation = G4Rotate3D(*rot); 319 | G4Transform3D transform = trans*rotation; 320 | assembly->MakeImprint(mother_logical, transform, 0, 0); 321 | } 322 | 323 | G4RunManager::GetRunManager()->GeometryHasBeenModified(); 324 | return NULL; 325 | } 326 | 327 | 328 | void DetectorConstruction::SetupCT() 329 | { 330 | if (verbose >= 4) 331 | G4cout << "DetectorConstruction::SetupCT" << G4endl; 332 | 333 | if (!voxeldata_param) { 334 | voxeldata_param = 335 | new G4VoxelDataParameterisation(array, materials, world_physical ); 336 | 337 | G4RotationMatrix* rotation = new G4RotationMatrix(); 338 | rotation->rotateZ(90*deg); 339 | rotation->rotateX(-90*deg); 340 | 341 | voxeldata_param->Construct(ct_position, rotation); 342 | voxeldata_param->SetRounding(25, -1000, 2000); 343 | 344 | std::map colours; 345 | for (int i=-2500; i<5000; i++) { 346 | double gray = (double) (i + 2500) / 7500.; 347 | double alpha = 1; 348 | 349 | if (i < -500) { 350 | gray = 0; 351 | alpha = 0; 352 | } 353 | 354 | if (gray > 1) 355 | gray = 1; 356 | 357 | colours[i] = new G4Colour(gray, gray, gray, alpha); 358 | } 359 | voxeldata_param->SetColourMap(colours); 360 | voxeldata_param->SetVisibility(false); 361 | 362 | detector = new SensitiveDetector("ct_detector"); 363 | 364 | G4SDManager* sd_manager = G4SDManager::GetSDMpointer(); 365 | sd_manager->AddNewDetector(detector); 366 | voxeldata_param->GetLogicalVolume()->SetSensitiveDetector(detector); 367 | 368 | G4RunManager::GetRunManager()->GeometryHasBeenModified(); 369 | } 370 | } 371 | 372 | 373 | std::map DetectorConstruction::MakeMaterialsMap(G4int increment) 374 | { 375 | if (verbose >= 4) 376 | G4cout << "DetectorConstruction::MakeMaterialsMap" << G4endl; 377 | 378 | // Our materials map or ramp 379 | std::map ramp; 380 | 381 | // Calculate intermediate points in each segment 382 | for (unsigned int i=0; i = 4) 405 | G4cout << "DetectorConstruction::MakeNewMaterial" << G4endl; 406 | 407 | G4NistManager* nist_manager = G4NistManager::Instance(); 408 | G4String new_name = base_material_name + G4UIcommand::ConvertToString(density); 409 | 410 | return nist_manager->BuildMaterialWithNewDensity(new_name, base_material_name, density*g/cm3); 411 | } 412 | 413 | -------------------------------------------------------------------------------- /linac/g4/src/EventAction.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #include "EventAction.hh" 23 | 24 | #include "G4Event.hh" 25 | #include "G4EventManager.hh" 26 | 27 | 28 | EventAction::EventAction() 29 | { 30 | } 31 | 32 | EventAction::~EventAction() 33 | { 34 | } 35 | 36 | void EventAction::BeginOfEventAction(const G4Event*) 37 | { 38 | } 39 | 40 | void EventAction::EndOfEventAction(const G4Event*) 41 | { 42 | } 43 | 44 | -------------------------------------------------------------------------------- /linac/g4/src/ParallelDetectorConstruction.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | 23 | // USER // 24 | #include "DetectorConstruction.hh" 25 | #include "ParallelDetectorConstruction.hh" 26 | 27 | // GEANT4 // 28 | #include "globals.hh" 29 | #include "G4RunManager.hh" 30 | #include "G4SDManager.hh" 31 | #include "G4VisAttributes.hh" 32 | #include "G4Color.hh" 33 | 34 | 35 | ParallelDetectorConstruction::ParallelDetectorConstruction(G4String name) 36 | : G4VUserParallelWorld(name) 37 | { 38 | this->verbose = 4; 39 | } 40 | 41 | 42 | ParallelDetectorConstruction::~ParallelDetectorConstruction() 43 | { 44 | } 45 | 46 | 47 | void ParallelDetectorConstruction::Construct() 48 | { 49 | world_physical = GetWorld(); 50 | world_logical = world_physical->GetLogicalVolume(); 51 | world_logical->SetVisAttributes(G4VisAttributes::Invisible); 52 | } 53 | 54 | G4VPhysicalVolume* ParallelDetectorConstruction::AddPhasespace(char* name, double radius, double z_position, bool kill) 55 | { 56 | if (verbose >= 4) 57 | G4cout << "DetectorConstruction::AddPhasespace: " << name << G4endl; 58 | 59 | DetectorConstruction* detector = (DetectorConstruction*) G4RunManager::GetRunManager()->GetUserDetectorConstruction(); 60 | 61 | G4Box* solid = new G4Box(name, radius, radius, 1*nm); 62 | G4LogicalVolume* logical = new G4LogicalVolume(solid, 0, name, 0, 0, 0); 63 | logical->SetVisAttributes(new G4VisAttributes(G4Color(1, 0, 1, 0.5))); 64 | 65 | G4VPhysicalVolume* physical = new G4PVPlacement(0, G4ThreeVector(0, 0, z_position*mm), 66 | logical, name, world_logical, false, 0); 67 | 68 | 69 | // Active scoring area is 1% smaller than actual plane - avoids navigation errors when point on edge with direction (0,0,0) 70 | Phasespace* phasespace_sensitive_detector = new Phasespace(name, radius - (radius*0.01)); 71 | phasespace_sensitive_detector->SetKillAtPlane(kill); 72 | phasespaces[name] = phasespace_sensitive_detector; 73 | 74 | G4SDManager* sensitive_detector_manager = G4SDManager::GetSDMpointer(); 75 | sensitive_detector_manager->AddNewDetector(phasespace_sensitive_detector); 76 | logical->SetSensitiveDetector(phasespace_sensitive_detector); 77 | 78 | return physical; 79 | } 80 | 81 | 82 | void ParallelDetectorConstruction::RemovePhasespace(char* name) { 83 | if (verbose >=4) 84 | G4cout << "DetectorConstruction::RemovePhasespace" << G4endl; 85 | 86 | phasespaces.erase(name); 87 | 88 | DetectorConstruction* detector = (DetectorConstruction*) G4RunManager::GetRunManager()->GetUserDetectorConstruction(); 89 | 90 | G4VPhysicalVolume* physical = detector->FindVolume(name, world_physical); 91 | delete physical; 92 | G4RunManager::GetRunManager()->GeometryHasBeenModified(); 93 | } 94 | 95 | -------------------------------------------------------------------------------- /linac/g4/src/Phasespace.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #include "globals.hh" 23 | 24 | #include "Phasespace.hh" 25 | #include "DetectorConstruction.hh" 26 | 27 | 28 | #include "G4ProcessType.hh" 29 | #include "G4HCofThisEvent.hh" 30 | #include "G4TouchableHistory.hh" 31 | #include "G4Step.hh" 32 | #include "G4Track.hh" 33 | #include "G4VProcess.hh" 34 | #include "G4Event.hh" 35 | #include "G4RunManager.hh" 36 | #include "G4SteppingManager.hh" 37 | #include "G4ThreeVector.hh" 38 | 39 | #include 40 | 41 | 42 | Phasespace::Phasespace(const G4String& name, G4double radius) : G4VSensitiveDetector(name) { 43 | 44 | // debug = false; 45 | this->name = name; 46 | kill = true; 47 | 48 | output_file_stream = new std::ofstream(name, std::ios::binary); 49 | phasespace_archive = new boost::archive::binary_oarchive(*output_file_stream); 50 | 51 | detector_construction = (DetectorConstruction*) (G4RunManager::GetRunManager()->GetUserDetectorConstruction()); 52 | 53 | this->radius = radius; 54 | record_count = 0; 55 | } 56 | 57 | Phasespace::~Phasespace() { 58 | Close(); 59 | // delete output_file_stream; 60 | // delete phasespace_archive; 61 | } 62 | 63 | void Phasespace::Close() { 64 | output_file_stream->close(); 65 | } 66 | 67 | void Phasespace::Initialize(G4HCofThisEvent*) { 68 | } 69 | 70 | G4bool Phasespace::ProcessHits(G4Step* aStep, G4TouchableHistory* touchable) { 71 | const G4Track* aTrack = aStep->GetTrack(); 72 | const G4String name = aTrack->GetDefinition()->GetParticleName(); 73 | 74 | G4ThreeVector position = aTrack->GetPosition(); 75 | G4ThreeVector direction = aTrack->GetMomentumDirection(); 76 | 77 | // Do not record hits that are outside/near the edge of the 'plane' 78 | if (abs(position.x()) >= radius || abs(position.y()) >= radius) 79 | return false; 80 | 81 | PhasespaceRecord record = PhasespaceRecord(aStep); 82 | 83 | *phasespace_archive << record; 84 | 85 | if (kill) 86 | aStep->GetTrack()->SetTrackStatus(fStopAndKill); 87 | 88 | record_count ++; 89 | // if (record_count % 1000 == 0) 90 | // G4cout << "Phasespace record count: " << record_count << G4endl; 91 | 92 | return true; 93 | } 94 | 95 | void Phasespace::EndOfEvent(G4HCofThisEvent*) { 96 | } 97 | 98 | void Phasespace::clear() { 99 | } 100 | 101 | void Phasespace::PrintAll() { 102 | } 103 | -------------------------------------------------------------------------------- /linac/g4/src/PhasespaceRecord.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #include "globals.hh" 23 | 24 | #include "PhasespaceRecord.hh" 25 | 26 | #include "G4TouchableHistory.hh" 27 | #include "G4Step.hh" 28 | #include "G4Track.hh" 29 | #include "G4Event.hh" 30 | #include "G4ThreeVector.hh" 31 | 32 | 33 | PhasespaceRecord::PhasespaceRecord() { 34 | 35 | } 36 | 37 | PhasespaceRecord::PhasespaceRecord(G4Step* step) { 38 | const G4Track* track = step->GetTrack(); 39 | 40 | position_x = track->GetPosition().x(); 41 | position_y = track->GetPosition().y(); 42 | position_z = track->GetPosition().z(); 43 | 44 | momentum_x = track->GetMomentum().x(); 45 | momentum_y = track->GetMomentum().y(); 46 | momentum_z = track->GetMomentum().z(); 47 | 48 | kinetic_energy = track->GetKineticEnergy(); 49 | 50 | weight = track->GetWeight(); 51 | 52 | G4String type = track->GetParticleDefinition()->GetParticleName(); 53 | if (type == "e+") { 54 | particle_type = 1; 55 | } else if (type == "e-") { 56 | particle_type = -1; 57 | } else { 58 | particle_type = 0; 59 | } 60 | } 61 | 62 | PhasespaceRecord::~PhasespaceRecord() { 63 | } 64 | /* 65 | template 66 | void PhasespaceRecord::serialize(Archive & ar, const unsigned int version); 67 | ar & position_x; 68 | ar & position_y; 69 | ar & position_z; 70 | 71 | ar & momentum_x; 72 | ar & momentum_y; 73 | ar & momentum_z; 74 | 75 | ar & kinetic_energy; 76 | } 77 | */ 78 | G4bool PhasespaceRecord::CheckIt(G4double xlow, G4double xhigh, 79 | G4double ylow, G4double yhigh, 80 | G4double zlow, G4double zhigh) 81 | { 82 | if ((isnan(position_x)) || 83 | (isnan(position_y)) || 84 | (isnan(position_z))) { 85 | return false; 86 | } 87 | 88 | G4double tol_low = 1e-100; 89 | if (((std::abs(position_x) < tol_low) && (std::abs(position_x) > 0)) || 90 | ((std::abs(position_y) < tol_low) && (std::abs(position_y) > 0)) || 91 | ((std::abs(position_z) < tol_low) && (std::abs(position_z) > 0))) { 92 | return false; 93 | } 94 | 95 | G4double tol_high = 1e10; 96 | if ((std::abs(position_x) > tol_high) || 97 | (std::abs(position_y) > tol_high) || 98 | (std::abs(position_z) > tol_high)) { 99 | return false; 100 | } 101 | 102 | if ((position_x < xlow) || (position_x > xhigh) || 103 | (position_y < ylow) || (position_y > yhigh) || 104 | (position_z < zlow) || (position_z > zhigh)) { 105 | return false; 106 | } 107 | 108 | return true; 109 | } 110 | 111 | G4ThreeVector PhasespaceRecord::GetPosition() { 112 | return G4ThreeVector(position_x, position_y, position_z); 113 | } 114 | 115 | G4ThreeVector PhasespaceRecord::GetMomentum() { 116 | return G4ThreeVector(momentum_x, momentum_y, momentum_z); 117 | } 118 | 119 | G4double PhasespaceRecord::GetKineticEnergy() { 120 | return kinetic_energy; 121 | } 122 | 123 | G4int PhasespaceRecord::GetParticleType() { 124 | return particle_type; 125 | } 126 | 127 | G4double PhasespaceRecord::GetWeight() { 128 | return weight; 129 | } 130 | -------------------------------------------------------------------------------- /linac/g4/src/PhysicsList.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | // USER// 23 | #include "PhysicsList.hh" 24 | 25 | // GEANT4 // 26 | #include "G4EmStandardPhysics_option1.hh" 27 | //#include "G4EmStandardPhysics_option2.hh" 28 | //#include "G4EmStandardPhysics_option3.hh" 29 | //#include "G4EmDNAPhysics.hh" 30 | //#include "G4EmLivermorePhysics.hh" 31 | //#include "G4EmPenelopePhysics.hh" 32 | 33 | #include "G4RegionStore.hh" 34 | 35 | #include "BremSplittingProcess.hh" 36 | 37 | #include "G4ParticleDefinition.hh" 38 | #include "G4ParticleWithCuts.hh" 39 | #include "G4ProcessManager.hh" 40 | #include "G4ProcessVector.hh" 41 | 42 | #include "G4ProductionCuts.hh" 43 | #include "G4ProductionCutsTable.hh" 44 | 45 | #include "G4ParticleTypes.hh" 46 | 47 | //includes for phsyics processes 48 | #include "G4ParallelWorldProcess.hh" 49 | 50 | #include "G4ComptonScattering.hh" 51 | #include "G4PhotoElectricEffect.hh" 52 | #include "G4GammaConversion.hh" 53 | #include "G4RayleighScattering.hh" 54 | 55 | #include "G4eMultipleScattering.hh" 56 | 57 | #include "G4eIonisation.hh" 58 | #include "G4eBremsstrahlung.hh" 59 | #include "G4eplusAnnihilation.hh" 60 | 61 | // e+ 62 | #include "G4eIonisation.hh" 63 | #include "G4PenelopeIonisationModel.hh" 64 | #include "G4eBremsstrahlung.hh" 65 | #include "G4eplusAnnihilation.hh" 66 | 67 | 68 | //include penelope models 69 | 70 | #include "G4PenelopeRayleighModel.hh" 71 | #include "G4PenelopeComptonModel.hh" 72 | #include "G4PenelopePhotoElectricModel.hh" 73 | #include "G4PenelopeGammaConversionModel.hh" 74 | #include "G4PenelopeIonisationModel.hh" 75 | #include "G4PenelopeBremsstrahlungModel.hh" 76 | #include "G4PenelopeAnnihilationModel.hh" 77 | 78 | #include "G4LivermoreBremsstrahlungModel.hh" 79 | #include "G4LivermoreIonisationModel.hh" 80 | #include "G4LivermoreGammaConversionModel.hh" 81 | #include "G4LivermoreComptonModel.hh" 82 | #include "G4LivermorePhotoElectricModel.hh" 83 | #include "G4LivermoreRayleighModel.hh" 84 | 85 | #include "G4StepLimiter.hh" 86 | #include "G4EmProcessOptions.hh" 87 | 88 | #include "G4PhotoNuclearProcess.hh" 89 | #include "G4GammaNuclearReaction.hh" 90 | #include "G4hMultipleScattering.hh" 91 | #include "G4ionIonisation.hh" 92 | #include "G4hIonisation.hh" 93 | 94 | #include "G4RayleighScattering.hh" 95 | //#include "G4PEEffectFluoModel.hh" 96 | //#include "G4KleinNishinaModel.hh" 97 | 98 | 99 | PhysicsList::PhysicsList() 100 | { 101 | 102 | defaultCutValue = 1*cm; 103 | gamma_cuts = defaultCutValue; 104 | e_cuts = defaultCutValue; 105 | 106 | RegisterPhysics(new G4EmStandardPhysics_option1()); 107 | //RegisterPhysics(new G4EmStandardPhysics_option2()); 108 | //RegisterPhysics(new G4EmStandardPhysics_option3()); 109 | //RegisterPhysics(new G4EmLivermorePhysics()); 110 | //RegisterPhysics(new G4EmPenelopePhysics()); 111 | } 112 | 113 | PhysicsList::~PhysicsList() 114 | {;} 115 | 116 | void PhysicsList::ConstructParticle() 117 | { 118 | G4VModularPhysicsList::ConstructParticle(); 119 | /* 120 | G4Gamma::GammaDefinition(); 121 | G4Electron::ElectronDefinition(); 122 | G4Positron::PositronDefinition(); 123 | G4Proton::ProtonDefinition();//needed for range cuts apparently!!!!!!!!! 124 | */ 125 | } 126 | 127 | void PhysicsList::ConstructProcess() 128 | { 129 | AddParallelWorldProcess(); 130 | G4VModularPhysicsList::ConstructProcess(); 131 | /* 132 | AddTransportation(); 133 | 134 | theParticleIterator->reset(); 135 | 136 | while ( (*theParticleIterator)()){ 137 | 138 | G4ParticleDefinition* particle = theParticleIterator->value(); 139 | G4ProcessManager* pmanager = particle->GetProcessManager(); 140 | G4String particleName = particle->GetParticleName(); 141 | 142 | if(particleName == "gamma"){ 143 | //G4EmStandardPhysics_option3 144 | G4PhotoElectricEffect* pe = new G4PhotoElectricEffect; 145 | //pe->SetModel(new G4PEEffectFluoModel()); 146 | G4ComptonScattering* cs = new G4ComptonScattering; 147 | //cs->SetModel(new G4KleinNishinaModel()); 148 | pmanager->AddDiscreteProcess(pe); 149 | pmanager->AddDiscreteProcess(cs); 150 | pmanager->AddDiscreteProcess(new G4GammaConversion); 151 | // pmanager->AddDiscreteProcess(new G4RayleighScattering); 152 | } else if (particleName == "e-"){ 153 | //G4EmStandardPhysics_option3 154 | G4eMultipleScattering* msc = new G4eMultipleScattering(); 155 | //msc->AddEmModel(0, new G4UrbanMscModel93()); 156 | msc->SetStepLimitType(fUseDistanceToBoundary); 157 | pmanager->AddProcess(msc, -1, 1, 1); 158 | G4eIonisation* eIoni = new G4eIonisation(); 159 | eIoni->SetStepFunction(0.2, 100*um); 160 | pmanager->AddProcess(eIoni, -1, 2, 2); 161 | G4eBremsstrahlung* bremProcess = new G4eBremsstrahlung(); 162 | BremSplittingProcess* bremSplitting = new BremSplittingProcess(); 163 | bremSplitting->RegisterProcess(bremProcess); 164 | pmanager->AddProcess(bremSplitting, -1,-3, 3); 165 | pmanager->AddProcess(new G4StepLimiter, -1, -1, 4);//step limiter required for phantom 166 | } else if (particleName == "e+"){ 167 | //G4EmStandardPhysics_option3 168 | G4eMultipleScattering* msc = new G4eMultipleScattering(); 169 | //msc->AddEmModel(0, new G4UrbanMscModel93()); 170 | msc->SetStepLimitType(fUseDistanceToBoundary); 171 | pmanager->AddProcess(msc, -1, 1, 1); 172 | G4eIonisation* eIoni = new G4eIonisation(); 173 | eIoni->SetStepFunction(0.2, 100*um); 174 | pmanager->AddProcess(eIoni, -1, 2, 2); 175 | pmanager->AddProcess(new G4eBremsstrahlung, -1,-3, 3); 176 | pmanager->AddProcess(new G4eplusAnnihilation,0,-1, 4); 177 | } 178 | } 179 | 180 | //G4EmStandardPhysics_option3 181 | // activate range cuts!!! THIS IS A BUG AND SHOULD BE FIXED BY GEANT4 DUDES 182 | //MACRO COMMANDS DON'T WORK1!! 183 | G4EmProcessOptions emOptions; 184 | emOptions.SetApplyCuts(true); 185 | 186 | // Multiple Coulomb scattering 187 | //??? 188 | emOptions.SetPolarAngleLimit(0.2); 189 | 190 | // Physics tables 191 | // 192 | emOptions.SetMinEnergy(100*eV); 193 | emOptions.SetMaxEnergy(100*MeV); 194 | //opt.SetDEDXBinning(100); 195 | //opt.SetLambdaBinning(100); 196 | */ 197 | } 198 | 199 | 200 | void PhysicsList::AddParallelWorldProcess() 201 | { 202 | // Add parallel world process 203 | G4ParallelWorldProcess* theParallelWorldProcess 204 | = new G4ParallelWorldProcess("paraWorldProc"); 205 | theParallelWorldProcess->SetParallelWorld("parallel_world"); 206 | theParallelWorldProcess->SetLayeredMaterialFlag(); 207 | 208 | theParticleIterator->reset(); 209 | while ((*theParticleIterator)()){ 210 | G4ParticleDefinition* particle = theParticleIterator->value(); 211 | //if (particle!=G4ChargedGeantino::Definition()) { 212 | G4ProcessManager* pmanager = particle->GetProcessManager(); 213 | pmanager->AddProcess(theParallelWorldProcess); 214 | 215 | if(theParallelWorldProcess->IsAtRestRequired(particle)) { 216 | pmanager->SetProcessOrdering(theParallelWorldProcess, idxAtRest, 9999); 217 | } 218 | 219 | pmanager->SetProcessOrdering(theParallelWorldProcess, idxAlongStep, 1); 220 | pmanager->SetProcessOrdering(theParallelWorldProcess, idxPostStep, 9999); 221 | //} 222 | } 223 | 224 | } 225 | 226 | 227 | void PhysicsList::SetCuts() 228 | { 229 | SetCutsWithDefault(); 230 | /* 231 | G4Region* region = G4RegionStore::GetInstance()->GetRegion("ShortCuts"); 232 | 233 | G4ProductionCuts* cuts = new G4ProductionCuts(); 234 | cuts->SetProductionCut(0.1*mm,G4ProductionCuts::GetIndex("gamma")); 235 | cuts->SetProductionCut(0.1*mm,G4ProductionCuts::GetIndex("e-")); 236 | cuts->SetProductionCut(0.1*mm,G4ProductionCuts::GetIndex("e+")); 237 | 238 | region->SetProductionCuts(cuts); 239 | */ 240 | SetCutValue(gamma_cuts, "gamma"); 241 | SetCutValue(e_cuts, "e-"); 242 | SetCutValue(e_cuts, "e+"); 243 | } 244 | 245 | -------------------------------------------------------------------------------- /linac/g4/src/PrimaryGeneratorAction.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | // USER // 23 | #include "PrimaryGeneratorAction.hh" 24 | 25 | // GEANT4 // 26 | #include "globals.hh" 27 | #include "Randomize.hh" 28 | 29 | #include "G4RunManager.hh" 30 | #include "G4Event.hh" 31 | #include "G4ParticleTable.hh" 32 | #include "G4ParticleDefinition.hh" 33 | 34 | 35 | PrimaryGeneratorAction::PrimaryGeneratorAction() 36 | { 37 | phasespace_particle_gun = new G4ParticleGun(); 38 | particle_gun = new G4GeneralParticleSource(); 39 | 40 | G4ParticleTable* particle_table = G4ParticleTable::GetParticleTable(); 41 | electron = particle_table->FindParticle("e-"); 42 | gamma = particle_table->FindParticle("gamma"); 43 | positron = particle_table->FindParticle("e+"); 44 | 45 | particle_gun->GetCurrentSource()->SetParticleDefinition(electron); 46 | particle_gun->GetCurrentSource()->GetPosDist()->SetPosDisType("Beam"); 47 | particle_gun->GetCurrentSource()->GetPosDist()->SetBeamSigmaInR(1*mm); 48 | particle_gun->GetCurrentSource()->GetEneDist()->SetMonoEnergy(6*MeV); 49 | 50 | // particle_gun->SetParticleDefinition(particle); 51 | // particle_gun->SetParticlePosition(G4ThreeVector(0., 0., 1005.)); 52 | // particle_gun->SetParticleEnergy(6.*MeV); 53 | // particle_gun->SetParticleMomentumDirection(G4ThreeVector(0.,0.,-1.)); 54 | 55 | redistribute = false; 56 | rotation = G4ThreeVector(); 57 | Reset(); 58 | } 59 | 60 | 61 | void PrimaryGeneratorAction::Reset() 62 | { 63 | recycling_number = 1; 64 | phasespace_record_repeat = 0; 65 | count = 0; 66 | } 67 | 68 | 69 | PrimaryGeneratorAction::~PrimaryGeneratorAction() 70 | { 71 | } 72 | 73 | 74 | void PrimaryGeneratorAction::GeneratePrimaries(G4Event* event) 75 | { 76 | if (from_phasespace) { 77 | GeneratePhasespacePrimaries(event); 78 | } else { 79 | particle_gun->GeneratePrimaryVertex(event); 80 | } 81 | } 82 | 83 | void PrimaryGeneratorAction::GeneratePhasespacePrimaries(G4Event* event) 84 | { 85 | if (phasespace_record_repeat == 0) { 86 | 87 | phasespace_record = PhasespaceRecord(); 88 | try { 89 | *phasespace_archive >> phasespace_record; 90 | } catch (...) { 91 | G4cout << "ABORTING RUN" << G4endl; 92 | G4cout << "Particles in phasespace: " << count << G4endl; 93 | 94 | phasespace_record_repeat = 0; 95 | count = 0; 96 | 97 | G4RunManager* run_manager = G4RunManager::GetRunManager(); 98 | run_manager->AbortRun(); 99 | } 100 | 101 | G4ParticleDefinition* particle = gamma; 102 | 103 | if (phasespace_record.GetParticleType() == -1) { 104 | particle = electron; 105 | } else if (phasespace_record.GetParticleType() == 1) { 106 | particle = positron; 107 | } 108 | 109 | phasespace_particle_gun->SetParticleDefinition(particle); 110 | phasespace_particle_gun->SetParticleEnergy(phasespace_record.GetKineticEnergy()); 111 | } 112 | 113 | phasespace_record_repeat++; 114 | count++; 115 | 116 | if (phasespace_record_repeat > recycling_number) { 117 | phasespace_record_repeat = 0; 118 | } 119 | 120 | // Sanity check 121 | if (phasespace_record.CheckIt(xlow, xhigh, ylow, yhigh, zlow, zhigh) == false) { 122 | return; 123 | } 124 | 125 | G4ThreeVector pos = G4ThreeVector(phasespace_record.GetPosition()); 126 | G4ThreeVector mom = G4ThreeVector(phasespace_record.GetMomentum()); 127 | 128 | if (redistribute) { 129 | G4double angle = G4UniformRand() * 360.0*deg; 130 | 131 | pos.rotateZ(angle); 132 | mom.rotateZ(angle); 133 | } 134 | 135 | // gantry rotation correction 136 | pos.rotateY(-rotation.y()*deg); 137 | mom.rotateY(-rotation.y()*deg); 138 | 139 | phasespace_particle_gun->SetParticlePosition(pos); 140 | phasespace_particle_gun->SetParticleMomentumDirection(mom); 141 | 142 | phasespace_particle_gun->GeneratePrimaryVertex(event); 143 | event->GetPrimaryVertex()->SetWeight(phasespace_record.GetWeight()); 144 | } 145 | 146 | -------------------------------------------------------------------------------- /linac/g4/src/SensitiveDetector.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #include "globals.hh" 23 | 24 | #include "SensitiveDetector.hh" 25 | #include "DetectorConstruction.hh" 26 | 27 | 28 | #include "G4ProcessType.hh" 29 | #include "G4HCofThisEvent.hh" 30 | #include "G4TouchableHistory.hh" 31 | #include "G4Step.hh" 32 | #include "G4Track.hh" 33 | #include "G4VProcess.hh" 34 | #include "G4Event.hh" 35 | #include "G4RunManager.hh" 36 | #include "G4SteppingManager.hh" 37 | #include "G4ThreeVector.hh" 38 | 39 | #include "boost/python.hpp" 40 | #include "pyublas/numpy.hpp" 41 | #include 42 | 43 | 44 | SensitiveDetector::SensitiveDetector(const G4String& name) : G4VSensitiveDetector(name) { 45 | 46 | debug = false; 47 | 48 | x_dim = 101; 49 | y_dim = x_dim; 50 | z_dim = 100; 51 | 52 | x_min = 0; 53 | y_min = 0; 54 | z_min = 0; 55 | 56 | x_max = x_dim; 57 | y_max = y_dim; 58 | z_max = z_dim; 59 | 60 | x_res = 4*mm; 61 | y_res = x_res; 62 | z_res = x_res; 63 | 64 | volume = x_res*y_res*z_res; 65 | 66 | detector_construction = (DetectorConstruction*) (G4RunManager::GetRunManager()->GetUserDetectorConstruction()); 67 | 68 | npy_intp dims[] = {x_max - x_min, y_max - y_min, z_max - z_min}; 69 | 70 | energy_histogram = pyublas::numpy_vector (3, dims); 71 | std::fill(energy_histogram.begin(), energy_histogram.end(), 0.0); 72 | 73 | energysq_histogram = pyublas::numpy_vector (3, dims); 74 | std::fill(energysq_histogram.begin(), energysq_histogram.end(), 0.0); 75 | 76 | counts_histogram = pyublas::numpy_vector (3, dims); 77 | std::fill(counts_histogram.begin(), counts_histogram.end(), 0.0); 78 | } 79 | 80 | SensitiveDetector::~SensitiveDetector() { 81 | } 82 | 83 | void SensitiveDetector::Initialize(G4HCofThisEvent*) { 84 | } 85 | 86 | G4bool SensitiveDetector::ProcessHits(G4Step* aStep, G4TouchableHistory* touchable) { 87 | const G4Track* aTrack = aStep->GetTrack(); 88 | const G4String name = aTrack->GetDefinition()->GetParticleName(); 89 | 90 | G4double energy_deposit = aStep->GetTotalEnergyDeposit(); 91 | 92 | if(energy_deposit == 0) { 93 | if (debug) G4cout << "No enegy to deposit." << G4endl << G4endl; 94 | return false; 95 | } 96 | 97 | G4double voxel_mass = aTrack->GetMaterial()->GetDensity() * volume; 98 | 99 | 100 | G4ThreeVector position = aTrack->GetPosition(); 101 | //G4ThreeVector world_position = aTrack->GetPosition(); 102 | ////G4ThreeVector world_position = aStep->GetPreStepPoint()->GetPosition(); 103 | //G4ThreeVector position = aStep->GetPreStepPoint()->GetTouchableHandle()-> 104 | // GetHistory()->GetTopTransform().TransformPoint(world_position); 105 | 106 | int x_index = std::floor((position.x() + (x_dim/2. * x_res)) / x_res); 107 | int y_index = std::floor((position.y() + (y_dim/2. * y_res)) / y_res); 108 | //int z_index = std::floor((position.z() + 300*mm + (z_dim/2. * z_res)) / z_res); 109 | int z_index = std::floor((position.z() + (z_dim/2. * z_res)) / z_res); 110 | 111 | if (debug) { 112 | G4cout << "Solid name: " << aTrack->GetVolume()->GetLogicalVolume()->GetName() << G4endl; 113 | G4cout << "Total energy: " << aTrack->GetTotalEnergy() << G4endl; 114 | G4cout << "Enegy to deposit: " << energy_deposit << " MeV" << G4endl; 115 | G4cout << "Voxel material: " << aTrack->GetMaterial()->GetName() << G4endl; 116 | G4cout << "Voxel mass: " << voxel_mass << G4endl; 117 | G4cout << "Voxel volume: " << volume << G4endl; 118 | G4cout << "Position: " 119 | << position.x() << " " 120 | << position.y() << " " 121 | << position.z() << " " << G4endl; 122 | G4cout << "Histogram index: " 123 | << x_index << " " 124 | << y_index << " " 125 | << z_index << " " << G4endl; 126 | if (x_index != std::abs(x_index)) { 127 | G4cout << "Error: X index" << G4endl; 128 | } 129 | if (y_index != std::abs(y_index)) { 130 | G4cout << "Error: Y index" << G4endl; 131 | } 132 | if (z_index != std::abs(z_index)) { 133 | G4cout << "Error: Z index" << G4endl; 134 | } 135 | } 136 | 137 | 138 | if (x_index < x_min || x_index >= x_max) { 139 | if (debug) {G4cout << "Out of bounds: X index" << G4endl;} 140 | return false; 141 | } 142 | if (y_index < y_min || y_index >= y_max) { 143 | if (debug) {G4cout << "Out of bounds: Y index" << G4endl;} 144 | return false; 145 | } 146 | if (z_index < z_min || z_index >= z_max) { 147 | if (debug) {G4cout << "Out of bounds: Z index" << G4endl;} 148 | return false; 149 | } 150 | 151 | x_index -= x_min; 152 | y_index -= y_min; 153 | z_index -= z_min; 154 | 155 | if (debug){ 156 | G4cout << "New index: " << x_index << " " << y_index << " " << z_index << " " << G4endl; 157 | } 158 | energy_histogram.sub(x_index, y_index, z_index) += energy_deposit/voxel_mass; 159 | energysq_histogram.sub(x_index, y_index, z_index) += std::pow(energy_deposit, 2.); 160 | counts_histogram.sub(x_index, y_index, z_index) += aTrack->GetWeight(); 161 | 162 | if (debug) G4cout << G4endl; 163 | 164 | return true; 165 | } 166 | 167 | void SensitiveDetector::EndOfEvent(G4HCofThisEvent*) { 168 | } 169 | 170 | void SensitiveDetector::clear() { 171 | } 172 | 173 | void SensitiveDetector::PrintAll() { 174 | } 175 | -------------------------------------------------------------------------------- /linac/g4/src/SteppingAction.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #include "SteppingAction.hh" 23 | #include "DetectorConstruction.hh" 24 | 25 | #include "G4SteppingManager.hh" 26 | #include "G4Track.hh" 27 | #include "G4Step.hh" 28 | #include "G4StepPoint.hh" 29 | #include "G4TrackStatus.hh" 30 | #include "G4VPhysicalVolume.hh" 31 | #include "G4ParticleDefinition.hh" 32 | #include "G4ParticleTypes.hh" 33 | 34 | #include "G4Event.hh" 35 | #include "G4RunManager.hh" 36 | 37 | SteppingAction::SteppingAction() 38 | { 39 | } 40 | 41 | SteppingAction::~SteppingAction() 42 | {;} 43 | 44 | void SteppingAction::UserSteppingAction(const G4Step*) 45 | { 46 | } 47 | -------------------------------------------------------------------------------- /linac/g4/src/StopKillShield.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2012 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | 22 | #include "StopKillShield.hh" 23 | 24 | // GEANT4 // 25 | #include "G4ThreeVector.hh" 26 | #include "G4SDManager.hh" 27 | 28 | 29 | StopKillSheild::StopKillSheild(G4String name):G4VSensitiveDetector(name) 30 | { 31 | } 32 | 33 | 34 | StopKillSheild::~StopKillSheild() 35 | { 36 | } 37 | 38 | 39 | void StopKillSheild::Initialize(G4HCofThisEvent*) 40 | { 41 | } 42 | 43 | 44 | G4bool StopKillSheild::ProcessHits(G4Step* aStep,G4TouchableHistory*) 45 | { 46 | aStep->GetTrack()->SetTrackStatus(fStopAndKill); 47 | return true; 48 | } 49 | 50 | void StopKillSheild::EndOfEvent(G4HCofThisEvent*){ 51 | 52 | } 53 | -------------------------------------------------------------------------------- /linac/geometry.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import math 3 | import inspect 4 | 5 | from math import * 6 | from itertools import repeat 7 | 8 | import yaml 9 | 10 | from Geant4 import G4Tubs, G4Box, G4ThreeVector, G4RotationMatrix, G4Color 11 | from Geant4 import mm, deg, keV, MeV 12 | 13 | 14 | # Default values for repeated properties 15 | default_multiples = { 16 | 'translation' : [0, 0, 0], 17 | 'rotation' : [0, 0, 0], 18 | 'colour' : [1, 1, 1, 1], 19 | } 20 | 21 | # Register for functions that enable rotation/translation 22 | # of a component within the geometry (jaws for example). 23 | transformers = {} 24 | 25 | def register_transformer(name, f): 26 | transformers[name] = f 27 | 28 | ## MLC transformers ## 29 | 30 | def mlc_diverge(i, interval=None, position=None, shift=0, z_rotation=0, centre=0, repeat=0): 31 | offset = -(interval * repeat / 2. - interval) 32 | divergance = math.atan((i*interval + offset + centre)/(1000 - position - 750)) 33 | return [-divergance/deg, 0, z_rotation] 34 | 35 | def mlc_interleave(i, interval=None, position=None, shift=0): 36 | offset = -(interval * 20 / 2. - interval + shift) 37 | return [0, i*interval + offset, position] 38 | 39 | def mlc_arc(i, interval=None, position=None, shift=0, repeat=0): 40 | offset = -(interval * repeat / 2. - interval + shift) 41 | return [0, i*interval + offset, 1000 - math.sqrt((1000 - position)**2 - (i*interval + offset)**2)] 42 | 43 | register_transformer('mlc_diverge', mlc_diverge) 44 | register_transformer('mlc_interleave', mlc_interleave) 45 | register_transformer('mlc_arc', mlc_arc) 46 | 47 | ## Basic repeated geometry transformers ## 48 | 49 | def repeat_x(i, interval=None, origin=None): 50 | return [origin[0] + i*interval, origin[1], origin[2]] 51 | 52 | def repeat_y(i, interval=None, origin=None): 53 | return [origin[0], origin[1] + i*interval, origin[2]] 54 | 55 | def repeat_z(i, interval=None, origin=None): 56 | return [origin[0], origin[1], origin[2] + i*interval] 57 | 58 | register_transformer('repeat_x', repeat_x) 59 | register_transformer('repeat_y', repeat_y) 60 | register_transformer('repeat_z', repeat_z) 61 | 62 | 63 | class Volume(object): 64 | """A solid placed within the geometry 65 | 66 | A solid can be any GEANT4 primitive. 67 | 68 | CAD Files: 69 | Using CADMesh a CAD file is loaded into the geometry as a G4TessellatedSolid, 70 | the user can specify if the volume is left as a normal tessellated solid or 71 | loaded as a tetrahedral mesh (for fast/er navigation). 72 | 73 | Attributes: 74 | name: The desired name of the solid 75 | translation: G4ThreeVector position of the solid within its mother volume 76 | rotation: G4ThreeVector rotation of the solid about its center 77 | colour: G4Colour as displayed by the VisManager 78 | material: The name of the target G4Material (it has to already exist) 79 | tessellated: If tetrahedralisation if not performed, otherwise 80 | """ 81 | def __init__(self, name, **kwargs): 82 | self.name = name 83 | 84 | self.config = kwargs 85 | self.filename = '' 86 | 87 | self.scale = 1 88 | self.translation = [0, 0, 0] 89 | self.rotation = [0, 0, 0] 90 | self._rotation_matrix = None 91 | 92 | self.colour = (1, 0, 0, 1) 93 | self.material = 'G4_AIR' 94 | 95 | self.scorer = None 96 | 97 | self.tessellated = True 98 | 99 | for key, val in kwargs.iteritems(): 100 | if hasattr(self, key): 101 | setattr(self, key, val) 102 | 103 | if key == "cylinder": 104 | self.solid = "cylinder" 105 | self.radius = val["radius"] 106 | self.length = val["length"] 107 | if key == "tube": 108 | self.solid = "tube" 109 | self.inner_radius = val["inner_radius"] 110 | self.outer_radius = val["outer_radius"] 111 | self.length = val["length"] 112 | if key == "slab": 113 | self.solid = "slab" 114 | self.side = val["side"] 115 | self.thickness = val["thickness"] 116 | if key == "cube": 117 | self.solid = "slab" 118 | self.side = val["side"] 119 | self.thickness = val["side"] 120 | 121 | self.daughters = {} 122 | if kwargs.has_key("daughters"): 123 | self._init_daughters(**kwargs) 124 | 125 | ## Language mappings ## 126 | 127 | @property 128 | def color(self): 129 | """Catch incorrect spelling of "colour" 130 | """ 131 | return self.colour 132 | 133 | @color.setter 134 | def color(self, colour): 135 | self.colour = colour 136 | 137 | ## Getters for rotation/translation as G4* objects ## 138 | 139 | @property 140 | def translation_vector(self): 141 | """Return the current translations as a G4ThreeVector 142 | """ 143 | return G4ThreeVector(*self.translation) 144 | 145 | @property 146 | def rotation_vector(self): 147 | """Return the x-, y-, z-direction rotations as a G4ThreeVector 148 | """ 149 | return G4ThreeVector(self.rotation[0], self.rotation[1], self.rotation[2]) 150 | 151 | @property 152 | def rotation_matrix(self): 153 | """Return the x-, y-, z-direction rotations as a G4RotationMatrix 154 | """ 155 | self._rotation_matrix = G4RotationMatrix() 156 | self._rotation_matrix.rotateX(self.rotation[0]*deg) 157 | self._rotation_matrix.rotateY(self.rotation[1]*deg) 158 | self._rotation_matrix.rotateZ(self.rotation[2]*deg) 159 | return self._rotation_matrix 160 | 161 | @property 162 | def color(self): 163 | """Return the colour as a G4Color 164 | """ 165 | return G4Color(*self.colour) 166 | 167 | ## Getters/setters for translation/rotation ## 168 | 169 | @property 170 | def x_position(self): 171 | return self.translation[0] 172 | 173 | @x_position.setter 174 | def x_position(self, x): 175 | self.translation[0] = x 176 | 177 | @property 178 | def y_position(self): 179 | return self.translation[1] 180 | 181 | @y_position.setter 182 | def y_position(self, y): 183 | self.translation[1] = y 184 | 185 | @property 186 | def z_position(self): 187 | return self.translation[2] 188 | 189 | @z_position.setter 190 | def z_position(self, z): 191 | self.translation[2] = z 192 | 193 | @property 194 | def x_rotation(self): 195 | return self.rotation[0] 196 | 197 | @x_rotation.setter 198 | def x_rotation(self, x): 199 | self.rotation[0] = x 200 | 201 | @property 202 | def y_rotation(self): 203 | return self.rotation[1] 204 | 205 | @y_rotation.setter 206 | def y_rotation(self, y): 207 | self.rotation[1] = y 208 | 209 | @property 210 | def z_rotation(self): 211 | return self.rotation[2] 212 | 213 | @z_rotation.setter 214 | def z_rotation(self, z): 215 | self.rotation[2] = z 216 | 217 | ## Initialisers ## 218 | 219 | def _init_daughters(self, **kwargs): 220 | """If a `Volume` has daugther volumes, iterativley initialise them and 221 | unpack repeats of the same volume if required. 222 | """ 223 | for name, daughter in kwargs['daughters'].iteritems(): 224 | if daughter.has_key('inherit'): 225 | d = copy.deepcopy(kwargs['daughters'][daughter['inherit']]) 226 | d.update(daughter) 227 | del d['inherit'] 228 | daughter = d 229 | 230 | try: 231 | repeats = daughter['repeat'] 232 | except KeyError: 233 | repeats = 1 234 | 235 | if repeats > 1: 236 | daughters = self._unpack_repeats(name, daughter, repeats) 237 | self.daughters.update(daughters) 238 | else: 239 | self.daughters[name] = Volume(name, **daughter) 240 | 241 | def _unpack_repeats(self, name, daughter, repeats): 242 | """Construct individual Volumes for those specified as repeats 243 | 244 | The geometry configuration does not require all instances of volumes to be 245 | explicity defined, repated volumes can be specified with lists provided for 246 | the parameters that vary. 247 | 248 | Args: 249 | name: The base name of the volume 250 | daughter: The instance of the base volume 251 | repeasts: The number of copies to make 252 | """ 253 | 254 | multiples = {} 255 | for m, default in default_multiples.iteritems(): 256 | if not daughter.has_key(m): 257 | multiples[m] = list(repeat(default, repeats)) 258 | continue 259 | 260 | if isinstance(daughter[m], dict): 261 | # with functions/transformers 262 | f = transformers[daughter[m]['function']] 263 | 264 | spec = inspect.getargspec(f) 265 | argnames = spec.args[-len(spec.defaults):] 266 | 267 | args = {} 268 | for k in argnames: 269 | args[k] = daughter[k] 270 | 271 | r = [] 272 | for i in range(repeats): 273 | r.append(f(i, **args)) 274 | multiples[m] = r 275 | 276 | elif isinstance(daughter[m], list): 277 | if isinstance(daughter[m][0], list): 278 | multiples[m] = daughter[m] 279 | else: 280 | multiples[m] = list(repeat(daughter[m], repeats)) 281 | else: 282 | # something is wrong 283 | pass 284 | 285 | daughters = [] 286 | for i in range(repeats): 287 | d = copy.deepcopy(daughter) 288 | for k, v in multiples.iteritems(): 289 | d[k] = copy.deepcopy(multiples[k][i]) 290 | n = "%s_%i" % (name, i) 291 | daughters.append((n, Volume(n, **d))) 292 | 293 | return daughters 294 | 295 | 296 | class Linac(object): 297 | """The Python object representation of the geometry configuration 298 | 299 | Attributes: 300 | config: configuration yaml loaded as a dict 301 | head: Treatment head Mother volume 302 | vacuum: Vacuum parts Mother volume 303 | phasespaces: All phasespace files used or created 304 | gun: The particle gun configuration 305 | """ 306 | def __init__(self, filename): 307 | self.config = yaml.load(file(filename)) 308 | 309 | self.world = Volume('world', **self.config['world']) 310 | self.phasespaces = self.config['phasespaces'] 311 | 312 | self.gun = self.config["gun"] 313 | 314 | def rounded_leaf_position(self, leaf_radius, radius_position, 315 | field_size, iso_position=1000.): 316 | """Calculator for positioning a leaf/jaw with a rounded end. 317 | 318 | Attributes: 319 | leaf_radius: the radius on the end of the leaf 320 | radius_position: the position of the center of the leaf radius 321 | field_size: target field opening 322 | iso_position: distance from the source to the iso center 323 | """ 324 | theta = atan(field_size / iso_position) 325 | delta = (leaf_radius / cos(theta)) - leaf_radius 326 | 327 | if abs(field_size) == field_size: 328 | return (field_size / iso_position * radius_position) + delta 329 | else: 330 | return (field_size / iso_position * radius_position) - delta 331 | 332 | ## Define rectangular fields ## 333 | 334 | def rectangular_field_jaws(self, x1, x2, y1, y2): 335 | raise NotImplementedError("Definition of a rectangular jaw field must be implemented by the user") 336 | 337 | def rectangular_field_mlc(self, x1, x2, y1, y2): 338 | raise NotImplementedError("Definition of a rectangular MLC field must be implemented by the user") 339 | 340 | def rectangular_field(self, x1, x2, y1, y2): 341 | """Convenience function for calling the user defined jaw/MLC rectangular 342 | field setters both together. 343 | """ 344 | self.rectangular_field_jaws(x1, x2, y1, y2) 345 | self.rectangular_field_mlc(x1, x2, y1, y2) 346 | 347 | ## Define square fields ## 348 | 349 | def square_field_jaws(self, size, x_offset=0, y_offset=0): 350 | """Set a square field for the jaw only. 351 | """ 352 | size = size/2. 353 | self.rectangular_field_jaws(size + x_offset, size + x_offset, size + y_offset, size + y_offset) 354 | 355 | def square_field_mlc(self, size, x_offset=0, y_offset=0): 356 | """Set a square field for the MLC only. 357 | """ 358 | size = size/2. 359 | self.rectangular_field_mlc(size + x_offset, size + x_offset, size + y_offset, size + y_offset) 360 | 361 | def square_field(self, size, x_offset=0, y_offset=0): 362 | """Convenience function for setting a square field given the field size length. 363 | """ 364 | self.square_field_jaws(size, x_offset, y_offset) 365 | self.square_field_mlc(size, x_offset, y_offset) 366 | 367 | ## Define arbitrary fields ## 368 | 369 | def arbitary_field_mlc(self, bank1_positions, bank2_positions): 370 | raise NotImplementedError("Definition of an arbitary MLC field must be implemented by the user") 371 | 372 | ## Move the gantry/collimator ## 373 | 374 | def rotate_gantry(self, angle): 375 | """Rotate the gantry to the nominated angular position. This is NOT 376 | and incremental rotation. 377 | """ 378 | offset_angle = (self.world.daughters['head'].rotation_vector.y - angle)*deg 379 | 380 | self.world.daughters['head'].rotation = (self.world.daughters['head'].rotation_vector.x, 381 | angle, 382 | self.world.daughters['head'].rotation_vector.z) 383 | 384 | t = self.world.daughters['head'].translation_vector 385 | t = t.rotateY(offset_angle) 386 | self.world.daughters['head'].translation = (t.x, t.y, t.z) 387 | 388 | def rotate_collimator(self, angle): 389 | """Rotation the collimator to the nominated angular position. 390 | """ 391 | self.world.daughters['head'].rotation = (angle, 392 | self.world.daughters['head'].rotation_vector.y, 393 | self.world.daughters['head'].rotation_vector.z) 394 | 395 | -------------------------------------------------------------------------------- /linac/simulation.py: -------------------------------------------------------------------------------- 1 | # Standard Library 2 | import random 3 | 4 | # GEANT4 5 | import Geant4 6 | from Geant4 import G4ThreeVector, G4RotationMatrix, G4Color, mm, deg, MeV 7 | 8 | # External 9 | import numpy 10 | import pyublas 11 | 12 | # User 13 | import g4 14 | 15 | 16 | class Simulation(object): 17 | """The base GEANT4 application 18 | 19 | The simulation proper is initialised here, along with the geometry described 20 | by the world `Volume` and each daughter `Volume` within. 21 | """ 22 | def __init__(self, name, config, phsp_dir='.', run_id=0): 23 | self.name = name 24 | self.run_id = run_id 25 | 26 | self.config = config 27 | self.geometry_modified = False 28 | 29 | self.geometry = {} 30 | 31 | self.phsp_dir = phsp_dir 32 | 33 | self.source = None 34 | self.phasespaces = [] 35 | 36 | self.detector_construction = g4.DetectorConstruction() 37 | 38 | side = self.config.world.side*mm 39 | self.detector_construction.SetWorldSize(G4ThreeVector(side, side, side)) 40 | self.detector_construction.SetWorldMaterial(self.config.world.material) 41 | self.detector_construction.SetWorldColour(self.config.world.color) 42 | 43 | Geant4.gRunManager.SetUserInitialization(self.detector_construction) 44 | 45 | self.physics_list = g4.PhysicsList() 46 | Geant4.gRunManager.SetUserInitialization(self.physics_list) 47 | 48 | self.primary_generator = g4.PrimaryGeneratorAction() 49 | Geant4.gRunManager.SetUserAction(self.primary_generator) 50 | 51 | self.event_action = g4.EventAction() 52 | Geant4.gRunManager.SetUserAction(self.event_action) 53 | 54 | self.stepping_action = g4.SteppingAction() 55 | Geant4.gRunManager.SetUserAction(self.stepping_action) 56 | 57 | self.rand_engine= Geant4.Ranlux64Engine() 58 | Geant4.HepRandom.setTheEngine(self.rand_engine) 59 | self.seed = random.randint(0, 2**32) 60 | Geant4.HepRandom.setTheSeed(self.seed) 61 | 62 | Geant4.gRunManager.Initialize() 63 | 64 | self.build_geometry() 65 | 66 | ## Primary generator ## 67 | 68 | def reset_source(self): 69 | """Reset the primary generator action to its default state. 70 | 71 | Especially in the case of using a phasespace file as the source, 72 | resetting it has the effect of replaying it again from the beginning 73 | on the next run. 74 | """ 75 | self.primary_generator.Reset() 76 | 77 | def enable_phasespace_source(self, name): 78 | """Set the primary generator action source to draw from an existing phasespace file. If 79 | the nominated phasespace file is open for recoding, it will be disabled automatically. 80 | """ 81 | if name in self.phasespaces: 82 | self.disable_phasespace(name) 83 | 84 | self.source = name 85 | 86 | def disable_phasespace_source(self): 87 | """Remove any phasespace set as the primary generator action source, defaults to 88 | using a general particle source (GPS). 89 | """ 90 | self.source = None 91 | 92 | ## Physics ## 93 | 94 | def set_cuts(self, gamma=1., electron=1.): 95 | """Set or override the default cuts for gammas and electrons through all parts of 96 | the simulation geometry. 97 | """ 98 | self.physics_list.OverrideCuts(gamma, electron) 99 | 100 | ## Voxelised phantom data ## 101 | 102 | def set_ct(self, directory, acquisition=1): 103 | """Nominate a DICOM directory as acquisition to load as voxelised geometry. 104 | """ 105 | self.detector_construction.UseCT(directory, acquisition) 106 | 107 | def set_array(self, filename, x=1., y=1., z=1.): 108 | """Use a `numpy` array as voxelised geometry. 109 | """ 110 | self.detector_construction.UseArray(filename, x, y, z) 111 | 112 | def set_ct_position(self, position): 113 | """Coerce the loaded voxel data to the specified origin. 114 | """ 115 | pos = G4ThreeVector(*position) 116 | self.detector_construction.SetCTPosition(pos) 117 | 118 | def crop_ct_x(self, xmin, xmax): 119 | """Crop the voxel data in the x-direction. 120 | """ 121 | self.detector_construction.CropX(xmin, xmax) 122 | 123 | def crop_ct_y(self, ymin, ymax): 124 | """Crop the voxel data in the y-direction. 125 | """ 126 | self.detector_construction.CropY(ymin, ymax) 127 | 128 | def crop_ct_z(self, zmin, zmax): 129 | """Crop the voxel data in the z-direction. 130 | """ 131 | self.detector_construction.CropZ(zmin, zmax) 132 | 133 | def get_ct_origin(self): 134 | """Get the voxel data origin (usually reported for DICOM-CT unless otherwise set). 135 | """ 136 | return self.detector_construction.GetCTOrigin() 137 | 138 | def hide_ct(self, hide): 139 | """Hide the voxel data from the viewer. 140 | """ 141 | self.detector_construction.HideCT(hide) 142 | 143 | def use_phantom(self, use): 144 | """Nide the voxel data from the navigator. 145 | """ 146 | self.detector_construction.UsePhantom(use) 147 | 148 | ## Scoring ## 149 | 150 | def save_histograms(self, directory, name, runid): 151 | """Dump the saved `numpy` array histograms, that align with the voxel data,to disk. 152 | """ 153 | energy_data = self.detector_construction.GetEnergyHistogram() 154 | numpy.save("%s/energy_%s_%s_%s" % (directory, self.name, name, runid), energy_data) 155 | 156 | energy2_data = self.detector_construction.GetEnergySqHistogram() 157 | numpy.save("%s/energy2_%s_%s_%s" % (directory, self.name, name, runid), energy2_data) 158 | 159 | counts_data = self.detector_construction.GetCountsHistogram() 160 | numpy.save("%s/counts_%s_%s_%s" % (directory, self.name, name, runid), counts_data) 161 | 162 | def zero_histograms(self): 163 | """Zero all historams without regard for their content. 164 | """ 165 | self.detector_construction.ZeroHistograms() 166 | 167 | ## Visualisation/Session ## 168 | 169 | def show(self): 170 | """Show the geometry using built-in visualisation. Requires a `macros/vis.mac` macros. 171 | """ 172 | Geant4.gUImanager.ExecuteMacroFile("macros/vis.mac") 173 | 174 | def start_session(self): 175 | """Start a GEANT4 command line users session (`g4py`). 176 | """ 177 | Geant4.StartUISession() 178 | 179 | ## Geometry ## 180 | 181 | def build_materials(self): 182 | """Build the materials defined in the user `Linac` configureation. 183 | """ 184 | for material in self.config["materials"]: 185 | self.detector_construction.AddMaterial(material["name"], material["density"], cb) 186 | 187 | def build_geometry(self): 188 | """Recursively build the user defined geometry. 189 | """ 190 | def build(volume, mother): 191 | for name, params in volume.daughters.iteritems(): 192 | if params.filename != "": 193 | physical = self.detector_construction.AddCADComponent(name, params.filename, 194 | params.material, params.scale, params.translation_vector, params.rotation_vector, 195 | params.color, params.tessellated, mother) 196 | if hasattr(params, "solid"): 197 | if params.solid == "cylinder": 198 | physical = self.detector_construction.AddTube(name, 199 | 0, params.radius, params.length, 200 | params.translation_vector, params.rotation_vector, 201 | params.material, params.color, mother) 202 | if params.solid == "tube": 203 | physical = self.detector_construction.AddTube(name, 204 | params.inner_radius, params.outer_radius, params.length, 205 | params.translation_vector, params.rotation_vector, 206 | params.material, params.color, mother) 207 | if params.solid == "slab": 208 | physical = self.detector_construction.AddSlab(name, params.side, 209 | params.thickness, params.material, params.translation_vector, 210 | params.rotation_vector, params.color, mother) 211 | 212 | if params.scorer == "StopKillSheild": 213 | self.detector_construction.SetAsStopKillSheild(physical) 214 | 215 | self.geometry[name] = physical 216 | 217 | build(params, physical.GetLogicalVolume()) 218 | 219 | mother = self.detector_construction.GetWorld() 220 | build(self.config.world, mother) 221 | 222 | self.build_phasespaces() 223 | 224 | def update_geometry(self): 225 | """Recursively update the user defined geometry. 226 | """ 227 | def update(volume): 228 | for name, params in volume.daughters.iteritems(): 229 | physical = self.geometry[name] 230 | 231 | physical.SetRotation(params.rotation_matrix) 232 | physical.SetTranslation(params.translation_vector) 233 | 234 | update(volume.daughters[name]) 235 | 236 | update(self.config.world) 237 | 238 | self.build_phasespaces() 239 | 240 | run_manager = Geant4.G4RunManager.GetRunManager() 241 | run_manager.GeometryHasBeenModified() 242 | 243 | ## Phasespace files ## 244 | 245 | def get_phasespace_filename(self, name): 246 | """Generate a filename from the name of the phasespace as in the `Linac` configuration 247 | """ 248 | return "%s/%s_%s_%s.phsp" % (self.phsp_dir, name, self.name, self.run_id) 249 | 250 | def enable_phasespace(self, name): 251 | self.phasespaces.append(name) 252 | 253 | def disable_phasespace(self, name): 254 | """Close an open phasespace file, and remove it from the geometry. 255 | """ 256 | self.detector_construction.RemovePhasespace(self.get_phasespace_filename(name)) 257 | self.phasespaces.remove(name) 258 | 259 | def disable_all_phasespaces(self): 260 | map(self.disable_phasespace, self.phasespaces) 261 | 262 | def build_phasespaces(self): 263 | """Create an empty phasespace file to write into, and insert it into the geometry. 264 | """ 265 | for phasespace in self.phasespaces: 266 | ps = self.config.phasespaces[phasespace] 267 | self.detector_construction.AddPhasespace(self.get_phasespace_filename(phasespace), 268 | ps["radius"], ps["z_position"], ps["kill"]) 269 | 270 | ## Run ## 271 | 272 | def beam_on(self, histories, fwhm=2.0*mm, energy=6*MeV): 273 | """Shoot particles from the primary generator into the geometry. Here we automatically 274 | select between a bare source, or phasespace if one is specified. 275 | """ 276 | self.update_geometry() 277 | 278 | if self.source is not None: 279 | self.primary_generator.SetSource(self.get_phasespace_filename(self.source)) 280 | 281 | z = self.config.phasespaces[self.source]["z_position"] 282 | self.primary_generator.SetGantryRotation(self.config.world.daughters["head"].rotation_vector) 283 | self.primary_generator.SetPhasespaceLimits(-200, 200, -200, 200, z-0.1, z+0.1) 284 | self.primary_generator.SetRedistribute(self.config.phasespaces[self.source]["redistribute"]) 285 | self.primary_generator.SetRecyclingNumber(self.config.gun["recycling_number"]) 286 | else: 287 | self.primary_generator.SetSource(None) 288 | 289 | self.primary_generator.SetFWHM(fwhm) 290 | self.primary_generator.SetEnergy(energy) 291 | self.primary_generator.SetPosition(G4ThreeVector(0., 0., 1050.)) 292 | self.primary_generator.SetDirection(G4ThreeVector(0, 0, -1)) 293 | 294 | Geant4.gRunManager.BeamOn(int(histories)) 295 | 296 | 297 | -------------------------------------------------------------------------------- /utils/phsp_inspector/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # License & Copyright 2 | # =================== 3 | # 4 | # Copyright 2013 Christopher M Poole 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | cmake_minimum_required(VERSION 2.6 FATAL_ERROR) 21 | project(phsp_inspector) 22 | 23 | find_package(Geant4 REQUIRED ui_all vis_all) 24 | find_package(PythonLibs REQUIRED) 25 | find_package(Boost REQUIRED COMPONENTS python serialization iostreams) 26 | 27 | include(${Geant4_USE_FILE}) 28 | include_directories(${PYTHON_INCLUDE_DIRS}) 29 | include_directories(${PROJECT_SOURCE_DIR}/include) 30 | include_directories(/usr/local/include) 31 | 32 | # PhasespaceRecord.* 33 | include_directories(../../linac/g4/include) 34 | file(GLOB sources ../../linac/g4/src/PhasespaceRecord.cc) 35 | file(GLOB headers ../../linac/g4/include/PhasespaceRecord.hh) 36 | 37 | 38 | SET(LIBRARY_OUTPUT_PATH "../phsp_inspector") 39 | add_library(phsp_inspector "SHARED" lib_phsp_inspector.cc ${sources} ${headers}) 40 | 41 | target_link_libraries(phsp_inspector ${Geant4_LIBRARIES}) 42 | target_link_libraries(phsp_inspector ${Boost_LIBRARIES}) 43 | target_link_libraries(phsp_inspector ${Python_LIBRARIES}) 44 | 45 | -------------------------------------------------------------------------------- /utils/phsp_inspector/lib_phsp_inspector.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // License & Copyright 3 | // =================== 4 | // 5 | // Copyright 2013 Christopher M Poole 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | // Standard Template Library // 22 | #include 23 | #include 24 | 25 | // linac // 26 | #include "PhasespaceRecord.hh" 27 | 28 | // boost::python // 29 | #include "boost/python.hpp" 30 | #include "boost/python/converter/builtin_converters.hpp" 31 | #include "boost/python/suite/indexing/vector_indexing_suite.hpp" 32 | 33 | // PyUBLAS // 34 | #include "pyublas/numpy.hpp" 35 | 36 | // boost::serialization // 37 | #include "boost/archive/binary_iarchive.hpp" 38 | #include "boost/archive/binary_oarchive.hpp" 39 | 40 | 41 | using namespace boost::python; 42 | 43 | 44 | class PhasespaceInspector { 45 | public: 46 | PhasespaceInspector() { 47 | }; 48 | 49 | void Read(std::string filename) { 50 | input_file_stream = new std::ifstream(filename.c_str(), std::ios::binary); 51 | phasespace_archive = new boost::archive::binary_iarchive(*input_file_stream); 52 | 53 | PhasespaceRecord phasespace_record; 54 | 55 | while(1) { 56 | phasespace_record = PhasespaceRecord(); 57 | try { 58 | *phasespace_archive >> phasespace_record; 59 | this->energy.push_back(phasespace_record.GetKineticEnergy()); 60 | this->weight.push_back(phasespace_record.GetWeight()); 61 | this->direction_x.push_back(phasespace_record.GetMomentum().x()); 62 | this->direction_y.push_back(phasespace_record.GetMomentum().y()); 63 | this->direction_z.push_back(phasespace_record.GetMomentum().z()); 64 | this->position.push_back(phasespace_record.GetPosition()); 65 | this->particle_type.push_back(phasespace_record.GetParticleType()); 66 | } catch (...) { 67 | std::cout << "Reached end of archive. Aborting." << std::endl; 68 | break; 69 | } 70 | } 71 | }; 72 | 73 | pyublas::numpy_vector GetEnergy() { 74 | return Get(this->energy); 75 | }; 76 | 77 | pyublas::numpy_vector GetWeight() { 78 | return Get(this->weight); 79 | }; 80 | 81 | pyublas::numpy_vector GetDirectionX() { 82 | return Get(this->direction_x); 83 | }; 84 | 85 | pyublas::numpy_vector GetDirectionY() { 86 | return Get(this->direction_y); 87 | }; 88 | 89 | pyublas::numpy_vector GetDirectionZ() { 90 | return Get(this->direction_z); 91 | }; 92 | 93 | private: 94 | template 95 | pyublas::numpy_vector Get(std::vector target) { 96 | pyublas::numpy_vector return_target(target.size()); 97 | std::copy(target.begin(), target.end(), return_target.begin()); 98 | return return_target; 99 | }; 100 | 101 | private: 102 | std::ifstream* input_file_stream; 103 | boost::archive::binary_iarchive* phasespace_archive; 104 | 105 | std::vector energy; 106 | std::vector weight; 107 | std::vector direction_x; 108 | std::vector direction_y; 109 | std::vector direction_z; 110 | std::vector position; 111 | std::vector particle_type; 112 | }; 113 | 114 | 115 | BOOST_PYTHON_MODULE(libphsp_inspector) { 116 | class_("PhasespaceInspector") 117 | .def("Read", &PhasespaceInspector::Read) 118 | .add_property("energy", &PhasespaceInspector::GetEnergy) 119 | .add_property("weight", &PhasespaceInspector::GetWeight) 120 | .add_property("direction_x", &PhasespaceInspector::GetDirectionX) 121 | .add_property("direction_y", &PhasespaceInspector::GetDirectionY) 122 | .add_property("direction_z", &PhasespaceInspector::GetDirectionZ) 123 | ; 124 | } 125 | 126 | -------------------------------------------------------------------------------- /utils/phsp_inspector/phsp/test1.phsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/christopherpoole/linac/98f452a3028a8c8c46c63c00f78507db77801a8f/utils/phsp_inspector/phsp/test1.phsp -------------------------------------------------------------------------------- /utils/phsp_inspector/phsp/test2.phsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/christopherpoole/linac/98f452a3028a8c8c46c63c00f78507db77801a8f/utils/phsp_inspector/phsp/test2.phsp -------------------------------------------------------------------------------- /utils/phsp_inspector/phsp_inspector/__init__.py: -------------------------------------------------------------------------------- 1 | import pyublas 2 | 3 | from libphsp_inspector import PhasespaceInspector 4 | 5 | -------------------------------------------------------------------------------- /utils/phsp_inspector/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | import pyublas 4 | import numpy 5 | import pylab 6 | 7 | from phsp_inspector import PhasespaceInspector 8 | 9 | 10 | if __name__ == "__main__": 11 | filenames = sys.argv[1:] 12 | 13 | for f in filenames: 14 | inspector = PhasespaceInspector() 15 | inspector.Read(f) 16 | 17 | pylab.hist(inspector.energy, bins=numpy.arange(0, 6, 0.1), alpha=1./len(filenames), label=f) 18 | 19 | pylab.legend() 20 | pylab.show() 21 | 22 | --------------------------------------------------------------------------------