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