Loading...
Searching...
No Matches
RE06DetectorConstruction.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/// \file RE06/src/RE06DetectorConstruction.cc
27/// \brief Implementation of the RE06DetectorConstruction class
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"
45#include "G4MultiFunctionalDetector.hh"
46#include "G4VPrimitiveScorer.hh"
47#include "G4PSEnergyDeposit.hh"
48#include "G4PSNofSecondary.hh"
49#include "G4PSTrackLength.hh"
50#include "G4PSNofStep.hh"
51#include "G4PSMinKinEAtGeneration.hh"
52#include "G4VSDFilter.hh"
53#include "G4SDParticleFilter.hh"
54#include "G4ios.hh"
55
58#include "RE06ParallelWorld.hh"
59
60#include "G4PhysicalConstants.hh"
61#include "G4SystemOfUnits.hh"
62
63//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
64
65G4ThreadLocal G4bool RE06DetectorConstruction::fConstructedSDandField = false;
66
69 fNumberOfLayers(40),
70 fTotalThickness (2.0*m),
71 fLayerThickness(0.),
72 fConstructed(false),
73 fWorldMaterial(0),
74 fAbsorberMaterial(0),
75 fGapMaterial(0),
76 fLayerSolid(0),
77 fGapSolid(0),
78 fWorldLogical(0),
79 fWorldPhysical(0),
80 fSerial(false),
81 fDetectorMessenger(0),
82 fVerboseLevel(1)
83{
85
86 for(size_t i=0;i<3;i++)
87 {
88 fCalorLogical[i] = 0;
89 fLayerLogical[i] = 0;
90 fGapLogical[i] = 0;
91 fCalorPhysical[i] = 0;
92 fLayerPhysical[i] = 0;
93 fGapPhysical[i] = 0;
94 }
95
96 fCalName[0] = "Calor-A";
97 fCalName[1] = "Calor-B";
98 fCalName[2] = "Calor-C";
99
101}
102
103//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
104
107
109{
110 if(!fConstructed)
111 {
112 fConstructed = true;
115 }
116 if (GetVerboseLevel()>0) {
118 }
119 return fWorldPhysical;
120}
121
130
131//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
132
134{
135 G4String name, symbol; //a=mass of a mole;
136 G4double a, z, density; //z=mean number of protons;
137 G4int iz; //iz=number of protons in an isotope;
138 G4int n; // n=number of nucleons in an isotope;
139
140 G4int ncomponents, natoms;
141 G4double abundance, fractionmass;
142 G4double temperature, pressure;
143
144 //
145 // define Elements
146 //
147
148 a = 1.01*g/mole;
149 G4Element* H = new G4Element(name="Hydrogen",symbol="H" , z= 1., a);
150
151 a = 12.01*g/mole;
152 G4Element* C = new G4Element(name="Carbon" ,symbol="C" , z= 6., a);
153
154 a = 14.01*g/mole;
155 G4Element* N = new G4Element(name="Nitrogen",symbol="N" , z= 7., a);
156
157 a = 16.00*g/mole;
158 G4Element* O = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
159
160 //
161 // define an Element from isotopes, by relative abundance
162 //
163
164 G4Isotope* U5 = new G4Isotope(name="U235", iz=92, n=235, a=235.01*g/mole);
165 G4Isotope* U8 = new G4Isotope(name="U238", iz=92, n=238, a=238.03*g/mole);
166
167 G4Element* U = new G4Element(name="enriched Uranium",symbol="U",ncomponents=2);
168 U->AddIsotope(U5, abundance= 90.*perCent);
169 U->AddIsotope(U8, abundance= 10.*perCent);
170
171 //
172 // define simple materials
173 //
174
175 new G4Material(name="Aluminium", z=13., a=26.98*g/mole, density=2.700*g/cm3);
176 new G4Material(name="Silicon", z=14., a= 28.09*g/mole, density= 2.33*g/cm3);
177 new G4Material(name="Iron", z=26., a=55.85*g/mole, density=7.87*g/cm3);
178 new G4Material(name="ArgonGas",z=18., a= 39.95*g/mole, density=1.782*mg/cm3);
179 new G4Material(name="He", z=2., a=4.0*g/mole, density=0.1786e-03*g/cm3);
180
181 density = 1.390*g/cm3;
182 a = 39.95*g/mole;
183 G4Material* lAr = new G4Material(name="liquidArgon", z=18., a, density);
184
185 density = 11.35*g/cm3;
186 a = 207.19*g/mole;
187 G4Material* Pb = new G4Material(name="Lead" , z=82., a, density);
188
189 //
190 // define a material from elements. case 1: chemical molecule
191 //
192
193 density = 1.000*g/cm3;
194 G4Material* H2O = new G4Material(name="Water", density, ncomponents=2);
195 H2O->AddElement(H, natoms=2);
196 H2O->AddElement(O, natoms=1);
197
198 density = 1.032*g/cm3;
199 G4Material* Sci = new G4Material(name="Scintillator", density, ncomponents=2);
200 Sci->AddElement(C, natoms=9);
201 Sci->AddElement(H, natoms=10);
202
203 //
204 // define a material from elements. case 2: mixture by fractional mass
205 //
206
207 density = 1.290*mg/cm3;
208 G4Material* Air = new G4Material(name="Air" , density, ncomponents=2);
209 Air->AddElement(N, fractionmass=0.7);
210 Air->AddElement(O, fractionmass=0.3);
211
212 //
213 // examples of vacuum
214 //
215
216 density = universe_mean_density;
217 pressure = 3.e-18*pascal;
218 temperature = 2.73*kelvin;
219 G4Material* Vacuum = new G4Material(name="Galactic", z=1., a=1.01*g/mole,
220 density,kStateGas,temperature,pressure);
221
222 if (GetVerboseLevel()>1) {
223 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
224 }
225
226 //default materials of the calorimeter
227 fWorldMaterial = Vacuum;
229 fGapMaterial = lAr;
230}
231
232//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
233
235{
236 //
237 // World
238 //
239 G4VSolid* worldSolid = new G4Box("World",2.*m,2.*m,fTotalThickness*2.);
240 fWorldLogical = new G4LogicalVolume(worldSolid,fWorldMaterial,"World");
241 fWorldPhysical = new G4PVPlacement(0,G4ThreeVector(),fWorldLogical,"World",
242 0,false,0);
243
244 //
245 // Calorimeter
246 //
247 G4VSolid* calorSolid = new G4Box("Calor",0.5*m,0.5*m,fTotalThickness/2.);
248 G4int i;
249 for(i=0;i<3;i++)
250 {
251 fCalorLogical[i]
252 = new G4LogicalVolume(calorSolid,fAbsorberMaterial,fCalName[i]);
253 if(fSerial)
254 {
255 fCalorPhysical[i] = new G4PVPlacement(0,
256 G4ThreeVector(0.,0.,G4double(i-1)*fTotalThickness),
257 fCalorLogical[i],fCalName[i],fWorldLogical,false,i);
258 }
259 else
260 {
261 fCalorPhysical[i] = new G4PVPlacement(0,
262 G4ThreeVector(0.,G4double(i-1)*m,0.),
263 fCalorLogical[i],fCalName[i],fWorldLogical,false,i);
264 }
265 }
266
267 //
268 // Layers --- as absorbers
269 //
270 fLayerSolid = new G4Box("Layer",0.5*m,0.5*m,fLayerThickness/2.);
271 for(i=0;i<3;i++)
272 {
273 fLayerLogical[i]
276 = new G4PVReplica(fCalName[i]+"_Layer",fLayerLogical[i],fCalorLogical[i],
278 }
279
280 //
281 // Gap
282 //
283 fGapSolid = new G4Box("Gap",0.5*m,0.5*m,fLayerThickness/4.);
284 for(i=0;i<3;i++)
285 {
287 fGapPhysical[i] = new G4PVPlacement(0,G4ThreeVector(0.,0.,fLayerThickness/4.),
288 fGapLogical[i],fCalName[i]+"_gap",fLayerLogical[i],false,0);
289 }
290
291 //
292 // Regions
293 //
294 for(i=0;i<3;i++)
295 {
296 G4Region* aRegion = new G4Region(fCalName[i]);
297 fCalorLogical[i]->SetRegion(aRegion);
298 aRegion->AddRootLogicalVolume(fCalorLogical[i]);
299 }
300
301 //
302 // Visualization attributes
303 //
304 fWorldLogical->SetVisAttributes(G4VisAttributes::GetInvisible());
305 G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
306 simpleBoxVisAtt->SetVisibility(true);
307 for(i=0;i<3;i++)
308 {
309 fCalorLogical[i]->SetVisAttributes(simpleBoxVisAtt);
310 fLayerLogical[i]->SetVisAttributes(simpleBoxVisAtt);
311 fGapLogical[i]->SetVisAttributes(simpleBoxVisAtt);
312 }
313
314}
315
316//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
317
319{
320 G4SDManager::GetSDMpointer()->SetVerboseLevel(1);
321 G4String filterName, particleName;
322
323 G4SDParticleFilter* gammaFilter
324 = new G4SDParticleFilter(filterName="gammaFilter",particleName="gamma");
325 G4SDParticleFilter* electronFilter
326 = new G4SDParticleFilter(filterName="electronFilter",particleName="e-");
327 G4SDParticleFilter* positronFilter
328 = new G4SDParticleFilter(filterName="positronFilter",particleName="e+");
329 G4SDParticleFilter* epFilter
330 = new G4SDParticleFilter(filterName="epFilter");
331 epFilter->add(particleName="e-");
332 epFilter->add(particleName="e+");
333
334
335 for(G4int i=0;i<3;i++)
336 {
337 for(G4int j=0;j<2;j++)
338 {
339 // Loop counter j = 0 : absorber
340 // = 1 : gap
341 G4String detName = fCalName[i];
342 if(j==0)
343 { detName += "_abs"; }
344 else
345 { detName += "_gap"; }
347 G4SDManager::GetSDMpointer()->AddNewDetector(det);
348
349 // The second argument in each primitive means the "level" of geometrical
350 // hierarchy, the copy number of that level is used as the key of the
351 // G4THitsMap.
352 // For absorber (j = 0), the copy number of its own physical volume is used.
353 // For gap (j = 1), the copy number of its mother physical volume is used,
354 // since there is only one physical volume of gap is placed with respect
355 // to its mother.
356 G4VPrimitiveScorer* primitive;
357 primitive = new G4PSEnergyDeposit("eDep",j);
358 det->RegisterPrimitive(primitive);
359 primitive = new G4PSNofSecondary("nGamma",j);
360 primitive->SetFilter(gammaFilter);
361 det->RegisterPrimitive(primitive);
362 primitive = new G4PSNofSecondary("nElectron",j);
363 primitive->SetFilter(electronFilter);
364 det->RegisterPrimitive(primitive);
365 primitive = new G4PSNofSecondary("nPositron",j);
366 primitive->SetFilter(positronFilter);
367 det->RegisterPrimitive(primitive);
368 primitive = new G4PSMinKinEAtGeneration("minEkinGamma",j);
369 primitive->SetFilter(gammaFilter);
370 det->RegisterPrimitive(primitive);
371 primitive = new G4PSMinKinEAtGeneration("minEkinElectron",j);
372 primitive->SetFilter(electronFilter);
373 det->RegisterPrimitive(primitive);
374 primitive = new G4PSMinKinEAtGeneration("minEkinPositron",j);
375 primitive->SetFilter(positronFilter);
376 det->RegisterPrimitive(primitive);
377 primitive = new G4PSTrackLength("trackLength",j);
378 primitive->SetFilter(epFilter);
379 det->RegisterPrimitive(primitive);
380 primitive = new G4PSNofStep("nStep",j);
381 primitive->SetFilter(epFilter);
382 det->RegisterPrimitive(primitive);
383
384 if(j==0)
385 { SetSensitiveDetector(fLayerLogical[i], det); }
386 else
387 { SetSensitiveDetector(fGapLogical[i], det);}
388 }
389 }
390 G4SDManager::GetSDMpointer()->SetVerboseLevel(0);
391}
392
394{
395 G4cout
396 << "--------------------------------------------------------" << G4endl;
397 if(fSerial)
398 { G4cout << " Calorimeters are placed in serial." << G4endl; }
399 else
400 { G4cout << " Calorimeters are placed in parallel." << G4endl; }
401 G4cout
402 << " Absorber is made of " << fAbsorberMaterial->GetName() << G4endl
403 << " Gap is made of " << fGapMaterial->GetName() << G4endl
404 << "--------------------------------------------------------" << G4endl;
405}
406
407//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
408
410{
411 // search the material by its name
412 G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
413 if(pttoMaterial)
414 {
415 fAbsorberMaterial = pttoMaterial;
416 if(fConstructed) for(size_t i=0;i<3;i++)
417 {
418 fCalorLogical[i]->SetMaterial(fAbsorberMaterial);
419 fLayerLogical[i]->SetMaterial(fAbsorberMaterial);
420 }
421 G4RunManager::GetRunManager()->GeometryHasBeenModified();
422 if (GetVerboseLevel()>1) {
424 }
425 }
426 else
427 {
428 G4cerr
429 << materialChoice << " is not defined. - Command is ignored." << G4endl;
430 }
431}
432
433//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
434
437
438//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
439
441{
442 // search the material by its name
443 G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
444 if(pttoMaterial)
445 {
446 fGapMaterial = pttoMaterial;
447 if(fConstructed) for(size_t i=0;i<3;i++)
448 { fGapLogical[i]->SetMaterial(fGapMaterial); }
449 G4RunManager::GetRunManager()->GeometryHasBeenModified();
450 if (GetVerboseLevel()>1) {
452 }
453 }
454 else
455 {
456 G4cerr
457 << materialChoice << " is not defined. - Command is ignored." << G4endl;
458 }
459}
460
463
464//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
465
467{
468 if(fSerial==serial) return;
469 fSerial=serial;
471 (G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction());
472 if(gen) gen->SetSerial(fSerial);
473 if(!fConstructed) return;
474 for(G4int i=0;i<3;i++)
475 {
476 if(fSerial)
477 {
479 ->SetTranslation(G4ThreeVector(0.,0.,G4double(i-1)*2.*m));
480 }
481 else
482 {
484 ->SetTranslation(G4ThreeVector(0.,G4double(i-1)*m,0.));
485 }
486 }
487 ((RE06ParallelWorld*)GetParallelWorld(0))->SetSerialGeometry(serial);
488 G4RunManager::GetRunManager()->GeometryHasBeenModified();
489}
490
491//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
492
494{
495 fNumberOfLayers = nl;
497 if(!fConstructed) return;
498
499 fLayerSolid->SetZHalfLength(fLayerThickness/2.);
500 fGapSolid->SetZHalfLength(fLayerThickness/4.);
501 for(size_t i=0;i<3;i++)
502 {
503 fCalorLogical[i]->RemoveDaughter(fLayerPhysical[i]);
504 delete fLayerPhysical[i];
506 = new G4PVReplica(fCalName[i]+"_Layer",fLayerLogical[i],fCalorLogical[i],
508 fGapPhysical[i]->SetTranslation(G4ThreeVector(0.,0.,fLayerThickness/4.));
509 }
510 G4RunManager::GetRunManager()->GeometryHasBeenModified();
511}
512
513//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
514
516{
517 static G4bool isAdded = false;
518
519 if( isAdded ) return;
520
521 G4String name, symbol; //a=mass of a mole;
522 G4double a, z, density; //z=mean number of protons;
523
524 G4int ncomponents, natoms;
525
526 //
527 // define simple materials
528 //
529
530 new G4Material(name="Copper", z=29., a=63.546*g/mole, density=8.96*g/cm3);
531 new G4Material(name="Tungsten", z=74., a=183.84*g/mole, density=19.3*g/cm3);
532
533 G4Element* C = G4Element::GetElement("Carbon");
534 G4Element* O = G4Element::GetElement("Oxygen");
535
536
537 G4Material* CO2 =
538 new G4Material("CarbonicGas", density= 27.*mg/cm3, ncomponents=2,
539 kStateGas, 325.*kelvin, 50.*atmosphere);
540 CO2->AddElement(C, natoms=1);
541 CO2->AddElement(O, natoms=2);
542
543 isAdded = true;
544
545}
546
547//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
std::vector< ExP01TrackerHit * > a
Definition of the RE06DetectorConstruction class.
Definition of the RE06DetectorMessenger class.
Definition of the RE06ParallelWorld class.
Definition of the RE06PrimaryGeneratorAction class.
G4VPhysicalVolume * fCalorPhysical[3]
G4double fLayerThickness
= fTotalThickness / fNumberOfLayers
static G4ThreadLocal G4bool fConstructedSDandField
void SetGapMaterial(G4String materialChoice)
G4VPhysicalVolume * fGapPhysical[3]
G4double fTotalThickness
total thinkness of one calorimeter
virtual G4VPhysicalVolume * Construct()
void SetAbsorberMaterial(G4String materialChoice)
RE06DetectorMessenger * fDetectorMessenger

Applications | User Support | Publications | Collaboration