Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
B3DetectorConstruction.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$
27 //
30 
32 
33 #include "G4NistManager.hh"
34 #include "G4Box.hh"
35 #include "G4Tubs.hh"
36 #include "G4LogicalVolume.hh"
37 #include "G4PVPlacement.hh"
38 #include "G4RotationMatrix.hh"
39 #include "G4Transform3D.hh"
40 #include "G4SDManager.hh"
42 #include "G4VPrimitiveScorer.hh"
43 #include "G4PSEnergyDeposit.hh"
44 #include "G4PSDoseDeposit.hh"
45 #include "G4VisAttributes.hh"
46 #include "G4PhysicalConstants.hh"
47 #include "G4SystemOfUnits.hh"
48 
49 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
50 
53  fLogicCryst(0),fLogicPatient(0),
54  fCheckOverlaps(true)
55 {
56  DefineMaterials();
57 }
58 
59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
60 
62 { }
63 
64 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
65 
66 void B3DetectorConstruction::DefineMaterials()
67 {
69 
70  G4bool isotopes = false;
71 
72  G4Element* O = man->FindOrBuildElement("O" , isotopes);
73  G4Element* Si = man->FindOrBuildElement("Si", isotopes);
74  G4Element* Lu = man->FindOrBuildElement("Lu", isotopes);
75 
76  G4Material* LSO = new G4Material("Lu2SiO5", 7.4*g/cm3, 3);
77  LSO->AddElement(Lu, 2);
78  LSO->AddElement(Si, 1);
79  LSO->AddElement(O , 5);
80 }
81 
82 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
83 
85 {
86  // Gamma detector Parameters
87  //
88  G4double cryst_dX = 6*cm, cryst_dY = 6*cm, cryst_dZ = 3*cm;
89  G4int nb_cryst = 32;
90  G4int nb_rings = 9;
91  //
92  G4double dPhi = twopi/nb_cryst, half_dPhi = 0.5*dPhi;
93  G4double cosdPhi = std::cos(half_dPhi);
94  G4double tandPhi = std::tan(half_dPhi);
95  //
96  G4double ring_R1 = 0.5*cryst_dY/tandPhi;
97  G4double ring_R2 = (ring_R1+cryst_dZ)/cosdPhi;
98  //
99  G4double detector_dZ = nb_rings*cryst_dX;
100  //
102  G4Material* default_mat = nist->FindOrBuildMaterial("G4_AIR", false);
103  G4Material* cryst_mat = nist->FindOrBuildMaterial("Lu2SiO5");
104 
105  //
106  // World
107  //
108  G4double world_sizeXY = 2.4*ring_R2;
109  G4double world_sizeZ = 1.2*detector_dZ;
110 
111  G4Box* solidWorld =
112  new G4Box("World", //its name
113  0.5*world_sizeXY, 0.5*world_sizeXY, 0.5*world_sizeZ); //its size
114 
115  G4LogicalVolume* logicWorld =
116  new G4LogicalVolume(solidWorld, //its solid
117  default_mat, //its material
118  "World"); //its name
119 
120  G4VPhysicalVolume* physWorld =
121  new G4PVPlacement(0, //no rotation
122  G4ThreeVector(), //at (0,0,0)
123  logicWorld, //its logical volume
124  "World", //its name
125  0, //its mother volume
126  false, //no boolean operation
127  0, //copy number
128  fCheckOverlaps); // checking overlaps
129 
130  //
131  // ring
132  //
133  G4Tubs* solidRing =
134  new G4Tubs("Ring", ring_R1, ring_R2, 0.5*cryst_dX, 0., twopi);
135 
136  G4LogicalVolume* logicRing =
137  new G4LogicalVolume(solidRing, //its solid
138  default_mat, //its material
139  "Ring"); //its name
140 
141  //
142  // define crystal
143  //
144  G4double gap = 0.5*mm; //a gap for wrapping
145  G4double dX = cryst_dX - gap, dY = cryst_dY - gap;
146  G4Box* solidCryst = new G4Box("crystal", dX/2, dY/2, cryst_dZ/2);
147 
148  fLogicCryst =
149  new G4LogicalVolume(solidCryst, //its solid
150  cryst_mat, //its material
151  "crystal"); //its name
152 
153  // place crystals within a ring
154  //
155  for (G4int icrys = 0; icrys < nb_cryst ; icrys++) {
156  G4double phi = icrys*dPhi;
158  rotm.rotateY(90*deg);
159  rotm.rotateZ(phi);
160  G4ThreeVector uz = G4ThreeVector(std::cos(phi), std::sin(phi),0.);
161  G4ThreeVector position = (ring_R1+0.5*cryst_dZ)*uz;
162  G4Transform3D transform = G4Transform3D(rotm,position);
163 
164  new G4PVPlacement(transform, //rotation,position
165  fLogicCryst, //its logical volume
166  "crystal", //its name
167  logicRing, //its mother volume
168  false, //no boolean operation
169  icrys, //copy number
170  fCheckOverlaps); // checking overlaps
171  }
172 
173  //
174  // full detector
175  //
176  G4Tubs* solidDetector =
177  new G4Tubs("Detector", ring_R1, ring_R2, 0.5*detector_dZ, 0., twopi);
178 
179  G4LogicalVolume* logicDetector =
180  new G4LogicalVolume(solidDetector, //its solid
181  default_mat, //its material
182  "Detector"); //its name
183 
184  //
185  // place rings within detector
186  //
187  G4double OG = -0.5*(detector_dZ + cryst_dX);
188  for (G4int iring = 0; iring < nb_rings ; iring++) {
189  OG += cryst_dX;
190  new G4PVPlacement(0, //no rotation
191  G4ThreeVector(0,0,OG), //position
192  logicRing, //its logical volume
193  "ring", //its name
194  logicDetector, //its mother volume
195  false, //no boolean operation
196  iring, //copy number
197  fCheckOverlaps); // checking overlaps
198  }
199 
200  //
201  // place detector in world
202  //
203  new G4PVPlacement(0, //no rotation
204  G4ThreeVector(), //at (0,0,0)
205  logicDetector, //its logical volume
206  "Detector", //its name
207  logicWorld, //its mother volume
208  false, //no boolean operation
209  0, //copy number
210  fCheckOverlaps); // checking overlaps
211 
212  //
213  // patient
214  //
215  G4double patient_radius = 8*cm;
216  G4double patient_dZ = 10*cm;
217  G4Material* patient_mat = nist->FindOrBuildMaterial("G4_BRAIN_ICRP", false);
218 
219  G4Tubs* solidPatient =
220  new G4Tubs("Patient", 0., patient_radius, 0.5*patient_dZ, 0., twopi);
221 
222  fLogicPatient =
223  new G4LogicalVolume(solidPatient, //its solid
224  patient_mat, //its material
225  "Patient"); //its name
226 
227  //
228  // place patient in world
229  //
230  new G4PVPlacement(0, //no rotation
231  G4ThreeVector(), //at (0,0,0)
232  fLogicPatient, //its logical volume
233  "Patient", //its name
234  logicWorld, //its mother volume
235  false, //no boolean operation
236  0, //copy number
237  fCheckOverlaps); // checking overlaps
238 
239  // Visualization attributes
240  //
243 
244  // Print materials
246 
247  //
248  CreateScorers();
249 
250  //
251  //always return the physical World
252  //
253  return physWorld;
254 }
255 
256 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
257 
258 void B3DetectorConstruction::CreateScorers()
259 {
261  SDman->SetVerboseLevel(2);
262 
263  // declare crystal as a MultiFunctionalDetector scorer
264  //
266  G4VPrimitiveScorer* primitiv1 = new G4PSEnergyDeposit("edep");
267  cryst->RegisterPrimitive(primitiv1);
268  SDman->AddNewDetector(cryst);
269  fLogicCryst->SetSensitiveDetector(cryst);
270 
271  // declare patient as a MultiFunctionalDetector scorer
272  //
273  G4MultiFunctionalDetector* patient = new G4MultiFunctionalDetector("patient");
274  G4VPrimitiveScorer* primitiv2 = new G4PSDoseDeposit("dose");
275  patient->RegisterPrimitive(primitiv2);
276  SDman->AddNewDetector(patient);
277  fLogicPatient->SetSensitiveDetector(patient);
278 }
279 
280 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......