Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/electromagnetic/TestEm9/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 /// \file electromagnetic/TestEm9/src/DetectorConstruction.cc
 27 /// \brief Implementation of the DetectorConstruction class
 28 //
 29 //
 30 //
 31 /////////////////////////////////////////////////////////////////////////
 32 //
 33 // TestEm9: Crystal calorimeter
 34 //
 35 // Created: 31.01.03 V.Ivanchenko
 36 //
 37 // Modified:
 38 //
 39 ////////////////////////////////////////////////////////////////////////
 40 //
 41 
 42 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 43 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 44 
 45 #include "DetectorConstruction.hh"
 46 
 47 #include "DetectorMessenger.hh"
 48 
 49 #include "G4Box.hh"
 50 #include "G4Colour.hh"
 51 #include "G4GeometryManager.hh"
 52 #include "G4LogicalVolume.hh"
 53 #include "G4LogicalVolumeStore.hh"
 54 #include "G4NistManager.hh"
 55 #include "G4PVPlacement.hh"
 56 #include "G4PVReplica.hh"
 57 #include "G4PhysicalVolumeStore.hh"
 58 #include "G4ProductionCuts.hh"
 59 #include "G4Region.hh"
 60 #include "G4RegionStore.hh"
 61 #include "G4RunManager.hh"
 62 #include "G4SolidStore.hh"
 63 #include "G4SystemOfUnits.hh"
 64 #include "G4TransportationManager.hh"
 65 #include "G4UnitsTable.hh"
 66 #include "G4VisAttributes.hh"
 67 #include "G4ios.hh"
 68 
 69 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 70 
 71 DetectorConstruction::DetectorConstruction()
 72   : G4VUserDetectorConstruction(),
 73     fCalMaterial(0),
 74     fVertMaterial(0),
 75     fAbsMaterial(0),
 76     fWorldMaterial(0),
 77     fYorkMaterial(0),
 78     fLogicWorld(0),
 79     fLogicCal(0),
 80     fLogicA1(0),
 81     fLogicA2(0),
 82     fLogicA3(0),
 83     fLogicA4(0),
 84     fVertexRegion(0),
 85     fMuonRegion(0),
 86     fVertexDetectorCuts(0),
 87     fMuonDetectorCuts(0),
 88     fDetectorMessenger(0)
 89 {
 90   fDetectorMessenger = new DetectorMessenger(this);
 91 
 92   fEcalLength = 36. * cm;
 93   fEcalWidth = 6. * cm;
 94   fVertexLength = 3. * cm;
 95   fPadLength = 0.1 * mm;
 96   fPadWidth = 0.02 * mm;
 97   fAbsLength = 2. * mm;
 98   fWorldZ = 0.0;
 99   fLogicWorld = 0;
100   fLogicCal = 0;
101   fLogicA1 = 0;
102   fLogicA2 = 0;
103   fLogicA3 = 0;
104   fLogicA4 = 0;
105   fVertexRegion = 0;
106   fMuonRegion = 0;
107 
108   DefineMaterials();
109   fVertexDetectorCuts = new G4ProductionCuts();
110   fMuonDetectorCuts = new G4ProductionCuts();
111 }
112 
113 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
114 
115 DetectorConstruction::~DetectorConstruction()
116 {
117   delete fDetectorMessenger;
118   delete fVertexDetectorCuts;
119   delete fMuonDetectorCuts;
120 }
121 
122 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
123 
124 G4VPhysicalVolume* DetectorConstruction::Construct()
125 {
126   return ConstructVolumes();
127 }
128 
129 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
130 
131 void DetectorConstruction::DefineMaterials()
132 {
133   // Default materials
134 
135   G4NistManager* man = G4NistManager::Instance();
136   //  man->SetVerbose(1);
137   fWorldMaterial = man->FindOrBuildMaterial("G4_AIR");
138   fAbsMaterial = man->FindOrBuildMaterial("G4_Al");
139   fVertMaterial = man->FindOrBuildMaterial("G4_Si");
140   fYorkMaterial = man->FindOrBuildMaterial("G4_Fe");
141   fCalMaterial = man->FindOrBuildMaterial("G4_CESIUM_IODIDE");
142 }
143 
144 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
145 
146 G4VPhysicalVolume* DetectorConstruction::ConstructVolumes()
147 {
148   // Cleanup old geometry
149 
150   G4GeometryManager::GetInstance()->OpenGeometry();
151 
152   if (G4NistManager::Instance()->GetVerbose() > 0)
153     G4cout << *(G4Material::GetMaterialTable()) << G4endl;
154 
155   if (fVertexRegion) {
156     delete fVertexRegion;
157     delete fMuonRegion;
158   }
159   fVertexRegion = new G4Region("VertexDetector");
160   fVertexRegion->SetProductionCuts(fVertexDetectorCuts);
161 
162   fMuonRegion = new G4Region("MuonDetector");
163   fMuonRegion->SetProductionCuts(fMuonDetectorCuts);
164 
165   G4SolidStore::GetInstance()->Clean();
166   G4LogicalVolumeStore::GetInstance()->Clean();
167   G4PhysicalVolumeStore::GetInstance()->Clean();
168 
169   if (fVertexLength < fPadLength * 5.0) fVertexLength = fPadLength * 5.0;
170   G4double gap = 0.01 * mm;
171   G4double biggap = 2. * cm;
172   G4double york = 10. * cm;
173 
174   fWorldZ = 2. * fVertexLength + 3. * fAbsLength + 0.5 * (fEcalLength + york) + biggap * 2.;
175 
176   G4double worldX = fEcalWidth * 3.0;
177   G4double vertexZ = -fWorldZ + fVertexLength * 2.0 + fAbsLength + biggap;
178   G4double absZ2 = -fWorldZ + fVertexLength * 4.0 + fAbsLength * 3.5 + biggap;
179   G4double ecalZ =
180     -fWorldZ + fVertexLength * 4.0 + fAbsLength * 4.0 + fEcalLength * 0.5 + 2. * biggap;
181   G4double yorkZ =
182     -fWorldZ + fVertexLength * 4.0 + fAbsLength * 5.0 + fEcalLength + york * 0.5 + 3. * biggap;
183 
184   //
185   // World
186   //
187   G4Box* solidW = new G4Box("World", worldX, worldX, fWorldZ);
188   fLogicWorld = new G4LogicalVolume(solidW, fWorldMaterial, "World");
189   G4VPhysicalVolume* world =
190     new G4PVPlacement(0, G4ThreeVector(), "World", fLogicWorld, 0, false, 0);
191 
192   //
193   // Ecal
194   //
195   G4Box* solidE = new G4Box("VolE", worldX, worldX, fEcalLength * 0.5 + gap);
196   G4LogicalVolume* logicECal = new G4LogicalVolume(solidE, fWorldMaterial, "VolE");
197   G4VPhysicalVolume* physE =
198     new G4PVPlacement(0, G4ThreeVector(0., 0., ecalZ), "VolE", logicECal, world, false, 0);
199 
200   G4Box* solidC = new G4Box("Ecal", fEcalWidth * 0.5, fEcalWidth * 0.5, fEcalLength * 0.5);
201   fLogicCal = new G4LogicalVolume(solidC, fCalMaterial, "Ecal");
202 
203   G4cout << "Ecal is " << G4BestUnit(fEcalLength, "Length") << " of " << fCalMaterial->GetName()
204          << G4endl;
205 
206   // Crystals
207 
208   G4double x0 = -(fEcalWidth + gap) * 2.0;
209   G4double y = x0;
210   G4double x;
211   G4int k = 0;
212   G4int i, j;
213 
214   for (i = 0; i < 5; i++) {
215     x = x0;
216     for (j = 0; j < 5; j++) {
217       new G4PVPlacement(0, G4ThreeVector(x, y, 0.), "Ecal", fLogicCal, physE, false, k);
218       k++;
219       x += fEcalWidth + gap;
220     }
221     y += fEcalWidth + gap;
222   }
223 
224   // Absorber
225 
226   G4Box* solidA = new G4Box("Abso", worldX, worldX, fAbsLength * 0.5);
227   fLogicA2 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs2");
228   new G4PVPlacement(0, G4ThreeVector(0., 0., absZ2), "Abs2", fLogicA2, world, false, 0);
229 
230   G4cout << "Absorber is " << G4BestUnit(fAbsLength, "Length") << " of " << fAbsMaterial->GetName()
231          << G4endl;
232 
233   // York
234 
235   G4Box* solidYV = new G4Box("VolY", worldX, worldX, york * 0.5 + fAbsLength);
236   G4LogicalVolume* logicYV = new G4LogicalVolume(solidYV, fYorkMaterial, "VolY");
237   G4VPhysicalVolume* physYV =
238     new G4PVPlacement(0, G4ThreeVector(0., 0., yorkZ), "VolY", logicYV, world, false, 0);
239 
240   G4Box* solidY = new G4Box("York", worldX, worldX, york * 0.5);
241   G4LogicalVolume* logicY = new G4LogicalVolume(solidY, fYorkMaterial, "York");
242   new G4PVPlacement(0, G4ThreeVector(), "York", logicY, physYV, false, 0);
243 
244   fLogicA3 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs3");
245   fLogicA4 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs4");
246 
247   new G4PVPlacement(0, G4ThreeVector(0., 0., -(york + fAbsLength) * 0.5), "Abs3", fLogicA3, physYV,
248                     false, 0);
249   new G4PVPlacement(0, G4ThreeVector(0., 0., (york + fAbsLength) * 0.5), "Abs4", fLogicA4, physYV,
250                     false, 0);
251 
252   // Vertex volume
253   G4Box* solidVV = new G4Box("VolV", worldX, worldX, fVertexLength * 2. + fAbsLength + gap);
254   G4LogicalVolume* logicVV = new G4LogicalVolume(solidVV, fWorldMaterial, "VolV");
255   G4VPhysicalVolume* physVV =
256     new G4PVPlacement(0, G4ThreeVector(0., 0., vertexZ), "VolV", logicVV, world, false, 0);
257 
258   // Absorber
259   fLogicA1 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs1");
260   new G4PVPlacement(0, G4ThreeVector(0., 0., fVertexLength * 2. - fAbsLength * 0.5), "Abs1",
261                     fLogicA1, physVV, false, 0);
262 
263   // Vertex
264   G4double vertWidth = fEcalWidth / 5.;
265   G4int npads = (G4int)(vertWidth / fPadWidth);
266   // G4cout << " vertWidth= " << vertWidth << " padWidth= " << padWidth
267   //          << " npads= " << npads << G4endl;
268   //  insure beam to hit a middle of central pad
269   npads = (npads / 2) * 2 + 1;
270   x0 = -0.5 * (fPadWidth + vertWidth);
271   G4double x1 = 0.5 * vertWidth + gap;
272   G4double z = -(fVertexLength + fAbsLength);
273 
274   G4Box* solidVD = new G4Box("VertDet", x1, fEcalWidth * 0.5 + gap, fPadLength * 0.5);
275   G4LogicalVolume* logicVD = new G4LogicalVolume(solidVD, fVertMaterial, "VertDet");
276   logicVD->SetSolid(solidVD);
277 
278   G4Box* solidV = new G4Box("Vert", fPadWidth * 0.5, fEcalWidth * 0.5, fPadLength * 0.5);
279   G4LogicalVolume* logicV = new G4LogicalVolume(solidV, fVertMaterial, "Vert");
280 
281   for (i = 0; i < 3; i++) {
282     new G4PVPlacement(0, G4ThreeVector(0., 0., z), "VertDet", logicVD, physVV, false, i);
283     z += fVertexLength;
284   }
285   x = x0;
286 
287   for (j = 0; j < npads; j++) {
288     new G4PVPlacement(0, G4ThreeVector(x, 0., 0.), logicV, "Vert", logicVD, false, k);
289     x += fPadWidth;
290   }
291 
292   G4cout << "Vertex is " << G4BestUnit(fVertexLength, "Length") << " of 3 layers of Si of "
293          << G4BestUnit(fPadLength, "Length") << " npads= " << npads << G4endl;
294 
295   // Define region for the vertex detector
296   fVertexRegion->AddRootLogicalVolume(logicVV);
297   fVertexRegion->AddRootLogicalVolume(fLogicA3);
298 
299   // Define region for the muon detector
300   fMuonRegion->AddRootLogicalVolume(logicYV);
301 
302   // color regions
303   logicVV->SetVisAttributes(G4VisAttributes::GetInvisible());
304   logicV->SetVisAttributes(G4VisAttributes::GetInvisible());
305   logicECal->SetVisAttributes(G4VisAttributes::GetInvisible());
306   logicYV->SetVisAttributes(G4VisAttributes::GetInvisible());
307 
308   G4VisAttributes* regWcolor = new G4VisAttributes(G4Colour(0.3, 0.3, 0.3));
309   fLogicWorld->SetVisAttributes(regWcolor);
310 
311   G4VisAttributes* regVcolor = new G4VisAttributes(G4Colour(0., 0.3, 0.7));
312   logicVD->SetVisAttributes(regVcolor);
313 
314   G4VisAttributes* regCcolor = new G4VisAttributes(G4Colour(0., 0.7, 0.3));
315   fLogicCal->SetVisAttributes(regCcolor);
316 
317   G4VisAttributes* regAcolor = new G4VisAttributes(G4Colour(1., 0.5, 0.5));
318   fLogicA1->SetVisAttributes(regAcolor);
319   fLogicA2->SetVisAttributes(regAcolor);
320   fLogicA3->SetVisAttributes(regAcolor);
321   fLogicA4->SetVisAttributes(regAcolor);
322 
323   G4VisAttributes* regMcolor = new G4VisAttributes(G4Colour(1., 1., 0.));
324   logicY->SetVisAttributes(regMcolor);
325 
326   // always return world
327   G4cout << "### New geometry is constructed" << G4endl;
328 
329   return world;
330 }
331 
332 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
333 
334 void DetectorConstruction::SetEcalMaterial(const G4String& mat)
335 {
336   // search the material by its name
337   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(mat);
338   if (pttoMaterial && pttoMaterial != fCalMaterial) {
339     fCalMaterial = pttoMaterial;
340     if (fLogicCal) {
341       fLogicCal->SetMaterial(fCalMaterial);
342       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
343     }
344   }
345 }
346 
347 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
348 
349 void DetectorConstruction::SetAbsMaterial(const G4String& mat)
350 {
351   // search the material by its name
352   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(mat);
353   if (pttoMaterial && pttoMaterial != fAbsMaterial) {
354     fAbsMaterial = pttoMaterial;
355     if (fLogicA1) {
356       fLogicA1->SetMaterial(fAbsMaterial);
357       fLogicA2->SetMaterial(fAbsMaterial);
358       fLogicA3->SetMaterial(fAbsMaterial);
359       fLogicA4->SetMaterial(fAbsMaterial);
360       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
361     }
362   }
363 }
364 
365 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
366 
367 void DetectorConstruction::UpdateGeometry()
368 {
369   G4RunManager::GetRunManager()->PhysicsHasBeenModified();
370   G4RunManager::GetRunManager()->DefineWorldVolume(ConstructVolumes());
371 }
372 
373 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
374 
375 void DetectorConstruction::SetEcalLength(G4double val)
376 {
377   if (val > 0.0) {
378     fEcalLength = val;
379     G4RunManager::GetRunManager()->GeometryHasBeenModified();
380   }
381 }
382 
383 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
384 
385 void DetectorConstruction::SetEcalWidth(G4double val)
386 {
387   if (val > 0.0) {
388     fEcalWidth = val;
389     G4RunManager::GetRunManager()->GeometryHasBeenModified();
390   }
391 }
392 
393 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
394 
395 void DetectorConstruction::SetVertexLength(G4double val)
396 {
397   if (val > 0.0) {
398     fVertexLength = val;
399     G4RunManager::GetRunManager()->GeometryHasBeenModified();
400   }
401 }
402 
403 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
404 
405 void DetectorConstruction::SetPadLength(G4double val)
406 {
407   if (val > 0.0) {
408     fPadLength = val;
409     G4RunManager::GetRunManager()->GeometryHasBeenModified();
410   }
411 }
412 
413 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
414 
415 void DetectorConstruction::SetPadWidth(G4double val)
416 {
417   if (val > 0.0) {
418     fPadWidth = val;
419     G4RunManager::GetRunManager()->GeometryHasBeenModified();
420   }
421 }
422 
423 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
424 
425 void DetectorConstruction::SetAbsLength(G4double val)
426 {
427   if (val > 0.0) {
428     fAbsLength = val;
429     G4RunManager::GetRunManager()->GeometryHasBeenModified();
430   }
431 }
432 
433 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
434