Class Reference for E1039 Core & Analysis Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PHG4SimpleEventGenerator.cc
Go to the documentation of this file.
2 
3 #include "PHG4Particlev2.h"
4 #include "PHG4InEvent.h"
5 #include "PHG4VtxPoint.h"
7 
9 #include <phool/getClass.h>
10 
11 #include <phool/PHCompositeNode.h>
12 #include <phool/PHIODataNode.h>
13 
14 #include <Geant4/G4ParticleTable.hh>
15 #include <Geant4/G4ParticleDefinition.hh>
16 
17 #include <gsl/gsl_randist.h>
18 
19 #include <cstdlib>
20 #include <cmath>
21 #include <cassert>
22 
23 //Abi
24 #include <TGeoMaterial.h>
25 #include <phgeom/PHGeomUtility.h>
26 #include <TGeoManager.h>
27 
28 using namespace std;
29 
32  _particle_codes(),
33  _particle_names(),
34  _vertex_func_x(Uniform),
35  _vertex_func_y(Uniform),
36  _vertex_func_z(Uniform),
37  _t0(0.0),
38  _vertex_x(0.0),
39  _vertex_y(0.0),
40  _vertex_z(0.0),
41  _vertex_width_x(0.0),
42  _vertex_width_y(0.0),
43  _vertex_width_z(0.0),
44  _vertex_offset_x(0.0),
45  _vertex_offset_y(0.0),
46  _vertex_offset_z(0.0),
47  _vertex_size_func_r(Uniform),
48  _vertex_size_mean(0.0),
49  _vertex_size_width(0.0),
50  _eta_min(-1.25),
51  _eta_max(1.25),
52  _phi_min(-M_PI),
53  _phi_max(M_PI),
54  _pt_min(0.0),
55  _pt_max(10.0),
56  _pt_gaus_width(0.0),
57  _p_min(NAN),
58  _p_max(NAN),
59  _p_gaus_width(NAN),
60  _px_min(NAN), _px_max(NAN),
61  _py_min(NAN), _py_max(NAN),
62  _pz_min(NAN), _pz_max(NAN),
63  _ineve(NULL)
64  //_legacy_vertexgenerator(nullptr)
65 {
66 
67  //_vertexGen = new SQPrimaryVertexGen();
68  return;
69 }
70 
71 void PHG4SimpleEventGenerator::add_particles(const std::string &name, const unsigned int num) {
72  _particle_names.push_back(std::make_pair(name,num));
73  return;
74 }
75 
76 void PHG4SimpleEventGenerator::add_particles(const int pid, const unsigned int num) {
77  _particle_codes.push_back(std::make_pair(pid,num));
78  return;
79 }
80 
81 void PHG4SimpleEventGenerator::set_t0(const double t0) {
82  _t0 = t0;
83  return;
84 }
85 
86 void PHG4SimpleEventGenerator::set_eta_range(const double min, const double max) {
87  if (min > max)
88  {
89  cout << "not setting eta bc etamin " << min << " > etamax: " << max << endl;
90  return;
91  }
92  _eta_min = min;
93  _eta_max = max;
94  return;
95 }
96 
97 void PHG4SimpleEventGenerator::set_phi_range(const double min, const double max) {
98  if (min > max)
99  {
100  cout << "not setting phi bc phimin " << min << " > phimax: " << max << endl;
101  return;
102  }
103  _phi_min = min;
104  _phi_max = max;
105  return;
106 }
107 
108 void PHG4SimpleEventGenerator::set_pt_range(const double min, const double max, const double pt_gaus_width) {
109  if (min > max)
110  {
111  cout << "not setting pt bc ptmin " << min << " > ptmax: " << max << endl;
112  return;
113  }
114  assert(pt_gaus_width >=0 );
115 
116  _pt_min = min;
117  _pt_max = max;
118  _pt_gaus_width = pt_gaus_width;
119  _p_min = NAN;
120  _p_max = NAN;
121  _p_gaus_width = NAN;
122  return;
123 }
124 
125 void PHG4SimpleEventGenerator::set_p_range(const double min, const double max, const double p_gaus_width) {
126  if (min > max)
127  {
128  cout << "not setting p bc ptmin " << min << " > ptmax: " << max << endl;
129  return;
130  }
131  assert(p_gaus_width >=0 );
132  _pt_min = NAN;
133  _pt_max = NAN;
134  _pt_gaus_width = NAN;
135  _p_min = min;
136  _p_max = max;
137  _p_gaus_width = p_gaus_width;
138  return;
139 }
140 
142  _vertex_func_x = x;
143  _vertex_func_y = y;
144  _vertex_func_z = z;
145  return;
146 }
147 
148 void PHG4SimpleEventGenerator::set_vertex_distribution_mean(const double x, const double y, const double z) {
149  _vertex_x = x;
150  _vertex_y = y;
151  _vertex_z = z;
152  return;
153 }
154 
155 void PHG4SimpleEventGenerator::set_vertex_distribution_width(const double x, const double y, const double z) {
156  _vertex_width_x = x;
157  _vertex_width_y = y;
158  _vertex_width_z = z;
159  return;
160 }
161 
162 void PHG4SimpleEventGenerator::set_existing_vertex_offset_vector(const double x, const double y, const double z) {
163  _vertex_offset_x = x;
164  _vertex_offset_y = y;
165  _vertex_offset_z = z;
166  return;
167 }
168 
170  _vertex_size_func_r = r;
171  return;
172 }
173 
174 void PHG4SimpleEventGenerator::set_vertex_size_parameters(const double mean, const double width) {
175  _vertex_size_mean = mean;
176  _vertex_size_width = width;
177  return;
178 }
179 
181 
182  if ((_vertex_func_x != Uniform)&&(_vertex_func_x != Gaus)) {
183  cout << PHWHERE << "::Error - unknown vertex distribution function requested" << endl;
185  }
186  if ((_vertex_func_y != Uniform)&&(_vertex_func_y != Gaus)) {
187  cout << PHWHERE << "::Error - unknown vertex distribution function requested" << endl;
189  }
190  if ((_vertex_func_z != Uniform)&&(_vertex_func_z != Gaus)) {
191  cout << PHWHERE << "::Error - unknown vertex distribution function requested" << endl;
193  }
194 
195  _ineve = findNode::getClass<PHG4InEvent>(topNode, "PHG4INEVENT");
196  if (!_ineve) {
197  PHNodeIterator iter( topNode );
198  PHCompositeNode *dstNode;
199  dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
200 
201  _ineve = new PHG4InEvent();
202  PHDataNode<PHObject> *newNode = new PHDataNode<PHObject>(_ineve, "PHG4INEVENT", "PHObject");
203  dstNode->addNode(newNode);
204  }
205 
206  if (verbosity > 0) {
207  cout << "================ PHG4SimpleEventGenerator::InitRun() ======================" << endl;
208  cout << " Random seed = " << get_seed() << endl;
209  cout << " Particles:" << endl;
210  for (unsigned int i=0; i<_particle_codes.size(); ++i) {
211  cout << " " << _particle_codes[i].first << ", count = " << _particle_codes[i].second << endl;
212  }
213  for (unsigned int i=0; i<_particle_names.size(); ++i) {
214  cout << " " << _particle_names[i].first << ", count = " << _particle_names[i].second << endl;
215  }
217  cout << " Vertex Distribution: Set to reuse a previously generated sim vertex" << endl;
218  cout << " Vertex offset vector (x,y,z) = (" << _vertex_offset_x << ","<< _vertex_offset_y << ","<< _vertex_offset_z << ")" << endl;
219  } else {
220  cout << " Vertex Distribution Function (x,y,z) = (";
221  if (_vertex_func_x == Uniform) cout << "Uniform,";
222  else if (_vertex_func_x == Gaus) cout << "Gaus,";
223  if (_vertex_func_y == Uniform) cout << "Uniform,";
224  else if (_vertex_func_y == Gaus) cout << "Gaus,";
225  if (_vertex_func_z == Uniform) cout << "Uniform";
226  else if (_vertex_func_z == Gaus) cout << "Gaus";
227  cout << ")" << endl;
228  cout << " Vertex mean (x,y,z) = (" << _vertex_x << ","<< _vertex_y << ","<< _vertex_z << ")" << endl;
229  cout << " Vertex width (x,y,z) = (" << _vertex_width_x << ","<< _vertex_width_y << ","<< _vertex_width_z << ")" << endl;
230  }
231  cout << " Vertex size function (r) = (";
232  if (_vertex_size_func_r == Uniform) cout << "Uniform";
233  else if (_vertex_size_func_r == Gaus) cout << "Gaus";
234  cout << ")" << endl;
235  cout << " Vertex size (mean) = (" << _vertex_size_mean << ")" << endl;
236  cout << " Vertex size (width) = (" << _vertex_size_width << ")" << endl;
237  cout << " Eta range = " << _eta_min << " - " << _eta_max << endl;
238  cout << " Phi range = " << _phi_min << " - " << _phi_max << endl;
239  cout << " pT range = " << _pt_min << " - " << _pt_max << endl;
240  cout << " t0 = " << _t0 << endl;
241  cout << "===========================================================================" << endl;
242  }
243 
244  // the definition table should be filled now, so convert codes into names
245  for (unsigned int i=0;i<_particle_codes.size();++i) {
246  int pdgcode = _particle_codes[i].first;
247  unsigned int count = _particle_codes[i].second;
248  string pdgname = get_pdgname(pdgcode);
249  _particle_names.push_back(make_pair(pdgname,count));
250  }
251 
253 }
254 
256  if (verbosity > 0) {
257  cout << "====================== PHG4SimpleEventGenerator::process_event() =====================" << endl;
258  cout <<"PHG4SimpleEventGenerator::process_event - reuse_existing_vertex = "<<reuse_existing_vertex<<endl;
259  }
260 
261  // vtx_x, vtx_y and vtx_z are doubles from the base class
262  // common methods modify those, please no private copies
263  // at some point we might rely on them being up to date
264  if (!ReuseExistingVertex(topNode))
265  {
266  // generate a new vertex point
267  vtx_x = smearvtx(_vertex_x,_vertex_width_x,_vertex_func_x);
268  vtx_y = smearvtx(_vertex_y,_vertex_width_y,_vertex_func_y);
269  vtx_z = smearvtx(_vertex_z,_vertex_width_z,_vertex_func_z);
270  }
271 
272 
273  vtx_x += _vertex_offset_x;
274  vtx_y += _vertex_offset_y;
275  vtx_z += _vertex_offset_z;
276 
277  if (verbosity > 0) {
278  cout <<"PHG4SimpleEventGenerator::process_event - vertex center"<<reuse_existing_vertex
279  << vtx_x<<", "<< vtx_y<<", "<< vtx_z<<" cm"
280  <<endl;
281  }
282 
283  int vtxindex = -1;
284  int trackid = -1;
285  for (unsigned int i=0; i<_particle_names.size(); ++i) {
286 
287  string pdgname = _particle_names[i].first;
288  int pdgcode = get_pdgcode(pdgname);
289  unsigned int nparticles = _particle_names[i].second;
290 
291  for (unsigned int j=0; j<nparticles; ++j) {
292 
293  if ((_vertex_size_width > 0.0)||(_vertex_size_mean != 0.0)) {
294 
295  double r = smearvtx(_vertex_size_mean,_vertex_size_width,_vertex_size_func_r);
296 
297  double x = 0.0;
298  double y = 0.0;
299  double z = 0.0;
300  gsl_ran_dir_3d(RandomGenerator,&x,&y,&z);
301  x *= r;
302  y *= r;
303  z *= r;
304 
305  vtxindex = _ineve->AddVtx(vtx_x+x,vtx_y+y,vtx_z+z,_t0);
306  } else if ((i==0)&&(j==0)) {
307  vtxindex = _ineve->AddVtx(vtx_x,vtx_y,vtx_z,_t0);
308  }
309 
310  ++trackid;
311 
312  double px = std::numeric_limits<double>::max();
313  double py = std::numeric_limits<double>::max();
314  double pz = std::numeric_limits<double>::max();
315 
316  if(std::isnan(_px_min)) {
317  double eta = (_eta_max-_eta_min) * gsl_rng_uniform_pos(RandomGenerator) + _eta_min;
318  double phi = (_phi_max-_phi_min) * gsl_rng_uniform_pos(RandomGenerator) + _phi_min;
319 
320  double pt;
321  if (!std::isnan(_p_min) && !std::isnan(_p_max) && !std::isnan(_p_gaus_width)) {
322  pt = ((_p_max-_p_min) * gsl_rng_uniform_pos(RandomGenerator) + _p_min + gsl_ran_gaussian(RandomGenerator, _p_gaus_width)) / cosh(eta);
323  } else if (!std::isnan(_pt_min) && !std::isnan(_pt_max) && !std::isnan(_pt_gaus_width)) {
324  pt = (_pt_max-_pt_min) * gsl_rng_uniform_pos(RandomGenerator) + _pt_min + gsl_ran_gaussian(RandomGenerator, _pt_gaus_width);
325  } else {
326  cout << PHWHERE << "Error: neither a p range or pt range was specified" << endl;
327  exit(-1);
328  }
329 
330  px = pt*cos(phi);
331  py = pt*sin(phi);
332  pz = pt*sinh(eta);
333  } else {
334  px = (_px_max-_px_min) * gsl_rng_uniform_pos(RandomGenerator) + _px_min;
335  py = (_py_max-_py_min) * gsl_rng_uniform_pos(RandomGenerator) + _py_min;
336  pz = (_pz_max-_pz_min) * gsl_rng_uniform_pos(RandomGenerator) + _pz_min;
337  }
338 
339  double m = get_mass(pdgcode);
340  double e = sqrt(px*px+py*py+pz*pz+m*m);
341 
342  PHG4Particle *particle = new PHG4Particlev2();
343  particle->set_track_id(trackid);
344  particle->set_vtx_id(vtxindex);
345  particle->set_parent_id(0);
346  particle->set_name(pdgname);
347  particle->set_pid(pdgcode);
348  particle->set_px(px);
349  particle->set_py(py);
350  particle->set_pz(pz);
351  particle->set_e(e);
352 
353  _ineve->AddParticle(vtxindex, particle);
354  if (embedflag != 0) _ineve->AddEmbeddedParticle(particle,embedflag);
355  }
356  }
357 
358  if (verbosity > 0) {
359  _ineve->identify();
360  cout << "======================================================================================" << endl;
361  }
362 
364 }
365 
367  const double x_max, const double y_min, const double y_max,
368  const double z_min, const double z_max) {
369  _px_min = x_min; _px_max = x_max;
370  _py_min = y_min; _py_max = y_max;
371  _pz_min = z_min; _pz_max = z_max;
372 }
373 
374 double
375 PHG4SimpleEventGenerator::smearvtx(const double position, const double width, FUNCTION dist) const
376 {
377  double res = position;
378  if (dist == Uniform)
379  {
380  res = (position-width) + 2*gsl_rng_uniform_pos(RandomGenerator)*width;
381  }
382  else if (dist == Gaus)
383  {
384  res = position + gsl_ran_gaussian(RandomGenerator,width);
385  }
386  return res;
387 }
int verbosity
The verbosity level. 0 means not verbose at all.
Definition: Fun4AllBase.h:75
void set_t0(const double t0)
set the starting time for the event
PHNode * findFirst(const std::string &, const std::string &)
void add_particles(const std::string &name, const unsigned int count)
interface for adding particles by name
#define PHWHERE
Definition: phool.h:23
int InitRun(PHCompositeNode *topNode)
virtual void set_pz(const double x)
Definition: PHG4Particle.h:36
void AddEmbeddedParticle(PHG4Particle *particle, int flag)
Definition: PHG4InEvent.h:25
PHBoolean addNode(PHNode *)
virtual int ReuseExistingVertex(PHCompositeNode *topNode)
PHG4SimpleEventGenerator(const std::string &name="EVTGENERATOR")
int AddParticle(const int vtxid, PHG4Particle *particle)
Definition: PHG4InEvent.cc:63
FUNCTION
supported function distributions
virtual void set_px(const double x)
Definition: PHG4Particle.h:34
virtual void set_py(const double x)
Definition: PHG4Particle.h:35
virtual void set_e(const double e)
Definition: PHG4Particle.h:37
#define NULL
Definition: Pdb.h:9
void set_vertex_distribution_function(FUNCTION x, FUNCTION y, FUNCTION z)
toss a new vertex according to a Uniform or Gaus distribution
virtual void set_parent_id(const int i)
Definition: PHG4Particle.h:30
int process_event(PHCompositeNode *topNode)
std::string get_pdgname(const int pdgcode) const
void set_vertex_distribution_mean(const double x, const double y, const double z)
set the mean value of the vertex distribution
void set_vertex_distribution_width(const double x, const double y, const double z)
set the width of the vertex distribution function about the mean
virtual void set_pid(const int i)
Definition: PHG4Particle.h:33
int AddVtx(const double x, const double y, const double z, const double t)
Definition: PHG4InEvent.cc:38
virtual void set_track_id(const int i)
Definition: PHG4Particle.h:28
void set_vertex_size_parameters(const double mean, const double width)
set the dimensions of the distribution of particles about the vertex
virtual void set_name(const std::string &name)
Definition: PHG4Particle.h:32
void set_vertex_size_function(FUNCTION r)
set the distribution function of particles about the vertex
void set_existing_vertex_offset_vector(const double x, const double y, const double z)
set an offset vector from the existing vertex
void set_eta_range(const double eta_min, const double eta_max)
range of randomized eta values
virtual void set_vtx_id(const int i)
Definition: PHG4Particle.h:29
void set_p_range(const double p_min, const double p_max, const double p_gaus_width=0)
double get_mass(const int pdgcode) const
virtual void identify(std::ostream &os=std::cout) const
Definition: PHG4InEvent.cc:134
void set_pt_range(const double pt_min, const double pt_max, const double pt_gaus_width=0)
int get_pdgcode(const std::string &name) const
void set_pxpypz_range(const double x_min, const double x_max, const double y_min, const double y_max, const double z_min, const double z_max)
void set_phi_range(const double phi_min, const double phi_max)
range of randomized phi values