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