Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 // Hadrontherapy advanced example for Geant4
27 // See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy
28 
29 #include "G4UnitsTable.hh"
30 #include "G4SystemOfUnits.hh"
31 #include "G4LogicalVolume.hh"
32 #include "G4VPhysicalVolume.hh"
33 #include "G4PVPlacement.hh"
34 #include "G4PVReplica.hh"
35 #include "G4Box.hh"
36 #include "G4ThreeVector.hh"
37 #include "G4Material.hh"
38 #include "G4NistManager.hh"
39 #include "G4GeometryManager.hh"
40 #include "G4SolidStore.hh"
41 #include "G4LogicalVolumeStore.hh"
42 
43 
44 
45 #include "G4SDManager.hh"
46 #include "G4RunManager.hh"
47 
48 #include "G4PhysicalVolumeStore.hh"
49 
50 #include "G4ThreeVector.hh"
51 
52 #include "globals.hh"
53 #include "G4Transform3D.hh"
54 #include "G4RotationMatrix.hh"
55 #include "G4Colour.hh"
56 #include "G4UserLimits.hh"
57 
58 #include "G4VisAttributes.hh"
59 
61 #include "HadrontherapyDummySD.hh"
63 
66  : G4VUserParallelWorld(aString),RODetector(0),RODetectorXDivision(0),
67  RODetectorYDivision(0),RODetectorZDivision(0),worldLogical(0),RODetectorLog(0),
68  RODetectorXDivisionLog(0),RODetectorYDivisionLog(0),RODetectorZDivisionLog(0),
69  sensitiveLogicalVolume(0)
70 {
71  isBuilt = false;
72  isInitialized = false;
73 }
74 
76 
78  G4double detectorDimX,
79  G4double detectorDimY,
80  G4double detectorDimZ,
81  G4int numberOfVoxelsX,
82  G4int numberOfVoxelsY,
83  G4int numberOfVoxelsZ)
84 {
85  detectorToWorldPosition = pos;
86  detectorSizeX = detectorDimX;
87  detectorSizeY= detectorDimY;
88  detectorSizeZ=detectorDimZ;
89  numberOfVoxelsAlongX=numberOfVoxelsX;
90  numberOfVoxelsAlongY=numberOfVoxelsY;
91  numberOfVoxelsAlongZ=numberOfVoxelsZ;
92 
93  isInitialized = true;
94 
95 
96 
97 }
98 
100 {
101  //Nothing happens if the RO geometry is not built. But parameters are properly set.
102  if (!isBuilt)
103  {
104  //G4Exception("HadrontherapyDetectorROGeometry::UpdateROGeometry","had001",
105  // JustWarning,"Cannot update geometry before it is built");
106  return;
107  }
108 
109  //1) Update the dimensions of the G4Boxes
110  G4double halfDetectorSizeX = detectorSizeX;
111  G4double halfDetectorSizeY = detectorSizeY;
112  G4double halfDetectorSizeZ = detectorSizeZ;
113 
114  RODetector->SetXHalfLength(halfDetectorSizeX);
115  RODetector->SetYHalfLength(halfDetectorSizeY);
116  RODetector->SetZHalfLength(halfDetectorSizeZ);
117 
118  G4double halfXVoxelSizeX = halfDetectorSizeX/numberOfVoxelsAlongX;
119  G4double halfXVoxelSizeY = halfDetectorSizeY;
120  G4double halfXVoxelSizeZ = halfDetectorSizeZ;
121  G4double voxelXThickness = 2*halfXVoxelSizeX;
122 
123  RODetectorXDivision->SetXHalfLength(halfXVoxelSizeX);
124  RODetectorXDivision->SetYHalfLength(halfXVoxelSizeY);
125  RODetectorXDivision->SetZHalfLength(halfXVoxelSizeZ);
126 
127  G4double halfYVoxelSizeX = halfXVoxelSizeX;
128  G4double halfYVoxelSizeY = halfDetectorSizeY/numberOfVoxelsAlongY;
129  G4double halfYVoxelSizeZ = halfDetectorSizeZ;
130  G4double voxelYThickness = 2*halfYVoxelSizeY;
131 
132  RODetectorYDivision->SetXHalfLength(halfYVoxelSizeX);
133  RODetectorYDivision->SetYHalfLength(halfYVoxelSizeY);
134  RODetectorYDivision->SetZHalfLength(halfYVoxelSizeZ);
135 
136  G4double halfZVoxelSizeX = halfXVoxelSizeX;
137  G4double halfZVoxelSizeY = halfYVoxelSizeY;
138  G4double halfZVoxelSizeZ = halfDetectorSizeZ/numberOfVoxelsAlongZ;
139  G4double voxelZThickness = 2*halfZVoxelSizeZ;
140 
141  RODetectorZDivision->SetXHalfLength(halfZVoxelSizeX);
142  RODetectorZDivision->SetYHalfLength(halfZVoxelSizeY);
143  RODetectorZDivision->SetZHalfLength(halfZVoxelSizeZ);
144 
145  //Delete and re-build the relevant physical volumes
146  G4PhysicalVolumeStore* store =
148 
149  //Delete...
150  G4VPhysicalVolume* myVol = store->GetVolume("RODetectorPhys");
151  store->DeRegister(myVol);
152  //..and rebuild
153  G4VPhysicalVolume *RODetectorPhys = new G4PVPlacement(0,
154  detectorToWorldPosition,
155  RODetectorLog,
156  "RODetectorPhys",
157  worldLogical,
158  false,0);
159 
160  myVol = store->GetVolume("RODetectorXDivisionPhys");
161  store->DeRegister(myVol);
162  G4VPhysicalVolume *RODetectorXDivisionPhys = new G4PVReplica("RODetectorXDivisionPhys",
163  RODetectorXDivisionLog,
164  RODetectorPhys,
165  kXAxis,
166  numberOfVoxelsAlongX,
167  voxelXThickness);
168  myVol = store->GetVolume("RODetectorYDivisionPhys");
169  store->DeRegister(myVol);
170  G4VPhysicalVolume *RODetectorYDivisionPhys = new G4PVReplica("RODetectorYDivisionPhys",
171  RODetectorYDivisionLog,
172  RODetectorXDivisionPhys,
173  kYAxis,
174  numberOfVoxelsAlongY,
175  voxelYThickness);
176 
177  myVol = store->GetVolume("RODetectorZDivisionPhys");
178  store->DeRegister(myVol);
179  new G4PVReplica("RODetectorZDivisionPhys",
180  RODetectorZDivisionLog,
181  RODetectorYDivisionPhys,
182  kZAxis,
183  numberOfVoxelsAlongZ,
184  voxelZThickness);
185 
186  return;
187 
188 }
189 
192 {;}
193 
196 {
197  // A dummy material is used to fill the volumes of the readout geometry.
198  // (It will be allowed to set a NULL pointer in volumes of such virtual
199  // division in future, since this material is irrelevant for tracking.)
200 
201 
202  //
203  // World
204  //
205  G4VPhysicalVolume* ghostWorld = GetWorld();
206  worldLogical = ghostWorld->GetLogicalVolume();
207 
208  if (!isInitialized)
209  {
210  G4Exception("HadrontherapyDetectorROGeometry::Construct","had001",
211  FatalException,"Parameters of the RO geometry are not initialized");
212  return;
213  }
214 
215 
216  G4double halfDetectorSizeX = detectorSizeX;
217  G4double halfDetectorSizeY = detectorSizeY;
218  G4double halfDetectorSizeZ = detectorSizeZ;
219 
220  // World volume of ROGeometry ... SERVE SOLO PER LA ROG
221 
222  // Detector ROGeometry
223  RODetector = new G4Box("RODetector",
224  halfDetectorSizeX,
225  halfDetectorSizeY,
226  halfDetectorSizeZ);
227 
228  RODetectorLog = new G4LogicalVolume(RODetector,
229  0,
230  "RODetectorLog",
231  0,0,0);
232 
233 
234 
235  G4VPhysicalVolume *RODetectorPhys = new G4PVPlacement(0,
236  detectorToWorldPosition,RODetectorLog,
237  "RODetectorPhys",
238  worldLogical,
239  false,0);
240 
241 
242 
243 
244  // Division along X axis: the detector is divided in slices along the X axis
245 
246  G4double halfXVoxelSizeX = halfDetectorSizeX/numberOfVoxelsAlongX;
247  G4double halfXVoxelSizeY = halfDetectorSizeY;
248  G4double halfXVoxelSizeZ = halfDetectorSizeZ;
249  G4double voxelXThickness = 2*halfXVoxelSizeX;
250 
251 
252  RODetectorXDivision = new G4Box("RODetectorXDivision",
253  halfXVoxelSizeX,
254  halfXVoxelSizeY,
255  halfXVoxelSizeZ);
256 
257  RODetectorXDivisionLog = new G4LogicalVolume(RODetectorXDivision,
258  0,
259  "RODetectorXDivisionLog",
260  0,0,0);
261 
262  G4VPhysicalVolume *RODetectorXDivisionPhys = new G4PVReplica("RODetectorXDivisionPhys",
263  RODetectorXDivisionLog,
264  RODetectorPhys,
265  kXAxis,
266  numberOfVoxelsAlongX,
267  voxelXThickness);
268 
269  // Division along Y axis: the slices along the X axis are divided along the Y axis
270 
271  G4double halfYVoxelSizeX = halfXVoxelSizeX;
272  G4double halfYVoxelSizeY = halfDetectorSizeY/numberOfVoxelsAlongY;
273  G4double halfYVoxelSizeZ = halfDetectorSizeZ;
274  G4double voxelYThickness = 2*halfYVoxelSizeY;
275 
276  RODetectorYDivision = new G4Box("RODetectorYDivision",
277  halfYVoxelSizeX,
278  halfYVoxelSizeY,
279  halfYVoxelSizeZ);
280 
281  RODetectorYDivisionLog = new G4LogicalVolume(RODetectorYDivision,
282  0,
283  "RODetectorYDivisionLog",
284  0,0,0);
285 
286  G4VPhysicalVolume *RODetectorYDivisionPhys = new G4PVReplica("RODetectorYDivisionPhys",
287  RODetectorYDivisionLog,
288  RODetectorXDivisionPhys,
289  kYAxis,
290  numberOfVoxelsAlongY,
291  voxelYThickness);
292 
293  // Division along Z axis: the slices along the Y axis are divided along the Z axis
294 
295  G4double halfZVoxelSizeX = halfXVoxelSizeX;
296  G4double halfZVoxelSizeY = halfYVoxelSizeY;
297  G4double halfZVoxelSizeZ = halfDetectorSizeZ/numberOfVoxelsAlongZ;
298  G4double voxelZThickness = 2*halfZVoxelSizeZ;
299 
300  RODetectorZDivision = new G4Box("RODetectorZDivision",
301  halfZVoxelSizeX,
302  halfZVoxelSizeY,
303  halfZVoxelSizeZ);
304 
305  RODetectorZDivisionLog = new G4LogicalVolume(RODetectorZDivision,
306  0,
307  "RODetectorZDivisionLog",
308  0,0,0);
309 
310  new G4PVReplica("RODetectorZDivisionPhys",
311  RODetectorZDivisionLog,
312  RODetectorYDivisionPhys,
313  kZAxis,
314  numberOfVoxelsAlongZ,
315  voxelZThickness);
316 
317  sensitiveLogicalVolume = RODetectorZDivisionLog;
318  isBuilt = true;
319 }
320 
322 {
323 
324  G4String sensitiveDetectorName = "RODetector";
325 
326  HadrontherapyDetectorSD* detectorSD = new HadrontherapyDetectorSD(sensitiveDetectorName);
328  SetSensitiveDetector(sensitiveLogicalVolume,detectorSD);
329 
330 
331 }
332 
void SetZHalfLength(G4double dz)
Definition: G4Box.cc:174
G4VPhysicalVolume * GetWorld()
Definition: G4Box.hh:64
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
void AddNewDetector(G4VSensitiveDetector *aSD)
Definition: G4SDManager.cc:71
G4LogicalVolume * GetLogicalVolume() const
static G4SDManager * GetSDMpointer()
Definition: G4SDManager.cc:40
void SetYHalfLength(G4double dy)
Definition: G4Box.cc:154
void SetXHalfLength(G4double dx)
Definition: G4Box.cc:134
double G4double
Definition: G4Types.hh:76
G4VPhysicalVolume * GetVolume(const G4String &name, G4bool verbose=true) const
static const G4double pos