Class Reference for E1039 Core & Analysis Software
SQSingleMuonGen.cxx
Go to the documentation of this file.
1 #include "SQSingleMuonGen.h"
2 
4 #include <g4main/PHG4InEvent.h>
7 
9 #include <phool/getClass.h>
10 
11 #include <phool/PHCompositeNode.h>
12 #include <phool/PHIODataNode.h>
13 #include <phool/PHRandomSeed.h>
14 #include <phool/recoConsts.h>
15 
16 #include <Geant4/G4ParticleTable.hh>
17 #include <Geant4/G4ParticleDefinition.hh>
18 
19 #include <TMath.h>
20 #include <TGenPhaseSpace.h>
21 
22 #include <cstdlib>
23 #include <cmath>
24 #include <cassert>
25 
26 SQSingleMuonGen::SQSingleMuonGen(const std::string& name):
28  _ineve(nullptr),
29  _truth(nullptr),
30  _target_only(true),
31  _enable_geom_cut(true),
32  _enable_real_mom_dist(true),
33  _ctau(2.6E-8*29979245800.),
34  _mom_min(1.),
35  _mom_max(100.),
36  _pt_max(4.),
37  _charge_ratio(0.5),
38  _m_muon(0.105658),
39  _m_pion(0.13957),
40  _pt_dist(nullptr),
41  _vtx_x0(0.),
42  _vtx_y0(0.),
43  _rndm(PHRandomSeed())
44 {
45  for(int i = 0; i < 6; ++i) _pz_dist[i] = nullptr;
46 }
47 
49 {
50  PHNodeIterator iter(topNode);
51  PHCompositeNode* dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
52 
53  _truth = new SQSingleMuonTruthInfo();
54  PHIODataNode<PHObject>* truthNode = new PHIODataNode<PHObject>(_truth, "TruthInfo", "PHObject");
55  dstNode->addNode(truthNode);
56 
57  _ineve = findNode::getClass<PHG4InEvent>(topNode, "PHG4INEVENT");
58  if(!_ineve)
59  {
60  _ineve = new PHG4InEvent();
61  PHIODataNode<PHObject>* eveNode = new PHIODataNode<PHObject>(_ineve, "PHG4INEVENT", "PHObject");
62  dstNode->addNode(eveNode);
63  }
64 
65  _pt_dist = new TF1("PtDistr", "TMath::Landau(x, 0.416742, 0.174227)", 0., _pt_max);
66  _pz_dist[0] = new TF1("PzDistr1", "0.161*(x^-2.396)", _mom_min, _mom_max);
67  _pz_dist[1] = new TF1("PzDistr2", "0.527*(x^-1.996)", _mom_min, _mom_max);
68  _pz_dist[2] = new TF1("PzDistr3", "0.489*(x^-2.200)", _mom_min, _mom_max);
69  _pz_dist[3] = new TF1("PzDistr4", "0.302*(x^-1.900)", _mom_min, _mom_max);
70  _pz_dist[4] = new TF1("PzDistr5", "0.174*(x^-1.750)", _mom_min, _mom_max);
71  _pz_dist[5] = new TF1("PzDistr6", "0.909*(x^-1.850)", _mom_min > 8. ? _mom_min : 8., _mom_max);
72 
74  _vtx_x0 = rc->get_DoubleFlag("X_BEAM");
75  _vtx_y0 = rc->get_DoubleFlag("Y_BEAM");
76 
78 }
79 
81 {
82  for(int i = 0; i < 6; ++i)
83  {
84  if(_pz_dist[i] != nullptr) delete _pz_dist[i];
85  }
86  if(_pt_dist != nullptr) delete _pt_dist;
87 }
88 
90 {
91  int nTries = 0;
92  bool accepted = false;
93  while(!accepted)
94  {
95  //Generate mother particle first
96  generatePrimaryVtx();
97  generateMotherParticle();
98 
99  //Decay the mother particle, and get the muon's vtx and mom
100  decayMotherParticle();
101 
102  accepted = _enable_geom_cut ? geometryCut() : true;
103  ++nTries;
104  }
105 
106  if(Verbosity() > 10) std::cout << "Generated single muon within acceptance after " << nTries << " tries." << std::endl;
107 
108  int pdgcode = _truth->motherPid > 0 ? 13 : -13;
109  std::string pdgname = get_pdgname(pdgcode);
110 
111  //Generate a muon and set common features
112  int vtxID = _ineve->AddVtx(_truth->muVtx.X(), _truth->muVtx.Y(), _truth->muVtx.Z(), 0.);
113  PHG4Particle* particle = new PHG4Particlev2();
114  particle->set_track_id(0);
115  particle->set_vtx_id(vtxID);
116  particle->set_parent_id(0);
117  particle->set_pid(pdgcode);
118  particle->set_name(pdgname);
119 
120  double e = TMath::Sqrt(_truth->muMom.Mag2() + _m_muon*_m_muon);
121  particle->set_px(_truth->muMom.X());
122  particle->set_py(_truth->muMom.Y());
123  particle->set_pz(_truth->muMom.Z());
124  particle->set_e(e);
125  _ineve->AddParticle(vtxID, particle); //ownership of particle is transferred to _ineve and released in its Reset action
126 
128  {
129  _ineve->identify();
130  }
131 
133 }
134 
135 void SQSingleMuonGen::generateMotherParticle()
136 {
137  int pid = _rndm.Rndm() < _charge_ratio ? 211 : -211;
138  std::string name = get_pdgname(pid);
139 
140  double pz, pt;
141  if(_enable_real_mom_dist)
142  {
143  pt = _pt_dist->GetRandom();
144  if(pt < 0.1)
145  {
146  pz = _pz_dist[0]->GetRandom();
147  }
148  else if(pt < 0.2)
149  {
150  pz = _pz_dist[1]->GetRandom();
151  }
152  else if(pt < 0.3)
153  {
154  pz = _pz_dist[2]->GetRandom();
155  }
156  else if(pt < 0.4)
157  {
158  pz = _pz_dist[3]->GetRandom();
159  }
160  else if(pt < 0.5)
161  {
162  pz = _pz_dist[4]->GetRandom();
163  }
164  else
165  {
166  pz = _pz_dist[5]->GetRandom();
167  }
168  }
169  else
170  {
171  pz = _mom_min + (_mom_max - _mom_min)*_rndm.Rndm();
172  pt = _rndm.Rndm()*_pt_max;
173  }
174 
175  double phi = _rndm.Rndm()*TMath::TwoPi();
176  double px = pt*TMath::Cos(phi);
177  double py = pt*TMath::Sin(phi);
178 
179  _truth->motherPid = pid;
180  _truth->motherMom = TVector3(px, py, pz);
181 }
182 
183 void SQSingleMuonGen::decayMotherParticle()
184 {
185  TGenPhaseSpace evtgen;
186  double m[2] = {_m_muon, 0.};
187 
188  TLorentzVector W;
189  W.SetVectM(_truth->motherMom, _m_pion);
190  evtgen.SetDecay(W, 2, m);
191  evtgen.Generate();
192 
193  TLorentzVector* p = evtgen.GetDecay(0);
194  _truth->muMom = p->Vect();
195 
196  // Get the decay vector
197  double ctau1 = _ctau*W.Gamma();
198  _truth->decayLength = _rndm.Exp(ctau1);
199  _truth->muVtx = _truth->decayLength*_truth->muMom.Unit() + _truth->motherVtx;
200 }
201 
202 bool SQSingleMuonGen::geometryCut()
203 {
204  if(fabs(_truth->muMom.Px()/_truth->muMom.Pz()) > 0.15) return false;
205  if(fabs(_truth->muMom.Py()/_truth->muMom.Pz()) > 0.15) return false;
206  if(_truth->muMom.Mag() < 10.) return false;
207 
208  if(_truth->decayLength > 300.) return false;
209  return true;
210 }
211 
212 bool SQSingleMuonGen::generatePrimaryVtx()
213 {
214  double z = -300.;
215  _truth->motherVtx.SetXYZ(_vtx_x0, _vtx_y0, z);
216  return true;
217 }
@ VERBOSITY_A_LOT
Output a lot of messages.
Definition: Fun4AllBase.h:48
virtual int Verbosity() const
Gets the verbosity of this module.
Definition: Fun4AllBase.h:64
PHBoolean addNode(PHNode *)
virtual double get_DoubleFlag(const std::string &name) const
Definition: PHFlag.cc:49
int AddParticle(const int vtxid, PHG4Particle *particle)
Definition: PHG4InEvent.cc:63
int AddVtx(const double x, const double y, const double z, const double t)
Definition: PHG4InEvent.cc:38
virtual void identify(std::ostream &os=std::cout) const
Definition: PHG4InEvent.cc:134
std::string get_pdgname(const int pdgcode) const
virtual void set_parent_id(const int i)
Definition: PHG4Particle.h:30
virtual void set_vtx_id(const int i)
Definition: PHG4Particle.h:29
virtual void set_pid(const int i)
Definition: PHG4Particle.h:33
virtual void set_e(const double e)
Definition: PHG4Particle.h:37
virtual void set_py(const double x)
Definition: PHG4Particle.h:35
virtual void set_track_id(const int i)
Definition: PHG4Particle.h:28
virtual void set_name(const std::string &name)
Definition: PHG4Particle.h:32
virtual void set_px(const double x)
Definition: PHG4Particle.h:34
virtual void set_pz(const double x)
Definition: PHG4Particle.h:36
PHNode * findFirst(const std::string &, const std::string &)
virtual ~SQSingleMuonGen()
SQSingleMuonGen(const std::string &name="SINGLEGEN")
int InitRun(PHCompositeNode *topNode)
int process_event(PHCompositeNode *topNode)
static recoConsts * instance()
Definition: recoConsts.cc:7