VMC Examples Version 6.8
Loading...
Searching...
No Matches
A01MCApplication.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Virtual Monte Carlo examples
3// Copyright (C) 2007 - 2014 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 A01MCApplication.cxx
11/// \brief Implementation of the A01MCApplication class
12///
13/// Geant4 example A01 adapted to Virtual Monte Carlo
14///
15/// \date 12/05/2012
16/// \author I. Hrivnacova; IPN, Orsay
17
18#include <Riostream.h>
19#include <TGeoManager.h>
20#include <TGeoUniformMagField.h>
21#include <TInterpreter.h>
22#include <TPDGCode.h>
23#include <TParticle.h>
24#include <TParticlePDG.h>
25#include <TROOT.h>
26#include <TRandom.h>
27#include <TVector3.h>
28#include <TVirtualGeoTrack.h>
29#include <TVirtualMC.h>
30
31#include <TMCRootManager.h>
32
33#include "A01DriftChamberSD.h"
34#include "A01EmCalorimeterSD.h"
35#include "A01HadCalorimeterSD.h"
36#include "A01HodoscopeSD.h"
37#include "A01MCApplication.h"
38#include "A01MagField.h"
39#include "A01PrimaryGenerator.h"
41#include "Ex03MCStack.h"
42
43using namespace std;
44
45/// \cond CLASSIMP
46ClassImp(A01MCApplication)
47 /// \endcond
48
49 //_____________________________________________________________________________
50 A01MCApplication::A01MCApplication(const char* name, const char* title)
51 : TVirtualMCApplication(name, title),
52 fRootManager(0),
53 fWriteStack(true),
54 fWriteHits(true),
55 fUseLocalMagField(false),
56 fVerbose(0),
57 fStack(0),
66 fMagField(0),
67 fIsMaster(kTRUE)
68{
69 /// Standard constructor
70 /// \param name The MC application name
71 /// \param title The MC application description
72
73 // Create a user stack
74 fStack = new Ex03MCStack(1000);
75
76 // Create detector construction
77 fDetConstruction = new A01RootDetectorConstruction("A01geometry.root");
78
79 // Create SDs
80 fDriftChamberSD1 = new A01DriftChamberSD("Chamber1", "wirePlane1Logical");
81 fDriftChamberSD2 = new A01DriftChamberSD("Chamber2", "wirePlane2Logical");
82 fEmCalorimeterSD = new A01EmCalorimeterSD("EmCalorimeter");
83 fHadCalorimeterSD = new A01HadCalorimeterSD("HadCalorimeter");
84 fHodoscopeSD1 = new A01HodoscopeSD("Hodoscope1", "hodoscope1Logical");
85 fHodoscopeSD2 = new A01HodoscopeSD("Hodoscope2", "hodoscope2Logical");
86
87 // Create a primary generator
89
90 // Constant magnetic field (in kiloGauss)
91 // field value: 1.0*tesla (= 10.0 kiloGauss) in y
92 if (!fUseLocalMagField) {
93 fMagField = new A01MagField(0, 10.0, 0);
94 }
95}
96
97//_____________________________________________________________________________
99 : TVirtualMCApplication(origin.GetName(), origin.GetTitle()),
100 fRootManager(0),
101 fWriteStack(origin.fWriteStack),
102 fWriteHits(origin.fWriteHits),
104 fVerbose(origin.fVerbose),
105 fStack(0),
111 fHodoscopeSD1(0),
112 fHodoscopeSD2(0),
114 fMagField(0),
115 fIsMaster(kFALSE)
116{
117 /// Copy constructor (for clonig on worker thread in MT mode).
118 /// \param origin The source object (on master).
119
120 // Create a user stack
121 fStack = new Ex03MCStack(1000);
122
123 // Create SDs
130
131 // Create a primary generator
134
135 // Constant magnetic field (in kiloGauss)
136 // field value: 1.0*tesla (= 10.0 kiloGauss) in y
137 if (!fUseLocalMagField) {
138 fMagField = new A01MagField(0, 10.0, 0);
139 }
140}
141
142//_____________________________________________________________________________
145 fRootManager(0),
146 fWriteStack(true),
147 fWriteHits(true),
148 fUseLocalMagField(false),
149 fStack(0),
155 fHodoscopeSD1(0),
156 fHodoscopeSD2(0),
158 fMagField(0),
159 fIsMaster(kTRUE)
160{
161 /// Default constructor
162}
163
164//_____________________________________________________________________________
166{
167 /// Destructor
168
169 // cout << "A01MCApplication::~A01MCApplication " << this << endl;
170
171 delete fRootManager;
172 delete fStack;
173 if (fIsMaster) delete fDetConstruction;
174 delete fDriftChamberSD1;
175 delete fDriftChamberSD2;
176 delete fEmCalorimeterSD;
177 delete fHadCalorimeterSD;
178 delete fHodoscopeSD1;
179 delete fHodoscopeSD2;
180 delete fPrimaryGenerator;
181 delete fMagField;
182 delete gMC;
183
184 // cout << "Done A01MCApplication::~A01MCApplication " << this << endl;
185}
186
187//
188// private methods
189//
190
191//_____________________________________________________________________________
193{
194 /// Register stack in the Root manager.
195
196 if (fWriteStack && fRootManager) {
197 // cout << "A01MCApplication::RegisterStack: " << endl;
198 fRootManager->Register("stack", "Ex03MCStack", &fStack);
199 }
200}
201
202//
203// public methods
204//
205
206//_____________________________________________________________________________
207void A01MCApplication::InitMC(const char* setup)
208{
209 /// Initialize MC.
210 /// The selection of the concrete MC is done in the macro.
211 /// \param setup The name of the configuration macro
212
213 fVerbose.InitMC();
214
215 if (TString(setup) != "") {
216 gROOT->LoadMacro(setup);
217 gInterpreter->ProcessLine("Config()");
218 if (!gMC) {
219 Fatal(
220 "InitMC", "Processing Config() has failed. (No MC is instantiated.)");
221 }
222 }
223
224// MT support available from root v 5.34/18
225#if ROOT_VERSION_CODE >= 336402
226 // Create Root manager
227 if (!gMC->IsMT()) {
228 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
229 // fRootManager->SetDebug(true);
230 }
231#else
232 // Create Root manager
233 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
234 // fRootManager->SetDebug(true);
235#endif
236
237 // Set data to MC
238 gMC->SetStack(fStack);
239 gMC->SetMagField(fMagField);
240
241 // Init MC
242 gMC->Init();
243 gMC->BuildPhysics();
244
246}
247
248//_____________________________________________________________________________
249void A01MCApplication::RunMC(Int_t nofEvents)
250{
251 /// Run MC.
252 /// \param nofEvents Number of events to be processed
253
254 fVerbose.RunMC(nofEvents);
255
256 gMC->ProcessRun(nofEvents);
257 FinishRun();
258}
259
260//_____________________________________________________________________________
262{
263 /// Finish MC run.
264
265 fVerbose.FinishRun();
266
267 if (fRootManager && (fWriteStack || fWriteHits)) {
268 fRootManager->WriteAll();
269 fRootManager->Close();
270 }
271}
272
273//_____________________________________________________________________________
275{
276 // cout << "A01MCApplication::CloneForWorker " << this << endl;
277 return new A01MCApplication(*this);
278}
279
280//_____________________________________________________________________________
282{
283 // cout << "A01MCApplication::InitForWorker " << this << endl;
284
285 // Create Root manager
286 Int_t threadRank = 1;
287 // The real thread rank will be set in MCRootManager
288 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite, threadRank);
289 // fRootManager->SetDebug(true);
290
291 // Set data to MC
292 gMC->SetStack(fStack);
293 gMC->SetMagField(fMagField);
294
296}
297
298//_____________________________________________________________________________
300{
301 // cout << "A01MCApplication::FinishWorkerRun: " << endl;
302 if (fRootManager) {
303 fRootManager->WriteAll();
304 fRootManager->Close();
305 }
306}
307
308//_____________________________________________________________________________
310{
311 /// Read \em i -th event and print hits.
312 /// \param i The number of event to be read
313
314 if ( ! fRootManager ) {
315 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kRead);
316 }
317
318 fDriftChamberSD1->Register();
319 fDriftChamberSD2->Register();
320 fEmCalorimeterSD->Register();
321 fHadCalorimeterSD->Register();
322 fHodoscopeSD1->Register();
323 fHodoscopeSD2->Register();
325 fRootManager->ReadEvent(i);
326}
327
328//_____________________________________________________________________________
330{
331 /// Construct geometry using detector contruction class.
332
333 fVerbose.ConstructGeometry();
334 fDetConstruction->ConstructGeometry();
335}
336
337//_____________________________________________________________________________
339{
340 /// Initialize geometry
341
342 fVerbose.InitGeometry();
343
344 // Set cuts in G3 equivalent to 1mm cut in G4
345 if (TString(gMC->GetName()) == "TGeant3TGeo") SetCuts();
346
347 fDriftChamberSD1->Initialize();
348 fDriftChamberSD2->Initialize();
349 fEmCalorimeterSD->Initialize();
350 fHadCalorimeterSD->Initialize();
351 fHodoscopeSD1->Initialize();
352 fHodoscopeSD2->Initialize();
353}
354
355//_____________________________________________________________________________
357{
358 /// Nothing to be done
359
360 fVerbose.AddParticles();
361}
362
363//_____________________________________________________________________________
365{
366 /// Nothing to be done
367
368 fVerbose.AddIons();
369}
370
371//_____________________________________________________________________________
373{
374 /// Fill the user stack (derived from TVirtualMCStack) with primary particles.
375
376 fVerbose.GeneratePrimaries();
377 fPrimaryGenerator->GeneratePrimaries();
378}
379
380//_____________________________________________________________________________
382{
383 /// User actions at beginning of event
384
385 fVerbose.BeginEvent();
386
387 // Clear TGeo tracks (if filled)
388 if (TString(gMC->GetName()) == "TGeant3TGeo" &&
389 gGeoManager->GetListOfTracks() && gGeoManager->GetTrack(0) &&
390 ((TVirtualGeoTrack*)gGeoManager->GetTrack(0))->HasPoints()) {
391
392 gGeoManager->ClearTracks();
393 // if (gPad) gPad->Clear();
394 }
395}
396
397//_____________________________________________________________________________
399{
400 /// User actions at beginning of a primary track.
401
402 fVerbose.BeginPrimary();
403}
404
405//_____________________________________________________________________________
407{
408 /// User actions at beginning of each track
409
410 fVerbose.PreTrack();
411}
412
413//_____________________________________________________________________________
415{
416 /// User actions at each step
417
418 fVerbose.Stepping();
419 fDriftChamberSD1->ProcessHits();
420 fDriftChamberSD2->ProcessHits();
421 fEmCalorimeterSD->ProcessHits();
422 fHadCalorimeterSD->ProcessHits();
423 fHodoscopeSD1->ProcessHits();
424 fHodoscopeSD2->ProcessHits();
425}
426
427//_____________________________________________________________________________
429{
430 /// User actions after finishing each track
431
432 fVerbose.PostTrack();
433}
434
435//_____________________________________________________________________________
437{
438 /// User actions after finishing each primary track
439
440 fVerbose.FinishPrimary();
441}
442
443//_____________________________________________________________________________
445{
446 /// User actions after finishing an event
447
448 fVerbose.FinishEvent();
449
450 // Geant3 + TGeo
451 // (use TGeo functions for visualization)
452 if (TString(gMC->GetName()) == "TGeant3TGeo") {
453
454 // Draw volume
455 gGeoManager->SetVisOption(0);
456 gGeoManager->SetTopVisible();
457 gGeoManager->GetTopVolume()->Draw();
458
459 // Draw tracks (if filled)
460 // Available when this feature is activated via
461 // gMC->SetCollectTracks(kTRUE);
462 if (gGeoManager->GetListOfTracks() && gGeoManager->GetTrack(0) &&
463 ((TVirtualGeoTrack*)gGeoManager->GetTrack(0))->HasPoints()) {
464
465 gGeoManager->DrawTracks("/*"); // this means all tracks
466 }
467 }
468
469 if (fWriteStack || fWriteHits) {
470 fRootManager->Fill();
471 }
472
473 // Print info about primary particle
474 TParticle* primary = fStack->GetParticle(0);
475 cout << endl
476 << ">>> Event " << gMC->CurrentEvent()
477 << " >>> Simulation truth : " << primary->GetPDG()->GetName() << " ("
478 << primary->Px() * 1e03 << ", " << primary->Py() * 1e03 << ", "
479 << primary->Pz() * 1e03 << ") MeV" << endl;
480
481 // Call detectors
482 fHodoscopeSD1->EndOfEvent();
483 fHodoscopeSD2->EndOfEvent();
484 fDriftChamberSD1->EndOfEvent();
485 fDriftChamberSD2->EndOfEvent();
486 fEmCalorimeterSD->EndOfEvent();
487 fHadCalorimeterSD->EndOfEvent();
488
489 fStack->Reset();
490}
491
492//_____________________________________________________________________________
493void A01MCApplication::SetWriteHits(Bool_t writeHits)
494{
495 /// (In)Activate writing hits on file and propagate this option
496 /// to all SDs
497 /// \param writeHits The new value of the option
498
499 fWriteHits = writeHits;
500 fHodoscopeSD1->SetWriteHits(writeHits);
501 fHodoscopeSD2->SetWriteHits(writeHits);
502 fDriftChamberSD1->SetWriteHits(writeHits);
503 fDriftChamberSD2->SetWriteHits(writeHits);
504 fEmCalorimeterSD->SetWriteHits(writeHits);
505 fHadCalorimeterSD->SetWriteHits(writeHits);
506}
507
508//_____________________________________________________________________________
510{
511 /// Set the option to use local magnetic field (working only with Geant4 !)
512 /// \param localMagField The new value of the option
513
514 fUseLocalMagField = localMagField;
515 fDetConstruction->SetUseLocalMagField(localMagField);
516
517 // delete existing global field
518 delete fMagField;
519 fMagField = 0;
520}
521
522//_____________________________________________________________________________
524{
525 /// Set cuts for e-, gamma equivalent to 1mm cut in G4.
526
527 Int_t mediumId = gMC->MediumId("Air");
528 if (mediumId) {
529 gMC->Gstpar(mediumId, "CUTGAM", 990.e-09);
530 gMC->Gstpar(mediumId, "BCUTE", 990.e-09);
531 gMC->Gstpar(mediumId, "CUTELE", 990.e-09);
532 gMC->Gstpar(mediumId, "DCUTE", 990.e-09);
533 }
534
535 mediumId = gMC->MediumId("G4_Galactic");
536 if (mediumId) {
537 gMC->Gstpar(mediumId, "CUTGAM", 990.e-09);
538 gMC->Gstpar(mediumId, "BCUTE", 990.e-09);
539 gMC->Gstpar(mediumId, "CUTELE", 990.e-09);
540 gMC->Gstpar(mediumId, "DCUTE", 990.e-09);
541 }
542
543 mediumId = gMC->MediumId("Scintillator");
544 if (mediumId) {
545 gMC->Gstpar(mediumId, "CUTGAM", 2.40367 - 06);
546 gMC->Gstpar(mediumId, "BCUTE", 356.639e-06);
547 gMC->Gstpar(mediumId, "CUTELE", 356.639e-06);
548 gMC->Gstpar(mediumId, "DCUTE", 356.639e-06);
549 }
550
551 mediumId = gMC->MediumId("ArgonGas");
552 if (mediumId) {
553 gMC->Gstpar(mediumId, "CUTGAM", 990.e-09);
554 gMC->Gstpar(mediumId, "BCUTE", 990.e-09);
555 gMC->Gstpar(mediumId, "CUTELE", 990.e-09);
556 gMC->Gstpar(mediumId, "DCUTE", 990.e-09);
557 }
558
559 mediumId = gMC->MediumId("CsI");
560 if (mediumId) {
561 gMC->Gstpar(mediumId, "CUTGAM", 38.5665e-06);
562 gMC->Gstpar(mediumId, "BCUTE", 689.033e-06);
563 gMC->Gstpar(mediumId, "CUTELE", 689.033e-06);
564 gMC->Gstpar(mediumId, "DCUTE", 689.033e-06);
565 }
566
567 mediumId = gMC->MediumId("Lead");
568 if (mediumId) {
569 gMC->Gstpar(mediumId, "CUTGAM", 101.843e-06);
570 gMC->Gstpar(mediumId, "BCUTE", 1.36749e-03);
571 gMC->Gstpar(mediumId, "CUTELE", 1.36749e-03);
572 gMC->Gstpar(mediumId, "DCUTE", 1.36749e-03);
573 }
574}
Definition of the A01DriftChamberSD class.
Definition of the A01EmCalorimeterSD class.
Definition of the A01HadCalorimeterSD class.
Definition of the A01HodoscopeSD class.
Definition of the A01MCApplication class.
Definition of the A01MagField class.
Definition of the A01PrimaryGenerator class.
Definition of the A01RootDetectorConstruction class.
The calorimeter sensitive detector.
The EM calorimeter sensitive detector.
The hadron calorimeter sensitive detector.
The calorimeter sensitive detector.
Implementation of the TVirtualMCApplication.
void ReadEvent(Int_t i)
void SetWriteHits(Bool_t writeHits)
void RunMC(Int_t nofEvents)
A01HodoscopeSD * fHodoscopeSD2
Hodoscope 2 SD.
A01MagField * fMagField
Magnetic field.
virtual void GeneratePrimaries()
A01DriftChamberSD * fDriftChamberSD1
Drift Chamber 1 SD.
virtual void Stepping()
virtual void BeginPrimary()
Bool_t fIsMaster
If is on master thread.
A01RootDetectorConstruction * fDetConstruction
Detector construction.
virtual void PreTrack()
virtual void AddParticles()
virtual void FinishRunOnWorker()
virtual void ConstructGeometry()
virtual void FinishEvent()
virtual void FinishPrimary()
A01DriftChamberSD * fDriftChamberSD2
Drift Chamber 2 SD.
void InitMC(const char *setup)
virtual void InitGeometry()
TMCVerbose fVerbose
VMC verbose helper.
A01HadCalorimeterSD * fHadCalorimeterSD
Had Calorimeter SD.
Bool_t fWriteStack
Option to write stack.
Bool_t fUseLocalMagField
Option to use local magnetic field (working only with Geant4 !).
Ex03MCStack * fStack
VMC stack.
virtual void BeginEvent()
A01PrimaryGenerator * fPrimaryGenerator
Primary generator.
A01MCApplication(const char *name, const char *title)
void SetUseLocalMagField(Bool_t localMagField)
virtual void InitOnWorker()
virtual void AddIons()
virtual TVirtualMCApplication * CloneForWorker() const
virtual void PostTrack()
TMCRootManager * fRootManager
Root manager.
void RegisterStack() const
A01EmCalorimeterSD * fEmCalorimeterSD
Em Calorimeter SD.
A01HodoscopeSD * fHodoscopeSD1
Hodoscope 1 SD.
Definition of a uniform magnetic field within a given region.
Definition A01MagField.h:30
The primary generator.
The detector construction (via TGeo ).
Implementation of the TVirtualMCStack interface.
Definition Ex03MCStack.h:36