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