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