source: trunk/examples/novice/N07/src/ExN07DetectorConstruction.cc@ 1191

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

update

File size: 15.5 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//
27// $Id: ExN07DetectorConstruction.cc,v 1.8 2007/05/04 01:49:28 asaim Exp $
28// GEANT4 tag $Name: $
29//
30//
31
32#include "ExN07DetectorConstruction.hh"
33
34#include "G4RunManager.hh"
35
36#include "G4Material.hh"
37#include "G4Box.hh"
38#include "G4LogicalVolume.hh"
39#include "G4PVPlacement.hh"
40#include "G4PVReplica.hh"
41
42#include "G4VisAttributes.hh"
43#include "G4Colour.hh"
44
45#include "G4SDManager.hh"
46#include "G4MultiFunctionalDetector.hh"
47#include "G4VPrimitiveScorer.hh"
48#include "G4PSEnergyDeposit.hh"
49#include "G4PSNofSecondary.hh"
50#include "G4PSTrackLength.hh"
51#include "G4PSNofStep.hh"
52#include "G4PSMinKinEAtGeneration.hh"
53#include "G4VSDFilter.hh"
54#include "G4SDParticleFilter.hh"
55#include "G4ios.hh"
56
57#include "ExN07DetectorMessenger.hh"
58#include "ExN07PrimaryGeneratorAction.hh"
59#include "ExN07ParallelWorld.hh"
60
61ExN07DetectorConstruction::ExN07DetectorConstruction()
62:constructed(false),worldMaterial(0),absorberMaterial(0),gapMaterial(0),
63 layerSolid(0),gapSolid(0),worldLogical(0),worldPhysical(0),serial(false),
64 verboseLevel(1)
65{
66 numberOfLayers = 40;
67 totalThickness = 2.0*m;
68 layerThickness = totalThickness / numberOfLayers;
69
70 for(size_t i=0;i<3;i++)
71 {
72 calorLogical[i] = 0;
73 layerLogical[i] = 0;
74 gapLogical[i] = 0;
75 calorPhysical[i] = 0;
76 layerPhysical[i] = 0;
77 gapPhysical[i] = 0;
78 }
79
80 calName[0] = "Calor-A";
81 calName[1] = "Calor-B";
82 calName[2] = "Calor-C";
83
84 detectorMessenger = new ExN07DetectorMessenger(this);
85}
86
87ExN07DetectorConstruction::~ExN07DetectorConstruction()
88{ delete detectorMessenger;}
89
90G4VPhysicalVolume* ExN07DetectorConstruction::Construct()
91{
92 if(!constructed)
93 {
94 constructed = true;
95 DefineMaterials();
96 SetupGeometry();
97 SetupDetectors();
98 }
99 if (GetVerboseLevel()>0) {
100 PrintCalorParameters();
101 }
102 return worldPhysical;
103}
104
105void ExN07DetectorConstruction::DefineMaterials()
106{
107 G4String name, symbol; //a=mass of a mole;
108 G4double a, z, density; //z=mean number of protons;
109 G4int iz; //iz=number of protons in an isotope;
110 G4int n; // n=number of nucleons in an isotope;
111
112 G4int ncomponents, natoms;
113 G4double abundance, fractionmass;
114 G4double temperature, pressure;
115
116 //
117 // define Elements
118 //
119
120 a = 1.01*g/mole;
121 G4Element* H = new G4Element(name="Hydrogen",symbol="H" , z= 1., a);
122
123 a = 12.01*g/mole;
124 G4Element* C = new G4Element(name="Carbon" ,symbol="C" , z= 6., a);
125
126 a = 14.01*g/mole;
127 G4Element* N = new G4Element(name="Nitrogen",symbol="N" , z= 7., a);
128
129 a = 16.00*g/mole;
130 G4Element* O = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
131
132 //
133 // define an Element from isotopes, by relative abundance
134 //
135
136 G4Isotope* U5 = new G4Isotope(name="U235", iz=92, n=235, a=235.01*g/mole);
137 G4Isotope* U8 = new G4Isotope(name="U238", iz=92, n=238, a=238.03*g/mole);
138
139 G4Element* U = new G4Element(name="enriched Uranium",symbol="U",ncomponents=2);
140 U->AddIsotope(U5, abundance= 90.*perCent);
141 U->AddIsotope(U8, abundance= 10.*perCent);
142
143 //
144 // define simple materials
145 //
146
147 new G4Material(name="Aluminium", z=13., a=26.98*g/mole, density=2.700*g/cm3);
148 new G4Material(name="Silicon", z=14., a= 28.09*g/mole, density= 2.33*g/cm3);
149 new G4Material(name="Iron", z=26., a=55.85*g/mole, density=7.87*g/cm3);
150 new G4Material(name="ArgonGas",z=18., a= 39.95*g/mole, density=1.782*mg/cm3);
151 new G4Material(name="He", z=2., a=4.0*g/mole, density=0.1786e-03*g/cm3);
152
153 density = 1.390*g/cm3;
154 a = 39.95*g/mole;
155 G4Material* lAr = new G4Material(name="liquidArgon", z=18., a, density);
156
157 density = 11.35*g/cm3;
158 a = 207.19*g/mole;
159 G4Material* Pb = new G4Material(name="Lead" , z=82., a, density);
160
161 //
162 // define a material from elements. case 1: chemical molecule
163 //
164
165 density = 1.000*g/cm3;
166 G4Material* H2O = new G4Material(name="Water", density, ncomponents=2);
167 H2O->AddElement(H, natoms=2);
168 H2O->AddElement(O, natoms=1);
169
170 density = 1.032*g/cm3;
171 G4Material* Sci = new G4Material(name="Scintillator", density, ncomponents=2);
172 Sci->AddElement(C, natoms=9);
173 Sci->AddElement(H, natoms=10);
174
175 //
176 // define a material from elements. case 2: mixture by fractional mass
177 //
178
179 density = 1.290*mg/cm3;
180 G4Material* Air = new G4Material(name="Air" , density, ncomponents=2);
181 Air->AddElement(N, fractionmass=0.7);
182 Air->AddElement(O, fractionmass=0.3);
183
184 //
185 // examples of vacuum
186 //
187
188 density = universe_mean_density;
189 pressure = 3.e-18*pascal;
190 temperature = 2.73*kelvin;
191 G4Material* Vacuum = new G4Material(name="Galactic", z=1., a=1.01*g/mole,
192 density,kStateGas,temperature,pressure);
193
194 if (GetVerboseLevel()>1) {
195 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
196 }
197
198 //default materials of the calorimeter
199 worldMaterial = Vacuum;
200 absorberMaterial = Pb;
201 gapMaterial = lAr;
202}
203
204void ExN07DetectorConstruction::SetupGeometry()
205{
206 //
207 // World
208 //
209 G4VSolid* worldSolid = new G4Box("World",2.*m,2.*m,totalThickness*2.);
210 worldLogical = new G4LogicalVolume(worldSolid,worldMaterial,"World");
211 worldPhysical = new G4PVPlacement(0,G4ThreeVector(),worldLogical,"World",
212 0,false,0);
213
214 //
215 // Calorimeter
216 //
217 G4VSolid* calorSolid = new G4Box("Calor",0.5*m,0.5*m,totalThickness/2.);
218 G4int i;
219 for(i=0;i<3;i++)
220 {
221 calorLogical[i] = new G4LogicalVolume(calorSolid,absorberMaterial,calName[i]);
222 if(serial)
223 {
224 calorPhysical[i] = new G4PVPlacement(0,
225 G4ThreeVector(0.,0.,G4double(i-1)*totalThickness),
226 calorLogical[i],calName[i],worldLogical,false,i);
227 }
228 else
229 {
230 calorPhysical[i] = new G4PVPlacement(0,
231 G4ThreeVector(0.,G4double(i-1)*m,0.),
232 calorLogical[i],calName[i],worldLogical,false,i);
233 }
234 }
235
236 //
237 // Layers --- as absorbers
238 //
239 layerSolid = new G4Box("Layer",0.5*m,0.5*m,layerThickness/2.);
240 for(i=0;i<3;i++)
241 {
242 layerLogical[i] = new G4LogicalVolume(layerSolid,absorberMaterial,calName[i]+"_LayerLog");
243 layerPhysical[i] = new G4PVReplica(calName[i]+"_Layer",layerLogical[i],calorLogical[i],kZAxis,
244 numberOfLayers,layerThickness);
245 }
246
247 //
248 // Gap
249 //
250 gapSolid = new G4Box("Gap",0.5*m,0.5*m,layerThickness/4.);
251 for(i=0;i<3;i++)
252 {
253 gapLogical[i] = new G4LogicalVolume(gapSolid,gapMaterial,"Gap");
254 gapPhysical[i] = new G4PVPlacement(0,G4ThreeVector(0.,0.,layerThickness/4.),
255 gapLogical[i],calName[i]+"_gap",layerLogical[i],false,0);
256 }
257
258 //
259 // Regions
260 //
261 for(i=0;i<3;i++)
262 {
263 G4Region* aRegion = new G4Region(calName[i]);
264 calorLogical[i]->SetRegion(aRegion);
265 aRegion->AddRootLogicalVolume(calorLogical[i]);
266 }
267
268 //
269 // Visualization attributes
270 //
271 worldLogical->SetVisAttributes(G4VisAttributes::Invisible);
272 G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
273 simpleBoxVisAtt->SetVisibility(true);
274 for(i=0;i<3;i++)
275 {
276 calorLogical[i]->SetVisAttributes(simpleBoxVisAtt);
277 layerLogical[i]->SetVisAttributes(simpleBoxVisAtt);
278 gapLogical[i]->SetVisAttributes(simpleBoxVisAtt);
279 }
280
281}
282
283void ExN07DetectorConstruction::SetupDetectors()
284{
285 G4SDManager::GetSDMpointer()->SetVerboseLevel(1);
286 G4String filterName, particleName;
287
288 G4SDParticleFilter* gammaFilter = new G4SDParticleFilter(filterName="gammaFilter",particleName="gamma");
289 G4SDParticleFilter* electronFilter = new G4SDParticleFilter(filterName="electronFilter",particleName="e-");
290 G4SDParticleFilter* positronFilter = new G4SDParticleFilter(filterName="positronFilter",particleName="e+");
291 G4SDParticleFilter* epFilter = new G4SDParticleFilter(filterName="epFilter");
292 epFilter->add(particleName="e-");
293 epFilter->add(particleName="e+");
294
295
296 for(G4int i=0;i<3;i++)
297 {
298 for(G4int j=0;j<2;j++)
299 {
300 // Loop counter j = 0 : absorber
301 // = 1 : gap
302 G4String detName = calName[i];
303 if(j==0)
304 { detName += "_abs"; }
305 else
306 { detName += "_gap"; }
307 G4MultiFunctionalDetector* det = new G4MultiFunctionalDetector(detName);
308
309 // The second argument in each primitive means the "level" of geometrical hierarchy,
310 // the copy number of that level is used as the key of the G4THitsMap.
311 // For absorber (j = 0), the copy number of its own physical volume is used.
312 // For gap (j = 1), the copy number of its mother physical volume is used, since there
313 // is only one physical volume of gap is placed with respect to its mother.
314 G4VPrimitiveScorer* primitive;
315 primitive = new G4PSEnergyDeposit("eDep",j);
316 det->RegisterPrimitive(primitive);
317 primitive = new G4PSNofSecondary("nGamma",j);
318 primitive->SetFilter(gammaFilter);
319 det->RegisterPrimitive(primitive);
320 primitive = new G4PSNofSecondary("nElectron",j);
321 primitive->SetFilter(electronFilter);
322 det->RegisterPrimitive(primitive);
323 primitive = new G4PSNofSecondary("nPositron",j);
324 primitive->SetFilter(positronFilter);
325 det->RegisterPrimitive(primitive);
326 primitive = new G4PSMinKinEAtGeneration("minEkinGamma",j);
327 primitive->SetFilter(gammaFilter);
328 det->RegisterPrimitive(primitive);
329 primitive = new G4PSMinKinEAtGeneration("minEkinElectron",j);
330 primitive->SetFilter(electronFilter);
331 det->RegisterPrimitive(primitive);
332 primitive = new G4PSMinKinEAtGeneration("minEkinPositron",j);
333 primitive->SetFilter(positronFilter);
334 det->RegisterPrimitive(primitive);
335 primitive = new G4PSTrackLength("trackLength",j);
336 primitive->SetFilter(epFilter);
337 det->RegisterPrimitive(primitive);
338 primitive = new G4PSNofStep("nStep",j);
339 primitive->SetFilter(epFilter);
340 det->RegisterPrimitive(primitive);
341
342 G4SDManager::GetSDMpointer()->AddNewDetector(det);
343 if(j==0)
344 { layerLogical[i]->SetSensitiveDetector(det); }
345 else
346 { gapLogical[i]->SetSensitiveDetector(det); }
347 }
348 }
349 G4SDManager::GetSDMpointer()->SetVerboseLevel(0);
350}
351
352void ExN07DetectorConstruction::PrintCalorParameters() const
353{
354 G4cout << "--------------------------------------------------------" << G4endl;
355 if(serial)
356 { G4cout << " Calorimeters are placed in serial." << G4endl; }
357 else
358 { G4cout << " Calorimeters are placed in parallel." << G4endl; }
359 G4cout << " Absorber is made of " << absorberMaterial->GetName() << G4endl;
360 G4cout << " Gap is made of " << gapMaterial->GetName() << G4endl;
361 G4cout << "--------------------------------------------------------" << G4endl;
362}
363
364void ExN07DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
365{
366 // search the material by its name
367 G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
368 if(pttoMaterial)
369 {
370 absorberMaterial = pttoMaterial;
371 if(constructed) for(size_t i=0;i<3;i++)
372 {
373 calorLogical[i]->SetMaterial(absorberMaterial);
374 layerLogical[i]->SetMaterial(absorberMaterial);
375 }
376 G4RunManager::GetRunManager()->GeometryHasBeenModified();
377 if (GetVerboseLevel()>1) {
378 PrintCalorParameters();
379 }
380 }
381 else
382 { G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl; }
383}
384
385G4String ExN07DetectorConstruction::GetAbsorberMaterial() const
386{ return absorberMaterial->GetName(); }
387
388void ExN07DetectorConstruction::SetGapMaterial(G4String materialChoice)
389{
390 // search the material by its name
391 G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
392 if(pttoMaterial)
393 {
394 gapMaterial = pttoMaterial;
395 if(constructed) for(size_t i=0;i<3;i++)
396 { gapLogical[i]->SetMaterial(gapMaterial); }
397 G4RunManager::GetRunManager()->GeometryHasBeenModified();
398 if (GetVerboseLevel()>1) {
399 PrintCalorParameters();
400 }
401 }
402 else
403 { G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl; }
404}
405
406G4String ExN07DetectorConstruction::GetGapMaterial() const
407{ return gapMaterial->GetName(); }
408
409void ExN07DetectorConstruction::SetSerialGeometry(G4bool ser)
410{
411 if(serial==ser) return;
412 serial=ser;
413 ExN07PrimaryGeneratorAction* gen = (ExN07PrimaryGeneratorAction*)
414 (G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction());
415 if(gen) gen->SetSerial(serial);
416 if(!constructed) return;
417 for(G4int i=0;i<3;i++)
418 {
419 if(serial)
420 { calorPhysical[i]->SetTranslation(G4ThreeVector(0.,0.,G4double(i-1)*2.*m)); }
421 else
422 { calorPhysical[i]->SetTranslation(G4ThreeVector(0.,G4double(i-1)*m,0.)); }
423 }
424 ((ExN07ParallelWorld*)GetParallelWorld(0))->SetSerialGeometry(ser);
425 G4RunManager::GetRunManager()->GeometryHasBeenModified();
426}
427
428void ExN07DetectorConstruction::SetNumberOfLayers(G4int nl)
429{
430 numberOfLayers = nl;
431 layerThickness = totalThickness/numberOfLayers;
432 if(!constructed) return;
433
434 layerSolid->SetZHalfLength(layerThickness/2.);
435 gapSolid->SetZHalfLength(layerThickness/4.);
436 for(size_t i=0;i<3;i++)
437 {
438 calorLogical[i]->RemoveDaughter(layerPhysical[i]);
439 delete layerPhysical[i];
440 layerPhysical[i] = new G4PVReplica(calName[i]+"_Layer",layerLogical[i],calorLogical[i],kZAxis,
441 numberOfLayers,layerThickness);
442 gapPhysical[i]->SetTranslation(G4ThreeVector(0.,0.,layerThickness/4.));
443 }
444 G4RunManager::GetRunManager()->GeometryHasBeenModified();
445}
446
447void ExN07DetectorConstruction::AddMaterial()
448{
449 static G4bool isAdded = false;
450
451 if( isAdded ) return;
452
453 G4String name, symbol; //a=mass of a mole;
454 G4double a, z, density; //z=mean number of protons;
455
456 G4int ncomponents, natoms;
457
458 //
459 // define simple materials
460 //
461
462 new G4Material(name="Copper", z=29., a=63.546*g/mole, density=8.96*g/cm3);
463 new G4Material(name="Tungsten", z=74., a=183.84*g/mole, density=19.3*g/cm3);
464
465 G4Element* C = G4Element::GetElement("Carbon");
466 G4Element* O = G4Element::GetElement("Oxygen");
467
468
469 G4Material* CO2 =
470 new G4Material("CarbonicGas", density= 27.*mg/cm3, ncomponents=2,
471 kStateGas, 325.*kelvin, 50.*atmosphere);
472 CO2->AddElement(C, natoms=1);
473 CO2->AddElement(O, natoms=2);
474
475 isAdded = true;
476
477}
Note: See TracBrowser for help on using the repository browser.