VMC Examples Version 6.6
Loading...
Searching...
No Matches
Ex03cMCApplication.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 Ex03cMCApplication.cxx
11/// \brief Implementation of the Ex03cMCApplication class
12///
13/// Geant4 ExampleN03 adapted to Virtual Monte Carlo
14///
15/// \date 21/08/2019
16/// \author Benedikt Volkel, CERN
17
18#include "Ex03cMCApplication.h"
19#include "Ex03PrimaryGenerator.h"
20#include "Ex03cMCStack.h"
21
22#include <TMCRootManager.h>
23
24#include <TMCManager.h>
25
26#include <Riostream.h>
27#include <TGeoManager.h>
28#include <TGeoUniformMagField.h>
29#include <TInterpreter.h>
30#include <TPDGCode.h>
31#include <TParticle.h>
32#include <TROOT.h>
33#include <TRandom.h>
34#include <TTimer.h>
35#include <TVector3.h>
36#include <TVirtualGeoTrack.h>
37#include <TVirtualMC.h>
38
39#include <TLorentzVector.h>
40
41using namespace std;
42
43/// \cond CLASSIMP
44ClassImp(Ex03cMCApplication)
45 /// \endcond
46
47 //_____________________________________________________________________________
49 const char* name, const char* title, Bool_t isMulti, Bool_t splitSimulation)
50 : TVirtualMCApplication(name, title),
51 fRootManager(0),
52 fPrintModulo(1),
53 fEventNo(0),
54 fVerbose(0),
55 fStack(0),
56 fDetConstruction(0),
57 fCalorimeterSD(0),
58 fPrimaryGenerator(0),
59 fMagField(0),
60 fOldGeometry(kFALSE),
61 fIsControls(kFALSE),
62 fIsMaster(kTRUE),
63 fIsMultiRun(isMulti),
64 fSplitSimulation(splitSimulation),
65 fG3Id(-1),
66 fG4Id(-1),
67 fDebug(0)
68{
69 /// Standard constructor
70 /// \param name The MC application name
71 /// \param title The MC application description
72
73 if (splitSimulation && !isMulti) {
74 Fatal("Ex03cMCApplication",
75 "Cannot split simulation between engines without \"isMulti\" being "
76 "switched on");
77 }
78
79 cout << "--------------------------------------------------------------"
80 << endl;
81 cout << " VMC Example E03c: new version with multiple engines" << endl;
82 cout << "--------------------------------------------------------------"
83 << endl;
84
85 // Create a user stack
86 fStack = new Ex03cMCStack(1000);
87
88 // Create detector construction
89 fDetConstruction = new Ex03cDetectorConstruction();
90
91 // Create a calorimeter SD
92 fCalorimeterSD = new Ex03cCalorimeterSD("Calorimeter", fDetConstruction);
93
94 // Create a primary generator
95 fPrimaryGenerator = new Ex03PrimaryGenerator(fStack);
96
97 // Constant magnetic field (in kiloGauss)
98 fMagField = new TGeoUniformMagField();
99
100 if (isMulti) {
101 RequestMCManager();
102 fMCManager->SetUserStack(fStack);
103 }
104}
105
106//_____________________________________________________________________________
108 : TVirtualMCApplication(origin.GetName(), origin.GetTitle()),
109 fRootManager(0),
110 fPrintModulo(origin.fPrintModulo),
111 fEventNo(0),
112 fVerbose(origin.fVerbose),
113 fStack(0),
114 fDetConstruction(origin.fDetConstruction),
115 fCalorimeterSD(0),
116 fPrimaryGenerator(0),
117 fMagField(0),
118 fOldGeometry(origin.fOldGeometry),
119 fIsControls(origin.fIsControls),
120 fIsMaster(kFALSE),
121 fIsMultiRun(origin.fIsMultiRun),
122 fSplitSimulation(origin.fSplitSimulation),
123 fG3Id(origin.fG3Id),
124 fG4Id(origin.fG4Id),
125 fDebug(origin.fDebug)
126{
127 /// Copy constructor for cloning application on workers (in multithreading
128 /// mode) \param origin The source MC application
129
130 // Create new user stack
131 fStack = new Ex03cMCStack(1000);
132
133 // Create a calorimeter SD
136
137 // Create a primary generator
140
141 // Constant magnetic field (in kiloGauss)
142 fMagField = new TGeoUniformMagField(origin.fMagField->GetFieldValue()[0],
143 origin.fMagField->GetFieldValue()[1], origin.fMagField->GetFieldValue()[2]);
144}
145
146//_____________________________________________________________________________
149 fRootManager(0),
150 fPrintModulo(1),
151 fEventNo(0),
152 fStack(0),
153 fDetConstruction(0),
154 fCalorimeterSD(0),
155 fPrimaryGenerator(0),
156 fMagField(0),
157 fOldGeometry(kFALSE),
158 fIsControls(kFALSE),
159 fIsMaster(kTRUE),
160 fIsMultiRun(kFALSE),
161 fSplitSimulation(kFALSE),
162 fG3Id(-1),
163 fG4Id(-1),
164 fDebug(0)
165{
166 /// Default constructor
167}
168
169//_____________________________________________________________________________
171{
172 /// Destructor
173
174 // cout << "Ex03cMCApplication::~Ex03cMCApplication " << this << endl;
175
176 delete fRootManager;
177 delete fStack;
178 if (fIsMaster) delete fDetConstruction;
179 delete fCalorimeterSD;
180 delete fPrimaryGenerator;
181 delete fMagField;
182 if (!fIsMultiRun) {
183 delete fMC;
184 }
185
186 // cout << "Done Ex03cMCApplication::~Ex03cMCApplication " << this << endl;
187}
188
189//
190// private methods
191//
192
193//_____________________________________________________________________________
195{
196 /// Register stack in the Root manager.
197
198 if (fRootManager) {
199 // cout << "Ex03cMCApplication::RegisterStack: " << endl;
200 fRootManager->Register("stack", "Ex03cMCStack", &fStack);
201 }
202}
203
204//
205// public methods
206//
207
208//_____________________________________________________________________________
209void Ex03cMCApplication::InitMC(const char* setup)
210{
211 /// Initialize MC.
212 /// The selection (and creation) of the concrete MC is done in the macro.
213 /// If no macro is provided, the MC must be created before calling this
214 /// function. \param setup The name of the configuration macro.
215
216 fVerbose.InitMC();
217
218 if (TString(setup) != "") {
219 gROOT->LoadMacro(setup);
220 gInterpreter->ProcessLine("Config()");
221 if (!fMC) {
222 Fatal(
223 "InitMC", "Processing Config() has failed. (No MC is instantiated.)");
224 }
225 }
226
227// MT support available from root v 5.34/18
228#if ROOT_VERSION_CODE >= 336402
229 // Create Root manager
230 if (!fMC->IsMT()) {
231 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
232 // fRootManager->SetDebug(true);
233 }
234#else
235 // Create Root manager
236 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
237// fRootManager->SetDebug(true);
238#endif
239
240 fMC->SetStack(fStack);
241 fMC->SetRootGeometry();
242 fMC->SetMagField(fMagField);
243 fMC->Init();
244 fMC->BuildPhysics();
245
247
248 if (fDebug > 0) {
249 Info("InitMC", "Single run initialised");
250 }
251}
252
253//_____________________________________________________________________________
254void Ex03cMCApplication::InitMC(std::initializer_list<const char*> setupMacros)
255{
256 /// Initialize MC.
257 /// New function for initialization with multiple engines.
258 /// \param setupMacros The names of the configuration macros.
259
260 fVerbose.InitMC();
261
262 if (!fIsMultiRun) {
263 Fatal("InitMC",
264 "Initialisation of multiple engines not supported in single run");
265 }
266
267 if (setupMacros.size() > 0) {
268 for (const char* setup : setupMacros) {
269 gROOT->LoadMacro(setup);
270 gInterpreter->ProcessLine("Config()");
271 if (!fMC) {
272 Fatal(
273 "InitMC", "Processing Config() has failed. (No MC is instantiated.)");
274 }
275 // gInterpreter->UnloadAllSharedLibraryMaps();
276 gInterpreter->UnloadFile(setup);
277 }
278 }
279
280 InitMC();
281}
282
283//_____________________________________________________________________________
285{
286 /// Initialize MC.
287 /// New function for initialization with multiple engines.
288 /// The MCs must be created before calling this function.
289
290 if (!fIsMultiRun) {
291 Fatal("InitMC",
292 "Initialisation of multiple engines not supported in single run");
293 }
294
295// MT support available from root v 5.34/18
296#if ROOT_VERSION_CODE >= 336402
297 // Create Root manager
298 if (!fMC->IsMT()) {
299 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
300 // fRootManager->SetDebug(true);
301 }
302#else
303 // Create Root manager
304 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
305// fRootManager->SetDebug(true);
306#endif
307
308 fMCManager->Init([this](TVirtualMC* mc) {
309 mc->SetRootGeometry();
310 mc->SetMagField(this->fMagField);
311 mc->Init();
312 mc->BuildPhysics();
313 });
315
316 fG3Id = fMCManager->GetEngineId("TGeant3TGeo");
317 fG4Id = fMCManager->GetEngineId("TGeant4");
318 if (fDebug > 0) {
319 Info("InitMC", "Multi run initialised");
320 std::cout << "Engine IDs\n"
321 << "TGeant3TGeo: " << fG3Id << "\n"
322 << "TGeant4: " << fG4Id << std::endl;
323 }
324}
325
326//_____________________________________________________________________________
327void Ex03cMCApplication::RunMC(Int_t nofEvents)
328{
329 /// Run MC.
330 /// \param nofEvents Number of events to be processed
331
332 fVerbose.RunMC(nofEvents);
333
334 // Prepare a timer
335 TTimer timer;
336
337 if (!fIsMultiRun) {
338 if (fDebug > 0) {
339 Info("RunMC", "Start single run");
340 std::cout << "Simulation entirely done with engine " << fMC->GetName()
341 << std::endl;
342 timer.Start();
343 }
344 fMC->ProcessRun(nofEvents);
345 }
346 else {
347 if (fDebug > 0) {
348 Info("RunMC", "Start multi run");
349 if (fSplitSimulation) {
350 std::cout << "GAPX simulated with engine "
351 << fMCManager->GetEngine(0)->GetName() << "\n"
352 << "ABSO simulated with engine "
353 << fMCManager->GetEngine(1)->GetName() << std::endl;
354 }
355 else {
356 std::cout << "Simulation entirely done with engine "
357 << fMCManager->GetCurrentEngine()->GetName() << std::endl;
358 }
359 timer.Start();
360 }
361 fMCManager->Run(nofEvents);
362 }
363 if (fDebug > 0) {
364 timer.Stop();
365 Info("RunMC", "Transport finished.");
366 timer.Print();
367 }
368 FinishRun();
369}
370
371//_____________________________________________________________________________
373{
374 /// Finish MC run.
375
376 fVerbose.FinishRun();
377 // cout << "Ex03cMCApplication::FinishRun: " << endl;
378 if (fRootManager) {
379 fRootManager->WriteAll();
380 fRootManager->Close();
381 }
382}
383
384//_____________________________________________________________________________
389
390//_____________________________________________________________________________
392{
393 // cout << "Ex03cMCApplication::InitForWorker " << this << endl;
394
395 // Create Root manager
396 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
397 // fRootManager->SetDebug(true);
398
399 // Set data to MC
400 fMC->SetStack(fStack);
401 fMC->SetMagField(fMagField);
402
404}
405
406//_____________________________________________________________________________
408{
409 // cout << "Ex03cMCApplication::FinishWorkerRun: " << endl;
410 if (fRootManager) {
411 fRootManager->WriteAll();
412 fRootManager->Close();
413 }
414}
415
416//_____________________________________________________________________________
418{
419 /// Read \em i -th event and prints hits.
420 /// \param i The number of event to be read
421
424 fRootManager->ReadEvent(i);
425}
426
427//_____________________________________________________________________________
429{
430 /// Construct geometry using detector contruction class.
431 /// The detector contruction class is using TGeo functions or
432 /// TVirtualMC functions (if oldGeometry is selected)
433
434 fVerbose.ConstructGeometry();
435
436 if (fOldGeometry) {
437 Fatal("ConstructGeometry", "Cannot run with old geomtry");
438 }
441 // TGeoManager::Import("geometry.root");
442 // fMC->SetRootGeometry();
443}
444
445//_____________________________________________________________________________
447{
448 /// Initialize geometry
449
450 fVerbose.InitGeometry();
451
453
455
457}
458
459//_____________________________________________________________________________
461{
462 /// Example of user defined particle with user defined decay mode
463
464 fVerbose.AddParticles();
465
466 // Define the 2 body phase space decay for He5
467 Int_t mode[6][3];
468 Float_t bratio[6];
469
470 for (Int_t kz = 0; kz < 6; kz++) {
471 bratio[kz] = 0.;
472 mode[kz][0] = 0;
473 mode[kz][1] = 0;
474 mode[kz][2] = 0;
475 }
476 bratio[0] = 100.;
477 mode[0][0] = kNeutron; // neutron (2112)
478 mode[0][1] = 1000020040; // alpha
479
480 // Overwrite a decay mode already defined in MCs
481 // Kaon Short: 310 normally decays in two modes
482 // pi+, pi- 68.61 %
483 // pi0, pi0 31.39 %
484 // and we force only the mode pi0, pi0
485
486 Int_t mode2[6][3];
487 Float_t bratio2[6];
488
489 for (Int_t kz = 0; kz < 6; kz++) {
490 bratio2[kz] = 0.;
491 mode2[kz][0] = 0;
492 mode2[kz][1] = 0;
493 mode2[kz][2] = 0;
494 }
495 bratio2[0] = 100.;
496 mode2[0][0] = kPi0; // pi0 (111)
497 mode2[0][1] = kPi0; // pi0 (111)
498
499 // Define particle
500 fMC->DefineParticle(1000020050, "He5", kPTHadron, 5.03427, 2.0, 0.002, "Ion",
501 0.0, 0, 1, 0, 0, 0, 0, 0, 5, kFALSE);
502 fMC->SetDecayMode(1000020050, bratio, mode);
503 fMC->SetDecayMode(kK0Short, bratio2, mode2);
504}
505
506//_____________________________________________________________________________
508{
509 /// Example of user defined ion
510
511 fVerbose.AddIons();
512 fMC->DefineIon("MyIon", 34, 70, 12, 0.);
513}
514
515//_____________________________________________________________________________
517{
518 /// Fill the user stack (derived from TVirtualMCStack) with primary particles.
519
520 fVerbose.GeneratePrimaries();
521
522 TVector3 origin(fDetConstruction->GetWorldSizeX(),
524
526}
527
528//_____________________________________________________________________________
530{
531 /// User actions at beginning of event
532
533 fVerbose.BeginEvent();
534
535 // Clear TGeo tracks (if filled)
536 if (!fIsMultiRun && TString(fMC->GetName()) == "TGeant3TGeo" &&
537 gGeoManager->GetListOfTracks() && gGeoManager->GetTrack(0) &&
538 ((TVirtualGeoTrack*)gGeoManager->GetTrack(0))->HasPoints()) {
539
540 gGeoManager->ClearTracks();
541 // if (gPad) gPad->Clear();
542 }
543
544 fEventNo++;
545 if (fEventNo % fPrintModulo == 0) {
546 cout << "\n---> Begin of event: " << fEventNo << endl;
547 // ??? How to do this in VMC
548 // HepRandom::showEngineStatus();
549 }
550}
551
552//_____________________________________________________________________________
554{
555 /// User actions at beginning of a primary track.
556 /// If test for user defined decay is activated,
557 /// the primary track ID is printed on the screen.
558
559 fVerbose.BeginPrimary();
560
562 cout << " Primary track ID = " << fStack->GetCurrentTrackNumber() << endl;
563 }
564}
565
566//_____________________________________________________________________________
568{
569 /// User actions at beginning of each track
570 /// If test for user defined decay is activated,
571 /// the decay products of the primary track (K0Short)
572 /// are printed on the screen.
573
574 fVerbose.PreTrack();
575
576 // print info about K0Short decay products
578 Int_t parentID = fStack->GetCurrentParentTrackNumber();
579
580 if (parentID >= 0 &&
581 fStack->GetParticle(parentID)->GetPdgCode() == kK0Short &&
582 fStack->GetCurrentTrack()->GetUniqueID() == kPDecay) {
583 // The production process is saved as TParticle unique ID
584 // via Ex03cMCStack
585
586 cout << " Current track " << fStack->GetCurrentTrack()->GetName()
587 << " is a decay product of Parent ID = "
589 }
590 }
591}
592
593//_____________________________________________________________________________
595{
596 /// User actions at each step
597
598 fVerbose.Stepping();
599
601
602 TLorentzVector pos;
603 TLorentzVector mom;
604
605 fMC->TrackPosition(pos);
606 fMC->TrackMomentum(mom);
607
608 if (fDebug > 1) {
609 std::cout << "Current engine " << fMC->GetName() << "\n"
610 << "Track ID=" << fStack->GetCurrentTrackNumber() << "\n"
611 << "Momentum\n"
612 << "E=" << mom.T() << ", Px=" << mom.X() << ", Py=" << mom.Y()
613 << ", Pz=" << mom.Z() << std::endl;
614 }
615
616 // Now transfer track
617 if (fSplitSimulation) {
618 Int_t targetId = -1;
619 if (fMC->GetId() == 0 && strcmp(fMC->CurrentVolName(), "ABSO") == 0) {
620 targetId = 1;
621 }
622 else if (fMC->GetId() == 1 && strcmp(fMC->CurrentVolName(), "GAPX") == 0) {
623 targetId = 0;
624 }
625 if (targetId > -1) {
626 if (fDebug > 1) {
627 Info("Stepping", "Transfer track");
628 }
629 fMCManager->TransferTrack(targetId);
630 }
631 }
632}
633
634//_____________________________________________________________________________
636{
637 /// User actions after finishing of each track
638 fVerbose.PostTrack();
639}
640
641//_____________________________________________________________________________
643{
644 /// User actions after finishing of a primary track
645
646 fVerbose.FinishPrimary();
647
649 cout << endl;
650 }
651}
652
653//_____________________________________________________________________________
655{
656 /// User actions after finishing of an event
657
658 fVerbose.FinishEvent();
659
660 // Geant3 + TGeo
661 // (use TGeo functions for visualization)
662 if (!fIsMultiRun && TString(fMC->GetName()) == "TGeant3TGeo") {
663
664 // Draw volume
665 gGeoManager->SetVisOption(0);
666 gGeoManager->SetTopVisible();
667 gGeoManager->GetTopVolume()->Draw();
668
669 // Draw tracks (if filled)
670 // Available when this feature is activated via
671 // fMC->SetCollectTracks(kTRUE);
672 if (gGeoManager->GetListOfTracks() && gGeoManager->GetTrack(0) &&
673 ((TVirtualGeoTrack*)gGeoManager->GetTrack(0))->HasPoints()) {
674
675 gGeoManager->DrawTracks("/*"); // this means all tracks
676 }
677 }
678
679 fRootManager->Fill();
680
682
684
685 fStack->Reset();
686}
Definition of the Ex03cMCApplication class.
Definition of the Ex03cMCStack class.
The primary generator.
virtual void GeneratePrimaries(const TVector3 &worldSize)
Bool_t GetUserDecay() const
Return true if particle with user decay is activated.
The calorimeter sensitive detector.
The detector construction (via TGeo )
Implementation of the TVirtualMCApplication.
TGeoUniformMagField * fMagField
Magnetic field.
TMCRootManager * fRootManager
Root manager.
Ex03PrimaryGenerator * fPrimaryGenerator
Primary generator.
Ex03cDetectorConstruction * fDetConstruction
Dector construction.
Int_t fG3Id
engine ID of Geant3
TMCVerbose fVerbose
VMC verbose helper.
Ex03cCalorimeterSD * fCalorimeterSD
Calorimeter SD.
virtual void GeneratePrimaries()
void RunMC(Int_t nofEvents)
Bool_t fOldGeometry
Option for geometry definition.
Bool_t fIsControls
Option to activate special controls.
Int_t fPrintModulo
The event modulus number to be printed.
Bool_t fIsMultiRun
Flag if having multiple engines.
virtual TVirtualMCApplication * CloneForWorker() const
Bool_t fIsMaster
If is on master thread.
Bool_t fSplitSimulation
Split geometry given user criteria.
Ex03cMCStack * fStack
VMC stack.
Int_t fEventNo
Event counter.
virtual void ConstructGeometry()
virtual void FinishRunOnWorker()
Int_t fG4Id
engine ID of Geant4
Int_t fDebug
debug option for multiple run
Implementation of the TVirtualMCStack interface.
virtual TParticle * GetCurrentTrack() const
virtual Int_t GetCurrentParentTrackNumber() const
virtual Int_t GetCurrentTrackNumber() const
TParticle * GetParticle(Int_t id) const