VMC Examples Version 6.6
Loading...
Searching...
No Matches
Ex03DetectorConstruction.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Virtual Monte Carlo examples
3// Copyright (C) 2014 - 2018 Ivana Hrivnacova
4// All rights reserved.
5//
6// For the licensing terms see geant4_vmc/LICENSE.
7// Contact: root-vmc@cern.ch
8//-------------------------------------------------
9
10/// \file Ex03DetectorConstruction.cxx
11/// \brief Implementation of the Ex03DetectorConstruction class
12///
13/// Geant4 ExampleN03 adapted to Virtual Monte Carlo \n
14/// Id: ExN03DetectorConstruction.cc,v 1.11 2002/01/09 17:24:12 ranjard Exp \n
15///
16/// 11/12/2008:
17/// - Updated materials definition using directly Root objects
18/// - Added new materials according to:
19/// Id: ExN03DetectorConstruction.cc,v 1.24 2008/08/12 20:00:03 gum Exp
20/// GEANT4 tag Name: geant4-09-01-ref-09
21/// - Changed cuts in SetCuts() according to Geant4 09-01-ref-09
22///
23/// \date 06/03/2002
24/// \author I. Hrivnacova; IPN, Orsay
25
26#include <Riostream.h>
27#include <TGeoElement.h>
28#include <TGeoManager.h>
29#include <TGeoMaterial.h>
30#include <TList.h>
31#include <TThread.h>
32#include <TVirtualMC.h>
33
34#include <set>
35
36#include "Ex03DetectorConstruction.h"
37
38using namespace std;
39
40/// \cond CLASSIMP
42 /// \endcond
43
44 //_____________________________________________________________________________
46 : TObject(),
47 fNbOfLayers(0),
48 fWorldSizeX(0.),
49 fWorldSizeYZ(0.),
50 fCalorSizeYZ(0.),
51 fCalorThickness(0.),
52 fLayerThickness(0.),
53 fAbsorberThickness(0.),
54 fGapThickness(0.),
55 fDefaultMaterial("Galactic"),
56 fAbsorberMaterial("Lead"),
57 fGapMaterial("liquidArgon")
58{
59 /// Default constuctor
60
61 // default parameter values of the calorimeter (in cm)
62 fAbsorberThickness = 1.;
63 fGapThickness = 0.5;
64 fNbOfLayers = 10;
65 fCalorSizeYZ = 10.;
66
67 ComputeCalorParameters();
68}
69
70//_____________________________________________________________________________
72{
73 /// Destructor
74}
75
76//
77// private methods
78//
79
80//_____________________________________________________________________________
82{
83 /// Compute derived parameters of the calorimeter
84
87
90}
91
92//
93// public methods
94//
95
96//_____________________________________________________________________________
98{
99 /// Construct materials using TGeo modeller
100
101 //
102 // Tracking medias (defaut parameters)
103 //
104
105 // Create Root geometry manager
106 new TGeoManager("E03_geometry", "E03 VMC example geometry");
107
108 //--------- Material definition ---------
109
110 TString name; // Material name
111 Double_t a; // Mass of a mole in g/mole
112 Double_t z; // Atomic number
113 Double_t density; // Material density in g/cm3
114
115 //
116 // define simple materials
117 //
118
119 new TGeoMaterial("Aluminium", a = 26.98, z = 13., density = 2.700);
120
121 new TGeoMaterial("liquidArgon", a = 39.95, z = 18., density = 1.390);
122
123 new TGeoMaterial("Lead", a = 207.19, z = 82., density = 11.35);
124
125 //
126 // define a material from elements. case 1: chemical molecule
127 //
128
129 // Elements
130
131 TGeoElement* elH = new TGeoElement("Hydrogen", "H", z = 1, a = 1.01);
132 TGeoElement* elC = new TGeoElement("Carbon", "C", z = 6., a = 12.01);
133 TGeoElement* elN = new TGeoElement("Nitrogen", "N", z = 7., a = 14.01);
134 TGeoElement* elO = new TGeoElement("Oxygen", "O", z = 8., a = 16.00);
135 TGeoElement* elSi = new TGeoElement("Silicon", "Si", z = 14., a = 28.09);
136
137 /*
138 // define an Element from isotopes, by relative abundance
139 // (cannot be done with TGeo)
140
141 G4Isotope* U5 = new G4Isotope("U235", iz=92, n=235, a=235.01*g/mole);
142 G4Isotope* U8 = new G4Isotope("U238", iz=92, n=238, a=238.03*g/mole);
143
144 G4Element* U = new G4Element("enriched Uranium",symbol="U",ncomponents=2);
145 U->AddIsotope(U5, abundance= 90.*perCent);
146 U->AddIsotope(U8, abundance= 10.*perCent);
147 */
148
149 TGeoMixture* matH2O = new TGeoMixture("Water", 2, density = 1.000);
150 matH2O->AddElement(elH, 2);
151 matH2O->AddElement(elO, 1);
152 // overwrite computed meanExcitationEnergy with ICRU recommended value
153 // (cannot be done with TGeo)
154 // H2O->GetIonisation()->SetMeanExcitationEnergy(75.0*eV);
155
156 TGeoMixture* matSci = new TGeoMixture("Scintillator", 2, density = 1.032);
157 matSci->AddElement(elC, 9);
158 matSci->AddElement(elH, 10);
159
160 TGeoMixture* matMyl = new TGeoMixture("Mylar", 3, density = 1.397);
161 matMyl->AddElement(elC, 10);
162 matMyl->AddElement(elH, 8);
163 matMyl->AddElement(elO, 4);
164
165 TGeoMixture* matSiO2 = new TGeoMixture("quartz", 2, density = 2.200);
166 matSiO2->AddElement(elSi, 1);
167 matSiO2->AddElement(elO, 2);
168
169 //
170 // define a material from elements. case 2: mixture by fractional mass
171 //
172
173 TGeoMixture* matAir = new TGeoMixture("Air", 2, density = 1.29e-03);
174 matAir->AddElement(elN, 0.7);
175 matAir->AddElement(elO, 0.3);
176
177 //
178 // Define a material from elements and/or others materials (mixture of
179 // mixtures)
180 //
181
182 TGeoMixture* matAerog = new TGeoMixture("Aerogel", 3, density = 0.200);
183 matAerog->AddElement(matSiO2, 0.625);
184 matAerog->AddElement(matH2O, 0.374);
185 matAerog->AddElement(elC, 0.001);
186
187 //
188 // examples of gas in non STP conditions
189 //
190
191 TGeoMixture* matCO2 = new TGeoMixture("CarbonicGas", 2, density = 1.842e-03);
192 matCO2->AddElement(elC, 1);
193 matCO2->AddElement(elO, 2);
194
195 Double_t atmosphere = 6.32421e+08;
196 Double_t pressure = 50. * atmosphere;
197 Double_t temperature = 325.;
198 matCO2->SetPressure(pressure);
199 matCO2->SetTemperature(temperature);
200 matCO2->SetState(TGeoMaterial::kMatStateGas);
201
202 TGeoMixture* matSteam = new TGeoMixture("WaterSteam", 1, density = 0.3e-03);
203 matSteam->AddElement(matH2O, 1.0);
204
205 pressure = 2. * atmosphere;
206 temperature = 500.;
207 matSteam->SetPressure(pressure);
208 matSteam->SetTemperature(temperature);
209 matSteam->SetState(TGeoMaterial::kMatStateGas);
210
211 //
212 // examples of vacuum
213 //
214
215 new TGeoMaterial("Galactic", a = 1.e-16, z = 1.e-16, density = 1.e-16);
216
217 TGeoMixture* matBeam = new TGeoMixture("Beam", 1, density = 1.e-5);
218 matBeam->AddElement(matAir, 1.0);
219
220 pressure = 2. * atmosphere;
221 temperature = STP_temperature;
222 matBeam->SetPressure(pressure);
223 matBeam->SetTemperature(temperature);
224 matBeam->SetState(TGeoMaterial::kMatStateGas);
225
226 //
227 // Tracking media
228 //
229
230 // Paremeter for tracking media
231 Double_t param[20];
232 param[0] = 0; // isvol - Not used
233 param[1] = 2; // ifield - User defined magnetic field
234 param[2] = 10.; // fieldm - Maximum field value (in kiloGauss)
235 param[3] = -20.; // tmaxfd - Maximum angle due to field deflection
236 param[4] = -0.01; // stemax - Maximum displacement for multiple scat
237 param[5] = -.3; // deemax - Maximum fractional energy loss, DLS
238 param[6] = .001; // epsil - Tracking precision
239 param[7] = -.8; // stmin
240 for (Int_t i = 8; i < 20; ++i) param[i] = 0.;
241
242 Int_t mediumId = 0;
243 TList* materials = gGeoManager->GetListOfMaterials();
244 TIter next(materials);
245 while (TObject* obj = next()) {
246 TGeoMaterial* material = (TGeoMaterial*)obj;
247 new TGeoMedium(material->GetName(), ++mediumId, material, param);
248 }
249}
250
251//_____________________________________________________________________________
253{
254 /// Contruct volumes using TGeo modeller
255
256 // Complete the Calor parameters definition
258
259 Double_t* ubuf = 0;
260
261 // Media Ids
262 Int_t defaultMediumId =
263 gGeoManager->GetMedium(fDefaultMaterial.Data())->GetId();
264 Int_t absorberMediumId =
265 gGeoManager->GetMedium(fAbsorberMaterial.Data())->GetId();
266 Int_t gapMediumId = gGeoManager->GetMedium(fGapMaterial.Data())->GetId();
267
268 //
269 // World
270 //
271
272 Double_t world[3];
273 world[0] = fWorldSizeX / 2.;
274 world[1] = fWorldSizeYZ / 2.;
275 world[2] = fWorldSizeYZ / 2.;
276 TGeoVolume* top =
277 gGeoManager->Volume("WRLD", "BOX", defaultMediumId, world, 3);
278 gGeoManager->SetTopVolume(top);
279
280 //
281 // Calorimeter
282 //
283 if (fCalorThickness > 0.) {
284
285 Double_t calo[3];
286 calo[0] = fCalorThickness / 2.;
287 calo[1] = fCalorSizeYZ / 2.;
288 calo[2] = fCalorSizeYZ / 2.;
289 gGeoManager->Volume("CALO", "BOX", defaultMediumId, calo, 3);
290
291 Double_t posX = 0.;
292 Double_t posY = 0.;
293 Double_t posZ = 0.;
294 gGeoManager->Node("CALO", 1, "WRLD", posX, posY, posZ, 0, kTRUE, ubuf);
295
296 // Divide calorimeter along X axis to place layers
297 //
298 Double_t start = -calo[0];
299 Double_t width = fCalorThickness / fNbOfLayers;
300 gGeoManager->Division("CELL", "CALO", 1, fNbOfLayers, start, width);
301
302 //
303 // Layer
304 //
305 Double_t layer[3];
306 layer[0] = fLayerThickness / 2.;
307 layer[1] = fCalorSizeYZ / 2.;
308 layer[2] = fCalorSizeYZ / 2.;
309 gGeoManager->Volume("LAYE", "BOX", defaultMediumId, layer, 3);
310
311 posX = 0.;
312 posY = 0.;
313 posZ = 0.;
314 gGeoManager->Node("LAYE", 1, "CELL", posX, posY, posZ, 0, kTRUE, ubuf);
315 }
316
317 //
318 // Absorber
319 //
320
321 if (fAbsorberThickness > 0.) {
322
323 Double_t abso[3];
324 abso[0] = fAbsorberThickness / 2;
325 abso[1] = fCalorSizeYZ / 2.;
326 abso[2] = fCalorSizeYZ / 2.;
327 gGeoManager->Volume("ABSO", "BOX", absorberMediumId, abso, 3);
328
329 Double_t posX = -fGapThickness / 2.;
330 Double_t posY = 0.;
331 Double_t posZ = 0.;
332 gGeoManager->Node("ABSO", 1, "LAYE", posX, posY, posZ, 0, kTRUE, ubuf);
333 }
334
335 //
336 // Gap
337 //
338
339 if (fGapThickness > 0.) {
340
341 Double_t gap[3];
342 gap[0] = fGapThickness / 2;
343 gap[1] = fCalorSizeYZ / 2.;
344 gap[2] = fCalorSizeYZ / 2.;
345 gGeoManager->Volume("GAPX", "BOX", gapMediumId, gap, 3);
346
347 Double_t posX = fAbsorberThickness / 2.;
348 Double_t posY = 0.;
349 Double_t posZ = 0.;
350 gGeoManager->Node("GAPX", 1, "LAYE", posX, posY, posZ, 0, kTRUE, ubuf);
351 }
352
353 /*
354 //
355 // Visualization attributes
356 //
357 logicWorld->SetVisAttributes (G4VisAttributes::Invisible);
358 G4VisAttributes* simpleBoxVisAtt= new
359 G4VisAttributes(G4Colour(1.0,1.0,1.0));
360 simpleBoxVisAtt->SetVisibility(true);
361 logicCalor->SetVisAttributes(simpleBoxVisAtt);
362 */
363
364 // close geometry
365 gGeoManager->CloseGeometry();
366
367 // notify VMC about Root geometry
368 gMC->SetRootGeometry();
369
371}
372
373//_____________________________________________________________________________
375{
376 /// Set cuts for e-, gamma equivalent to 1mm cut in G4.
377
378 // created material names
379 std::set<TString> createdMaterials;
380 createdMaterials.insert(fDefaultMaterial);
381 createdMaterials.insert(fAbsorberMaterial);
382 createdMaterials.insert(fGapMaterial);
383
384 // Cuts for e-, gamma equivalent to 1mm cut in G4,
385 // or 10keV (minimal value accepted by Geant3) if lower
386 std::vector<MaterialCuts> materialCutsVector = {
387 MaterialCuts("Aluminium", 10.e-06, 10.e-06, 597.e-06, 597.e-06),
388 MaterialCuts("liquidArgon", 10.e-06, 10.e-06, 342.9e-06, 342.9e-06),
389 MaterialCuts("Lead", 100.5e-06, 100.5e-06, 1.378e-03, 1.378e-03),
390 MaterialCuts("Water", 10.e-06, 10.e-06, 347.2e-06, 347.2e-06),
391 MaterialCuts("Scintillator", 10.e-06, 10.e-06, 355.8e-06, 355.8e-06),
392 MaterialCuts("Mylar", 10.e-06, 10.e-06, 417.5e-06, 417.5e-06),
393 MaterialCuts("quartz", 10.e-06, 10.e-06, 534.1e-06, 534.1e-06),
394 MaterialCuts("Air", 10.e-06, 10.e-06, 10.e-06, 10.e-06),
395 MaterialCuts("Aerogel", 10.e-06, 10.e-06, 119.0e-06, 119.0e-06),
396 MaterialCuts("CarbonicGas", 10.e-09, 10.e-06, 10.e-06, 10.e-06),
397 MaterialCuts("WaterSteam", 10.e-06, 10.e-06, 10.e-06, 10.e-06),
398 MaterialCuts("Galactic", 10.e-06, 10.e-06, 10.e-06, 10.e-06),
399 MaterialCuts("Beam", 10.e-06, 10.e-06, 10.e-06, 10.e-06)
400 };
401
402 // set VMC cutes for created media
403 for (auto materialCuts : materialCutsVector) {
404 // skip materials which were not created (to avoid warning)
405 if (createdMaterials.find(materialCuts.fName) == createdMaterials.end())
406 continue;
407 // set VMC cutes for the medium
408 Int_t mediumId = gMC->MediumId(materialCuts.fName);
409 if (mediumId) {
410 // Set cuts as defined in the vector
411 // gMC->Gstpar(mediumId, "CUTGAM", materialCuts.fCUTGAM);
412 // gMC->Gstpar(mediumId, "BCUTE", materialCuts.fBCUTE);
413 // gMC->Gstpar(mediumId, "CUTELE", materialCuts.fCUTELE);
414 // gMC->Gstpar(mediumId, "DCUTE", materialCuts.fDCUTE);
415 //
416 // Set 100 keV cut everywhere
417 Double_t cut = 100.e-06;
418 gMC->Gstpar(mediumId, "CUTGAM", cut);
419 gMC->Gstpar(mediumId, "BCUTE", cut);
420 gMC->Gstpar(mediumId, "CUTELE", cut);
421 gMC->Gstpar(mediumId, "DCUTE", cut);
422 }
423 }
424}
425
426//_____________________________________________________________________________
428{
429 /// This function demonstrate how to inactivate physics processes via VMC
430 /// controls. Here gamma processes are inactivated in Lead medium. Note that
431 /// while in Geant3 this mechanism is used to speed-up simulation, this may
432 /// cause slow down in Geant4 simulation where implementation of this
433 /// mechanism is quite tricky.
434
435 Int_t mediumId = gMC->MediumId("Lead");
436 if (mediumId) {
437 gMC->Gstpar(mediumId, "COMP", 0);
438 gMC->Gstpar(mediumId, "PAIR", 0);
439 gMC->Gstpar(mediumId, "PHOT", 0);
440 }
441}
442
443//_____________________________________________________________________________
445{
446 /// Print calorimeter parameters
447
448 cout << "\n------------------------------------------------------------"
449 << "\n---> The calorimeter is " << fNbOfLayers << " layers of: [ "
450 << fAbsorberThickness << "cm of " << fAbsorberMaterial << " + "
451 << fGapThickness << "cm of " << fGapMaterial << " ] "
452 << "\n------------------------------------------------------------\n";
453}
454
455//_____________________________________________________________________________
457{
458 /// Set the number of layers.
459 /// \param value The new number of calorimeter layers
460
461 fNbOfLayers = value;
462}
463
464//_____________________________________________________________________________
465void Ex03DetectorConstruction::SetDefaultMaterial(const TString& materialName)
466{
467 /// Set default material
468 /// \param materialName The new default material name.
469
470 fDefaultMaterial = materialName;
471}
472
473//_____________________________________________________________________________
474void Ex03DetectorConstruction::SetAbsorberMaterial(const TString& materialName)
475{
476 /// Set absorer material
477 /// \param materialName The new absorber material name.
478
479 fAbsorberMaterial = materialName;
480}
481
482//_____________________________________________________________________________
483void Ex03DetectorConstruction::SetGapMaterial(const TString& materialName)
484{
485 /// Set gap material
486 /// \param materialName The new gap material name.
487
488 fGapMaterial = materialName;
489}
490
491//_____________________________________________________________________________
493{
494 /// Change the transverse size and recompute the calorimeter parameters
495 /// \param value The new calorimeter tranverse size
496
497 fCalorSizeYZ = value;
498}
499
500//_____________________________________________________________________________
502{
503 /// Change the absorber thickness and recompute the calorimeter parameters
504 /// \param value The new absorber thickness
505
506 fAbsorberThickness = value;
507}
508
509//_____________________________________________________________________________
511{
512 /// Change the gap thickness and recompute the calorimeter parameters
513 /// \param value The new gap thickness
514
515 fGapThickness = value;
516}
517
518/*
519//_____________________________________________________________________________
520void Ex03DetectorConstruction::UpdateGeometry()
521{
522// Not available in VMC
523}
524*/
The detector construction (via TGeo )
Double_t fWorldSizeYZ
The world size y,z component.
Int_t fNbOfLayers
The number of calorimeter layers.
Double_t fGapThickness
The gap thickness.
TString fDefaultMaterial
The default material name.
void SetAbsorberThickness(Double_t value)
TString fAbsorberMaterial
The absorber material name.
Double_t fLayerThickness
The calorimeter layer thickness.
TString fGapMaterial
The gap material name.
Double_t fAbsorberThickness
The absorber thickness.
void SetAbsorberMaterial(const TString &materialName)
void SetDefaultMaterial(const TString &materialName)
Double_t fCalorThickness
The calorimeter thickness.
Double_t fWorldSizeX
The world size x component.
void SetGapMaterial(const TString &materialName)
Double_t fCalorSizeYZ
The calorimeter size y,z component.