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