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 //
26 //
27 // $Id$
28 //
29 //
30 
31 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
32 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
33 
34 #include "DetectorConstruction.hh"
35 #include "DetectorMessenger.hh"
36 
37 #include "G4Material.hh"
38 #include "G4NistManager.hh"
39 
40 #include "G4Box.hh"
41 #include "G4LogicalVolume.hh"
42 #include "G4PVPlacement.hh"
43 #include "G4PVReplica.hh"
44 #include "G4UniformMagField.hh"
45 
46 #include "G4GeometryManager.hh"
47 #include "G4PhysicalVolumeStore.hh"
48 #include "G4LogicalVolumeStore.hh"
49 #include "G4SolidStore.hh"
50 
51 #include "G4VisAttributes.hh"
52 #include "G4Colour.hh"
53 #include "G4PhysicalConstants.hh"
54 #include "G4SystemOfUnits.hh"
55 
56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
57 
59 :AbsorberMaterial(0),GapMaterial(0),defaultMaterial(0),
60  solidWorld(0),logicWorld(0),physiWorld(0),
61  solidCalor(0),logicCalor(0),physiCalor(0),
62  solidLayer(0),logicLayer(0),physiLayer(0),
63  solidAbsorber(0),logicAbsorber(0),physiAbsorber(0),
64  solidGap (0),logicGap (0),physiGap (0),
65  magField(0)
66 {
67  // default parameter values of the calorimeter
68  AbsorberThickness = 10.*mm;
69  GapThickness = 5.*mm;
70  NbOfLayers = 10;
71  CalorSizeYZ = 10.*cm;
72  ComputeCalorParameters();
73 
74  // materials
75  DefineMaterials();
76  SetAbsorberMaterial("Lead");
77  SetGapMaterial("liquidArgon");
78 
79  // create commands for interactive definition of the calorimeter
80  detectorMessenger = new DetectorMessenger(this);
81 }
82 
83 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
84 
86 { delete detectorMessenger;}
87 
88 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
89 
91 {
92  return ConstructCalorimeter();
93 }
94 
95 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
96 
97 void DetectorConstruction::DefineMaterials()
98 {
99  //This function illustrates the possible ways to define materials
100 
101 G4String symbol; //a=mass of a mole;
102 G4double a, z, density; //z=mean number of protons;
103 G4int iz, n; //iz=number of protons in an isotope;
104  // n=number of nucleons in an isotope;
105 
106 G4int ncomponents, natoms;
107 G4double abundance, fractionmass;
108 
109 //
110 // define Elements
111 //
112 
113 G4Element* H = new G4Element("Hydrogen",symbol="H" , z= 1., a= 1.01*g/mole);
114 G4Element* C = new G4Element("Carbon" ,symbol="C" , z= 6., a= 12.01*g/mole);
115 G4Element* N = new G4Element("Nitrogen",symbol="N" , z= 7., a= 14.01*g/mole);
116 G4Element* O = new G4Element("Oxygen" ,symbol="O" , z= 8., a= 16.00*g/mole);
117 G4Element* Si = new G4Element("Silicon",symbol="Si" , z= 14., a= 28.09*g/mole);
118 
119 //
120 // define an Element from isotopes, by relative abundance
121 //
122 
123 G4Isotope* U5 = new G4Isotope("U235", iz=92, n=235, a=235.01*g/mole);
124 G4Isotope* U8 = new G4Isotope("U238", iz=92, n=238, a=238.03*g/mole);
125 
126 G4Element* U = new G4Element("enriched Uranium",symbol="U",ncomponents=2);
127 U->AddIsotope(U5, abundance= 90.*perCent);
128 U->AddIsotope(U8, abundance= 10.*perCent);
129 
130 //
131 // define simple materials
132 //
133 
134 new G4Material("Aluminium", z=13., a=26.98*g/mole, density=2.700*g/cm3);
135 new G4Material("liquidArgon", z=18., a= 39.95*g/mole, density= 1.390*g/cm3);
136 new G4Material("Lead" , z=82., a= 207.19*g/mole, density= 11.35*g/cm3);
137 
138 //
139 // define a material from elements. case 1: chemical molecule
140 //
141 
142 G4Material* H2O =
143 new G4Material("Water", density= 1.000*g/cm3, ncomponents=2);
144 H2O->AddElement(H, natoms=2);
145 H2O->AddElement(O, natoms=1);
146 // overwrite computed meanExcitationEnergy with ICRU recommended value
148 
149 G4Material* Sci =
150 new G4Material("Scintillator", density= 1.032*g/cm3, ncomponents=2);
151 Sci->AddElement(C, natoms=9);
152 Sci->AddElement(H, natoms=10);
153 
154 G4Material* Myl =
155 new G4Material("Mylar", density= 1.397*g/cm3, ncomponents=3);
156 Myl->AddElement(C, natoms=10);
157 Myl->AddElement(H, natoms= 8);
158 Myl->AddElement(O, natoms= 4);
159 
160 G4Material* SiO2 =
161 new G4Material("quartz",density= 2.200*g/cm3, ncomponents=2);
162 SiO2->AddElement(Si, natoms=1);
163 SiO2->AddElement(O , natoms=2);
164 
165 //
166 // define a material from elements. case 2: mixture by fractional mass
167 //
168 
169 G4Material* Air =
170 new G4Material("Air" , density= 1.290*mg/cm3, ncomponents=2);
171 Air->AddElement(N, fractionmass=0.7);
172 Air->AddElement(O, fractionmass=0.3);
173 
174 //
175 // define a material from elements and/or others materials (mixture of mixtures)
176 //
177 
178 G4Material* Aerog =
179 new G4Material("Aerogel", density= 0.200*g/cm3, ncomponents=3);
180 Aerog->AddMaterial(SiO2, fractionmass=62.5*perCent);
181 Aerog->AddMaterial(H2O , fractionmass=37.4*perCent);
182 Aerog->AddElement (C , fractionmass= 0.1*perCent);
183 
184 //
185 // examples of gas in non STP conditions
186 //
187 
188 G4Material* CO2 =
189 new G4Material("CarbonicGas", density= 1.842*mg/cm3, ncomponents=2,
190  kStateGas, 325.*kelvin, 50.*atmosphere);
191 CO2->AddElement(C, natoms=1);
192 CO2->AddElement(O, natoms=2);
193 
194 G4Material* steam =
195 new G4Material("WaterSteam", density= 0.3*mg/cm3, ncomponents=1,
196  kStateGas, 500.*kelvin, 2.*atmosphere);
197 steam->AddMaterial(H2O, fractionmass=1.);
198 
199 //
200 // examples of vacuum
201 //
202 
203 G4Material* Vacuum =
204 new G4Material("Galactic", z=1., a=1.01*g/mole,density= universe_mean_density,
205  kStateGas, 2.73*kelvin, 3.e-18*pascal);
206 
207 G4Material* beam =
208 new G4Material("Beam", density= 1.e-5*g/cm3, ncomponents=1,
210 beam->AddMaterial(Air, fractionmass=1.);
211 
212 //
213 // or use G4-NIST materials data base
214 //
216 man->FindOrBuildMaterial("G4_SODIUM_IODIDE");
217 
218 // print table
219 //
221 
222 //default materials of the World
223 defaultMaterial = Vacuum;
224 }
225 
226 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
227 
228 G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter()
229 {
230 
231  // Clean old geometry, if any
232  //
237 
238  // complete the Calor parameters definition
239  ComputeCalorParameters();
240 
241  //
242  // World
243  //
244  solidWorld = new G4Box("World", //its name
245  WorldSizeX/2,WorldSizeYZ/2,WorldSizeYZ/2); //its size
246 
247  logicWorld = new G4LogicalVolume(solidWorld, //its solid
248  defaultMaterial, //its material
249  "World"); //its name
250 
251  physiWorld = new G4PVPlacement(0, //no rotation
252  G4ThreeVector(), //at (0,0,0)
253  logicWorld, //its logical volume
254  "World", //its name
255  0, //its mother volume
256  false, //no boolean operation
257  0); //copy number
258 
259  //
260  // Calorimeter
261  //
262  solidCalor=0; logicCalor=0; physiCalor=0;
263  solidLayer=0; logicLayer=0; physiLayer=0;
264 
265  if (CalorThickness > 0.)
266  { solidCalor = new G4Box("Calorimeter", //its name
267  CalorThickness/2,CalorSizeYZ/2,CalorSizeYZ/2);//size
268 
269  logicCalor = new G4LogicalVolume(solidCalor, //its solid
270  defaultMaterial, //its material
271  "Calorimeter"); //its name
272 
273  physiCalor = new G4PVPlacement(0, //no rotation
274  G4ThreeVector(), //at (0,0,0)
275  logicCalor, //its logical volume
276  "Calorimeter", //its name
277  logicWorld, //its mother volume
278  false, //no boolean operation
279  0); //copy number
280 
281  //
282  // Layer
283  //
284  solidLayer = new G4Box("Layer", //its name
285  LayerThickness/2,CalorSizeYZ/2,CalorSizeYZ/2); //size
286 
287  logicLayer = new G4LogicalVolume(solidLayer, //its solid
288  defaultMaterial, //its material
289  "Layer"); //its name
290  if (NbOfLayers > 1)
291  physiLayer = new G4PVReplica("Layer", //its name
292  logicLayer, //its logical volume
293  logicCalor, //its mother
294  kXAxis, //axis of replication
295  NbOfLayers, //number of replica
296  LayerThickness); //width of replica
297  else
298  physiLayer = new G4PVPlacement(0, //no rotation
299  G4ThreeVector(), //at (0,0,0)
300  logicLayer, //its logical volume
301  "Layer", //its name
302  logicCalor, //its mother volume
303  false, //no boolean operation
304  0); //copy number
305  }
306 
307  //
308  // Absorber
309  //
310  solidAbsorber=0; logicAbsorber=0; physiAbsorber=0;
311 
312  if (AbsorberThickness > 0.)
313  { solidAbsorber = new G4Box("Absorber", //its name
314  AbsorberThickness/2,CalorSizeYZ/2,CalorSizeYZ/2);
315 
316  logicAbsorber = new G4LogicalVolume(solidAbsorber, //its solid
317  AbsorberMaterial, //its material
318  AbsorberMaterial->GetName()); //name
319 
320  physiAbsorber = new G4PVPlacement(0, //no rotation
321  G4ThreeVector(-GapThickness/2,0.,0.), //its position
322  logicAbsorber, //its logical volume
323  AbsorberMaterial->GetName(), //its name
324  logicLayer, //its mother
325  false, //no boolean operat
326  0); //copy number
327 
328  }
329 
330  //
331  // Gap
332  //
333  solidGap=0; logicGap=0; physiGap=0;
334 
335  if (GapThickness > 0.)
336  { solidGap = new G4Box("Gap",
337  GapThickness/2,CalorSizeYZ/2,CalorSizeYZ/2);
338 
339  logicGap = new G4LogicalVolume(solidGap,
340  GapMaterial,
341  GapMaterial->GetName());
342 
343  physiGap = new G4PVPlacement(0, //no rotation
344  G4ThreeVector(AbsorberThickness/2,0.,0.), //its position
345  logicGap, //its logical volume
346  GapMaterial->GetName(), //its name
347  logicLayer, //its mother
348  false, //no boolean operat
349  0); //copy number
350  }
351 
353 
354  //
355  // Visualization attributes
356  //
358 
359  G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
360  simpleBoxVisAtt->SetVisibility(true);
361  logicCalor->SetVisAttributes(simpleBoxVisAtt);
362 
363  /*
364  // Below are vis attributes that permits someone to test / play
365  // with the interactive expansion / contraction geometry system of the
366  // vis/OpenInventor driver :
367  {G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,0.0));
368  simpleBoxVisAtt->SetVisibility(true);
369  delete logicCalor->GetVisAttributes();
370  logicCalor->SetVisAttributes(simpleBoxVisAtt);}
371 
372  {G4VisAttributes* atb= new G4VisAttributes(G4Colour(1.0,0.0,0.0));
373  logicLayer->SetVisAttributes(atb);}
374 
375  {G4VisAttributes* atb= new G4VisAttributes(G4Colour(0.0,1.0,0.0));
376  atb->SetForceSolid(true);
377  logicAbsorber->SetVisAttributes(atb);}
378 
379  {//Set opacity = 0.2 then transparency = 1 - 0.2 = 0.8
380  G4VisAttributes* atb= new G4VisAttributes(G4Colour(0.0,0.0,1.0,0.2));
381  atb->SetForceSolid(true);
382  logicGap->SetVisAttributes(atb);}
383  */
384 
385  //
386  //always return the physical World
387  //
388  return physiWorld;
389 }
390 
391 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
392 
394 {
395  G4cout << "\n------------------------------------------------------------"
396  << "\n---> The calorimeter is " << NbOfLayers << " layers of: [ "
397  << AbsorberThickness/mm << "mm of " << AbsorberMaterial->GetName()
398  << " + "
399  << GapThickness/mm << "mm of " << GapMaterial->GetName() << " ] "
400  << "\n------------------------------------------------------------\n";
401 }
402 
403 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
404 
406 {
407  // search the material by its name
408  G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
409  if (pttoMaterial) AbsorberMaterial = pttoMaterial;
410 }
411 
412 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
413 
415 {
416  // search the material by its name
417  G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
418  if (pttoMaterial) GapMaterial = pttoMaterial;
419 }
420 
421 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
422 
424 {
425  // change Absorber thickness and recompute the calorimeter parameters
426  AbsorberThickness = val;
427 }
428 
429 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
430 
432 {
433  // change Gap thickness and recompute the calorimeter parameters
434  GapThickness = val;
435 }
436 
437 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
438 
440 {
441  // change the transverse size and recompute the calorimeter parameters
442  CalorSizeYZ = val;
443 }
444 
445 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
446 
448 {
449  NbOfLayers = val;
450 }
451 
452 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
453 
454 #include "G4FieldManager.hh"
456 
458 {
459  //apply a global uniform magnetic field along Z axis
460  G4FieldManager* fieldMgr
462 
463  if(magField) delete magField; //delete the existing magn field
464 
465  if(fieldValue!=0.) // create a new one if non nul
466  { magField = new G4UniformMagField(G4ThreeVector(0.,0.,fieldValue));
467  fieldMgr->SetDetectorField(magField);
468  fieldMgr->CreateChordFinder(magField);
469  } else {
470  magField = 0;
471  fieldMgr->SetDetectorField(magField);
472  }
473 }
474 
475 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
476 
477 #include "G4RunManager.hh"
478 
480 {
481  G4RunManager::GetRunManager()->DefineWorldVolume(ConstructCalorimeter());
482 }
483 
484 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......