source: trunk/examples/extended/medical/GammaTherapy/src/DetectorConstruction.cc

Last change on this file was 807, checked in by garnier, 16 years ago

update

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