StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
HepMCInterface.cc
1 // HepMCInterface.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2012 Mikhail Kirsanov, Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // Function definitions (not found in the header) for the I_Pythia8 class,
7 // which converts a PYTHIA event record to the standard HepMC format.
8 
9 // Mikhail.Kirsanov@cern.ch
10 
11 // For GCC versions >= 4.6.0 can turn off shadow warnings
12 #if ((__GNUC__*100)+__GNUC_MINOR__) >= 406
13 #pragma GCC diagnostic ignored "-Wshadow"
14 #endif
15 
16 #include "HepMCInterface.h"
17 #include "HepMC/GenEvent.h"
18 
19 // Switch shadow warnings back on
20 #if ((__GNUC__*100)+__GNUC_MINOR__) >= 406
21 #pragma GCC diagnostic warning "-Wshadow"
22 #endif
23 
24 namespace HepMC {
25 
26 //==========================================================================
27 
28 // Constructor and destructor.
29 
30 I_Pythia8::I_Pythia8():
31  m_trust_mothers_before_daughters(true),
32  m_trust_both_mothers_and_daughters(false),
33  m_print_inconsistency_errors(true),
34  m_crash_on_problem(false),
35  m_freepartonwarnings(true),
36  m_convert_to_mev(false),
37  m_mom_scale_factor(1.),
38  m_internal_event_number(0) {;}
39 
40 I_Pythia8::~I_Pythia8() {;}
41 
42 //--------------------------------------------------------------------------
43 
44 // Main method for conversion from PYTHIA event to HepMC event.
45 // Read one event from Pythia8 and fill GenEvent,
46 // and return T/F = success/failure.
47 
48 bool I_Pythia8::fill_next_event( Pythia8::Event& pyev, GenEvent* evt,
49  int ievnum ) {
50 
51  // 1. Error if no event passed.
52  if ( !evt ) {
53  std::cerr << "I_Pythia8::fill_next_event error - passed null event."
54  << std::endl;
55  return 0;
56  }
57 
58  // Event number counter.
59  if ( ievnum >= 0 ) {
60  evt->set_event_number(ievnum);
61  m_internal_event_number = ievnum;
62  } else {
63  evt->set_event_number(m_internal_event_number);
64  m_internal_event_number++;
65  }
66 
67  // Decide whether conversion from GeV to MeV is necessary.
68 #ifdef HEPMC_HAS_UNITS
69  set_convert_to_mev(false);
70 #else
71  set_convert_to_mev(true);
72 #endif
73 
74  // 2. Create a particle instance for each entry and fill a map, and
75  // a vector which maps from the particle index to the GenParticle address.
76  std::vector<GenParticle*> hepevt_particles( pyev.size() );
77  int i, istatus;
78  for ( i = 1; i < pyev.size(); ++i ) {
79 
80  // The new HepMC status codes of February 2009 are now used by
81  // default. If you want to recover the previous simpler behaviour
82  // comment out the next line and uncomment the following one.
83  istatus = pyev.statusHepMC(i);
84  // istatus = (pyev[i].status() > 0) ? 1 : 2;
85 
86  // Fill the particle.
87  hepevt_particles[i] = new GenParticle(
88  FourVector( m_mom_scale_factor*pyev[i].p().px(),
89  m_mom_scale_factor*pyev[i].p().py(),
90  m_mom_scale_factor*pyev[i].p().pz(),
91  m_mom_scale_factor*pyev[i].p().e() ),
92  pyev[i].id(), istatus );
93  hepevt_particles[i]->suggest_barcode(i);
94 
95  // Colour flow uses index 1 and 2.
96  int colType = pyev[i].colType();
97  if (colType == 1 || colType == 2)
98  hepevt_particles[i]->set_flow(1, pyev[i].col());
99  if (colType == -1 || colType == 2)
100  hepevt_particles[i]->set_flow(2, pyev[i].acol());
101  }
102 
103  // Here we assume that the first two particles in the list
104  // are the incoming beam particles.
105  evt->set_beam_particles( hepevt_particles[1], hepevt_particles[2] );
106 
107  // 3 + 4. Loop over particles AGAIN, this time creating vertices.
108  // We build EITHER the production or decay vertex for each entry in
109  // hepevt, depending on the switch m_trust_mothers_before_daughters.
110  // Note: the HEPEVT pointers are bi-directional, so sufficient to do one.
111  for ( i = 1; i < pyev.size(); ++i ) {
112 
113  // 3. Build the production_vertex (if necessary).
114  if ( m_trust_mothers_before_daughters ||
115  m_trust_both_mothers_and_daughters ) {
116  GenParticle *p = hepevt_particles[i];
117 
118  // 3a. Search to see if a production vertex already exists.
119  std::vector<int> mothers = pyev.motherList(i);
120  unsigned int imother = 0;
121  int mother = -1; // note that in Pythia8 there is a particle number 0!
122  if ( !mothers.empty() ) mother = mothers[imother];
123  GenVertex* prod_vtx = p->production_vertex();
124  while ( !prod_vtx && mother > 0 ) {
125  prod_vtx = hepevt_particles[mother]->end_vertex();
126  if ( prod_vtx ) prod_vtx->add_particle_out( p );
127  imother++;
128  if ( imother < mothers.size() ) mother = mothers[imother];
129  else mother = -1;
130  }
131 
132  // 3b. If no suitable production vertex exists - and the particle has
133  // at least one mother or position information to store - make one.
134  FourVector prod_pos( pyev[i].xProd(), pyev[i].yProd(),
135  pyev[i].zProd(), pyev[i].tProd() );
136  unsigned int nparents = mothers.size();
137  if ( !prod_vtx && ( nparents > 0 || prod_pos != FourVector() ) ) {
138  prod_vtx = new GenVertex();
139  prod_vtx->add_particle_out( p );
140  evt->add_vertex( prod_vtx );
141  }
142 
143  // 3c. If prod_vtx doesn't already have position specified, fill it.
144  if ( prod_vtx && prod_vtx->position() == FourVector() )
145  prod_vtx->set_position( prod_pos );
146 
147  // 3d. loop over mothers to make sure their end_vertices are consistent.
148  imother = 0;
149  mother = -1;
150  if ( !mothers.empty() ) mother = mothers[imother];
151  while ( prod_vtx && mother > 0 ) {
152 
153  // If end vertex of the mother isn't specified, do it now.
154  if ( !hepevt_particles[mother]->end_vertex() ) {
155  prod_vtx->add_particle_in( hepevt_particles[mother] );
156 
157  // Problem scenario: the mother already has a decay vertex which
158  // differs from the daughter's production vertex. This means there is
159  // internal inconsistency in the HEPEVT event record. Print an error.
160  // Note: we could provide a fix by joining the two vertices with a
161  // dummy particle if the problem arises often.
162  } else if (hepevt_particles[mother]->end_vertex() != prod_vtx ) {
163  if ( m_print_inconsistency_errors ) std::cerr
164  << "HepMC::I_Pythia8: inconsistent mother/daugher "
165  << "information in Pythia8 event " << std::endl
166  << "i= " << i << " mother = " << mother
167  << "\n This warning can be turned off with the "
168  << "I_Pythia8::print_inconsistency_errors switch." << std::endl;
169  }
170 
171  // Variant with motherList.
172  imother++;
173  if ( imother < mothers.size() ) mother = mothers[imother];
174  else mother = -1;
175  }
176 
177  // 4. Building from the mothers not implemented so far.
178  } else {
179  std::cerr << "trust_daughters_before_mothers not implemented"
180  << std::endl;
181  return 0;
182  }
183  }
184 
185  // 5. Check for particles which come from nowhere, i.e. are without
186  // mothers or daughters. These need to be attached to a vertex, or else
187  // they will never become part of the event.
188  for ( i = 1; i < pyev.size(); ++i ) {
189  if ( !hepevt_particles[i]->end_vertex() &&
190  !hepevt_particles[i]->production_vertex() ) {
191  std::cerr << "hanging particle " << i << std::endl;
192  GenVertex* prod_vtx = new GenVertex();
193  prod_vtx->add_particle_out( hepevt_particles[i] );
194  evt->add_vertex( prod_vtx );
195  }
196 
197  // Also check for free partons (= gluons and quarks; not diquarks?).
198  if ( m_freepartonwarnings ) {
199  if ( hepevt_particles[i]->pdg_id() == 21 &&
200  !hepevt_particles[i]->end_vertex() ) {
201  std::cerr << "gluon without end vertex " << i << std::endl;
202  if ( m_crash_on_problem ) exit(1);
203  }
204  if ( abs(hepevt_particles[i]->pdg_id()) <= 6 &&
205  !hepevt_particles[i]->end_vertex() ) {
206  std::cerr << "quark without end vertex " << i << std::endl;
207  if ( m_crash_on_problem ) exit(1);
208  }
209  }
210  }
211 
212  // Done.
213  return true;
214 
215 }
216 
217 //--------------------------------------------------------------------------
218 
219 // Conversion from PYTHIA event to HepMC event, with PDF and
220 // some other info included. Return T/F = success/failure.
221 
222 bool I_Pythia8::fill_next_event( Pythia8::Pythia& pythia, GenEvent* evt,
223  int ievnum, bool convertGluonTo0 ) {
224 
225  // If hadronization is switched off then do not warn for free partons.
226  bool doHadr = pythia.flag("HadronLevel:all") &&
227  pythia.flag("HadronLevel:Hadronize");
228  if (!doHadr) m_freepartonwarnings = false;
229 
230  // Let the method above convert the event record. Check that it worked.
231  bool result = fill_next_event( pythia.event, evt, ievnum );
232  if ( result ) {
233 
234  // Store PDF information.
235  put_pdf_info(evt, pythia, convertGluonTo0 );
236 
237  // Store process code, scale, alpha_em, alpha_s.
238  evt->set_signal_process_id(pythia.info.code());
239  evt->set_event_scale(pythia.info.pTHat());
240  if (evt->alphaQED() <= 0) evt->set_alphaQED( pythia.info.alphaEM() );
241  if (evt->alphaQCD() <= 0) evt->set_alphaQCD( pythia.info.alphaS() );
242 
243  // Store event weight, which is in units of fb for Les Houches Event
244  // strategies +-4.
245  evt->weights().push_back( pythia.info.weight() );
246 
247  // HepMC 2.05 supports cross-section information in pb:
248 #ifdef HEPMC_HAS_CROSS_SECTION
250  xsec.set_cross_section( pythia.info.sigmaGen() * 1e9,
251  pythia.info.sigmaErr() * 1e9);
252  evt->set_cross_section(xsec);
253 #endif
254 
255  }
256 
257  // Done.
258  return result;
259 
260 }
261 
262 //--------------------------------------------------------------------------
263 
264 // Conversion of PDF info.
265 
266 void I_Pythia8::put_pdf_info( GenEvent* evt, Pythia8::Pythia& pythia,
267  bool convertGluonTo0 ) {
268 
269  // Flavours of incoming partons.
270  int id1 = pythia.info.id1();
271  int id2 = pythia.info.id2();
272  if ( convertGluonTo0 ) {
273  if ( id1 == 21 ) id1 = 0;
274  if ( id2 == 21 ) id2 = 0;
275  }
276 
277  // x, Q and x*f(x) for incoming partons.
278  double x1 = pythia.info.x1();
279  double x2 = pythia.info.x2();
280  double Q = pythia.info.QFac();
281  double pdf1 = pythia.info.pdf1();
282  double pdf2 = pythia.info.pdf2();
283 
284  // Store PDF info and done.
285  evt->set_pdf_info( PdfInfo( id1, id2, x1, x2, Q, pdf1, pdf2) ) ;
286 
287  }
288 
289 //==========================================================================
290 
291 } // end namespace HepMC
void set_cross_section(double xs, double xs_err)
Set cross section and error in pb.
The GenCrossSection class stores the generated cross section.