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