6 #include <Geant4/G4ParticleDefinition.hh>
7 #include <Geant4/G4ParticleTable.hh>
18 #include <HepMC/GenEvent.h>
20 #include <gsl/gsl_const.h>
21 #include <gsl/gsl_randist.h>
22 #include <gsl/gsl_rng.h>
43 bool operator()(
const HepMC::GenParticle *p)
45 if (!p->end_vertex() && p->status() == 1)
return 1;
63 , _particle_filter_on(false)
65 RandomGenerator = gsl_rng_alloc(gsl_rng_mt19937);
66 _particle_filter_pid.clear();
72 gsl_rng_free(RandomGenerator);
77 PHG4InEvent *ineve = findNode::getClass<PHG4InEvent>(topNode,
"PHG4INEVENT");
93 cout <<
Name() <<
" override random seed: " << phseed << endl;
95 gsl_rng_set(RandomGenerator, phseed);
102 PHHepMCGenEventMap *genevtmap = findNode::getClass<PHHepMCGenEventMap>(topNode,
"PHHepMCGenEventMap");
106 static bool once =
true;
112 cout <<
"HepMCNodeReader::process_event - No PHHepMCGenEventMap node. Do not perform HepMC->Geant4 input" << endl;
118 PHG4InEvent *ineve = findNode::getClass<PHG4InEvent>(topNode,
"PHG4INEVENT");
121 cout <<
PHWHERE <<
"no PHG4INEVENT node" << endl;
139 if (worldshape ==
"G4Tubs")
141 ishape = ShapeG4Tubs;
143 else if (worldshape ==
"G4Box")
149 cout <<
PHWHERE <<
" unknown world shape " << worldshape << endl;
165 cout <<
"HepMCNodeReader::process_event - this event is already simulated. Move on: ";
172 HepMC::GenEvent *evt = genevt->
getEvent();
175 cout <<
PHWHERE <<
" no evt pointer under HEPMC Node found:";
190 xshift += smeargauss(width_vx);
191 else if (width_vx < 0.0)
192 xshift += smearflat(width_vx);
195 yshift += smeargauss(width_vy);
196 else if (width_vy < 0.0)
197 yshift += smearflat(width_vy);
200 zshift += smeargauss(width_vz);
201 else if (width_vz < 0.0)
202 zshift += smearflat(width_vz);
204 std::list<HepMC::GenParticle *> finalstateparticles;
205 std::list<HepMC::GenParticle *>::const_iterator fiter;
208 const double mom_factor = HepMC::Units::conversion_factor(evt->momentum_unit(), HepMC::Units::GEV);
209 const double length_factor = HepMC::Units::conversion_factor(evt->length_unit(), HepMC::Units::CM);
210 const double time_factor = HepMC::Units::conversion_factor(evt->length_unit(), HepMC::Units::CM) / GSL_CONST_CGS_SPEED_OF_LIGHT * 1e9;
212 for (HepMC::GenEvent::vertex_iterator v = evt->vertices_begin();
213 v != evt->vertices_end();
216 finalstateparticles.clear();
217 for (HepMC::GenVertex::particle_iterator p =
218 (*v)->particles_begin(HepMC::children);
219 p != (*v)->particles_end(HepMC::children); ++p)
223 if(_particle_filter_on) {
226 finalstateparticles.push_back(*p);
230 if (!finalstateparticles.empty())
232 double xpos = (*v)->position().x() * length_factor + xshift;
233 double ypos = (*v)->position().y() * length_factor + yshift;
234 double zpos = (*v)->position().z() * length_factor + zshift;
235 double time = (*v)->position().t() * time_factor + tshift;
239 cout <<
"Vertex : " << endl;
241 cout <<
"id: " << (*v)->barcode() << endl;
242 cout <<
"x: " << xpos << endl;
243 cout <<
"y: " << ypos << endl;
244 cout <<
"z: " << zpos << endl;
245 cout <<
"t: " << time << endl;
246 cout <<
"Particles" << endl;
249 if (ishape == ShapeG4Tubs)
251 if (sqrt(xpos * xpos + ypos * ypos) > worldsizey / 2 ||
252 fabs(zpos) > worldsizez / 2)
254 cout <<
"vertex x/y/z" << xpos <<
"/" << ypos <<
"/" << zpos
255 <<
" outside world volume radius/z (+-) " << worldsizex / 2
256 <<
"/" << worldsizez / 2 <<
", dropping it and its particles"
261 else if (ishape == ShapeG4Box)
263 if (fabs(xpos) > worldsizex / 2 || fabs(ypos) > worldsizey / 2 ||
264 fabs(zpos) > worldsizez / 2)
266 cout <<
"Vertex x/y/z " << xpos <<
"/" << ypos <<
"/" << zpos
267 <<
" outside world volume x/y/z (+-) " << worldsizex / 2 <<
"/"
268 << worldsizey / 2 <<
"/" << worldsizez / 2
269 <<
", dropping it and its particles" << endl;
275 cout <<
PHWHERE <<
" shape " << ishape <<
" not implemented. exiting"
281 vtxindex = ineve->
AddVtx(xpos, ypos, zpos, time);
283 for (fiter = finalstateparticles.begin();
284 fiter != finalstateparticles.end();
292 particle->
set_pid((*fiter)->pdg_id());
293 particle->
set_px((*fiter)->momentum().px() * mom_factor);
294 particle->
set_py((*fiter)->momentum().py() * mom_factor);
295 particle->
set_pz((*fiter)->momentum().pz() * mom_factor);
313 double HepMCNodeReader::smeargauss(
const double width)
315 if (width == 0)
return 0;
316 return gsl_ran_gaussian(RandomGenerator, width);
320 for(
int pid : _particle_filter_pid) {
321 if(p->pdg_id() == pid)
return true;
326 double HepMCNodeReader::smearflat(
const double width)
328 if (width == 0)
return 0;
329 return 2.0 * width * (gsl_rng_uniform_pos(RandomGenerator) - 0.5);
335 cout <<
"HepMCNodeReader::VertexPosition - WARNING - this function is depreciated. "
336 <<
"HepMCNodeReader::VertexPosition() move all HEPMC subevents to a new vertex location. "
337 <<
"This also leads to a different vertex is used for HepMC subevent in Geant4 than that recorded in the HepMCEvent Node."
338 <<
"Recommendation: the vertex shifts are better controlled for individually HEPMC subevents in Fun4AllHepMCInputManagers and event generators."
350 cout <<
"HepMCNodeReader::SmearVertex - WARNING - this function is depreciated. "
351 <<
"HepMCNodeReader::SmearVertex() smear each HEPMC subevents to a new vertex location. "
352 <<
"This also leads to a different vertex is used for HepMC subevent in Geant4 than that recorded in the HepMCEvent Node."
353 <<
"Recommendation: the vertex smears are better controlled for individually HEPMC subevents in Fun4AllHepMCInputManagers and event generators."
364 cout <<
"HepMCNodeReader::Embed - WARNING - this function is depreciated. "
365 <<
"Embedding IDs are controlled for individually HEPMC subevents in Fun4AllHepMCInputManagers and event generators."
int get_embedding_id() const
PHHepMCGenEventMap is collection of HEPMC events input into this simulation map of embedding ID -> PH...
int verbosity
The verbosity level. 0 means not verbose at all.
int Init(PHCompositeNode *topNode)
PHNode * findFirst(const std::string &, const std::string &)
HepMCNodeReader(const std::string &name="HEPMCREADER")
virtual ~HepMCNodeReader()
virtual void set_pz(const double x)
void AddEmbeddedParticle(PHG4Particle *particle, int flag)
ConstReverseIter rbegin() const
iterator from lowest ID to highest, i.e. signal to background
PHBoolean addNode(PHNode *)
int AddParticle(const int vtxid, PHG4Particle *particle)
virtual HepMC::GenEvent * getEvent()
virtual void set_px(const double x)
void VertexPosition(const double v_x, const double v_y, const double v_z)
virtual void set_py(const double x)
std::map< int, PHHepMCGenEvent * >::reverse_iterator ReverseIter
static recoConsts * instance()
virtual float get_FloatFlag(const std::string &name) const
ConstReverseIter rend() const
const HepMC::FourVector & get_collision_vertex() const
collision vertex position in the Hall coordinate system, use PHENIX units of cm, ns ...
void SmearVertex(const double s_x, const double s_y, const double s_z)
virtual const std::string Name() const
Returns the name of this module.
bool is_simulated() const
whether this event has been processed in Geant4 simulation
bool PassParticleFilter(HepMC::GenParticle *p)
virtual int Verbosity() const
Gets the verbosity of this module.
virtual void set_barcode(const int barcode)
virtual const std::string get_CharFlag(const std::string &flag) const
static IsStateFinal isfinal
virtual void set_pid(const int i)
int AddVtx(const double x, const double y, const double z, const double t)
void Embed(const int i=1)
int process_event(PHCompositeNode *topNode)
virtual void identify(std::ostream &os=std::cout) const
virtual void identify(std::ostream &os=std::cout) const