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) 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 MCApplication.cxx
11/// \brief Implementation of the MCApplication class
12///
13/// Geant4 Monopole example adapted to Virtual Monte Carlo \n
14///
15/// \date 15/07/2018
16/// \author I. Hrivnacova; IPN, Orsay
17
18#include "MCApplication.h"
19#include "DetectorConstruction.h"
20#include "Ex03MCStack.h"
21
22#include <TMCRootManager.h>
23
24#include <Riostream.h>
25#include <TDatabasePDG.h>
26#include <TGeoManager.h>
27#include <TGeoMaterial.h>
28#include <TH1.h>
29#include <TInterpreter.h>
30#include <TLorentzVector.h>
31#include <TROOT.h>
32#include <TRandom.h>
33#include <TVirtualMC.h>
34
35using namespace std;
36
37/// \cond CLASSIMP
39 /// \endcond
40
41 namespace
42{
43 int G4lrint(double ad)
44 {
45 return (ad > 0) ? static_cast<int>(ad + .5) : static_cast<int>(ad - .5);
46 }
47}
48
49namespace VMC
50{
51namespace Monopole
52{
53
54std::vector<TH1D*> fHistograms;
55
56//_____________________________________________________________________________
57MCApplication::MCApplication(const char* name, const char* title)
58 : TVirtualMCApplication(name, title),
59 fRootManager(0),
60 fStack(0),
61 fDetConstruction(0),
62 fMagField(0),
63 fBinSize(0.),
64 fOffsetX(0.),
65 fProjRange(0.),
66 fProjRange2(0.),
67 fImedAl(0),
68 fNofEvents(0),
69 fIsMaster(kTRUE)
70{
71 /// Standard constructor
72 /// \param name The MC application name
73 /// \param title The MC application description
74
75 // Create a user stack
76 fStack = new Ex03MCStack(1000);
77
78 // Create detector construction
80
81 // Constant magnetic field (in kiloGauss)
82 fMagField = new TGeoUniformMagField(0, 0, 2);
83}
84
85//_____________________________________________________________________________
87 : TVirtualMCApplication(origin.GetName(), origin.GetTitle()),
88 fRootManager(0),
89 fStack(0),
90 fDetConstruction(origin.fDetConstruction),
91 fMagField(0),
92 fImedAl(origin.fImedAl),
93 fNofEvents(0),
94 fIsMaster(kFALSE)
95{
96 /// Copy constructor for cloning application on workers (in multithreading
97 /// mode) \param origin The source MC application
98
99 // Create new user stack
100 fStack = new Ex03MCStack(1000);
101
102 // Constant magnetic field (in kiloGauss)
103 fMagField = new TGeoUniformMagField(origin.fMagField->GetFieldValue()[0],
104 origin.fMagField->GetFieldValue()[1], origin.fMagField->GetFieldValue()[2]);
105}
106
107//_____________________________________________________________________________
110 fRootManager(0),
111 fStack(0),
112 fDetConstruction(0),
113 fMagField(0),
114 fBinSize(0.5),
115 fImedAl(0),
116 fNofEvents(0),
117 fIsMaster(kTRUE)
118{
119 /// Default constructor
120}
121
122//_____________________________________________________________________________
124{
125 /// Destructor
126
127 delete fStack;
128 if (fIsMaster) delete fDetConstruction;
129 delete fMagField;
130 delete gMC;
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//
149// public methods
150//
151
152//_____________________________________________________________________________
153void MCApplication::InitMC(const char* setup)
154{
155 /// Initialize MC.
156 /// The selection of the concrete MC is done in the macro.
157 /// \param setup The name of the configuration macro
158
159 if (TString(setup) != "") {
160 gROOT->LoadMacro(setup);
161 gInterpreter->ProcessLine("Config()");
162 if (!gMC) {
163 Fatal(
164 "InitMC", "Processing Config() has failed. (No MC is instantiated.)");
165 }
166 }
167
168 // MT support available from root v 5.34/18
169#if ROOT_VERSION_CODE >= 336402
170 // Create Root manager
171 if (!gMC->IsMT()) {
172 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
173 // fRootManager->SetDebug(true);
174 }
175#else
176 // Create Root manager
177 fRootManager = new TMCRootManager(GetName(), TMCRootManager::kWrite);
178 // fRootManager->SetDebug(true);
179#endif
180
181 gMC->SetStack(fStack);
182 gMC->SetMagField(fMagField);
183 gMC->Init();
184 gMC->BuildPhysics();
185
186 // Notify detector construction about initialization
188
189 // initialize projected range, tallies, Ebeam, and book histograms
190 // Double_t maxStepSize = 0.5;
191 fProjRange = 0.;
192 fProjRange2 = 0.;
193
194 Double_t length = fDetConstruction->GetAbsorberSizeX() * 10.; // in mm
195 Double_t binSize = fBinSize * 10.; // in mm
196 Int_t numBins = G4lrint(length / binSize);
197
198 // Define offset for filling histogram
199 fOffsetX = -0.5 * length; // in mm
200
201 // cout << "numBins, length, offsetX "
202 // << numBins << ", " << length << ", " << fOffsetX << endl;
203
204 // Create histograms
205 // fHistograms.push_back(new TH1D("Edep_x", "Edep (MeV/mm) along absorber
206 // (mm)", numBins, 0, length));
207 fHistograms.push_back(
208 new TH1D("h1", "Edep (MeV/mm) along absorber (mm)", numBins, 0, length));
209 // fHistograms.push_back(new TH1D("h2", "DEDX (MeV/mm) of proton", 100,
210 // -3., 7.)); fHistograms.push_back(new TH1D("h3", "DEDX (MeV/mm) of
211 // monopole", 100, -3., 7.)); fHistograms.push_back(new TH1D("h4", "Range(mm)
212 // of proton", 100, -3., 7.)); fHistograms.push_back(new TH1D("h5", "Range(mm)
213 // of monopole", 100, -3., 7.)); Control histograms fHistograms.push_back(new
214 // TH1D("x", "x", 100, -10, 10)); fHistograms.push_back(new TH1D("Edep (MeV)",
215 // "Edep (Mev)", 100, 0, 100));
216
218}
219
220//__________________________________________________________________________
221void MCApplication::RunMC(Int_t nofEvents)
222{
223 /// Run MC.
224 /// \param nofEvents Number of events to be processed
225
226 gMC->ProcessRun(nofEvents);
227 fNofEvents = nofEvents;
228 FinishRun();
229}
230
231//_____________________________________________________________________________
233{
234 /// Finish MC run.
235
236 // Get monopole mass from TDatabasePDG
237 TDatabasePDG* pdgDB = TDatabasePDG::Instance();
238 TParticlePDG* monopole = pdgDB->GetParticle(60000000);
239 Double_t mass = 0;
240 if (monopole) {
241 mass = monopole->Mass();
242 }
243
244 // run conditions
245 cout << "\n The run consists of " << fNofEvents << " monopole "
246 << " of " << mass << " GeV "
247 << " through " << fDetConstruction->GetAbsorberSizeX() << " cm of "
249 // << " (density: " << G4BestUnit(density,"Volumic Mass") << ")"
250 << endl;
251
252 // compute projected range and straggling
253
256 Double_t rms = fProjRange2 - fProjRange * fProjRange;
257 if (rms > 0.) {
258 rms = std::sqrt(rms);
259 }
260 else {
261 rms = 0.;
262 }
263
264 cout.precision(5);
265 cout << "\n projected Range= " << fProjRange << " cm "
266 << " rms= " << rms << " cm " << endl;
267
268 /*
269 G4double ekin[100], dedxproton[100], dedxmp[100];
270 G4EmCalculator calc;
271 calc.SetVerbose(0);
272 G4int i;
273 for(i = 0; i < 100; ++i) {
274 ekin[i] = std::pow(10., 0.1*G4double(i)) * keV;
275 dedxproton[i] =
276 calc.ComputeElectronicDEDX(ekin[i], "proton", matName);
277 dedxmp[i] =
278 calc.ComputeElectronicDEDX(ekin[i], "monopole", matName);
279 }
280
281 if(GetVerbose() > 0){
282 G4cout << "### Stopping Powers" << G4endl;
283 for(i=0; i<100; i++) {
284 G4cout << " E(MeV)= " << ekin[i] << " dedxp= " << dedxproton[i]
285 << " dedxmp= " << dedxmp[i]
286 << G4endl;
287 }
288 }
289 G4cout << "### End of stopping power table" << G4endl;
290
291 if(GetVerbose() > 0){
292 G4cout << "Range table for " << matName << G4endl;
293 }
294
295 for(i=0; i<100; ++i) {
296 G4double e = std::log10(ekin[i] / MeV) + 0.05;
297 fHisto->Fill(1, e, dedxproton[i]);
298 fHisto->Fill(2, e, dedxmp[i]);
299 fHisto->Fill(3, e,
300 std::log10(calc.GetRange(ekin[i],"proton",matName)/mm)); fHisto->Fill(4, e,
301 std::log10(calc.GetRange(ekin[i],"monopole",matName)/mm));
302 }
303 */
304 // normalize histogram
305 // G4double fac = (mm/MeV) / (nEvents * fBinLength);
306 Double_t fac = 1. / (fNofEvents * fBinSize * 10.);
307 fHistograms[0]->Scale(fac);
308
309 if (fRootManager) {
310 fRootManager->WriteAll();
311 fRootManager->Close();
312 }
313}
314
315/*
316
317//_____________________________________________________________________________
318TVirtualMCApplication* MCApplication::CloneForWorker() const
319{
320 return new MCApplication(*this);
321}
322
323//_____________________________________________________________________________
324void MCApplication::InitOnWorker()
325{
326 // Create Root manager
327 fRootManager
328 = new TMCRootManager(GetName(), TMCRootManager::kWrite);
329 //fRootManager->SetDebug(true);
330
331 gMC->SetStack(fStack);
332 gMC->SetMagField(fMagField);
333
334 RegisterStack();
335}
336
337//_____________________________________________________________________________
338void MCApplication::FinishRunOnWorker()
339{
340 //cout << "Ex03MCApplication::FinishWorkerRun: " << endl;
341 if ( fRootManager ) {
342 fRootManager->WriteAll();
343 fRootManager->Close();
344 }
345}
346*/
347
348//_____________________________________________________________________________
350{
351 /// Construct geometry using detector contruction class.
352 /// The detector contruction class is using TGeo functions.
353
355}
356
357//_____________________________________________________________________________
359{
360 /// Initialize geometry.
361
362 fImedAl = gMC->MediumId("Aluminium");
363}
364
365//_____________________________________________________________________________
367{
368 /// Fill the user stack (derived from TVirtualMCStack) with primary particles.
369
370 // Track ID (filled by stack)
371 Int_t ntr;
372
373 // Option: to be tracked
374 Int_t toBeDone = 1;
375
376 // Monopole
377 Int_t pdg = 60000000;
378
379 // Polarization
380 Double_t polx = 0.;
381 Double_t poly = 0.;
382 Double_t polz = 0.;
383
384 // Position
385 Double_t vx = -0.5 * (fDetConstruction->GetWorldSizeX()) + 1e-10; // + 1*um
386 Double_t vy = 0.;
387 Double_t vz = 0.;
388 Double_t tof = 0.08;
389
390 // Energy (in GeV)
391 Double_t kinEnergy = 100.;
392 Double_t mass = 100.;
393 Double_t e = mass + kinEnergy;
394
395 // Particle momentum
396 Double_t px, py, pz;
397 px = sqrt(e * e - mass * mass);
398 py = 0.;
399 pz = 0.;
400
401 // Add particle to stack
402 fStack->PushTrack(toBeDone, -1, pdg, px, py, pz, e, vx, vy, vz, tof, polx,
403 poly, polz, kPPrimary, ntr, 1., 0);
404}
405
406//_____________________________________________________________________________
408{
409 /// User actions at beginning of event.
410 /// Nothing to be done this example
411}
412
413//_____________________________________________________________________________
415{
416 /// User actions at beginning of a primary track.
417 /// Nothing to be done this example
418}
419
420//_____________________________________________________________________________
422{
423 /// User actions at beginning of each track.
424 /// Print info message.
425
426 // Check the monopole properties set via configuration macro
427 // cout << endl;
428 // std::cout << "&&&&& Track mass: " << gMC->TrackMass() << std::endl;
429 // std::cout << "&&&&& Track charge: " << gMC->TrackCharge() << std::endl;
430}
431
432//_____________________________________________________________________________
434{
435 /// User actions at each step.
436 /// Print track position, the current volume and current medium names.
437
438 static TLorentzVector prevPosition;
439
440 TLorentzVector position;
441 gMC->TrackPosition(position);
442
443 Double_t edep = gMC->Edep();
444 if (edep <= 0.) {
445 prevPosition = position;
446 return;
447 }
448
449 edep *= 1.e03; // convert in MeV
450
451 // Bragg curve
452 Double_t x = position.X() * 10.;
453 Double_t dx = (position.X() - prevPosition.X()) * 10.;
454 // cout << "prevPosition "
455 // << prevPosition.X() << ", " << prevPosition.Y() << ", " <<
456 // prevPosition.Z() << endl;
457 // cout << "position "
458 // << position.X() << ", " << position.Y() << ", " << position.Z() <<
459 // endl;
460 // cout << "dx= " << dx << endl;
461
462 Double_t random = gRandom->Uniform(0, 1);
463 x += dx * random - fOffsetX;
464
465 fHistograms[0]->Fill(x, edep);
466 // fHistograms[1]->Fill(x);
467 // fHistograms[2]->Fill(edep);
468
469 // keep position from previous step
470 prevPosition = position;
471}
472
473//_____________________________________________________________________________
475{
476 /// User actions after finishing of each track
477
478 // Skip secondary tracks
479 if (fStack->GetCurrentParentTrackNumber() != -1) return;
480
481 TLorentzVector position;
482 gMC->TrackPosition(position);
483
484 Double_t x = position.X() - fOffsetX / 10.; // in cm
485 fProjRange += x;
486 fProjRange2 += x * x;
487}
488
489//_____________________________________________________________________________
491{
492 /// User actions after finishing of a primary track.
493 /// Nothing to be done this example
494}
495
496//_____________________________________________________________________________
498{
499 /// User actions after finishing of an event
500
501 // fRootManager->Fill();
502 fStack->Reset();
503}
504
505//_____________________________________________________________________________
506void MCApplication::SetBinSize(Double_t binSize)
507{
508 /// Set Edep histogram bin size (in cm)
509
511 cerr << "Geometry alredy initialized: cannot set Edep histogram bin size"
512 << endl;
513 return;
514 }
515
516 fBinSize = binSize;
517}
518
519} // namespace Monopole
520} // namespace VMC
Implementation of the TVirtualMCStack interface.
Definition Ex03MCStack.h:36
virtual void PushTrack(Int_t toBeDone, Int_t parent, Int_t pdg, Double_t px, Double_t py, Double_t pz, Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t tof, Double_t polx, Double_t poly, Double_t polz, TMCProcess mech, Int_t &ntr, Double_t weight, Int_t is)
virtual Int_t GetCurrentParentTrackNumber() const
The detector construction (via TGeo )
void SetGeometryInitialized(Bool_t geometryInitialized)
Implementation of the TVirtualMCApplication.
Ex03MCStack * fStack
The VMC stack.
void InitMC(const char *setup)
Int_t fImedAl
The Aluminium medium Id.
void SetBinSize(Double_t binSize)
Double_t fBinSize
Edep histogram bin size.
Double_t fProjRange
Projected range.
void RunMC(Int_t nofEvents)
Bool_t fIsMaster
If is on master thread.
Int_t fNofEvents
Number of events.
Double_t fOffsetX
The Edep histogram offset.
DetectorConstruction * fDetConstruction
Dector construction.
TMCRootManager * fRootManager
Root manager.
TGeoUniformMagField * fMagField
Magnetic field.
Double_t fProjRange2
Projected range square.
std::vector< TH1D * > fHistograms