Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/basic/B3/B3a/src/DetectorConstruction.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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