VMC Examples Version 6.6
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 Gflash/src/MCApplication.cxx
11/// \brief Implementation of the Gflash::MCApplication class
12///
13/// Geant4 gflash adapted to Virtual Monte Carlo
14///
15/// \date 28/10/2015
16/// \author I. Hrivnacova; IPN, Orsay
17
18#include "MCApplication.h"
19#include "Ex03MCStack.h"
20#include "Hit.h"
21#include "PrimaryGenerator.h"
22
23#include <TMCRootManager.h>
24
25#include <Riostream.h>
26#include <TGeoManager.h>
27#include <TInterpreter.h>
28#include <TPDGCode.h>
29#include <TParticle.h>
30#include <TROOT.h>
31#include <TRandom.h>
32#include <TVector3.h>
33#include <TVirtualGeoTrack.h>
34#include <TVirtualMC.h>
35
36using namespace std;
37
38/// \cond CLASSIMP
40 /// \endcond
41
42 namespace VMC
43{
44 namespace Gflash
45 {
46
47 //_____________________________________________________________________________
48 MCApplication::MCApplication(const char* name, const char* title)
49 : TVirtualMCApplication(name, title),
50 fRootManager(0),
51 fEventNo(0),
52 fVerbose(0),
53 fStack(0),
54 fDetConstruction(0),
55 fSensitiveDetector(0),
56 fPrimaryGenerator(0),
57 fIsMaster(kTRUE)
58 {
59 /// Standard constructor
60 /// \param name The MC application name
61 /// \param title The MC application description
62
63 // Create a user stack
64 fStack = new Ex03MCStack(1000);
65
66 // Create detector construction
68
69 // Create a calorimeter SD
70 fSensitiveDetector = new SensitiveDetector("Calorimeter");
71
72 // Create a primary generator
74 }
75
76 //_____________________________________________________________________________
78 : TVirtualMCApplication(origin.GetName(), origin.GetTitle()),
79 fRootManager(0),
80 fEventNo(0),
81 fVerbose(origin.fVerbose),
82 fStack(0),
83 fDetConstruction(origin.fDetConstruction),
84 fSensitiveDetector(0),
85 fPrimaryGenerator(0),
86 fIsMaster(kFALSE)
87 {
88 /// Copy constructor for cloning application on workers (in multithreading
89 /// mode) \param origin The source MC application
90
91 // Create new user stack
92 fStack = new Ex03MCStack(1000);
93
94 // Create a calorimeter SD
96
97 // Create a primary generator
100 }
101
102 //_____________________________________________________________________________
105 fRootManager(0),
106 fEventNo(0),
107 fStack(0),
108 fDetConstruction(0),
109 fSensitiveDetector(0),
110 fPrimaryGenerator(0),
111 fIsMaster(kTRUE)
112 {
113 /// Default constructor
114 }
115
116 //_____________________________________________________________________________
118 {
119 /// Destructor
120
121 // cout << "MCApplication::~MCApplication " << this << endl;
122
123 delete fRootManager;
124 delete fStack;
125 if (fIsMaster) delete fDetConstruction;
126 delete fSensitiveDetector;
127 delete fPrimaryGenerator;
128 delete gMC;
129
130 // cout << "Done MCApplication::~MCApplication " << this << endl;
131 }
132
133 //
134 // private methods
135 //
136
137 //_____________________________________________________________________________
139 {
140 /// Register stack in the Root manager.
141
142 if (fRootManager) {
143 // cout << "MCApplication::RegisterStack: " << endl;
144 fRootManager->Register("stack", "Ex03MCStack", &fStack);
145 }
146 }
147
148 //_____________________________________________________________________________
150 {
151 /// Compute event statisics
152
153 cout << " ------ ExGflashEventAction::End of event nr. " << fEventNo
154 << " -----" << endl;
155
156 TClonesArray* hitsCollection = fSensitiveDetector->GetHitsCollection();
157
158 // Hits in sensitive Detector
159 int n_hit = hitsCollection->GetEntriesFast();
160 cout << " " << n_hit << " hits are stored in HitsCollection " << endl;
161
162 // Get (x,y,z) of vertex of initial particles
163 TVector3 vertexPosition = fPrimaryGenerator->GetVertexPosition();
164 TVector3 vertexDirection = fPrimaryGenerator->GetVertexDirection();
165
166 // ExGflashEventAction: Magicnumber
167 // Should be retrieved from detector construction
168 Double_t energyincrystal[100];
169 for (Int_t i = 0; i < 100; i++) energyincrystal[i] = 0.;
170
171 // For all Hits in sensitive detector
172 Double_t totE = 0;
173 for (Int_t i = 0; i < n_hit; i++) {
174 Hit* hit = static_cast<Hit*>(hitsCollection->At(i));
175
176 Double_t estep = hit->GetEdep();
177 if (estep > 0) {
178 totE += estep;
179 Int_t num = hit->GetCrystalNum();
180 energyincrystal[num] += estep;
181 // cout << " Crystal Nummer " << num << endl;
182
183 TVector3 hitpos = hit->GetPos();
184 TVector3 l(hitpos);
185 // distance from shower start
186 l = l - vertexPosition;
187 // projection on shower axis = longitudinal profile
188 TVector3 longitudinal(l);
189 // shower profiles (Radial)
190 TVector3 radial(vertexPosition.Cross(l));
191 }
192 }
193
194 // Find crystal with maximum energy
195 Double_t max = 0;
196 Int_t index = 0;
197 for (Int_t i = 0; i < 100; i++) {
198 // cout << i <<" " << energyincrystal[i] << G4endl;
199 if (max < energyincrystal[i]) {
200 max = energyincrystal[i];
201 index = i;
202 }
203 }
204 // cout << " NMAX " << index << G4endl;
205
206 // 3x3 matrix of crystals around the crystal with the maximum energy deposit
207 Double_t e3x3 = energyincrystal[index] + energyincrystal[index + 1] +
208 energyincrystal[index - 1] + energyincrystal[index - 10] +
209 energyincrystal[index - 9] + energyincrystal[index - 11] +
210 energyincrystal[index + 10] + energyincrystal[index + 11] +
211 energyincrystal[index + 9];
212
213 // 5x5 matrix of crystals around the crystal with the maximum energy deposit
214 Double_t e5x5 = energyincrystal[index] + energyincrystal[index + 1] +
215 energyincrystal[index - 1] + energyincrystal[index + 2] +
216 energyincrystal[index - 2] + energyincrystal[index - 10] +
217 energyincrystal[index - 9] + energyincrystal[index - 11] +
218 energyincrystal[index - 8] + energyincrystal[index - 12] +
219 energyincrystal[index + 10] + energyincrystal[index + 11] +
220 energyincrystal[index + 9] + energyincrystal[index + 12] +
221 energyincrystal[index + 8];
222
223 cout << " e1 " << energyincrystal[index] << " e3x3 " << e3x3
224 << " e5x5 " << e5x5 << " GeV" << endl;
225
226 cout << " Total energy deposited in the calorimeter: " << totE << " (GeV)"
227 << endl;
228 }
229
230 //
231 // public methods
232 //
233
234 //_____________________________________________________________________________
235 void MCApplication::InitMC(const char* setup)
236 {
237 /// Initialize MC.
238 /// The selection of the concrete MC is done in the macro.
239 /// \param setup The name of the configuration macro
240
241 fVerbose.InitMC();
242
243 if (TString(setup) != "") {
244 gROOT->LoadMacro(setup);
245 gInterpreter->ProcessLine("Config()");
246 if (!gMC) {
247 Fatal(
248 "InitMC", "Processing Config() has failed. (No MC is instantiated.)");
249 }
250 }
251
252// MT support available from root v 5.34/18
253#if ROOT_VERSION_CODE >= 336402
254 // Create Root manager
255 if (!gMC->IsMT()) {
256 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
257 // fRootManager->SetDebug(true);
258 }
259#else
260 // Create Root manager
261 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
262 // fRootManager->SetDebug(true);
263#endif
264
265 gMC->SetStack(fStack);
266 gMC->Init();
267 gMC->BuildPhysics();
268
270 }
271
272 //_____________________________________________________________________________
273 void MCApplication::RunMC(Int_t nofEvents)
274 {
275 /// Run MC.
276 /// \param nofEvents Number of events to be processed
277
278 fVerbose.RunMC(nofEvents);
279
280 gMC->ProcessRun(nofEvents);
281 FinishRun();
282 }
283
284 //_____________________________________________________________________________
286 {
287 /// Finish MC run.
288
289 fVerbose.FinishRun();
290 // cout << "MCApplication::FinishRun: " << endl;
291 if (fRootManager) {
292 fRootManager->WriteAll();
293 fRootManager->Close();
294 }
295 }
296
297 //_____________________________________________________________________________
299 {
300 return new MCApplication(*this);
301 }
302
303 //_____________________________________________________________________________
305 {
306 // cout << "MCApplication::InitForWorker " << this << endl;
307
308 // Create Root manager
309 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
310 // fRootManager->SetDebug(true);
311
312 // Set data to MC
313 gMC->SetStack(fStack);
314
316 }
317
318 //_____________________________________________________________________________
320 {
321 // cout << "MCApplication::FinishWorkerRun: " << endl;
322 if (fRootManager) {
323 fRootManager->WriteAll();
324 fRootManager->Close();
325 }
326 }
327
328 //_____________________________________________________________________________
330 {
331 /// Read \em i -th event and prints hits.
332 /// \param i The number of event to be read
333
336 fRootManager->ReadEvent(i);
337 }
338
339 //_____________________________________________________________________________
341 {
342 /// Construct geometry using detector contruction class.
343 /// The detector contruction class is using TGeo functions or
344 /// TVirtualMC functions (if oldGeometry is selected)
345
346 fVerbose.ConstructGeometry();
347
349 }
350
351 //_____________________________________________________________________________
353 {
354 /// Initialize geometry
355
356 fVerbose.InitGeometry();
357
359 }
360
361 //_____________________________________________________________________________
363 {
364 /// Fill the user stack (derived from TVirtualMCStack) with primary
365 /// particles.
366
367 fVerbose.GeneratePrimaries();
368
369 TVector3 origin;
371 }
372
373 //_____________________________________________________________________________
375 {
376 /// User actions at beginning of event
377
378 fVerbose.BeginEvent();
379
380 // Clear TGeo tracks (if filled)
381 if (TString(gMC->GetName()) == "TGeant3TGeo" &&
382 gGeoManager->GetListOfTracks() && gGeoManager->GetTrack(0) &&
383 ((TVirtualGeoTrack*)gGeoManager->GetTrack(0))->HasPoints()) {
384
385 gGeoManager->ClearTracks();
386 // if (gPad) gPad->Clear();
387 }
388
389 fEventNo++;
390 cout << " Start generating event Nr " << fEventNo << endl;
391
392 // start timer
393 fEventTimer = new TStopwatch();
394 fEventTimer->Start();
395 }
396
397 //_____________________________________________________________________________
399 {
400 /// User actions at beginning of a primary track.
401 /// If test for user defined decay is activated,
402 /// the primary track ID is printed on the screen.
403
404 fVerbose.BeginPrimary();
405 }
406
407 //_____________________________________________________________________________
409 {
410 /// User actions at beginning of each track
411 /// If test for user defined decay is activated,
412 /// the decay products of the primary track (K0Short)
413 /// are printed on the screen.
414
415 fVerbose.PreTrack();
416 }
417
418 //_____________________________________________________________________________
420 {
421 /// User actions at each step
422
423 // Work around for Fluka VMC, which does not call
424 // MCApplication::PreTrack()
425 //
426 // cout << "MCApplication::Stepping" << this << endl;
427 static Int_t trackId = 0;
428 if (TString(gMC->GetName()) == "TFluka" &&
429 gMC->GetStack()->GetCurrentTrackNumber() != trackId) {
430 fVerbose.PreTrack();
431 trackId = gMC->GetStack()->GetCurrentTrackNumber();
432 }
433
434 fVerbose.Stepping();
435
437 }
438
439 //_____________________________________________________________________________
441 {
442 /// User actions after finishing of each track
443
444 fVerbose.PostTrack();
445 }
446
447 //_____________________________________________________________________________
449 {
450 /// User actions after finishing of a primary track
451
452 fVerbose.FinishPrimary();
453 }
454
455 //_____________________________________________________________________________
457 {
458 /// User actions after finishing of an event
459
460 // VMC
461
462 fVerbose.FinishEvent();
463
464 fRootManager->Fill();
465 // The application code
466
467 fEventTimer->Stop();
468 cout << endl;
469 cout << "******************************************";
470 cout << endl;
471 cout << "Elapsed Time: " << endl;
472 fEventTimer->Print();
473 cout << endl;
474 cout << "******************************************" << endl;
475 // TO DO
476 // fDtime+=fTimerIntern.GetRealElapsed();
477
479
481
482 fStack->Reset();
483 }
484
485 } // namespace Gflash
486}
Implementation of the TVirtualMCStack interface.
Definition Ex03MCStack.h:36
The detector construction (via TGeo )
The calorimeter hit.
Definition Hit.h:37
Double_t GetEdep() const
Definition Hit.h:52
Int_t GetCrystalNum() const
Definition Hit.h:53
TVector3 GetPos() const
Definition Hit.h:54
Implementation of the TVirtualMCApplication.
virtual TVirtualMCApplication * CloneForWorker() const
Bool_t fIsMaster
If is on master thread.
Int_t fEventNo
Event counter.
TMCRootManager * fRootManager
Root manager.
DetectorConstruction * fDetConstruction
Dector construction.
void InitMC(const char *setup)
TMCVerbose fVerbose
VMC verbose helper.
Ex03MCStack * fStack
VMC stack.
PrimaryGenerator * fPrimaryGenerator
Primary generator.
SensitiveDetector * fSensitiveDetector
Calorimeter SD.
TStopwatch * fEventTimer
Event timer.
void RunMC(Int_t nofEvents)
TVector3 GetVertexPosition() const
Return the Vertex position.
virtual void GeneratePrimaries(const TVector3 &worldSize)
TVector3 GetVertexDirection() const
Return the Vertex direction.
The calorimeter sensitive detector.
TClonesArray * GetHitsCollection() const
Return the hits collection.