source: trunk/examples/extended/electromagnetic/TestEm3/src/DetectorConstruction.cc@ 1036

Last change on this file since 1036 was 807, checked in by garnier, 17 years ago

update

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