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 // $Id$
30 //
31 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
32 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
33 
34 #include "DetectorConstruction.hh"
35 #include "DetectorMessenger.hh"
36 
37 #include "G4NistManager.hh"
38 #include "G4Material.hh"
39 #include "G4Box.hh"
40 #include "G4LogicalVolume.hh"
41 #include "G4PVPlacement.hh"
42 #include "G4PVReplica.hh"
43 #include "G4UniformMagField.hh"
44 
45 #include "G4GeometryManager.hh"
46 #include "G4PhysicalVolumeStore.hh"
47 #include "G4LogicalVolumeStore.hh"
48 #include "G4SolidStore.hh"
49 
50 #include "G4UImanager.hh"
51 #include "G4UnitsTable.hh"
52 #include "G4PhysicalConstants.hh"
53 #include "G4SystemOfUnits.hh"
54 #include <iomanip>
55 
56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
57 
59 :fDefaultMaterial(0),fSolidWorld(0),fLogicWorld(0),fPhysiWorld(0),
60  fSolidCalor(0),fLogicCalor(0),fPhysiCalor(0),
61  fSolidLayer(0),fLogicLayer(0),fPhysiLayer(0),
62  fMagField(0)
63 {
64  // default parameter values of the calorimeter
65  fNbOfAbsor = 2;
66  fAbsorThickness[1] = 2.3*mm;
67  fAbsorThickness[2] = 5.7*mm;
68  fNbOfLayers = 50;
69  fCalorSizeYZ = 40.*cm;
70  ComputeCalorParameters();
71 
72  // materials
73  DefineMaterials();
74  SetWorldMaterial("Galactic");
75  SetAbsorMaterial(1,"Lead");
76  SetAbsorMaterial(2,"liquidArgon");
77 
78  // create commands for interactive definition of the calorimeter
79  fDetectorMessenger = new DetectorMessenger(this);
80 }
81 
82 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
83 
85 {
86  delete fDetectorMessenger;
87 }
88 
89 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
90 
92 {
93  return ConstructCalorimeter();
94 }
95 
96 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
97 
98 void DetectorConstruction::DefineMaterials()
99 {
100  // This function illustrates the possible ways to define materials using
101  // G4 database on G4Elements
103  manager->SetVerbose(0);
104  //
105  // define Elements
106  //
107  G4double z,a;
108 
109  G4Element* H = manager->FindOrBuildElement(1);
110  G4Element* C = manager->FindOrBuildElement(6);
111  G4Element* N = manager->FindOrBuildElement(7);
112  G4Element* O = manager->FindOrBuildElement(8);
113  G4Element* Si = manager->FindOrBuildElement(14);
114  G4Element* Ge = manager->FindOrBuildElement(32);
115  G4Element* Sb = manager->FindOrBuildElement(51);
116  G4Element* I = manager->FindOrBuildElement(53);
117  G4Element* Cs = manager->FindOrBuildElement(55);
118  G4Element* Pb = manager->FindOrBuildElement(82);
119  G4Element* Bi = manager->FindOrBuildElement(83);
120 
121  //
122  // define an Element from isotopes, by relative abundance
123  //
124  G4int iz, n; //iz=number of protons in an isotope;
125  // n=number of nucleons in an isotope;
126  G4int ncomponents;
127  G4double abundance;
128 
129  G4Isotope* U5 = new G4Isotope("U235", iz=92, n=235, a=235.01*g/mole);
130  G4Isotope* U8 = new G4Isotope("U238", iz=92, n=238, a=238.03*g/mole);
131 
132  G4Element* U = new G4Element("enriched Uranium", "U", ncomponents=2);
133  U->AddIsotope(U5, abundance= 90.*perCent);
134  U->AddIsotope(U8, abundance= 10.*perCent);
135 
136  //
137  // define simple materials
138  //
140 
141  new G4Material("liquidH2", z=1., a= 1.008*g/mole, density= 70.8*mg/cm3);
142  new G4Material("Aluminium", z=13., a= 26.98*g/mole, density= 2.700*g/cm3);
143  new G4Material("Titanium", z=22., a= 47.867*g/mole, density= 4.54*g/cm3);
144  new G4Material("Iron", z=26., a= 55.85*g/mole, density= 7.870*g/cm3);
145  new G4Material("Copper", z=29., a= 63.55*g/mole, density= 8.960*g/cm3);
146  new G4Material("Tungsten", z=74., a= 183.85*g/mole, density= 19.30*g/cm3);
147  new G4Material("Gold", z=79., a= 196.97*g/mole, density= 19.32*g/cm3);
148  new G4Material("Uranium", z=92., a= 238.03*g/mole, density= 18.95*g/cm3);
149 
150  //
151  // define a material from elements. case 1: chemical molecule
152  //
153  G4int natoms;
154 
155  G4Material* H2O =
156  new G4Material("Water", density= 1.000*g/cm3, ncomponents=2);
157  H2O->AddElement(H, natoms=2);
158  H2O->AddElement(O, natoms=1);
160  H2O->SetChemicalFormula("H_2O");
161 
162  G4Material* CH =
163  new G4Material("Polystyrene", density= 1.032*g/cm3, ncomponents=2);
164  CH->AddElement(C, natoms=1);
165  CH->AddElement(H, natoms=1);
166 
167  G4Material* Sci =
168  new G4Material("Scintillator", density= 1.032*g/cm3, ncomponents=2);
169  Sci->AddElement(C, natoms=9);
170  Sci->AddElement(H, natoms=10);
171 
172  Sci->GetIonisation()->SetBirksConstant(0.126*mm/MeV);
173 
174  G4Material* Lct =
175  new G4Material("Lucite", density= 1.185*g/cm3, ncomponents=3);
176  Lct->AddElement(C, 59.97*perCent);
177  Lct->AddElement(H, 8.07*perCent);
178  Lct->AddElement(O, 31.96*perCent);
179 
180  G4Material* Sili =
181  new G4Material("Silicon", density= 2.330*g/cm3, ncomponents=1);
182  Sili->AddElement(Si, natoms=1);
183 
184  G4Material* SiO2 =
185  new G4Material("quartz", density= 2.200*g/cm3, ncomponents=2);
186  SiO2->AddElement(Si, natoms=1);
187  SiO2->AddElement(O , natoms=2);
188 
189  G4Material* G10 =
190  new G4Material("NemaG10", density= 1.700*g/cm3, ncomponents=4);
191  G10->AddElement(Si, natoms=1);
192  G10->AddElement(O , natoms=2);
193  G10->AddElement(C , natoms=3);
194  G10->AddElement(H , natoms=3);
195 
196  G4Material* CsI =
197  new G4Material("CsI", density= 4.534*g/cm3, ncomponents=2);
198  CsI->AddElement(Cs, natoms=1);
199  CsI->AddElement(I , natoms=1);
201 
202  G4Material* BGO =
203  new G4Material("BGO", density= 7.10*g/cm3, ncomponents=3);
204  BGO->AddElement(O , natoms=12);
205  BGO->AddElement(Ge, natoms= 3);
206  BGO->AddElement(Bi, natoms= 4);
207 
208  //SiNx
209  density= 3.1 *g/cm3;
210  G4Material* SiNx= new G4Material("SiNx", density, ncomponents=3);
211  SiNx-> AddElement(Si, 300);
212  SiNx-> AddElement(N, 310);
213  SiNx-> AddElement(H, 6);
214 
215  //
216  // define gaseous materials using G4 NIST database
217  //
218  G4double fractionmass;
219 
220  G4Material* Air = manager->FindOrBuildMaterial("G4_AIR");
221  manager->ConstructNewGasMaterial("Air20","G4_AIR",293.*kelvin,1.*atmosphere);
222 
223  G4Material* lAr = manager->FindOrBuildMaterial("G4_lAr");
224  G4Material* lArEm3 = new G4Material("liquidArgon", density= 1.390*g/cm3, ncomponents=1);
225  lArEm3->AddMaterial(lAr, fractionmass=1.0);
226 
227  //
228  // define a material from elements and others materials (mixture of mixtures)
229  //
230 
231  G4Material* Lead = new G4Material("Lead", density= 11.35*g/cm3, ncomponents=1);
232  Lead->AddElement(Pb, fractionmass=1.0);
233 
234  G4Material* LeadSb = new G4Material("LeadSb", density= 11.35*g/cm3, ncomponents=2);
235  LeadSb->AddElement(Sb, fractionmass=4.*perCent);
236  LeadSb->AddElement(Pb, fractionmass=96.*perCent);
237 
238  G4Material* Aerog = new G4Material("Aerogel", density= 0.200*g/cm3, ncomponents=3);
239  Aerog->AddMaterial(SiO2, fractionmass=62.5*perCent);
240  Aerog->AddMaterial(H2O , fractionmass=37.4*perCent);
241  Aerog->AddElement (C , fractionmass= 0.1*perCent);
242 
243  //
244  // examples of gas in non STP conditions
245  //
246  G4double temperature, pressure;
247 
248  G4Material* CO2 =
249  new G4Material("CarbonicGas", density= 27.*mg/cm3, ncomponents=2,
250  kStateGas, temperature= 325.*kelvin, pressure= 50.*atmosphere);
251  CO2->AddElement(C, natoms=1);
252  CO2->AddElement(O, natoms=2);
253 
254  G4Material* steam =
255  new G4Material("WaterSteam", density= 1.0*mg/cm3, ncomponents=1,
256  kStateGas, temperature= 273*kelvin, pressure= 1*atmosphere);
257  steam->AddMaterial(H2O, fractionmass=1.);
258 
259  new G4Material("ArgonGas", z=18, a=39.948*g/mole, density= 1.782*mg/cm3,
260  kStateGas, 273.15*kelvin, 1*atmosphere);
261  //
262  // examples of vacuum
263  //
264 
265  density = universe_mean_density; //from PhysicalConstants.h
266  pressure = 3.e-18*pascal;
267  temperature = 2.73*kelvin;
268  new G4Material("Galactic", z=1., a=1.008*g/mole, density,
269  kStateGas,temperature,pressure);
270 
271  density = 1.e-5*g/cm3;
272  pressure = 2.e-2*bar;
273  temperature = STP_Temperature; //from PhysicalConstants.h
274  G4Material* beam =
275  new G4Material("Beam", density, ncomponents=1,
276  kStateGas,temperature,pressure);
277  beam->AddMaterial(Air, fractionmass=1.);
278 
279  // G4cout << *(G4Material::GetMaterialTable()) << G4endl;
280 }
281 
282 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
283 
284 void DetectorConstruction::ComputeCalorParameters()
285 {
286  // Compute derived parameters of the calorimeter
287  fLayerThickness = 0.;
288  for (G4int iAbs=1; iAbs<=fNbOfAbsor; iAbs++) {
289  fLayerThickness += fAbsorThickness[iAbs];
290  }
291  fCalorThickness = fNbOfLayers*fLayerThickness;
292  fWorldSizeX = 1.2*fCalorThickness;
293  fWorldSizeYZ = 1.2*fCalorSizeYZ;
294 }
295 
296 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
297 
298 G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter()
299 {
300  // complete the Calor parameters definition
301  ComputeCalorParameters();
302 
303  // Cleanup old geometry
308 
309  //
310  // World
311  //
312 
313  fSolidWorld = new G4Box("World", //its name
314  fWorldSizeX/2,fWorldSizeYZ/2,fWorldSizeYZ/2); //its size
315 
316  fLogicWorld = new G4LogicalVolume(fSolidWorld, //its solid
317  fDefaultMaterial, //its material
318  "World"); //its name
319 
320  fPhysiWorld = new G4PVPlacement(0, //no rotation
321  G4ThreeVector(), //at (0,0,0)
322  fLogicWorld, //its fLogical volume
323  "World", //its name
324  0, //its mother volume
325  false, //no boolean operation
326  0); //copy number
327  //
328  // Calorimeter
329  //
330 
331  fSolidCalor = new G4Box("Calorimeter", //its name
332  fCalorThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2);//size
333 
334  fLogicCalor = new G4LogicalVolume(fSolidCalor, //its solid
335  fDefaultMaterial, //its material
336  "Calorimeter"); //its name
337 
338  fPhysiCalor = new G4PVPlacement(0, //no rotation
339  G4ThreeVector(), //at (0,0,0)
340  fLogicCalor, //its fLogical volume
341  "Calorimeter", //its name
342  fLogicWorld, //its mother volume
343  false, //no boolean operation
344  0); //copy number
345 
346  //
347  // Layers
348  //
349 
350  fSolidLayer = new G4Box("Layer", //its name
351  fLayerThickness/2,fCalorSizeYZ/2,fCalorSizeYZ/2); //size
352 
353  fLogicLayer = new G4LogicalVolume(fSolidLayer, //its solid
354  fDefaultMaterial, //its material
355  "Layer"); //its name
356  if (fNbOfLayers > 1)
357  fPhysiLayer = new G4PVReplica("Layer", //its name
358  fLogicLayer, //its fLogical volume
359  fLogicCalor, //its mother
360  kXAxis, //axis of replication
361  fNbOfLayers, //number of replica
362  fLayerThickness); //witdth of replica
363  else
364  fPhysiLayer = new G4PVPlacement(0, //no rotation
365  G4ThreeVector(), //at (0,0,0)
366  fLogicLayer, //its fLogical volume
367  "Layer", //its name
368  fLogicCalor, //its mother volume
369  false, //no boolean operation
370  0); //copy number
371 
372  //
373  // Absorbers
374  //
375 
376  G4double xfront = -0.5*fLayerThickness;
377  for (G4int k=1; k<=fNbOfAbsor; k++) {
378  fSolidAbsor[k] = new G4Box("Absorber", //its name
379  fAbsorThickness[k]/2,fCalorSizeYZ/2,fCalorSizeYZ/2);
380 
381  fLogicAbsor[k] = new G4LogicalVolume(fSolidAbsor[k], //its solid
382  fAbsorMaterial[k], //its material
383  fAbsorMaterial[k]->GetName());
384 
385  G4double xcenter = xfront+0.5*fAbsorThickness[k];
386  xfront += fAbsorThickness[k];
387  fPhysiAbsor[k] = new G4PVPlacement(0, //no rotation
388  G4ThreeVector(xcenter,0.,0.), //its position
389  fLogicAbsor[k], //its logical volume
390  fAbsorMaterial[k]->GetName(), //its name
391  fLogicLayer, //its mother
392  false, //no boulean operat
393  k); //copy number
394 
395  }
396 
397 
399 
400  //always return the fPhysical World
401  //
402  return fPhysiWorld;
403 }
404 
405 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
406 
408 {
409  G4cout << "\n-------------------------------------------------------------"
410  << "\n ---> The calorimeter is " << fNbOfLayers << " layers of:";
411  for (G4int i=1; i<=fNbOfAbsor; i++)
412  {
413  G4cout << "\n \t" << std::setw(12) << fAbsorMaterial[i]->GetName() <<": "
414  << std::setw(6) << G4BestUnit(fAbsorThickness[i],"Length");
415  }
416  G4cout << "\n-------------------------------------------------------------\n";
417 
418  G4cout << "\n" << fDefaultMaterial << G4endl;
419  for (G4int j=1; j<=fNbOfAbsor; j++)
420  G4cout << "\n" << fAbsorMaterial[j] << G4endl;
421 
422  G4cout << "\n-------------------------------------------------------------\n";
423 }
424 
425 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
426 
428 {
429  // search the material by its name
430  G4Material* pttoMaterial =
432  if (pttoMaterial) fDefaultMaterial = pttoMaterial;
433 }
434 
435 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
436 
438 {
439  // set the number of Layers
440  //
441  if (ival < 1)
442  { G4cout << "\n --->warning from SetfNbOfLayers: "
443  << ival << " must be at least 1. Command refused" << G4endl;
444  return;
445  }
446  fNbOfLayers = ival;
447 }
448 
449 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
450 
452 {
453  // set the number of Absorbers
454  //
455  if (ival < 1 || ival > (MaxAbsor-1))
456  { G4cout << "\n ---> warning from SetfNbOfAbsor: "
457  << ival << " must be at least 1 and and most " << MaxAbsor-1
458  << ". Command refused" << G4endl;
459  return;
460  }
461  fNbOfAbsor = ival;
462 }
463 
464 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
465 
467 {
468  // search the material by its name
469  //
470  if (ival > fNbOfAbsor || ival <= 0)
471  { G4cout << "\n --->warning from SetAbsorMaterial: absor number "
472  << ival << " out of range. Command refused" << G4endl;
473  return;
474  }
475 
476  G4Material* pttoMaterial =
478  if (pttoMaterial) fAbsorMaterial[ival] = pttoMaterial;
479 }
480 
481 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
482 
484 {
485  // change Absorber thickness
486  //
487  if (ival > fNbOfAbsor || ival <= 0)
488  { G4cout << "\n --->warning from SetAbsorThickness: absor number "
489  << ival << " out of range. Command refused" << G4endl;
490  return;
491  }
492  if (val <= DBL_MIN)
493  { G4cout << "\n --->warning from SetAbsorThickness: thickness "
494  << val << " out of range. Command refused" << G4endl;
495  return;
496  }
497  fAbsorThickness[ival] = val;
498 }
499 
500 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
501 
503 {
504  // change the transverse size
505  //
506  if (val <= DBL_MIN)
507  { G4cout << "\n --->warning from SetfCalorSizeYZ: thickness "
508  << val << " out of range. Command refused" << G4endl;
509  return;
510  }
511  fCalorSizeYZ = val;
512 }
513 
514 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
515 
516 #include "G4FieldManager.hh"
518 
520 {
521  //apply a global uniform magnetic field along Z axis
522  //
523  G4FieldManager* fieldMgr
525 
526  if(fMagField) delete fMagField; //delete the existing magn field
527 
528  if(fieldValue!=0.) // create a new one if non nul
529  { fMagField = new G4UniformMagField(G4ThreeVector(0.,0.,fieldValue));
530  fieldMgr->SetDetectorField(fMagField);
531  fieldMgr->CreateChordFinder(fMagField);
532  } else {
533  fMagField = 0;
534  fieldMgr->SetDetectorField(fMagField);
535  }
536 }
537 
538 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
539 
540 #include "G4RunManager.hh"
541 
543 {
544  G4RunManager::GetRunManager()->DefineWorldVolume(ConstructCalorimeter());
545 }
546 
547 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......