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

Last change on this file since 1288 was 1230, checked in by garnier, 14 years ago

update to geant4.9.3

File size: 15.5 KB
Line 
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: geant4-09-03-cand-01 $
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.