VMC Examples Version 6.8
Loading...
Searching...
No Matches
Ex03dMCApplication.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 Ex03dMCApplication.cxx
11/// \brief Implementation of the Ex03dMCApplication class
12///
13/// Geant4 ExampleN03 adapted to Virtual Monte Carlo
14///
15/// \date 07/07/2026
16/// \author Radoslaw Karabowicz; GSI
17
18#include "Ex03dMCApplication.h"
19#include "Ex03DetectorConstructionOld.h"
20#include "Ex03PrimaryGenerator.h"
21#include "Ex03dMCStack.h"
22
23#include <Riostream.h>
24#include <TGeoManager.h>
25#include <TGeoUniformMagField.h>
26#include <TInterpreter.h>
27#include <TPDGCode.h>
28#include <TParticle.h>
29#include <TROOT.h>
30#include <TRandom.h>
31#include <TVector3.h>
32#include <TVirtualGeoTrack.h>
33#include <TVirtualMC.h>
34
35using namespace std;
36
37/// \cond CLASSIMP
38ClassImp(Ex03dMCApplication)
39 /// \endcond
40
41 //_____________________________________________________________________________
42 Ex03dMCApplication::Ex03dMCApplication(const char* name, const char* title)
43 : TVirtualMCApplication(name, title),
44 fRootManager(0),
45 fPrintModulo(1),
46 fEventNo(0),
47 fVerbose(0),
48 fStack(0),
52 fMagField(0),
53 fOldGeometry(kFALSE),
54 fIsControls(kFALSE),
55 fIsMaster(kTRUE)
56{
57 /// Standard constructor
58 /// \param name The MC application name
59 /// \param title The MC application description
60
61 cout << "--------------------------------------------------------------"
62 << endl;
63 cout << " VMC Example E03" << endl;
64 cout << "--------------------------------------------------------------"
65 << endl;
66
67 // Create a user stack
68 fStack = new Ex03dMCStack(1000);
69
70 // Create detector construction
72
73 // Create a calorimeter SD
75
76 // Create a primary generator
78
79 // Constant magnetic field (in kiloGauss)
80 fMagField = new TGeoUniformMagField();
81}
82
83//_____________________________________________________________________________
85 : TVirtualMCApplication(origin.GetName(), origin.GetTitle()),
86 fRootManager(0),
88 fEventNo(0),
89 fVerbose(origin.fVerbose),
90 fStack(0),
94 fMagField(0),
96 fIsMaster(kFALSE)
97{
98 /// Copy constructor for cloning application on workers (in multithreading
99 /// mode) \param origin The source MC application
100
101 // Create new user stack
102 fStack = new Ex03dMCStack(1000);
103
104 // Create a calorimeter SD
107
108 // Create a primary generator
111
112 // Constant magnetic field (in kiloGauss)
113 fMagField = new TGeoUniformMagField(origin.fMagField->GetFieldValue()[0],
114 origin.fMagField->GetFieldValue()[1], origin.fMagField->GetFieldValue()[2]);
115}
116
117//_____________________________________________________________________________
120 fRootManager(0),
121 fPrintModulo(1),
122 fEventNo(0),
123 fStack(0),
127 fMagField(0),
128 fOldGeometry(kFALSE),
129 fIsControls(kFALSE),
130 fIsMaster(kTRUE)
131{
132 /// Default constructor
133}
134
135//_____________________________________________________________________________
137{
138 /// Destructor
139
140 delete fRootManager;
141 delete fStack;
142 if (fIsMaster) delete fDetConstruction;
143 delete fCalorimeterSD;
144 delete fPrimaryGenerator;
145 delete fMagField;
146 delete gMC;
147}
148
149//
150// private methods
151//
152
153//_____________________________________________________________________________
155{
156 /// Register stack in the Root manager.
157
158 if (fRootManager) {
159 // cout << "Ex03dMCApplication::RegisterData: " << endl;
160 fStack->Register();
161 fCalorimeterSD->Register();
162 }
163}
164
165//
166// public methods
167//
168
169//_____________________________________________________________________________
171 const char* setup, TMCRootManager::StorageMode storageMode)
172{
173 /// Initialize MC.
174 /// The selection of the concrete MC is done in the macro.
175 /// \param setup The name of the configuration macro
176
177 fVerbose.InitMC();
178
179 if (TString(setup) != "") {
180 gROOT->LoadMacro(setup);
181 gInterpreter->ProcessLine("Config()");
182 if (!gMC) {
183 Fatal(
184 "InitMC", "Processing Config() has failed. (No MC is instantiated.)");
185 }
186 }
187
188 // The write optins must be set before creating TMCRootManager object
189 TMCRootManager::SetStorageMode(storageMode);
190 TMCRootManager::SetDebug(false);
191 TString fileModifier = TMCRootManager::GetFileModifier(storageMode);
192
193 // Create Root manager
194 if ((!gMC->IsMT()) || (storageMode != TMCRootManager::kTTree)) {
195 fRootManager = new TMCRootManager(
196 fileModifier + GetName(), TMCRootManager::kWrite);
197 }
198
199 RegisterData();
200 if (fRootManager) {
201 fRootManager->CreateRNTuple();
202 }
203
204 gMC->SetStack(fStack);
205 gMC->SetMagField(fMagField);
206 gMC->Init();
207 gMC->BuildPhysics();
208}
209
210//_____________________________________________________________________________
211void Ex03dMCApplication::RunMC(Int_t nofEvents)
212{
213 /// Run MC.
214 /// \param nofEvents Number of events to be processed
215
216 fVerbose.RunMC(nofEvents);
217
218 gMC->ProcessRun(nofEvents);
219 FinishRun();
220}
221
222//_____________________________________________________________________________
224{
225 /// Finish MC run.
226
227 fVerbose.FinishRun();
228 // cout << "Ex03dMCApplication::FinishRun: " << endl;
229 if (fRootManager) {
230 fRootManager->WriteAll();
231 fRootManager->Close();
232 }
233}
234
235//_____________________________________________________________________________
240
241//_____________________________________________________________________________
243{
244 // Create Root manager
245 Int_t threadRank = 1;
246 // The real thread rank will be set in MCRootManager
247
248 auto storageMode = TMCRootManager::GetStorageMode();
249 auto fileModifier = TMCRootManager::GetFileModifier(storageMode);
250
251 fRootManager = new TMCRootManager(
252 fileModifier + GetName(), TMCRootManager::kWrite, threadRank);
253
254 // Set data to MC
255 gMC->SetStack(fStack);
256 gMC->SetMagField(fMagField);
257
258 RegisterData();
259 fRootManager->CreateRNTuple();
260}
261
262//_____________________________________________________________________________
264{
265 // cout << "Ex03dMCApplication::FinishWorkerRun: " << endl;
266 if (fRootManager) {
267 fRootManager->WriteAll();
268 fRootManager->Close();
269 }
270}
271
272//_____________________________________________________________________________
273void Ex03dMCApplication::ReadEvent(Int_t i, TMCRootManager::StorageMode storageMode,
274 Int_t threadId)
275{
276 /// Read \em i -th event and prints hits.
277
278 if (!fRootManager) {
279 TMCRootManager::SetStorageMode(storageMode);
280 TMCRootManager::SetDebug(false);
281 TString fileModifier = TMCRootManager::GetFileModifier(storageMode);
282
283 std::cout << "Go to create Root manager: " << fileModifier + GetName() << std:: endl;
284
285 fRootManager = new TMCRootManager(
286 fileModifier + GetName(), TMCRootManager::kRead, threadId);
287 RegisterData();
288 }
289
290 fRootManager->ReadEvent(i);
291}
292
293//_____________________________________________________________________________
295{
296 /// Construct geometry using detector contruction class.
297 /// The detector contruction class is using TGeo functions or
298 /// TVirtualMC functions (if oldGeometry is selected)
299
300 fVerbose.ConstructGeometry();
301
302 if (!fOldGeometry) {
303 fDetConstruction->ConstructMaterials();
304 fDetConstruction->ConstructGeometry();
305 // TGeoManager::Import("geometry.root");
306 // gMC->SetRootGeometry();
307 }
308 else {
309 Ex03DetectorConstructionOld detConstructionOld;
310 detConstructionOld.ConstructMaterials();
311 detConstructionOld.ConstructGeometry();
312 }
313}
314
315//_____________________________________________________________________________
317{
318 /// Initialize geometry
319 fVerbose.InitGeometry();
320
321 fDetConstruction->SetCuts();
322
323 if (fIsControls) fDetConstruction->SetControls();
324
325 fCalorimeterSD->Initialize();
326}
327
328//_____________________________________________________________________________
330{
331 /// Example of user defined particle with user defined decay mode
332
333 fVerbose.AddParticles();
334
335 // Define particle
336 gMC->DefineParticle(1000020050, "He5", kPTHadron, 5.03427, 2.0, 0.002, "Ion",
337 0.0, 0, 1, 0, 0, 0, 0, 0, 5, kFALSE);
338
339 // Define the 2 body phase space decay for He5
340 Int_t mode[6][3];
341 Float_t bratio[6];
342
343 for (Int_t kz = 0; kz < 6; kz++) {
344 bratio[kz] = 0.;
345 mode[kz][0] = 0;
346 mode[kz][1] = 0;
347 mode[kz][2] = 0;
348 }
349 bratio[0] = 100.;
350 mode[0][0] = kNeutron; // neutron (2112)
351 mode[0][1] = 1000020040; // alpha
352
353 gMC->SetDecayMode(1000020050, bratio, mode);
354
355 // Overwrite a decay mode already defined in MCs
356 // Kaon Short: 310 normally decays in two modes
357 // pi+, pi- 68.61 %
358 // pi0, pi0 31.39 %
359 // and we force only the mode pi0, pi0
360
361 Int_t mode2[6][3];
362 Float_t bratio2[6];
363
364 for (Int_t kz = 0; kz < 6; kz++) {
365 bratio2[kz] = 0.;
366 mode2[kz][0] = 0;
367 mode2[kz][1] = 0;
368 mode2[kz][2] = 0;
369 }
370 bratio2[0] = 100.;
371 mode2[0][0] = kPi0; // pi0 (111)
372 mode2[0][1] = kPi0; // pi0 (111)
373
374 gMC->SetDecayMode(kK0Short, bratio2, mode2);
375}
376
377//_____________________________________________________________________________
379{
380 /// Example of user defined ion
381
382 fVerbose.AddIons();
383
384 gMC->DefineIon("MyIon", 34, 70, 12, 0.);
385}
386
387//_____________________________________________________________________________
389{
390 /// Fill the user stack (derived from TVirtualMCStack) with primary particles.
391
392 fVerbose.GeneratePrimaries();
393
394 TVector3 origin(fDetConstruction->GetWorldSizeX(),
395 fDetConstruction->GetCalorSizeYZ(), fDetConstruction->GetCalorSizeYZ());
396
397 fPrimaryGenerator->GeneratePrimaries(origin);
398}
399
400//_____________________________________________________________________________
402{
403 /// User actions at beginning of event
404
405 fVerbose.BeginEvent();
406
407 // Clear TGeo tracks (if filled)
408 if (TString(gMC->GetName()) == "TGeant3TGeo" &&
409 gGeoManager->GetListOfTracks() && gGeoManager->GetTrack(0) &&
410 ((TVirtualGeoTrack*)gGeoManager->GetTrack(0))->HasPoints()) {
411
412 gGeoManager->ClearTracks();
413 // if (gPad) gPad->Clear();
414 }
415
416 fEventNo++;
417 if (fEventNo % fPrintModulo == 0) {
418 cout << "\n---> Begin of event: " << fEventNo << endl;
419 // ??? How to do this in VMC
420 // HepRandom::showEngineStatus();
421 }
422}
423
424//_____________________________________________________________________________
426{
427 /// User actions at beginning of a primary track.
428 /// If test for user defined decay is activated,
429 /// the primary track ID is printed on the screen.
430
431 fVerbose.BeginPrimary();
432
433 if (fPrimaryGenerator->GetUserDecay()) {
434 cout << " Primary track ID = " << fStack->GetCurrentTrackNumber() << endl;
435 }
436}
437
438//_____________________________________________________________________________
440{
441 /// User actions at beginning of each track
442 /// If test for user defined decay is activated,
443 /// the decay products of the primary track (K0Short)
444 /// are printed on the screen.
445
446 fVerbose.PreTrack();
447
448 // print info about K0Short decay products
449 if (fPrimaryGenerator->GetUserDecay()) {
450 Int_t parentID = fStack->GetCurrentParentTrackNumber();
451
452 if (parentID >= 0 &&
453 fStack->GetParticle(parentID)->GetPdgCode() == kK0Short &&
454 fStack->GetCurrentTrack()->GetUniqueID() == kPDecay) {
455 // The production process is saved as TParticle unique ID
456 // via Ex03dMCStack
457
458 cout << " Current track " << fStack->GetCurrentTrack()->GetName()
459 << " is a decay product of Parent ID = "
460 << fStack->GetCurrentParentTrackNumber() << endl;
461 }
462 }
463}
464
465//_____________________________________________________________________________
467{
468 /// User actions at each step
469
470 // Work around for Fluka VMC, which does not call
471 // MCApplication::PreTrack()
472 //
473
474 static Int_t trackId = 0;
475 if (TString(gMC->GetName()) == "TFluka" &&
476 gMC->GetStack()->GetCurrentTrackNumber() != trackId) {
477 fVerbose.PreTrack();
478 trackId = gMC->GetStack()->GetCurrentTrackNumber();
479 }
480
481 fVerbose.Stepping();
482
483 fCalorimeterSD->ProcessHits();
484}
485
486//_____________________________________________________________________________
488{
489 /// User actions after finishing of each track
490
491 fVerbose.PostTrack();
492}
493
494//_____________________________________________________________________________
496{
497 /// User actions after finishing of a primary track
498
499 fVerbose.FinishPrimary();
500
501 if (fPrimaryGenerator->GetUserDecay()) {
502 cout << endl;
503 }
504}
505
506//_____________________________________________________________________________
508{
509 /// User actions after finishing of an event
510
511 fVerbose.FinishEvent();
512
513 // Geant3 + TGeo
514 // (use TGeo functions for visualization)
515 if (TString(gMC->GetName()) == "TGeant3TGeo") {
516
517 // Draw volume
518 gGeoManager->SetVisOption(0);
519 gGeoManager->SetTopVisible();
520 gGeoManager->GetTopVolume()->Draw();
521
522 // Draw tracks (if filled)
523 // Available when this feature is activated via
524 // gMC->SetCollectTracks(kTRUE);
525 if (gGeoManager->GetListOfTracks() && gGeoManager->GetTrack(0) &&
526 ((TVirtualGeoTrack*)gGeoManager->GetTrack(0))->HasPoints()) {
527
528 gGeoManager->DrawTracks("/*"); // this means all tracks
529 }
530 }
531
532 fRootManager->Fill();
533
534 if (fEventNo % fPrintModulo == 0) fCalorimeterSD->PrintTotal();
535
536 fCalorimeterSD->EndOfEvent();
537
538 fStack->Reset();
539}
Definition of the Ex03dMCApplication class.
The old detector construction (via VMC functions).
The detector construction (via TGeo ).
The primary generator.
The calorimeter sensitive detector.
Implementation of the TVirtualMCApplication.
TMCRootManager * fRootManager
Root manager.
virtual void GeneratePrimaries()
Ex03DetectorConstruction * fDetConstruction
Dector construction.
void RunMC(Int_t nofEvents)
virtual TVirtualMCApplication * CloneForWorker() const
TGeoUniformMagField * fMagField
Magnetic field.
Int_t fEventNo
Event counter.
virtual void ConstructGeometry()
Ex03dMCApplication(const char *name, const char *title)
Ex03dCalorimeterSD * fCalorimeterSD
Calorimeter SD.
Bool_t fIsControls
Option to activate special controls.
Ex03PrimaryGenerator * fPrimaryGenerator
Primary generator.
void ReadEvent(Int_t i, TMCRootManager::StorageMode storageMode=TMCRootManager::kRNTuple, Int_t threadId=-1)
Bool_t fOldGeometry
Option for geometry definition.
Ex03dMCStack * fStack
VMC stack.
void InitMC(const char *setup, TMCRootManager::StorageMode storageMode=TMCRootManager::kRNTuple)
TMCVerbose fVerbose
VMC verbose helper.
virtual void FinishRunOnWorker()
Bool_t fIsMaster
If is on master thread.
Int_t fPrintModulo
The event modulus number to be printed.
Implementation of the TVirtualMCStack interface.