VMC Examples Version 6.8
Loading...
Searching...
No Matches
MCApplication.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Virtual Monte Carlo examples
3// Copyright (C) 2007 - 2015 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 TR/src/MCApplication.cxx
11/// \brief Implementation of the MCApplication class
12///
13/// Geant4 TestEm10 adapted to Virtual Monte Carlo.
14///
15/// \date 18/12/2015
16/// \author I. Hrivnacova; IPN, Orsay
17
18#include "MCApplication.h"
19#include "DetectorConstruction.h"
20#include "Ex03MCStack.h"
21#include "PrimaryGenerator.h"
22#include "SensitiveDetector.h"
23
24#include <TMCRootManager.h>
25
26#include <Riostream.h>
27#include <TGeoManager.h>
28#include <TGeoUniformMagField.h>
29#include <TH1.h>
30#include <TInterpreter.h>
31#include <TPDGCode.h>
32#include <TParticle.h>
33#include <TROOT.h>
34#include <TVirtualGeoTrack.h>
35#include <TVirtualMC.h>
36
37using namespace std;
38
39/// \cond CLASSIMP
41 /// \endcond
42
43 namespace VMC
44{
45 namespace TR
46 {
47
48 std::vector<TH1D*> fHistograms;
49
50 //_____________________________________________________________________________
51 MCApplication::MCApplication(const char* name, const char* title)
52 : TVirtualMCApplication(name, title),
53 fRootManager(0),
54 fPrintModulo(1),
55 fEventNo(0),
56 fVerbose(0),
57 fStack(0),
61 fMagField(0),
62 fOldGeometry(kFALSE),
63 fIsControls(kFALSE),
64 fIsMaster(kTRUE)
65 {
66 /// Standard constructor
67 /// \param name The MC application name
68 /// \param title The MC application description
69
70 // Create a user stack
71 fStack = new Ex03MCStack(1000);
72
73 // Create detector construction
75
76 // Create a calorimeter SD
77 fSensitiveDetector = new SensitiveDetector("Absorber");
78
79 // Create a primary generator
81
82 // Constant magnetic field (in kiloGauss)
83 fMagField = new TGeoUniformMagField();
84 }
85
86 //_____________________________________________________________________________
88 : TVirtualMCApplication(origin.GetName(), origin.GetTitle()),
89 fRootManager(0),
91 fEventNo(0),
92 fVerbose(origin.fVerbose),
93 fStack(0),
97 fMagField(0),
99 fIsMaster(kFALSE)
100 {
101 /// Copy constructor for cloning application on workers (in multithreading
102 /// mode) \param origin The source MC application
103
104 // Create new user stack
105 fStack = new Ex03MCStack(1000);
106
107 // Create a calorimeter SD
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],
117 origin.fMagField->GetFieldValue()[2]);
118 }
119
120 //_____________________________________________________________________________
123 fRootManager(0),
124 fPrintModulo(1),
125 fEventNo(0),
126 fStack(0),
130 fMagField(0),
131 fOldGeometry(kFALSE),
132 fIsControls(kFALSE),
133 fIsMaster(kTRUE)
134 {
135 /// Default constructor
136 }
137
138 //_____________________________________________________________________________
140 {
141 /// Destructor
142
143 // cout << "MCApplication::~MCApplication " << this << endl;
144
145 delete fRootManager;
146 delete fStack;
147 if (fIsMaster) delete fDetConstruction;
148 delete fSensitiveDetector;
149 delete fPrimaryGenerator;
150 delete fMagField;
151 delete gMC;
152
153 // cout << "Done MCApplication::~MCApplication " << this << endl;
154 }
155
156 //
157 // private methods
158 //
159
160 //_____________________________________________________________________________
162 {
163 /// Register stack in the Root manager.
164
165 if (fRootManager) {
166 // cout << "MCApplication::RegisterStack: " << endl;
167 fRootManager->Register("stack", "Ex03MCStack", &fStack);
168 }
169 }
170
171 //_____________________________________________________________________________
173 {
174 /// Create histograms
175
176 fHistograms.push_back(new TH1D("1", "Edep", 100, 0., 0.1));
177 fHistograms.push_back(new TH1D("2", "XTR Gamma spectrum", 100, 0., 0.1));
178 fHistograms.push_back(
179 new TH1D("3", "Secondary Gamma spectrum", 100, 0., 0.1));
180 fHistograms.push_back(new TH1D("4", "Secondary e- spectrum", 100, 0., 0.1));
181 }
182
183 //
184 // public methods
185 //
186
187 //_____________________________________________________________________________
188 void MCApplication::InitMC(const char* setup)
189 {
190 /// Initialize MC.
191 /// The selection of the concrete MC is done in the macro.
192 /// \param setup The name of the configuration macro
193
194 fVerbose.InitMC();
195
196 if (TString(setup) != "") {
197 gROOT->LoadMacro(setup);
198 gInterpreter->ProcessLine("Config()");
199 if (!gMC) {
200 Fatal(
201 "InitMC", "Processing Config() has failed. (No MC is instantiated.)");
202 }
203 }
204
205// MT support available from root v 5.34/18
206#if ROOT_VERSION_CODE >= 336402
207 // Create Root manager
208 if (!gMC->IsMT()) {
209 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
210 // fRootManager->SetDebug(true);
211 }
212#else
213 // Create Root manager
214 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
215 // fRootManager->SetDebug(true);
216#endif
217 // Cretae histograms
218 BookHisto();
219
220 gMC->SetStack(fStack);
221 gMC->SetMagField(fMagField);
222 gMC->Init();
223 gMC->BuildPhysics();
224
226 }
227
228 //_____________________________________________________________________________
229 void MCApplication::RunMC(Int_t nofEvents)
230 {
231 /// Run MC.
232 /// \param nofEvents Number of events to be processed
233
234 fVerbose.RunMC(nofEvents);
235
236 gMC->ProcessRun(nofEvents);
237 FinishRun();
238 }
239
240 //_____________________________________________________________________________
242 {
243 /// Finish MC run.
244
245 fVerbose.FinishRun();
246 // cout << "MCApplication::FinishRun: " << endl;
247
248 // print run statisctics
249 cout << " ================== run summary =====================" << endl;
250 cout << " End of Run TotNbofEvents = " << fEventNo << endl;
251
252 cout << " Mean energy deposit in absorber = " << fHistograms[0]->GetMean()
253 << " +-" << fHistograms[0]->GetRMS() << " MeV " << endl;
254
255 cout << " Total number of XTR gammas = " << fHistograms[1]->GetEntries()
256 << endl;
257
258 cout << " Total number of all gammas = " << fHistograms[2]->GetEntries()
259 << endl;
260
261 if (fRootManager) {
262 fRootManager->WriteAll();
263 fRootManager->Close();
264 }
265 }
266
267 //_____________________________________________________________________________
269 {
270 return new MCApplication(*this);
271 }
272
273 //_____________________________________________________________________________
275 {
276 // cout << "MCApplication::InitForWorker " << this << endl;
277
278 // Create Root manager
279 Int_t threadRank = 1;
280 // The real thread rank will be set in MCRootManager
281 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite, threadRank);
282 // fRootManager->SetDebug(true);
283
284 // Set data to MC
285 gMC->SetStack(fStack);
286 gMC->SetMagField(fMagField);
287
289 }
290
291 //_____________________________________________________________________________
293 {
294 // cout << "MCApplication::FinishWorkerRun: " << endl;
295 if (fRootManager) {
296 fRootManager->WriteAll();
297 fRootManager->Close();
298 }
299 }
300
301 //_____________________________________________________________________________
303 {
304 /// Construct geometry using detector contruction class.
305 /// The detector contruction class is using TGeo functions or
306 /// TVirtualMC functions (if oldGeometry is selected)
307
308 fVerbose.ConstructGeometry();
309
310 fDetConstruction->ConstructGeometry();
311 }
312
313 //_____________________________________________________________________________
315 {
316 /// Initialize geometry
317
318 fVerbose.InitGeometry();
319
320 fSensitiveDetector->Initialize();
321 }
322
323 //_____________________________________________________________________________
325 {
326 /// Fill the user stack (derived from TVirtualMCStack) with primary
327 /// particles.
328
329 fVerbose.GeneratePrimaries();
330
331 fPrimaryGenerator->GeneratePrimaries();
332 }
333
334 //_____________________________________________________________________________
336 {
337 /// User actions at beginning of event
338
339 fVerbose.BeginEvent();
340
341 // Clear TGeo tracks (if filled)
342 if (TString(gMC->GetName()) == "TGeant3TGeo" &&
343 gGeoManager->GetListOfTracks() && gGeoManager->GetTrack(0) &&
344 ((TVirtualGeoTrack*)gGeoManager->GetTrack(0))->HasPoints()) {
345
346 gGeoManager->ClearTracks();
347 // if (gPad) gPad->Clear();
348 }
349
350 fEventNo++;
351 if (fEventNo % fPrintModulo == 0) {
352 cout << "\n---> Begin of event: " << fEventNo << endl;
353 }
354 }
355
356 //_____________________________________________________________________________
358 {
359 /// User actions at beginning of a primary track.
360
361 fVerbose.BeginPrimary();
362 }
363
364 //_____________________________________________________________________________
366 {
367 /// User actions at beginning of each track.
368 /// Fill spectra.
369
370 fVerbose.PreTrack();
371
372 // Gamma
373 if (gMC->TrackPid() == kGamma) {
374 // XTR gammas
375 Int_t creatorProcess = fStack->GetCurrentTrack()->GetUniqueID();
376
377// Available since 6.07/03 and 5.34/35
378// kpTransitionRadiation = 49
379#if ((ROOT_VERSION_CODE >= ROOT_VERSION(6, 7, 3)) || \
380 ((ROOT_VERSION_CODE <= ROOT_VERSION(6, 0, 0)) && \
381 (ROOT_VERSION_CODE >= ROOT_VERSION(5, 34, 35))))
382 if (creatorProcess == kPTransitionRadiation) {
383#else
384 if (creatorProcess == kPNull) {
385#endif
386 fHistograms[1]->Fill(gMC->Etot() * 1e+03);
387 }
388 fHistograms[2]->Fill(gMC->Etot() * 1e+03);
389 }
390
391 // Secondary e-
392 if (gMC->TrackPid() == kElectron &&
393 fStack->GetCurrentParentTrackNumber() != -1) {
394
395 fHistograms[3]->Fill((gMC->Etot() - gMC->TrackMass()) * 1e+03);
396 }
397 }
398
399 //_____________________________________________________________________________
401 {
402 /// User actions at each step
403
404 // Work around for Fluka VMC, which does not call
405 // MCApplication::PreTrack()
406 //
407 // cout << "MCApplication::Stepping" << this << endl;
408 static Int_t trackId = 0;
409 if (TString(gMC->GetName()) == "TFluka" &&
410 gMC->GetStack()->GetCurrentTrackNumber() != trackId) {
411 fVerbose.PreTrack();
412 trackId = gMC->GetStack()->GetCurrentTrackNumber();
413 }
414
415 fVerbose.Stepping();
416
417 fSensitiveDetector->ProcessHits();
418 }
419
420 //_____________________________________________________________________________
422 {
423 /// User actions after finishing of each track
424
425 fVerbose.PostTrack();
426 }
427
428 //_____________________________________________________________________________
430 {
431 /// User actions after finishing of a primary track
432
433 fVerbose.FinishPrimary();
434 }
435
436 //_____________________________________________________________________________
438 {
439 /// User actions after finishing of an event
440
441 fVerbose.FinishEvent();
442
443 // Geant3 + TGeo
444 // (use TGeo functions for visualization)
445 // if ( TString(gMC->GetName()) == "TGeant3TGeo") {
446
447 // // Draw volume
448 // gGeoManager->SetVisOption(0);
449 // gGeoManager->SetTopVisible();
450 // gGeoManager->GetTopVolume()->Draw();
451
452 // // Draw tracks (if filled)
453 // // Available when this feature is activated via
454 // // gMC->SetCollectTracks(kTRUE);
455 // if ( gGeoManager->GetListOfTracks() &&
456 // gGeoManager->GetTrack(0) &&
457 // ((TVirtualGeoTrack*)gGeoManager->GetTrack(0))->HasPoints() ) {
458
459 // gGeoManager->DrawTracks("/*"); // this means all tracks
460 // }
461 // }
462
463 // Fill Edep histogram in MeV
464 // cout << "Filling in h0 " <<
465 // fSensitiveDetector->GetHit(0)->GetEdep()*1e+03 << endl;
466 fHistograms[0]->Fill(fSensitiveDetector->GetEdep() * 1e+03);
467
468 fRootManager->Fill();
469
470 if (fEventNo % fPrintModulo == 0) {
471 fSensitiveDetector->Print();
472 }
473
474 fSensitiveDetector->EndOfEvent();
475 fStack->Reset();
476 }
477
478 } // namespace TR
479}
Implementation of the TVirtualMCStack interface.
Definition Ex03MCStack.h:36
The detector construction (via TGeo ).
Implementation of the TVirtualMCApplication.
virtual void InitGeometry()
virtual void FinishPrimary()
virtual void GeneratePrimaries()
Ex03MCStack * fStack
VMC stack.
virtual void ConstructGeometry()
MCApplication(const char *name, const char *title)
Bool_t fOldGeometry
Option for geometry definition.
Int_t fPrintModulo
The event modulus number to be printed.
Bool_t fIsControls
Option to activate special controls.
Bool_t fIsMaster
If is on master thread.
SensitiveDetector * fSensitiveDetector
Absorber SD.
PrimaryGenerator * fPrimaryGenerator
Primary generator.
TMCVerbose fVerbose
VMC verbose helper.
virtual TVirtualMCApplication * CloneForWorker() const
virtual void FinishRunOnWorker()
virtual void BeginPrimary()
void RunMC(Int_t nofEvents)
TGeoUniformMagField * fMagField
Magnetic field.
TMCRootManager * fRootManager
Root manager.
Int_t fEventNo
Event counter.
virtual void InitOnWorker()
void InitMC(const char *setup)
DetectorConstruction * fDetConstruction
Dector construction.
The primary generator.
The absorber sensitive detector.
std::vector< TH1D * > fHistograms