StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
HepMC3.h
1 // HepMC3.h is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 //
6 // Author: HepMC 3 Collaboration, hepmc-dev@.cern.ch
7 // Based on the HepMC2 interface by Mikhail Kirsanov, Mikhail.Kirsanov@cern.ch.
8 // Header file and function definitions for the Pythia8ToHepMC class,
9 // which converts a PYTHIA event record to the standard HepMC format.
10 
11 #ifndef Pythia8_HepMC3_H
12 #define Pythia8_HepMC3_H
13 
14 #include <vector>
15 #include "Pythia8/Pythia.h"
16 #include "HepMC3/GenVertex.h"
17 #include "HepMC3/GenParticle.h"
18 #include "HepMC3/GenEvent.h"
19 #include "HepMC3/WriterAscii.h"
20 
21 namespace HepMC3 {
22 
23 //==========================================================================
24 
26 
27 public:
28 
29  // Constructor and destructor
30  Pythia8ToHepMC3(): m_internal_event_number(0), m_print_inconsistency(true),
31  m_free_parton_warnings(true), m_crash_on_problem(false),
32  m_convert_gluon_to_0(false), m_store_pdf(true), m_store_proc(true),
33  m_store_xsec(true), m_store_weights(true) {}
34  virtual ~Pythia8ToHepMC3() {}
35 
36  // The recommended method to convert Pythia events into HepMC3 ones.
37  bool fill_next_event( Pythia8::Pythia& pythia, GenEvent* evt,
38  int ievnum = -1 ) { return fill_next_event( pythia.event, evt,
39  ievnum, &pythia.info, &pythia.settings); }
40 
41  // Alternative method to convert Pythia events into HepMC3 ones.
42  bool fill_next_event( Pythia8::Event& pyev, GenEvent* evt, int ievnum = -1,
43  const Pythia8::Info* pyinfo = 0, Pythia8::Settings* pyset = 0) {
44 
45  // 1. Error if no event passed.
46  if (!evt) {
47  std::cerr << "Pythia8ToHepMC3::fill_next_event error - "
48  << "passed null event." << std::endl;
49  return false;
50  }
51 
52  // Event number counter.
53  if ( ievnum >= 0 ) {
54  evt->set_event_number(ievnum);
55  m_internal_event_number = ievnum;
56  }
57  else {
58  evt->set_event_number(m_internal_event_number);
59  ++m_internal_event_number;
60  }
61 
62  // Set units to be GeV and mm, to agree with Pythia ones.
63  evt->set_units(Units::GEV,Units::MM);
64 
65  // 2. Fill particle information.
66  std::vector<GenParticlePtr> hepevt_particles;
67  hepevt_particles.reserve( pyev.size() );
68  for(int i = 0; i < pyev.size(); ++i) {
69  hepevt_particles.push_back( std::make_shared<GenParticle>(
70  FourVector( pyev[i].px(), pyev[i].py(), pyev[i].pz(), pyev[i].e() ),
71  pyev[i].id(), pyev[i].statusHepMC() ) );
72  hepevt_particles[i]->set_generated_mass( pyev[i].m() );
73  }
74 
75  // 3. Fill vertex information.
76  std::vector<GenVertexPtr> vertex_cache;
77  for (int i = 1; i < pyev.size(); ++i) {
78  std::vector<int> mothers = pyev[i].motherList();
79  if (mothers.size()) {
80  GenVertexPtr prod_vtx = hepevt_particles[mothers[0]]->end_vertex();
81  if (!prod_vtx) {
82  prod_vtx = make_shared<GenVertex>();
83  vertex_cache.push_back(prod_vtx);
84  for (unsigned int j = 0; j < mothers.size(); ++j)
85  prod_vtx->add_particle_in( hepevt_particles[mothers[j]] );
86  }
87  FourVector prod_pos( pyev[i].xProd(), pyev[i].yProd(),pyev[i].zProd(),
88  pyev[i].tProd() );
89 
90  // Update vertex position if necessary.
91  if (!prod_pos.is_zero() && prod_vtx->position().is_zero())
92  prod_vtx->set_position( prod_pos );
93  prod_vtx->add_particle_out( hepevt_particles[i] );
94  }
95  }
96 
97  // Reserve memory for the event.
98  evt->reserve( hepevt_particles.size(), vertex_cache.size() );
99 
100  // Here we assume that the first two particles are the beam particles.
101  vector<GenParticlePtr> beam_particles;
102  beam_particles.push_back(hepevt_particles[1]);
103  beam_particles.push_back(hepevt_particles[2]);
104 
105  // Add particles and vertices in topological order.
106  evt->add_tree( beam_particles );
107  // Attributes should be set after adding the particles to event.
108  for (int i = 0; i < pyev.size(); ++i) {
109  /* TODO: Set polarization */
110  // Colour flow uses index 1 and 2.
111  int colType = pyev[i].colType();
112  if (colType == -1 ||colType == 1 || colType == 2) {
113  int flow1 = 0, flow2 = 0;
114  if (colType == 1 || colType == 2) flow1 = pyev[i].col();
115  if (colType == -1 || colType == 2) flow2 = pyev[i].acol();
116  hepevt_particles[i]->add_attribute("flow1",
117  make_shared<IntAttribute>(flow1));
118  hepevt_particles[i]->add_attribute("flow2",
119  make_shared<IntAttribute>(flow2));
120  }
121  }
122 
123  // If hadronization switched on then no final coloured particles.
124  bool doHadr = (pyset == 0) ? m_free_parton_warnings
125  : pyset->flag("HadronLevel:all") && pyset->flag("HadronLevel:Hadronize");
126 
127  // 4. Check for particles which come from nowhere, i.e. are without
128  // mothers or daughters. These need to be attached to a vertex, or else
129  // they will never become part of the event.
130  for (int i = 1; i < pyev.size(); ++i) {
131 
132  // Check for particles not added to the event.
133  // NOTE: We have to check if this step makes any sense in
134  // the HepMC event standard.
135  if ( !hepevt_particles[i] ) {
136  std::cerr << "hanging particle " << i << std::endl;
137  GenVertexPtr prod_vtx;
138  prod_vtx->add_particle_out( hepevt_particles[i] );
139  evt->add_vertex(prod_vtx);
140  }
141 
142  // Also check for free partons (= gluons and quarks; not diquarks?).
143  if ( doHadr && m_free_parton_warnings ) {
144  if ( hepevt_particles[i]->pid() == 21
145  && !hepevt_particles[i]->end_vertex() ) {
146  std::cerr << "gluon without end vertex " << i << std::endl;
147  if ( m_crash_on_problem ) exit(1);
148  }
149  if ( std::abs(hepevt_particles[i]->pid()) <= 6
150  && !hepevt_particles[i]->end_vertex() ) {
151  std::cerr << "quark without end vertex " << i << std::endl;
152  if ( m_crash_on_problem ) exit(1);
153  }
154  }
155  }
156 
157  // 5. Store PDF, weight, cross section and other event information.
158  // Flavours of incoming partons.
159  if (m_store_pdf && pyinfo != 0) {
160  int id1pdf = pyinfo->id1pdf();
161  int id2pdf = pyinfo->id2pdf();
162  if ( m_convert_gluon_to_0 ) {
163  if (id1pdf == 21) id1pdf = 0;
164  if (id2pdf == 21) id2pdf = 0;
165  }
166 
167  // Store PDF information.
168  GenPdfInfoPtr pdfinfo = make_shared<GenPdfInfo>();
169  pdfinfo->set(id1pdf, id2pdf, pyinfo->x1pdf(), pyinfo->x2pdf(),
170  pyinfo->QFac(), pyinfo->pdf1(), pyinfo->pdf2() );
171  evt->set_pdf_info( pdfinfo );
172  }
173 
174  // Store process code, scale, alpha_em, alpha_s.
175  if (m_store_proc && pyinfo != 0) {
176  evt->add_attribute("signal_process_id",
177  std::make_shared<IntAttribute>( pyinfo->code()));
178  evt->add_attribute("event_scale",
179  std::make_shared<DoubleAttribute>(pyinfo->QRen()));
180  evt->add_attribute("alphaQCD",
181  std::make_shared<DoubleAttribute>(pyinfo->alphaS()));
182  evt->add_attribute("alphaQED",
183  std::make_shared<DoubleAttribute>(pyinfo->alphaEM()));
184  }
185 
186  // Store event weights.
187  if (m_store_weights && pyinfo != 0) {
188  evt->weights().clear();
189  //for (int iweight = 0; iweight < pyinfo->nWeights(); ++iweight) {
190  // evt->weights().push_back(pyinfo->weight(iweight));
191  //}
192  for (int iweight = 0; iweight < pyinfo->numberOfWeights();
193  ++iweight) {
194  double value = pyinfo->weightValueByIndex(iweight);
195  evt->weights().push_back(value);
196  }
197 
198  }
199 
200  // Store cross-section information in pb.
201  if (m_store_xsec && pyinfo != 0) {
202  // First set atribute to event, such that
203  // GenCrossSection::set_cross_section knows how many weights the
204  // event has and sets the number of cross sections accordingly.
205  GenCrossSectionPtr xsec = make_shared<GenCrossSection>();
206  evt->set_cross_section(xsec);
207  xsec->set_cross_section( pyinfo->sigmaGen() * 1e9,
208  pyinfo->sigmaErr() * 1e9);
209  // If multiweights with possibly different xsec, overwrite central value
210  vector<double> xsecVec = pyinfo->weightContainerPtr->getTotalXsec();
211  if (xsecVec.size() > 0) {
212  for (unsigned int iXsec = 0; iXsec < xsecVec.size(); ++iXsec) {
213  xsec->set_xsec(iXsec, xsecVec[iXsec]*1e9);
214  }
215  }
216  }
217 
218  // Done.
219  return true;
220  }
221 
222  // Read out values for some switches.
223  bool print_inconsistency() const { return m_print_inconsistency; }
224  bool free_parton_warnings() const { return m_free_parton_warnings; }
225  bool crash_on_problem() const { return m_crash_on_problem; }
226  bool convert_gluon_to_0() const { return m_convert_gluon_to_0; }
227  bool store_pdf() const { return m_store_pdf; }
228  bool store_proc() const { return m_store_proc; }
229  bool store_xsec() const { return m_store_xsec; }
230  bool store_weights() const { return m_store_weights; }
231 
232  // Set values for some switches.
233  void set_print_inconsistency(bool b = true) { m_print_inconsistency = b; }
234  void set_free_parton_warnings(bool b = true) { m_free_parton_warnings = b; }
235  void set_crash_on_problem(bool b = false) { m_crash_on_problem = b; }
236  void set_convert_gluon_to_0(bool b = false) { m_convert_gluon_to_0 = b; }
237  void set_store_pdf(bool b = true) { m_store_pdf = b; }
238  void set_store_proc(bool b = true) { m_store_proc = b; }
239  void set_store_xsec(bool b = true) { m_store_xsec = b; }
240  void set_store_weights(bool b = true) { m_store_weights = b; }
241 
242 private:
243 
244  // Following methods are not implemented for this class.
245  virtual bool fill_next_event( GenEvent* ) { return 0; }
246  virtual void write_event( const GenEvent* ) {}
247 
248  // Use of copy constructor is not allowed.
249  Pythia8ToHepMC3( const Pythia8ToHepMC3& ) {}
250 
251  // Data members.
252  int m_internal_event_number;
253  bool m_print_inconsistency, m_free_parton_warnings, m_crash_on_problem,
254  m_convert_gluon_to_0, m_store_pdf, m_store_proc, m_store_xsec,
255  m_store_weights;
256 
257  //GenRunInfo genRunInfo;
258 
259 };
260 
261 //==========================================================================
262 
263 } // end namespace HepMC3
264 
265 #endif // end Pythia8_HepMC3_H