Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GammaKnifeDetectorConstruction.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 
27 #include "G4SDManager.hh"
28 #include "G4RunManager.hh"
29 #include "G4Box.hh"
30 #include "G4Tubs.hh"
31 #include "G4Cons.hh"
32 #include "G4Orb.hh"
33 #include "G4LogicalVolume.hh"
34 #include "G4ThreeVector.hh"
35 #include "G4PVPlacement.hh"
36 #include "globals.hh"
37 #include "G4RotationMatrix.hh"
38 #include "G4Colour.hh"
39 #include "G4UserLimits.hh"
40 #include "G4VisAttributes.hh"
41 #include "G4NistManager.hh"
42 
45 
46 #include "G4SystemOfUnits.hh"
47 
49  : physicalTreatmentRoom(0),
50  patientPhysicalVolume(0),
51  patientLogicalVolume(0),
52  solidColl_helmet(0),
53  helmetSize(4)
54 {
55  // Messenger to change parameters of the geometry
56  detectorMessenger = new GammaKnifeDetectorMessenger(this);
57 }
58 
60 {
61  // if (phantomROGeometry) delete phantomROGeometry;
62  delete detectorMessenger;
63 }
64 
66 {
67  // Define the geometry components
68  ConstructBeamLine();
69 
70  return physicalTreatmentRoom;
71 }
72 
73 void GammaKnifeDetectorConstruction::ConstructBeamLine()
74 {
75  // NIST Materials
83 
84  // Steel as non-NIST material
88  G4Material* steel = new G4Material("StainlessSteel", 7.80 * g/cm3, 3 /* components */);
89  steel -> AddElement(elFe, 70 * perCent);
90  steel -> AddElement(elCr, 18 * perCent);
91  steel -> AddElement(elNi, 12 * perCent);
92 
93  // -----------------------------
94  // Treatment room - World volume
95  // -----------------------------
96 
97  // Treatment room sizes
98  const G4double worldX = 400.0 *cm;
99  const G4double worldY = 400.0 *cm;
100  const G4double worldZ = 400.0 *cm;
101 
102  G4Box* treatmentRoom = new G4Box("TreatmentRoom",worldX,worldY,worldZ);
103 
104  G4LogicalVolume* logicTreatmentRoom = new G4LogicalVolume(treatmentRoom,
105  air,
106  "logicTreatmentRoom",
107  0,0,0);
108 
109  physicalTreatmentRoom = new G4PVPlacement(0,
110  G4ThreeVector(),
111  "physicalTreatmentRoom",
112  logicTreatmentRoom,
113  0,false,0);
114 
115 
116  // The treatment room is invisible in the Visualisation
117  logicTreatmentRoom -> SetVisAttributes (G4VisAttributes::Invisible);
118 
119 
120  // Visualisation attributes of all elements colours
121  G4VisAttributes * grayFe = new G4VisAttributes(G4Colour(0.5 ,0.5 ,0.5));
122  grayFe -> SetVisibility(true);
123  grayFe -> SetForceSolid(true);
124 
125  G4VisAttributes * blueCobalt = new G4VisAttributes(G4Colour(0. ,0. ,0.7));
126  blueCobalt -> SetVisibility(true);
127  blueCobalt -> SetForceSolid(true);
128 
129  G4VisAttributes * graySS = new G4VisAttributes(G4Colour(0.9 ,0.9 ,0.9));
130  graySS -> SetVisibility(true);
131  graySS -> SetForceSolid(true);
132 
133  G4VisAttributes * grayAl = new G4VisAttributes(G4Colour(0.7 ,0.7 ,0.7));
134  grayAl -> SetVisibility(true);
135  grayAl -> SetForceSolid(true);
136 
137  G4VisAttributes * blackLead = new G4VisAttributes(G4Colour(0.2 ,0.2 ,0.2));
138  blackLead -> SetVisibility(true);
139  blackLead -> SetForceSolid(true);
140 
141 
142  G4VisAttributes * colorTungsten = new G4VisAttributes(G4Colour(0.3 ,0.3 ,0.3));
143  colorTungsten -> SetVisibility(true);
144  colorTungsten -> SetForceSolid(true);
145 
146 
147 
148 
149 
150  //--------------------------------------------
151  // Cylinder source "Tube_source"
152  //--------------------------------------------
153  G4double innerRadiusOfTheTube_source = 0.;
154  G4double outerRadiusOfTheTube_source = 0.5*mm;
155  G4double hightOfTheTube_source = 1*cm;
156  G4double startAngleOfTheTube = 0.*deg;
157  G4double spanningAngleOfTheTube = 360.*deg;
158 
159  G4ThreeVector positionTube_source = G4ThreeVector(0,0,-40.1*cm);
160 
161  solidTube_source = new G4Tubs("solidTube_source",
162  innerRadiusOfTheTube_source,
163  outerRadiusOfTheTube_source,
164  hightOfTheTube_source,
165  startAngleOfTheTube,
166  spanningAngleOfTheTube);
167  logicTube_source = new G4LogicalVolume(solidTube_source,cobalt,"logicTube_source",0,0,0);
168  physiTube_source = new G4PVPlacement(0,
169  positionTube_source,
170  logicTube_source,
171  "Tube_source",
172  logicTreatmentRoom,
173  false,
174  0);
175 
176  logicTube_source -> SetVisAttributes(blueCobalt);
177 
178 
179  //-------------------------------------
180  // Cylinder covering source "Tube"
181  //-------------------------------------
182  G4double innerRadiusOfTheTube = 0.5*mm;
183  G4double outerRadiusOfTheTube = 4.*mm;
184  G4double hightOfTheTube = 1*cm;
185 
186 
187  G4ThreeVector positionTube = G4ThreeVector(0,0,-40.1*cm);
188 
189  solidTube = new G4Tubs("solidTube",
190  innerRadiusOfTheTube,
191  outerRadiusOfTheTube,
192  hightOfTheTube,
193  startAngleOfTheTube,
194  spanningAngleOfTheTube);
195  logicTube = new G4LogicalVolume(solidTube,steel,"logicTube",0,0,0);
196  physiTube = new G4PVPlacement(0,
197  positionTube,
198  logicTube,
199  "Tube",
200  logicTreatmentRoom,
201  false,
202  0);
203 
204  logicTube -> SetVisAttributes(graySS);
205 
206  //---------------------------------------
207  // Cylinder covering source "Tube_Al"
208  //---------------------------------------
209  G4double innerRadiusOfTheTube_Al = 4.*mm;
210  G4double outerRadiusOfTheTube_Al = 15.*mm;
211  G4double hightOfTheTube_Al = 1*cm;
212 
213  G4ThreeVector positionTube_Al = G4ThreeVector(0,0,-40.1*cm);
214 
215  solidTube_Al = new G4Tubs("solidTube_Al",
216  innerRadiusOfTheTube_Al,
217  outerRadiusOfTheTube_Al,
218  hightOfTheTube_Al,
219  startAngleOfTheTube,
220  spanningAngleOfTheTube);
221  logicTube_Al = new G4LogicalVolume(solidTube_Al,Al,"logicTube_Al",0,0,0);
222  physiTube_Al = new G4PVPlacement(0,
223  positionTube_Al,
224  logicTube_Al,
225  "Tube_Al",
226  logicTreatmentRoom,
227  false,
228  0);
229 
230  logicTube_Al -> SetVisAttributes(grayAl);
231 
232  //----------------------------------------------
233  // Cylinder covering external part of the source "Tube_Fe"
234  //----------------------------------------------
235  G4double innerRadiusOfTheTube_Fe = 15.*mm;
236  G4double outerRadiusOfTheTube_Fe = 50.*mm;
237  G4double hightOfTheTube_Fe = 1*cm;
238 
239 
240  G4ThreeVector positionTube_Fe = G4ThreeVector(0,0,-40.1*cm);
241 
242  solidTube_Fe = new G4Tubs("solidTube_Fe",
243  innerRadiusOfTheTube_Fe,
244  outerRadiusOfTheTube_Fe,
245  hightOfTheTube_Fe,
246  startAngleOfTheTube,
247  spanningAngleOfTheTube);
248  logicTube_Fe = new G4LogicalVolume(solidTube_Fe,Fe,"logicTube_Fe",0,0,0);
249  physiTube_Fe = new G4PVPlacement(0,
250  positionTube_Fe,
251  logicTube_Fe,
252  "Tube_Fe",
253  logicTreatmentRoom,
254  false,
255  0);
256 
257  logicTube_Fe -> SetVisAttributes(grayFe);
258 
259 
260 
261 
262  //------------------------------------------------
263  // Cylinder covering posterior part "Tube_post"
264  //------------------------------------------------
265 
266  G4double innerRadiusOfTheTube_post = 0;
267  G4double outerRadiusOfTheTube_post = 50*mm;
268  G4double hightOfTheTube_post = 1*cm;
269 
270  G4ThreeVector positionTube_post = G4ThreeVector(0,0,-42.2*cm);
271 
272  solidTube_post = new G4Tubs("solidTube_post",
273  innerRadiusOfTheTube_post,
274  outerRadiusOfTheTube_post,
275  hightOfTheTube_post,
276  startAngleOfTheTube,
277  spanningAngleOfTheTube);
278  logicTube_post = new G4LogicalVolume(solidTube_post,Fe,"logicTube_post",0,0,0);
279  physiTube_post = new G4PVPlacement(0,
280  positionTube_post,
281  logicTube_post,
282  "Tube_post",
283  logicTreatmentRoom,
284  false,
285  0);
286 
287  logicTube_post -> SetVisAttributes(grayFe);
288 
289 
290  //------------------------------------------------
291  // Fixed cylinder collimator "Tube_coll"
292  //------------------------------------------------
293 
294  G4double innerRadiusOfTheTube_coll = 2.5*mm;
295  G4double outerRadiusOfTheTube_coll = 15.*mm;
296  G4double hightOfTheTube_coll = 3.25*cm;
297 
298  G4ThreeVector positionTube_coll = G4ThreeVector(0,0,-35.2*cm);
299 
300  solidTube_coll = new G4Tubs("solidTube_coll",
301  innerRadiusOfTheTube_coll,
302  outerRadiusOfTheTube_coll,
303  hightOfTheTube_coll,
304  startAngleOfTheTube,
305  spanningAngleOfTheTube);
306  logicTube_coll = new G4LogicalVolume(solidTube_coll,tungsten,"logicTube_coll",0,0,0);
307  physiTube_coll = new G4PVPlacement(0,
308  positionTube_coll,
309  logicTube_coll,
310  "Tube_coll",
311  logicTreatmentRoom,
312  false,
313  0);
314 
315  logicTube_coll -> SetVisAttributes(colorTungsten);
316 
317 
318  //------------------------------------------------
319  // Cylinder covering fixed collimator "Tube_coll_Fe"
320  //------------------------------------------------
321 
322  G4double innerRadiusOfTheTube_coll_Fe = 15.*mm;
323  G4double outerRadiusOfTheTube_coll_Fe = 50.*mm;
324  G4double hightOfTheTube_coll_Fe = 3.25*cm;
325 
326  G4ThreeVector positionTube_coll_Fe = G4ThreeVector(0,0,-35.2*cm);
327 
328  solidTube_coll_Fe = new G4Tubs("solidTube_coll_Fe",
329  innerRadiusOfTheTube_coll_Fe,
330  outerRadiusOfTheTube_coll_Fe,
331  hightOfTheTube_coll_Fe,
332  startAngleOfTheTube,
333  spanningAngleOfTheTube);
334  logicTube_coll_Fe = new G4LogicalVolume(solidTube_coll_Fe,Fe,"logicTube_coll_Fe",0,0,0);
335  physiTube_coll_Fe = new G4PVPlacement(0,
336  positionTube_coll_Fe,
337  logicTube_coll_Fe,
338  "Tube_coll_Fe",
339  logicTreatmentRoom,
340  false,
341  0);
342 
343  logicTube_coll_Fe -> SetVisAttributes(grayFe);
344 
345 
346  //------------------------------------------------
347  // Fixed truncated cone collimator "Coll_fixed"
348  //------------------------------------------------
349 
350  G4double Rmin1Coll_fixed = 2.5*mm;
351  G4double Rmax1Coll_fixed = 15.*mm;
352  G4double Rmin2Coll_fixed = 4.25*mm;
353  G4double Rmax2Coll_fixed = 15.*mm;
354  G4double hightColl_fixed = 4.625*cm;
355 
356 
357  G4ThreeVector positionColl_fixed = G4ThreeVector(0,0,-27.325*cm);
358 
359  solidColl_fixed = new G4Cons("solidColl_fixed",
360  Rmin1Coll_fixed,
361  Rmax1Coll_fixed,
362  Rmin2Coll_fixed,
363  Rmax2Coll_fixed,
364  hightColl_fixed,
365  startAngleOfTheTube,
366  spanningAngleOfTheTube);
367  logicColl_fixed = new G4LogicalVolume(solidColl_fixed,Pb,"logicColl_fixed",0,0,0);
368  physiColl_fixed = new G4PVPlacement(0,
369  positionColl_fixed,
370  logicColl_fixed,
371  "Coll_fixed",
372  logicTreatmentRoom,
373  false,
374  0);
375 
376  logicColl_fixed -> SetVisAttributes(blackLead);
377 
378 
379  //-----------------------------------------------------------
380  // Cilinder covering fixed collimator "Coll_fixed_Fe"
381  //-----------------------------------------------------------
382 
383  G4double Rmin1Coll_fixed_Fe = 15.*mm;
384  G4double Rmax1Coll_fixed_Fe = 50.*mm;
385  G4double Rmin2Coll_fixed_Fe = 15.*mm;
386  G4double Rmax2Coll_fixed_Fe = 40.*mm;
387  G4double hightColl_fixed_Fe = 4.625*cm;
388 
389 
390  G4ThreeVector positionColl_fixed_Fe = G4ThreeVector(0,0,-27.325*cm);
391 
392  solidColl_fixed_Fe = new G4Cons("solidColl_fixed_Fe",
393  Rmin1Coll_fixed_Fe,
394  Rmax1Coll_fixed_Fe,
395  Rmin2Coll_fixed_Fe,
396  Rmax2Coll_fixed_Fe,
397  hightColl_fixed_Fe,
398  startAngleOfTheTube, //
399  spanningAngleOfTheTube);
400  logicColl_fixed_Fe = new G4LogicalVolume(solidColl_fixed_Fe,Fe,"logicColl_fixed_Fe",0,0,0);
401  physiColl_fixed_Fe = new G4PVPlacement(0,
402  positionColl_fixed_Fe,
403  logicColl_fixed_Fe,
404  "Coll_fixed_Fe",
405  logicTreatmentRoom,
406  false,
407  0);
408 
409  logicColl_fixed_Fe -> SetVisAttributes(grayFe);
410 
411 
412  //------------------------------------------------
413  // Mobile truncate cone collimator "Coll_helmet"
414  //------------------------------------------------
415  G4double Rmax1Coll_helmet = 15.*mm;
416  G4double Rmax2Coll_helmet = 15.*mm;
417  G4double hightColl_helmet = 3.0*cm;
418 
419 
420  G4ThreeVector positionColl_helmet = G4ThreeVector(0,0,-19.5*cm);
421 
422  solidColl_helmet = new G4Cons("solidColl_helmet",
423  0.0, // will be set later
424  Rmax1Coll_helmet,
425  0.0, // will be set later
426  Rmax2Coll_helmet,
427  hightColl_helmet,
428  startAngleOfTheTube,
429  spanningAngleOfTheTube);
430  UpdateHelmet(); // Set the proper inner radii
431 
432  logicColl_helmet = new G4LogicalVolume(solidColl_helmet,tungsten,"logicColl_helmet",0,0,0);
433  physiColl_helmet = new G4PVPlacement(0,
434  positionColl_helmet,
435  logicColl_helmet,
436  "Coll_helmet",
437  logicTreatmentRoom,
438  false,
439  0);
440 
441  logicColl_helmet -> SetVisAttributes(colorTungsten);
442 
443  //--------------------------------------------------------------
444  // Truncated cone covering mobile collimator "Coll_helmet_Fe"
445  //--------------------------------------------------------------
446 
447  G4double Rmin1Coll_helmet_Fe = 15.*mm;
448  G4double Rmax1Coll_helmet_Fe = 40.*mm;
449  G4double Rmin2Coll_helmet_Fe = 15.*mm;
450  G4double Rmax2Coll_helmet_Fe = 30.*mm;
451  G4double hightColl_helmet_Fe = 3.0*cm;
452 
453  G4ThreeVector positionColl_helmet_Fe = G4ThreeVector(0,0,-19.5*cm);
454 
455  solidColl_helmet_Fe = new G4Cons("solidColl_helmet_Fe",
456  Rmin1Coll_helmet_Fe,
457  Rmax1Coll_helmet_Fe,
458  Rmin2Coll_helmet_Fe,
459  Rmax2Coll_helmet_Fe,
460  hightColl_helmet_Fe,
461  startAngleOfTheTube,
462  spanningAngleOfTheTube);
463  logicColl_helmet_Fe = new G4LogicalVolume(solidColl_helmet_Fe,Fe,"logicColl_helmet_Fe",0,0,0);
464  physiColl_helmet_Fe = new G4PVPlacement(0,
465  positionColl_helmet_Fe,
466  logicColl_helmet_Fe,
467  "Coll_helmet_Fe",
468  logicTreatmentRoom,
469  false,
470  0);
471 
472  logicColl_helmet_Fe -> SetVisAttributes(grayFe);
473 
474  //-----------------------------------------
475  // Patient --> water spherical phantom
476  //-----------------------------------------
477 
478 
479  G4Orb* patient = new G4Orb("patient",8.*cm);
480  patientLogicalVolume = new G4LogicalVolume(patient,
481  water,
482  "patientLog", 0, 0, 0);
483  patientPhysicalVolume = new G4PVPlacement( new G4RotationMatrix(),
484  G4ThreeVector(0., 0., 0.),
485  "patientPhys",
486  patientLogicalVolume,
487  physicalTreatmentRoom,
488  false,0);
489 
490  // Visualisation attributes of the patient
491  G4VisAttributes * redWire = new G4VisAttributes(G4Colour(0.8 ,0. ,0.));
492  redWire -> SetVisibility(true);
493  redWire -> SetForceWireframe(true);
494  redWire -> SetForceAuxEdgeVisible(true);
495  patientLogicalVolume -> SetVisAttributes(redWire);
496 
497 }
498 
499 void GammaKnifeDetectorConstruction::UpdateHelmet()
500 {
501  if (solidColl_helmet)
502  {
503  switch( helmetSize )
504  {
505  case 18:
506  solidColl_helmet->SetInnerRadiusMinusZ( 4.15 * mm );
507  solidColl_helmet->SetInnerRadiusPlusZ( 5.3 * mm );
508  break;
509 
510  case 14:
511  solidColl_helmet->SetInnerRadiusMinusZ( 3.15 * mm );
512  solidColl_helmet->SetInnerRadiusPlusZ( 4.25 * mm );
513  break;
514 
515  case 8:
516  solidColl_helmet->SetInnerRadiusMinusZ( 1.9 * mm );
517  solidColl_helmet->SetInnerRadiusPlusZ( 2.5 * mm );
518  break;
519 
520  case 4:
521  solidColl_helmet->SetInnerRadiusMinusZ( 1. * mm );
522  solidColl_helmet->SetInnerRadiusPlusZ( 1.25 * mm );
523  break;
524  }
525  // Inform the run manager about change in the geometry
527  }
528 }
529 
531 {
532  if (size != helmetSize) // Only if the size changes
533  {
534  // Allow only valid numbers
535  switch( size )
536  {
537  case 18:
538  case 14:
539  case 8:
540  case 4:
541  helmetSize = size;
542  G4cout << "Helmet size set to " << helmetSize << std::endl;
543  UpdateHelmet();
544  break;
545  default:
546  G4Exception("GammaKnifeDetectorConstruction::SetHelmetSize()", "GammaKnife001", FatalException, "Error: Invalid helmet size.");
547  return;
548  }
549  }
550 }
551 
552 
553