34 if ( run && !run->weight_names().empty() ) {
35 m_weights = std::vector<double>(run->weight_names().size(), 1.0);
40 return *(
reinterpret_cast<const std::vector<ConstGenParticlePtr>*
>(&
m_particles));
44 return *(
reinterpret_cast<const std::vector<ConstGenVertexPtr>*
>(&
m_vertices));
49 if ( !p || p->in_event() )
return;
57 if ( !p->production_vertex() ) {
68 std::lock_guard<std::recursive_mutex> rhs_lk(e.
m_lock_attributes, std::adopt_lock);
78 for (
auto att = attm->second.begin(); att != attm->second.end(); ++att) {
if (att->second) att->second->m_event =
nullptr;}
80 for (
auto v =
m_vertices.begin(); v !=
m_vertices.end(); ++v )
if (*v)
if ((*v)->m_event ==
this) (*v)->m_event =
nullptr;
81 for (
auto p =
m_particles.begin(); p !=
m_particles.end(); ++p )
if (*p)
if ((*p)->m_event ==
this) (*p)->m_event =
nullptr;
89 std::lock_guard<std::recursive_mutex> rhs_lk(e.
m_lock_attributes, std::adopt_lock);
100 if ( !v|| v->in_event() )
return;
104 v->m_id = -
static_cast<int>(
vertices().size());
107 for (
const auto& p: v->particles_in()) {
109 p->m_end_vertex = v->shared_from_this();
112 for (
const auto& p: v->particles_out()) {
114 p->m_production_vertex = v;
120 if ( !p || p->parent_event() !=
this )
return;
122 HEPMC3_DEBUG(30,
"GenEvent::remove_particle - called with particle: " << p->id());
123 GenVertexPtr end_vtx = p->end_vertex();
125 end_vtx->remove_particle_in(p);
128 if ( end_vtx->particles_in().empty() )
remove_vertex(end_vtx);
131 GenVertexPtr prod_vtx = p->production_vertex();
133 prod_vtx->remove_particle_out(p);
136 if ( prod_vtx->particles_out().empty() )
remove_vertex(prod_vtx);
139 HEPMC3_DEBUG(30,
"GenEvent::remove_particle - erasing particle: " << p->id())
147 auto vt2 = vt1.second.find(idx);
148 if (vt2 == vt1.second.end())
continue;
149 vt1.second.erase(vt2);
155 std::vector< std::pair< int, std::shared_ptr<Attribute> > > changed_attributes;
158 changed_attributes.clear();
160 for (
auto vt2 = vt1.second.begin(); vt2 != vt1.second.end(); ++vt2) {
161 if ( (*vt2).first > p->id() ) {
162 changed_attributes.emplace_back(*vt2);
166 std::sort(changed_attributes.begin(),changed_attributes.end(), [](
const std::pair<
int, std::shared_ptr<Attribute> > &a,
const std::pair<
int, std::shared_ptr<Attribute> > &b) { return a.first < b.first; });
167 for (
const auto& val: changed_attributes ) {
168 vt1.second.erase(val.first);
169 vt1.second[val.first-1] = val.second;
178 p->m_event =
nullptr;
183 std::sort(v.begin(), v.end(), [](
const GenParticlePtr& p1,
const GenParticlePtr& p2) { return p1->id() > p2->id();});
185 for (
auto p = v.begin(); p != v.end(); ++p) {
191 if ( !v || v->parent_event() !=
this )
return;
193 HEPMC3_DEBUG(30,
"GenEvent::remove_vertex - called with vertex: " << v->id());
194 std::shared_ptr<GenVertex> null_vtx;
196 for (
const auto& p: v->particles_in()) {
197 p->m_end_vertex = std::weak_ptr<GenVertex>();
200 for (
const auto& p: v->particles_out()) {
201 p->m_production_vertex = std::weak_ptr<GenVertex>();
208 HEPMC3_DEBUG(30,
"GenEvent::remove_vertex - erasing vertex: " << v->id())
215 auto vt2 = vt1.second.find(-idx);
216 if (vt2 == vt1.second.end())
continue;
217 vt1.second.erase(vt2);
224 std::vector< std::pair< int, std::shared_ptr<Attribute> > > changed_attributes;
227 changed_attributes.clear();
229 for (
auto vt2 = vt1.second.begin(); vt2 != vt1.second.end(); ++vt2) {
230 if ( (*vt2).first < v->id() ) {
231 changed_attributes.emplace_back(*vt2);
235 std::reverse(changed_attributes.begin(),changed_attributes.end());
236 std::sort(changed_attributes.begin(),changed_attributes.end(),[](
const std::pair<
int, std::shared_ptr<Attribute> > &a,
const std::pair<
int, std::shared_ptr<Attribute> > &b) { return a.first > b.first; });
237 for (
const auto& val: changed_attributes ) {
238 vt1.second.erase(val.first);
239 vt1.second[val.first+1] = val.second;
249 v->m_event =
nullptr;
255static bool visit_children(std::map<ConstGenVertexPtr, int> &a,
const ConstGenVertexPtr& v)
257 for (
const ConstGenParticlePtr& p: v->particles_out()) {
260 if (a[p->end_vertex()] != 0) {
return true; }
261 a[p->end_vertex()]++;
262 if (visit_children(a, p->end_vertex()))
return true;
272 bool has_cycles =
false;
273 std::map<GenVertexPtr, int> sortingv;
274 std::vector<GenVertexPtr> noinv;
275 if (existing_hc)
if (existing_hc->value() != 0) has_cycles =
true;
278 for (
const GenParticlePtr& p: parts) {
279 GenVertexPtr v = p->production_vertex();
280 if (v) sortingv[v]=0;
281 if ( !v || v->particles_in().empty()) {
282 GenVertexPtr v2 = p->end_vertex();
283 if (v2) {noinv.emplace_back(v2); sortingv[v2] = 0;}
286 for (
const GenVertexPtr& v: noinv) {
287 std::map<ConstGenVertexPtr, int> sorting_temp(sortingv.begin(), sortingv.end());
288 has_cycles = (has_cycles || visit_children(sorting_temp, v));
299 std::deque<GenVertexPtr> sorting;
302 for (
const auto& p: parts) {
303 const GenVertexPtr &v = p->production_vertex();
304 if ( !v || v->particles_in().empty() ) {
305 const GenVertexPtr &v2 = p->end_vertex();
306 if (v2) sorting.emplace_back(v2);
311 unsigned int sorting_loop_count = 0;
312 unsigned int max_deque_size = 0;
316 while ( !sorting.empty() ) {
318 if ( sorting.size() > max_deque_size ) max_deque_size = sorting.size();
319 ++sorting_loop_count;
322 GenVertexPtr &v = sorting.front();
327 for (
const auto& p: v->particles_in() ) {
328 GenVertexPtr v2 = p->production_vertex();
329 if ( v2 && !v2->in_event() && find(sorting.begin(), sorting.end(), v2) == sorting.end() ) {
330 sorting.push_front(v2);
337 if ( added )
continue;
340 if ( !v->in_event() ) {
344 for (
const auto& p: v->particles_out()) {
345 GenVertexPtr v2 = p->end_vertex();
346 if ( v2 && !v2->in_event()&& find(sorting.begin(), sorting.end(), v2) == sorting.end() ) {
347 sorting.emplace_back(v2);
363 std::vector< std::pair< int, std::shared_ptr<Attribute> > > changed_attributes;
364 for (
const auto& vt2 : vt1.second ) {
365 if ( vt2.first <= rootid ) {
366 changed_attributes.emplace_back(vt2);
369 for (
const auto& val : changed_attributes ) {
370 vt1.second.erase(val.first);
371 vt1.second[val.first == rootid? 0: val.first + 1] = val.second;
379 HEPMC3_WARNING_LEVEL(700,
"GenEvent::add_tree Suspicious looking rootvertex found. Will try to cope.")
385 << this->
particles().size() <<
", max deque size: "
386 << max_deque_size <<
", iterations: " << sorting_loop_count)
423 if (!status)
return std::const_pointer_cast<const GenVertex>(
m_rootvertex)->particles_out();
424 std::vector<ConstGenParticlePtr> ret;
425 for (
auto& p:
m_rootvertex->particles_out())
if (p->status() == status) ret.emplace_back(p);
430 return std::const_pointer_cast<const GenVertex>(
m_rootvertex)->particles_out();
443 if ( v->has_set_position() ) {
444 v->set_position(v->position() + delta);
451 long double cosa = std::cos(delta.
x());
452 long double sina = std::sin(delta.
x());
453 long double cosb = std::cos(delta.
y());
454 long double sinb = std::sin(delta.
y());
455 long double cosg = std::cos(delta.
z());
456 long double sing = std::sin(delta.
z());
461 long double tempX = mom.
x();
462 long double tempY = mom.
y();
463 long double tempZ = mom.
z();
465 long double tempY_ = cosa*tempY+sina*tempZ;
466 long double tempZ_ = -sina*tempY+cosa*tempZ;
470 long double tempX_ = cosb*tempX-sinb*tempZ;
471 tempZ_ = sinb*tempX+cosb*tempZ;
475 tempX_ = cosg*tempX+sing*tempY;
476 tempY_ = -sing*tempX+cosg*tempY;
481 p->set_momentum(temp);
488 long double tempX = pos.
x();
489 long double tempY = pos.
y();
490 long double tempZ = pos.
z();
492 long double tempY_ = cosa*tempY+sina*tempZ;
493 long double tempZ_ = -sina*tempY+cosa*tempZ;
497 long double tempX_ = cosb*tempX-sinb*tempZ;
498 tempZ_ = sinb*tempX+cosb*tempZ;
502 tempX_ = cosg*tempX+sing*tempY;
503 tempY_ = -sing*tempX+cosg*tempY;
508 v->set_position(temp);
517 if ( axis > 3 || axis < 0 )
526 for (
auto& v:
m_vertices) {
FourVector temp = v->position(); temp.
setX(-v->position().x()); v->set_position(temp);}
530 for (
auto& v:
m_vertices) {
FourVector temp = v->position(); temp.
setY(-v->position().y()); v->set_position(temp);}
534 for (
auto& v:
m_vertices) {
FourVector temp = v->position(); temp.
setZ(-v->position().z()); v->set_position(temp);}
538 for (
auto& v:
m_vertices) {
FourVector temp = v->position(); temp.
setT(-v->position().t()); v->set_position(temp);}
549 double deltalength2 = delta.
length2();
550 if (deltalength2 > 1.0)
555 if (std::abs(deltalength2-1.0) < std::numeric_limits<double>::epsilon())
560 if (std::abs(deltalength2) < std::numeric_limits<double>::epsilon())
565 long double deltaX = delta.
x();
566 long double deltaY = delta.
y();
567 long double deltaZ = delta.
z();
568 long double deltalength = std::sqrt(deltalength2);
569 long double gamma = 1.0/std::sqrt(1.0-deltalength2);
575 long double tempX = mom.
x();
576 long double tempY = mom.
y();
577 long double tempZ = mom.
z();
578 long double tempE = mom.
e();
579 long double nr = (deltaX*tempX+deltaY*tempY+deltaZ*tempZ)/deltalength;
580 long double gfac = (gamma-1)*nr/deltalength-tempE*gamma;
581 tempX+=(deltaX*gfac);
582 tempY+=(deltaY*gfac);
583 tempZ+=(deltaZ*gfac);
584 tempE = gamma*(tempE-deltalength*nr);
586 p->set_momentum(temp);
607 auto i2 = i1->second.find(
id);
608 if ( i2 == i1->second.end() )
return;
610 i1->second.erase(i2);
614 std::vector<std::string> results;
617 if ( vt1.second.count(
id) == 1 ) {
618 results.emplace_back(vt1.first);
644 for (
const ConstGenParticlePtr& p: this->
particles()) {
648 for (
const ConstGenVertexPtr& v: this->
vertices()) {
649 data.
vertices.emplace_back(v->data());
652 for (
const ConstGenParticlePtr& p: v->particles_in()) {
653 data.
links1.emplace_back(p->id());
654 data.
links2.emplace_back(v_id);
657 for (
const ConstGenParticlePtr& p: v->particles_out()) {
658 data.
links1.emplace_back(v_id);
659 data.
links2.emplace_back(p->id());
667 bool status = vt2.second->to_string(st);
697 m_particles.emplace_back(std::make_shared<GenParticle>(pd));
703 for (
const GenVertexData &vd: data.
vertices ) {
704 m_vertices.emplace_back(std::make_shared<GenVertex>(vd));
710 for (
unsigned int i = 0; i < data.
links1.size(); ++i) {
711 const int id1 = data.
links1[i];
712 const int id2 = data.
links2[i];
718 if ((id1 < 0 && id2 <0) || (id1 > 0 && id2 > 0)) {
730 for (
unsigned int i = 0; i < data.
attribute_id.size(); ++i) {
733 if (name.length() == 0)
continue;
738 if (
id > 0 &&
id <=
static_cast<int>(
m_particles.size()) ) {
741 if (
id < 0 && -
id <=
static_cast<int>(
m_vertices.size()) ) {
764 if (p1->in_event() && p1->parent_event() !=
this)
769 if (p1->production_vertex()) p1->production_vertex()->remove_particle_out(p1);
781 return run_info()->attribute_as_string(name);
786 auto i2 = i1->second.find(
id);
787 if (i2 == i1->second.end() )
return {};
789 if ( !i2->second )
return {};
792 i2->second->to_string(ret);
799 if (name.length() == 0)
return;
805 if (
id > 0 &&
id <=
static_cast<int>(
particles().size()) ) {
808 if (
id < 0 && -
id <=
static_cast<int>(
vertices().size()) ) {
809 att->m_vertex =
vertices()[-
id - 1];
814void GenEvent::add_attributes(
const std::vector<std::string> &names,
const std::vector<std::shared_ptr<Attribute> > &atts,
const std::vector<int>& ids) {
815 size_t N = names.size();
816 if ( N == 0 )
return;
817 if (N != atts.size())
return;
818 if (N != ids.size())
return;
820 std::vector<std::string> unames = names;
821 vector<std::string>::iterator ip;
822 ip = std::unique(unames.begin(), unames.end());
823 unames.resize(std::distance(unames.begin(), ip));
825 for (
const auto& name: unames) {
830 for (
size_t i = 0; i < N; i++) {
832 if (names.at(i).length() == 0)
continue;
833 if (!atts[i])
continue;
835 atts[i]->m_event =
this;
837 { atts[i]->m_particle =
m_particles[ids.at(i) - 1]; }
840 atts[i]->m_vertex =
m_vertices[-ids.at(i) - 1];
846void GenEvent::add_attributes(
const std::string& name,
const std::vector<std::shared_ptr<Attribute> > &atts,
const std::vector<int>& ids) {
847 if (name.length() == 0)
return;
848 size_t N = ids.size();
850 if ( N != atts.size())
return;
857 for (
size_t i = 0; i < N; i++) {
859 if (!atts[i])
continue;
860 tmap[ids.at(i)] = atts[i];
861 atts[i]->m_event =
this;
863 { atts[i]->m_particle =
m_particles[ids.at(i) - 1]; }
866 atts[i]->m_vertex =
m_vertices[-ids.at(i) - 1];
872 if (name.length() == 0)
return;
873 if (atts.empty())
return;
879 for (
const auto& att: atts) {
881 if (!att.second)
continue;
883 att.second->m_event =
this;
885 { att.second->m_particle =
m_particles[att.first - 1]; }
888 att.second->m_vertex =
m_vertices[-att.first - 1];
#define HEPMC3_WARNING_LEVEL(LEVEL, MESSAGE)
Macro for printing HEPMC3_HEPMC3_WARNING messages.
#define HEPMC3_DEBUG_CODE_BLOCK(x)
Macro for storing code useful for debugging.
#define HEPMC3_DEBUG(LEVEL, MESSAGE)
Macro for printing debug messages with appropriate debug level.
Definition of struct GenEventData.
Definition of class GenEvent.
Definition of class GenParticle.
Definition of class GenVertex.
double e() const
Energy component of momentum.
double t() const
Time component of position/displacement.
bool is_zero() const
Check if the length of this vertex is zero.
double x() const
x-component of position/displacement
double length2() const
Squared magnitude of (x, y, z) 3-vector.
double y() const
y-component of position/displacement
double z() const
z-component of position/displacement
GenEvent(Units::MomentumUnit mu=Units::GEV, Units::LengthUnit lu=Units::MM)
Event constructor without a run.
bool rotate(const FourVector &delta)
Rotate event using x,y,z components of delta as rotation angles.
std::shared_ptr< T > attribute(const std::string &name, const int &id=0) const
Get attribute of type T.
std::recursive_mutex m_lock_attributes
Mutex lock for the m_attibutes map.
void add_vertex(GenVertexPtr v)
Add vertex.
void shift_position_to(const FourVector &newpos)
Shift position of all vertices in the event to op.
int vertices_size() const
Vertices size, HepMC2 compatibility.
int event_number() const
Get event number.
std::vector< std::string > attribute_names(const int &id=0) const
Get list of attribute names.
void write_data(GenEventData &data) const
Fill GenEventData object.
std::shared_ptr< GenRunInfo > run_info() const
Get a pointer to the the GenRunInfo object.
void remove_particles(std::vector< GenParticlePtr > v)
Remove a set of particles.
void add_particle(GenParticlePtr p)
Add particle.
void set_units(Units::MomentumUnit new_momentum_unit, Units::LengthUnit new_length_unit)
Change event units Converts event from current units to new ones.
std::vector< double > m_weights
Event weights.
std::map< int, std::shared_ptr< Attribute > >::value_type att_val_t
Attribute map value type.
std::map< std::string, std::map< int, std::shared_ptr< Attribute > > >::value_type att_key_t
Attribute map key type.
void shift_position_by(const FourVector &delta)
Shift position of all vertices in the event by delta.
void remove_vertex(GenVertexPtr v)
Remove vertex from the event.
void reserve(const size_t &parts, const size_t &verts=0)
Reserve memory for particles and vertices.
void set_event_number(const int &num)
Set event number.
bool boost(const FourVector &delta)
Boost event using x,y,z components of delta as velocity fractions.
std::vector< ConstGenParticlePtr > beams() const
Vector of beam particles.
int m_event_number
Event number.
const std::vector< ConstGenVertexPtr > & vertices() const
Get list of vertices (const)
const Units::MomentumUnit & momentum_unit() const
Get momentum unit.
const Units::LengthUnit & length_unit() const
Get length unit.
bool reflect(const int axis)
Change sign of axis.
const FourVector & event_pos() const
Vertex representing the overall event position.
std::map< std::string, std::map< int, std::shared_ptr< Attribute > > > attributes() const
Get a copy of the list of attributes.
void add_attribute(const std::string &name, const std::shared_ptr< Attribute > &att, const int &id=0)
void read_data(const GenEventData &data)
Fill GenEvent based on GenEventData.
std::map< std::string, std::map< int, std::shared_ptr< Attribute > > > m_attributes
Map of event, particle and vertex attributes.
Units::MomentumUnit m_momentum_unit
Momentum unit.
void remove_attribute(const std::string &name, const int &id=0)
Remove attribute.
void remove_particle(GenParticlePtr p)
Remove particle from the event.
std::vector< GenVertexPtr > m_vertices
List of vertices.
GenVertexPtr m_rootvertex
The root vertex is stored outside the normal vertices list to block user access to it.
std::string attribute_as_string(const std::string &name, const int &id=0) const
Get attribute of any type as string.
const std::vector< double > & weights() const
Get event weight values as a vector.
void clear()
Remove contents of this event.
int particles_size() const
Particles size, HepMC2 compatibility.
Units::LengthUnit m_length_unit
Length unit.
std::shared_ptr< GenRunInfo > m_run_info
Global run information.
std::vector< GenParticlePtr > m_particles
List of particles.
void add_beam_particle(GenParticlePtr p1)
Add particle to root vertex.
void add_attributes(const std::vector< std::string > &names, const std::vector< std::shared_ptr< Attribute > > &atts, const std::vector< int > &ids)
Add multiple attributes to event.
void set_beam_particles(GenParticlePtr p1, GenParticlePtr p2)
Set incoming beam particles.
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const)
void add_tree(const std::vector< GenParticlePtr > &parts)
Add whole tree in topological order.
GenEvent & operator=(const GenEvent &)
Copy Assignment operator.
Stores vertex-related information.
static void convert(T &m, MomentumUnit from, MomentumUnit to)
Convert FourVector to different momentum unit.
LengthUnit
Position units.
MomentumUnit
Momentum units.
Stores serializable event information.
std::vector< GenVertexData > vertices
Vertices.
std::vector< int > links2
Second id of the vertex links.
int event_number
Event number.
std::vector< std::string > attribute_string
Attribute serialized as string.
std::vector< GenParticleData > particles
Particles.
std::vector< int > links1
First id of the vertex links.
std::vector< std::string > attribute_name
Attribute name.
Units::LengthUnit length_unit
Length unit.
std::vector< int > attribute_id
Attribute owner id.
FourVector event_pos
Event position.
std::vector< double > weights
Weights.
Units::MomentumUnit momentum_unit
Momentum unit.
Stores serializable particle information.