Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
examples/extended/medical/GammaTherapy/src/DetectorConstruction.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 // $Id: DetectorConstruction.cc 67994 2013-03-13 11:05:39Z gcosmo $
27 //
28 /// \file medical/GammaTherapy/src/DetectorConstruction.cc
29 /// \brief Implementation of the DetectorConstruction class
30 //
31 //
32 // -------------------------------------------------------------
33 // GEANT4 ibrem test
34 //
35 // Authors: V.Grichine, V.Ivanchenko
36 //
37 // Modified:
38 //
39 // 18-02-03 V.Ivanchenko create
40 //
41 // -------------------------------------------------------------
42 
43 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
44 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
45 
46 #include "DetectorConstruction.hh"
47 #include "DetectorMessenger.hh"
48 #include "PhantomSD.hh"
49 #include "TargetSD.hh"
50 #include "CheckVolumeSD.hh"
51 #include "Histo.hh"
52 
53 #include "G4Box.hh"
54 #include "G4Tubs.hh"
55 #include "G4LogicalVolume.hh"
56 #include "G4VPhysicalVolume.hh"
57 #include "G4PVPlacement.hh"
58 #include "G4Material.hh"
59 #include "G4SDManager.hh"
60 #include "PhantomSD.hh"
61 #include "G4NistManager.hh"
62 
63 #include "G4PhysicalVolumeStore.hh"
64 #include "G4LogicalVolumeStore.hh"
65 #include "G4SolidStore.hh"
66 #include "G4RunManager.hh"
67 
68 #include "G4VisAttributes.hh"
69 #include "G4Colour.hh"
70 
71 #include "globals.hh"
72 #include "G4PhysicalConstants.hh"
73 #include "G4SystemOfUnits.hh"
74 #include "G4ios.hh"
75 
76 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
77 
79 {
80  fLogicTarget1 = 0;
81  fLogicTarget2 = 0;
82 
83  fMessenger = new DetectorMessenger(this);
84 
85  fCheckSD = new CheckVolumeSD("checkSD");
86  (G4SDManager::GetSDMpointer())->AddNewDetector( fCheckSD );
87  fPhantomSD = new PhantomSD("phantomSD");
88  (G4SDManager::GetSDMpointer())->AddNewDetector( fPhantomSD );
89  fTargetSD = new TargetSD("targetSD");
90  (G4SDManager::GetSDMpointer())->AddNewDetector( fTargetSD );
91 
92  fDistanceVacuumTarget = 30.*mm,
93 
94  fDelta = 0.001*mm;
95 
96  fTargetRadius = 100.*mm;
97  fTarget1Z = 9.*mm;
98  fTarget2Z = 6.*mm;
99 
100  fGasVolumeRadius = 210.*mm;
101  fGasVolumeZ = 690.*mm;
102  fMylarVolumeZ = 0.02*mm;
103 
104  fCheckVolumeZ = 0.1*mm;
105  fCheckShiftZ = 200.*mm;
106 
107  fAbsorberRadius = 200.*mm;
108  fPhantomRadius = 300.*mm;
109  fPhantomZ = 300.*mm;
110 
111  fAirZ = 210.*mm;
112  fAbsorberShiftZ = 70.*mm;
113  fWindowZ = 0.05*mm;
114 
116  //man->SetVerbose(1);
117 
118  fTarget1Material = man->FindOrBuildMaterial("G4_Be");
119  fWindowMaterial = fTarget1Material;
120  fTarget2Material = man->FindOrBuildMaterial("G4_W");
121  fLightMaterial = man->FindOrBuildMaterial("G4_He");
122  fAbsorberMaterial= man->FindOrBuildMaterial("G4_WATER");
123  fWorldMaterial = man->FindOrBuildMaterial("G4_AIR");
124  fMylar = man->FindOrBuildMaterial("G4_MYLAR");
125 
127 }
128 
129 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
130 
132 {}
133 
134 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
135 
136 void DetectorConstruction::InitialiseGeometryParameters()
137 {
138  // Volumee sizes
139 
140  G4double factor = 1.2;
141 
142  fWorldXY = factor*std::max(fPhantomRadius,fGasVolumeRadius);
143  G4double nz = (G4int)((Histo::GetPointer())->GetNumberDivZ());
144  fAbsorberZ = fPhantomZ/nz;
145  fGasVolumeZ = 1000.*mm - fAbsorberShiftZ - fAirZ - fTarget1Z - fTarget2Z;
146 
147  G4double ztot = fGasVolumeZ + fAirZ + fPhantomZ + fDistanceVacuumTarget;
148  fTargetVolumeZ = fDistanceVacuumTarget + fTarget2Z + fTarget1Z + fDelta;
149  fWorldZ = factor*ztot*0.5;
150 
151  if(fCheckShiftZ < fDelta) { fCheckShiftZ = fDelta; }
152  if(fCheckShiftZ > fAirZ - fCheckVolumeZ -fDelta) {
153  fCheckShiftZ = fAirZ - fCheckVolumeZ -fDelta;
154  }
155 
156  // Z position of volumes from upstream to downstream
157 
158  fWindowPosZ = -(ztot + fWindowZ)*0.5;
159  fGeneratorPosZ = fWindowPosZ - 0.5*fWindowZ - fDelta;
160 
161  fTargetVolumePosZ= -0.5*(ztot - fTargetVolumeZ);
162  fTarget1PosZ = -0.5*(fTargetVolumeZ - fTarget1Z) + fDistanceVacuumTarget;
163  fTarget2PosZ = fTarget1PosZ + 0.5*(fTarget2Z + fTarget1Z);
164 
165  fGasVolumePosZ = fTargetVolumePosZ + 0.5*(fTargetVolumeZ + fGasVolumeZ);
166  fCheckVolumePosZ = fGasVolumePosZ + 0.5*(fGasVolumeZ + fCheckVolumeZ)
167  + fCheckShiftZ;
168  fMylarPosZ = fGasVolumePosZ + 0.5*(fGasVolumeZ + fMylarVolumeZ) + fDelta;
169 
170  fPhantomPosZ = fGasVolumePosZ + 0.5*(fGasVolumeZ + fPhantomZ) + fAirZ;
171  fAbsorberPosZ = fAbsorberShiftZ - 0.5*(fPhantomZ - fAbsorberZ);
172  (Histo::GetPointer())->SetAbsorberZ(fPhantomZ);
173  (Histo::GetPointer())->SetAbsorberR(fAbsorberRadius);
174  (Histo::GetPointer())->SetScoreZ(fAbsorberShiftZ);
175  G4double shiftZPh = fPhantomPosZ-0.5*fPhantomZ;
176  fPhantomSD->SetShiftZ(shiftZPh);
177 
178  G4cout << "===================================================" << G4endl;
179  G4cout << "# GammaTherapy Geometry #" << G4endl;
180  G4cout << "===================================================" << G4endl;
181  G4cout << " World width= " << fWorldZ/mm << " mm " << G4endl;
182  G4cout << " Window width= " << fWindowZ/mm << " mm position = "
183  << fWindowPosZ/mm << " mm:" << G4endl;
184  G4cout << " TargetV width= " << fTargetVolumeZ/mm << " mm position = "
185  << fTargetVolumePosZ/mm << " mm:" << G4endl;
186  G4cout << " Target1 width= " << fTarget1Z/mm << " mm position = "
187  << fTarget1PosZ/mm << " mm:" << G4endl;
188  G4cout << " Target2 width= " << fTarget2Z/mm << " mm position = "
189  << fTarget2PosZ/mm << " mm:" << G4endl;
190  G4cout << " Gas width= " << fGasVolumeZ/mm << " mm position = "
191  << fGasVolumePosZ/mm << " mm:" << G4endl;
192  G4cout << " Mylar width= " << fMylarVolumeZ/mm << " mm position = "
193  << fMylarPosZ/mm << " mm:" << G4endl;
194  G4cout << " Check width= " << fCheckVolumeZ/mm << " mm position = "
195  << fCheckVolumePosZ/mm << " mm:" << G4endl;
196  G4cout << " Air width= " << fAirZ/mm << " mm " << G4endl;
197  G4cout << " Phantom width= " << fPhantomZ/mm << " mm position = "
198  << fPhantomPosZ/mm << " mm:" << G4endl;
199  G4cout << " Absorb width= " << fAbsorberZ/mm << " mm position = "
200  << fAbsorberPosZ/mm << " mm:" << G4endl;
201  G4cout << " Absorb shift= " << shiftZPh/mm << " mm " << G4endl;
202  G4cout << " Target1 " << fTarget1Material->GetName() << G4endl;
203  G4cout << " Target2 " << fTarget2Material->GetName() << G4endl;
204  G4cout << " Phantom " << fAbsorberMaterial->GetName() << G4endl;
205  G4cout << "===================================================" << G4endl;
206 }
207 
208 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
209 
211 {
212  // Cleanup old geometry
216 
217  //
218  InitialiseGeometryParameters();
219 
220  //
221  // World
222  //
223  G4VPhysicalVolume* pv;
224 
225  G4Box* solidWorld = new G4Box("World",fWorldXY,fWorldXY,fWorldZ);
226  G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld,
227  fWorldMaterial,"World");
228  G4VPhysicalVolume* physWorld = new G4PVPlacement(0,G4ThreeVector(),"World",
229  logicWorld,0,false,0);
230 
231  // Be Vacuum window
232  G4Tubs* solidWin = new G4Tubs("Window",0.,fTargetRadius*0.25,0.5*fWindowZ,
233  0.,twopi);
234  G4LogicalVolume* logicWin = new G4LogicalVolume(solidWin,
235  fWindowMaterial,"Window");
236  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,fWindowPosZ),"Window",logicWin,
237  physWorld,false,0);
238 
239  // Target Volume
240  G4Tubs* solidTGVolume = new G4Tubs("TargetVolume",0.,fTargetRadius,
241  0.5*fTargetVolumeZ,0.,twopi);
242  G4LogicalVolume* logicTGVolume = new G4LogicalVolume(solidTGVolume,
243  fLightMaterial,
244  "TargetVolume");
245  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,fTargetVolumePosZ),
246  logicTGVolume,"TargetVolume",
247  logicWorld,false,0);
248 
249  // Target 1
250  G4Tubs* solidTarget1 = new G4Tubs("Target1",0.,fTargetRadius*0.5,
251  0.5*fTarget1Z,0.,twopi);
252  fLogicTarget1 = new G4LogicalVolume(solidTarget1,fTarget1Material,"Target1");
253  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,fTarget1PosZ),
254  fLogicTarget1,"Target1",
255  logicTGVolume,false,0);
256  (Histo::GetPointer())->SetTarget1(pv);
257  fLogicTarget1->SetSensitiveDetector(fTargetSD);
258 
259  // Target 2 (for combined targets)
260  G4Tubs* solidTarget2 = new G4Tubs("Target2",0.,fTargetRadius*0.5,
261  0.5*fTarget2Z,0.,twopi);
262  fLogicTarget2 = new G4LogicalVolume(solidTarget2,fTarget2Material,"Target2");
263  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,fTarget2PosZ),
264  fLogicTarget2,"Target2",
265  logicTGVolume,false,0);
266 
267  (Histo::GetPointer())->SetTarget2(pv);
268  fLogicTarget2->SetSensitiveDetector(fTargetSD);
269 
270  // Gas Volume
271  G4Tubs* solidGasVolume = new G4Tubs("GasVolume",0.,fGasVolumeRadius,
272  0.5*fGasVolumeZ,0.,twopi);
273  G4LogicalVolume* logicGasVolume = new G4LogicalVolume(solidGasVolume,
274  fLightMaterial,
275  "GasVolume");
276  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,fGasVolumePosZ),
277  "GasVolume",logicGasVolume,
278  physWorld,false,0);
279  (Histo::GetPointer())->SetGasVolume(pv);
280 
281  // Mylar window
282  G4Tubs* sMylarVolume = new G4Tubs("Mylar",0.,fGasVolumeRadius,
283  0.5*fMylarVolumeZ,0.,twopi);
284  G4LogicalVolume* lMylarVolume = new G4LogicalVolume(sMylarVolume,
285  fMylar,"Mylar");
286  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,fMylarPosZ),"Mylar",lMylarVolume,
287  physWorld,false,0);
288 
289  // Check Volume
290  G4Tubs* solidCheckVolume = new G4Tubs("CheckVolume",0.,fGasVolumeRadius,
291  0.5*fCheckVolumeZ,0.,twopi);
292  G4LogicalVolume* logicCheckVolume = new G4LogicalVolume(solidCheckVolume,
293  fWorldMaterial,
294  "CheckVolume");
295  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,fCheckVolumePosZ),
296  "CheckVolume",logicCheckVolume,
297  physWorld,false,0);
298  (Histo::GetPointer())->SetCheckVolume(pv);
299  logicCheckVolume->SetSensitiveDetector(fCheckSD);
300 
301  // Phantom
302  G4Box* solidPhantom = new G4Box("Phantom",fPhantomRadius,fPhantomRadius,
303  0.5*fPhantomZ);
304  G4LogicalVolume* logicPhantom = new G4LogicalVolume(solidPhantom,
305  fAbsorberMaterial,
306  "Phantom");
307  G4VPhysicalVolume* physPhantom =
308  new G4PVPlacement(0, G4ThreeVector(0.,0.,fPhantomPosZ),
309  "Phantom",logicPhantom,
310  physWorld,false,0);
311 
312  G4Tubs* solidPh = new G4Tubs("PhantomSD",0.,fAbsorberRadius,
313  0.5*fPhantomZ,0.,twopi);
314  G4LogicalVolume* logicPh = new G4LogicalVolume(solidPh,
315  fAbsorberMaterial,"PhantomSD");
316  G4VPhysicalVolume* physPh = new G4PVPlacement(0,G4ThreeVector(0.,0.,0.),
317  "Phantom",logicPh,
318  physPhantom,false,0);
319  G4cout << "Phantom R= " << fAbsorberRadius << " dz= " << 0.5*fPhantomZ
320  << G4endl;
321 
322  // Sensitive Absorber
323  G4double absWidth = 0.5*fAbsorberZ;
324  G4Tubs* solidAbsorber = new G4Tubs("Absorber",0.,fAbsorberRadius,absWidth,
325  0.,twopi);
326  G4LogicalVolume* logicAbsorber = new G4LogicalVolume(solidAbsorber,
327  fAbsorberMaterial,
328  "Absorber");
329  G4cout << "Absorber R= " << fAbsorberRadius << " dz= " << absWidth
330  << " posZ= " << fAbsorberPosZ<< G4endl;
331 
332  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,fAbsorberPosZ),"Absorber",
333  logicAbsorber,physPh,false,0);
334  (Histo::GetPointer())->SetPhantom(physPh);
335  G4int numR = (Histo::GetPointer())->GetNumberDivR();
336  G4double stepR = fAbsorberRadius/(G4double)numR;
337 
338  G4double r1 = 0.0;
339  G4double r2 = 0.0;
340  G4Tubs* solidRing;
341  G4LogicalVolume* logicRing;
342 
343  for(G4int k=0; k<numR; k++) {
344  r2 = r1 + stepR;
345  if(k == numR-1) r2 = fAbsorberRadius;
346  // G4cout << "New ring r1= " << r1 << " r2= " << r2
347  // << " dz= " << absWidth << G4endl;
348  solidRing = new G4Tubs("Ring",r1,r2,absWidth,0.,twopi);
349  logicRing = new G4LogicalVolume(solidRing,fAbsorberMaterial,"Ring");
350  logicRing->SetSensitiveDetector(fPhantomSD);
352  pv = new G4PVPlacement(0,G4ThreeVector(0.,0.,0.),logicRing,"Ring",
353  logicAbsorber,false,k);
354  r1 = r2;
355  }
356  //
357  // Sensitive Detectors: Absorber
358  //
359  logicPh->SetSensitiveDetector(fPhantomSD);
360  logicAbsorber->SetSensitiveDetector(fPhantomSD);
361  //
362  // Visualization attributes
363  //
364  G4VisAttributes* VisAtt = 0;
365  VisAtt = new G4VisAttributes(G4Colour(1.0,1.0,1.0));
366  VisAtt->SetVisibility(true);
367  logicAbsorber->SetVisAttributes(VisAtt);
368 
369  VisAtt= new G4VisAttributes(G4Colour(1.0,1.0,2.0));
370  VisAtt->SetVisibility(true);
371  logicPhantom->SetVisAttributes(VisAtt);
372 
373  VisAtt= new G4VisAttributes(G4Colour(1.0,0.0,2.0));
374  VisAtt->SetVisibility(true);
375  logicPh->SetVisAttributes(VisAtt);
376 
377  VisAtt= new G4VisAttributes(G4Colour(1.0,1.0,0.0));
378  VisAtt->SetVisibility(true);
379  logicAbsorber->SetVisAttributes(VisAtt);
380 
381  VisAtt= new G4VisAttributes(G4Colour(0.1,1.0,2.0));
382  VisAtt->SetVisibility(true);
383  logicWorld->SetVisAttributes(VisAtt);
384 
385  VisAtt= new G4VisAttributes(G4Colour(1.0,1.0,0.0));
386  VisAtt->SetVisibility(true);
387  logicGasVolume->SetVisAttributes(VisAtt);
388 
389  VisAtt= new G4VisAttributes(G4Colour(0.0,0.5,1.0));
390  VisAtt->SetVisibility(true);
391  fLogicTarget1->SetVisAttributes(VisAtt);
392  fLogicTarget2->SetVisAttributes(VisAtt);
393  logicTGVolume->SetVisAttributes(VisAtt);
394 
395  return physWorld;
396 }
397 
398 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
399 
401 {
402  // search the material by its name
403  G4Material* pttoMaterial =
405  if(!pttoMaterial) {
406  G4cout << "Material " << mat << " is not found out!" << G4endl;
407  } else if (pttoMaterial != fTarget1Material) {
408  G4cout << "New target1 material " << mat << G4endl;
409  if(fLogicTarget1) { fLogicTarget1->SetMaterial(fTarget1Material); }
411  }
412 }
413 
414 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
415 
417 {
418  // search the material by its name
419  G4Material* pttoMaterial =
421 
422  if(!pttoMaterial) {
423  G4cout << "Material " << mat << " is not found out!" << G4endl;
424  } else if (pttoMaterial != fTarget2Material) {
425  fTarget2Material = pttoMaterial;
426  G4cout << "New target2 material " << mat << G4endl;
427  if(fLogicTarget2) { fLogicTarget2->SetMaterial(fTarget2Material); }
429  }
430 }
431 
432 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
433 
435 {
437 }
438 
439 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void GeometryHasBeenModified(G4bool prop=true)
G4Material * FindOrBuildMaterial(const G4String &name, G4bool isotopes=true, G4bool warning=false)
void SetShiftZ(G4double val)
Definition: PhantomSD.hh:69
static Histo * GetPointer()
CLHEP::Hep3Vector G4ThreeVector
Definition: G4Box.hh:63
const G4String & GetName() const
Definition: G4Material.hh:176
void SetVisibility(G4bool)
Definition: G4Tubs.hh:84
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:564
static void Clean()
Definition: G4SolidStore.cc:79
int G4int
Definition: G4Types.hh:78
static G4NistManager * Instance()
static G4PhysicalVolumeStore * GetInstance()
G4GLOB_DLL std::ostream G4cout
void PhysicsHasBeenModified()
static G4LogicalVolumeStore * GetInstance()
static G4SolidStore * GetInstance()
static G4RunManager * GetRunManager()
Definition: G4RunManager.cc:74
Definition of the PhantomSD class.
T max(const T t1, const T t2)
brief Return the largest of the two arguments
static G4SDManager * GetSDMpointer()
Definition: G4SDManager.cc:40
static const G4VisAttributes Invisible
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
void SetMaterial(G4Material *pMaterial)
void SetVisAttributes(const G4VisAttributes *pVA)
void SetSensitiveDetector(G4VSensitiveDetector *pSDetector)