Version: SMASH-2.0.2
hepmcinterface.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2021 Christian Holm Christensen
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/hepmcinterface.h"
11 
12 #include "HepMC3/Print.h"
13 #include "HepMC3/Setup.h"
14 #include "smash/logging.h"
15 
16 namespace smash {
17 
18 HepMcInterface::HepMcInterface(const std::string& name, const bool full_event,
19  const int total_N, const int proj_N)
20  : OutputInterface(name),
21  event_(HepMC3::Units::GEV, HepMC3::Units::MM),
22  ion_(),
23  xs_(),
24  ip_(),
25  total_N_(total_N),
26  proj_N_(proj_N),
27  full_event_(full_event) {
28  logg[LOutput].debug() << "Name of output: " << name << " "
29  << (full_event_ ? "full event" : "final state only")
30  << " output" << std::endl;
31  ion_ = std::make_shared<HepMC3::GenHeavyIon>();
32  xs_ = std::make_shared<HepMC3::GenCrossSection>();
33 
34  HepMC3::Setup::set_debug_level(logg[LOutput].isEnabled<einhard::DEBUG>() ? 5
35  : 0);
36 }
37 
39  const int event_number,
40  const EventInfo& event) {
41  // Clear event and mapping and set event number
42  clear();
43 
44  // Set header stuff on event
45  ion_->impact_parameter = event.impact_parameter;
46  xs_->set_cross_section(1, 1); // Dummy values
47  event_.set_event_number(event_number);
48  event_.set_heavy_ion(ion_);
49  coll_.resize(total_N_);
50 
51  // Create IP only if final state
52  ip_ = std::make_shared<HepMC3::GenVertex>();
53  event_.add_vertex(ip_);
54 
55  // Count up projectile and target
56  smash::FourVector p_proj;
57  smash::FourVector p_targ;
58  AZ az_proj;
59  AZ az_targ;
60  bool is_coll = proj_N_ > 0 && total_N_ > 0;
61 
62  for (auto& data : particles) {
63  if (is_coll) {
64  if (!data.is_neutron() && !data.is_proton()) {
65  throw std::runtime_error(
66  "Particle of PID=" + std::to_string(data.pdgcode().get_decimal()) +
67  " is not a valid HepMC beam particle!");
68  }
69 
70  bool isproj = data.id() < proj_N_;
71  smash::FourVector& p = (isproj ? p_proj : p_targ);
72  AZ& az = (isproj ? az_proj : az_targ);
73  p += data.momentum();
74  az.second += data.is_proton();
75  az.first++;
76  }
77 
78  if (!full_event_ && is_coll) {
79  continue;
80  }
81 
82  // If we are not only adding final state particles, but all
83  // interactions, or not in collider modus, then we add all the
84  // incoming particles as outgoing (incoming for non-collider
85  // modus) of the vertex. In that way, we will keep track of
86  // participants and spectators as well as make the event
87  // structure consistent.
88  auto op = make_register(data, Status::fnal);
89  if (is_coll) {
90  ip_->add_particle_out(op);
91  } else {
92  ip_->add_particle_in(op);
93  }
94  }
95  // Make beam particles
96  if (is_coll) {
97  auto proj = make_gen(ion_pdg(az_proj), Status::beam, p_proj);
98  auto targ = make_gen(ion_pdg(az_targ), Status::beam, p_targ);
99 
100  // Add to interaction point if we need to
101  ip_->add_particle_in(proj);
102  ip_->add_particle_in(targ);
103  }
104 }
105 
107  const double /* density */) {
108  HepMC3::GenVertexPtr vp;
109  auto type = action.get_type();
110  int status = get_status(type);
111 
112  if (full_event_) {
113  FourVector v = action.get_interaction_point();
114  vp = std::make_shared<HepMC3::GenVertex>(
115  HepMC3::FourVector(v.x1(), v.x2(), v.x3(), v.x0()));
116  vp->add_attribute("weight", std::make_shared<HepMC3::FloatAttribute>(
117  action.get_total_weight()));
118  vp->add_attribute(
119  "partial_weight",
120  std::make_shared<HepMC3::FloatAttribute>(action.get_partial_weight()));
121  event_.add_vertex(vp);
122  }
123 
124  // Now mark participants
125  if (full_event_) {
126  for (auto& i : action.incoming_particles()) {
127  // Create tree
128  HepMC3::GenParticlePtr ip = find_or_make(i, status);
129  ip->set_status(status);
130  vp->add_particle_in(ip);
131  }
132  } else {
133  return;
134  }
135 
136  // Add outgoing particles
137  for (auto& o : action.outgoing_particles()) {
138  vp->add_particle_out(make_register(o, Status::fnal));
139  }
140 }
141 
143  const int32_t /*event_number*/,
144  const EventInfo& event) {
145  // In case this was an empty event
146  if (event.empty_event) {
147  clear();
148  return;
149  }
150  /* since the number of collisions is not an experimental obervable, we set it
151  * to -1.
152  */
153  ion_->Ncoll_hard = -1;
154  ion_->Ncoll = -1;
155  /* This should be the number of participants in the projectile nucleus.
156  * However, to avoid confusion with the Glauber model, we prefer to set it -1.
157  */
158  ion_->Npart_proj = -1;
159  /* his should be the number of participants in the target nucleus.
160  * However, to avoid confusion with the Glauber model, we prefer to set it -1.
161  */
162  ion_->Npart_targ = -1;
163  // If we only do final state events, then take particle
164  // Note, we should already have the particles if not only final
165  // state
166  // Take all passed particles and add as outgoing particles to event
167  for (auto& p : particles) {
168  if (!full_event_) {
169  auto h = make_register(p, Status::fnal);
170  ip_->add_particle_out(h);
171  } else if (map_.find(p.id()) == map_.end()) {
172  throw std::runtime_error("Dangling particle " + std::to_string(p.id()));
173  }
174  }
175 }
176 
178  event_.clear();
179  map_.clear();
180  ip_ = 0;
181  coll_ = 0;
182  ncoll_ = 0;
183  ncoll_hard_ = 0;
184 }
185 
187  if (t == ProcessType::Decay)
188  return Status::dcy;
189 
190  // Make all other codes SMASH specific
191  return static_cast<int>(t) + static_cast<int>(Status::off);
192 }
193 
194 HepMC3::GenParticlePtr HepMcInterface::make_gen(int pid, int status,
195  const smash::FourVector& mom,
196  double mass) {
197  auto p = std::make_shared<HepMC3::GenParticle>(
198  HepMC3::FourVector(mom.x1(), mom.x2(), mom.x3(), mom.x0()), pid, status);
199  if (mass > 0)
200  p->set_generated_mass(mass);
201  return p;
202 }
203 
204 HepMC3::GenParticlePtr HepMcInterface::make_register(const ParticleData& p,
205  int status) {
206  int id = p.id();
207  auto h = make_gen(p.pdgcode().get_decimal(), status, p.momentum(),
208  p.type().mass());
209  map_[id] = h;
210 
211  return h;
212 }
213 
214 HepMC3::GenParticlePtr HepMcInterface::find_or_make(const ParticleData& p,
215  int status,
216  bool force_new) {
217  int id = p.id();
218  if (!force_new) {
219  auto it = map_.find(id);
220  if (it != map_.end()) {
221  return it->second;
222  }
223  }
224 
225  return make_register(p, status);
226 }
227 
228 int HepMcInterface::ion_pdg(const AZ& az) const {
229  if (az.second == 1 && az.first == 1)
230  return 2212; // Proton
231  if (az.second == 1 && az.first == 0)
232  return 2112; // Neutron
233 
234  return 1'000'000'000 + az.second * 10'000 + az.first * 10;
235 }
236 } // namespace smash
smash::Action::get_type
virtual ProcessType get_type() const
Get the process type.
Definition: action.h:131
smash
Definition: action.h:24
hepmcinterface.h
smash::LOutput
static constexpr int LOutput
Definition: outputinterface.h:24
smash::HepMcInterface::map_
IdMap map_
Mapping from ID to particle.
Definition: hepmcinterface.h:196
smash::HepMcInterface::ncoll_hard_
int ncoll_hard_
counter of hard binary collisions (e.g., where both incoming particles are from the beams.
Definition: hepmcinterface.h:223
smash::HepMcInterface::at_interaction
void at_interaction(const Action &action, const double density) override
Writes collisions to event.
Definition: hepmcinterface.cc:106
smash::HepMcInterface::find_or_make
HepMC3::GenParticlePtr find_or_make(const ParticleData &p, int status=Status::fnal, bool force_new=false)
Find particle in mapping or generate it.
Definition: hepmcinterface.cc:214
smash::ParticleData
Definition: particledata.h:52
smash::HepMcInterface::event_
HepMC3::GenEvent event_
The event.
Definition: hepmcinterface.h:188
smash::ProcessType::Decay
@ Decay
resonance decay
smash::HepMcInterface::total_N_
const int total_N_
Total number of nucleons in projectile and target, needed for converting nuclei to single particles.
Definition: hepmcinterface.h:228
smash::FourVector::x3
double x3() const
Definition: fourvector.h:315
smash::Action::get_partial_weight
virtual double get_partial_weight() const =0
Return the specific weight for the chosen outgoing channel, which is mainly used for the partial weig...
smash::HepMcInterface::ncoll_
int ncoll_
counter of binary collisions (e.g., where both incoming particles are from the beams.
Definition: hepmcinterface.h:220
smash::HepMcInterface::make_gen
HepMC3::GenParticlePtr make_gen(int pid, int status, const smash::FourVector &mom, double mass=-1)
Make an HepMC particle.
Definition: hepmcinterface.cc:194
smash::FourVector::x1
double x1() const
Definition: fourvector.h:307
smash::EventInfo
Structure to contain custom data for output.
Definition: outputinterface.h:36
smash::logg
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
smash::Action::outgoing_particles
const ParticleList & outgoing_particles() const
Get the list of particles that resulted from the action.
Definition: action.h:245
smash::HepMcInterface::HepMcInterface
HepMcInterface(const std::string &name, const bool full_event, const int total_N, const int proj_N)
Create HepMC particle event in memory.
Definition: hepmcinterface.cc:18
smash::HepMcInterface::xs_
HepMC3::GenCrossSectionPtr xs_
Dummy cross-section.
Definition: hepmcinterface.h:192
smash::HepMcInterface::make_register
HepMC3::GenParticlePtr make_register(const ParticleData &p, int status=Status::fnal)
Find particle in mapping or generate it.
Definition: hepmcinterface.cc:204
smash::HepMcInterface::full_event_
bool full_event_
Whether the full event or only final-state particles are in the output.
Definition: hepmcinterface.h:235
smash::HepMcInterface::at_eventend
void at_eventend(const Particles &particles, const int32_t event_number, const EventInfo &event) override
Add the final particles information of an event to the central vertex.
Definition: hepmcinterface.cc:142
smash::FourVector::x0
double x0() const
Definition: fourvector.h:303
smash::FourVector::x2
double x2() const
Definition: fourvector.h:311
smash::OutputInterface
Abstraction of generic output.
Definition: outputinterface.h:66
smash::Action::get_total_weight
virtual double get_total_weight() const =0
Return the total weight value, which is mainly used for the weight output entry.
smash::HepMcInterface::ip_
HepMC3::GenVertexPtr ip_
The interaction point.
Definition: hepmcinterface.h:194
smash::Particles
Definition: particles.h:33
smash::HepMcInterface::ion_pdg
int ion_pdg(const AZ &az) const
Encode ion PDG.
Definition: hepmcinterface.cc:228
smash::EventInfo::empty_event
bool empty_event
True if no collisions happened.
Definition: outputinterface.h:52
smash::HepMcInterface::get_status
int get_status(const ProcessType &t) const
Convert SMASH process type to HepMC status.
Definition: hepmcinterface.cc:186
smash::HepMcInterface::clear
void clear()
Clear before an event.
Definition: hepmcinterface.cc:177
smash::HepMcInterface::ion_
HepMC3::GenHeavyIonPtr ion_
The heavy-ion structure.
Definition: hepmcinterface.h:190
logging.h
smash::Action
Definition: action.h:35
smash::HepMcInterface::at_eventstart
void at_eventstart(const Particles &particles, const int event_number, const EventInfo &event) override
Add the initial particles information of an event to the central vertex.
Definition: hepmcinterface.cc:38
smash::FourVector
Definition: fourvector.h:33
smash::Action::get_interaction_point
FourVector get_interaction_point() const
Get the interaction point.
Definition: action.cc:67
smash::pdg::p
constexpr int p
Proton.
Definition: pdgcode_constants.h:28
smash::HepMcInterface::coll_
CollCounter coll_
Collision counter.
Definition: hepmcinterface.h:217
smash::Action::incoming_particles
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
Definition: action.cc:57
smash::HepMcInterface::proj_N_
const int proj_N_
Total number of nucleons in projectile, needed for converting nuclei to single particles.
Definition: hepmcinterface.h:233
smash::HepMcInterface::AZ
std::pair< int, int > AZ
Pair of Atomic weight and number.
Definition: hepmcinterface.h:84
smash::ProcessType
ProcessType
Process Types are used to identify the type of the process.
Definition: processbranch.h:25