11 #ifndef Pythia8_HepMC2_H
12 #define Pythia8_HepMC2_H
17 #include "HepMC/IO_BaseClass.h"
18 #include "HepMC/IO_GenEvent.h"
19 #include "HepMC/GenEvent.h"
20 #include "HepMC/Units.h"
21 #include "Pythia8/Pythia.h"
29 class Pythia8ToHepMCException :
public std::exception {
32 virtual const char* what()
const throw() {
return "Pythia8ToHepMCException";}
40 class PartonEndVertexException :
public Pythia8ToHepMCException {
45 PartonEndVertexException(
int i,
int pdg_idIn) : Pythia8ToHepMCException() {
49 ss <<
"Bad end vertex at " << i <<
" for flavour " << pdg_idIn;
52 virtual ~PartonEndVertexException() throw() {}
55 virtual const char* what()
const throw() {
return msg.c_str();}
58 int index()
const {
return iSave;}
59 int pdg_id()
const {
return idSave;}
71 class Pythia8ToHepMC :
public IO_BaseClass {
76 Pythia8ToHepMC() : m_internal_event_number(0), m_print_inconsistency(true),
77 m_free_parton_exception(true), m_convert_gluon_to_0(false),
78 m_store_pdf(true), m_store_proc(true), m_store_xsec(true) {;}
79 virtual ~Pythia8ToHepMC() {;}
83 int ievnum = -1,
bool append =
false, GenParticle* rootParticle = 0,
84 int iBarcode = -1 ) {
return fill_next_event( pythia.event, evt, ievnum,
85 &pythia.info, &pythia.settings, append, rootParticle, iBarcode);}
91 GenParticle* rootParticle = 0,
int iBarcode = -1);
94 bool print_inconsistency()
const {
return m_print_inconsistency;}
95 bool free_parton_exception()
const {
return m_free_parton_exception;}
96 bool convert_gluon_to_0()
const {
return m_convert_gluon_to_0;}
97 bool store_pdf()
const {
return m_store_pdf;}
98 bool store_proc()
const {
return m_store_proc;}
99 bool store_xsec()
const {
return m_store_xsec;}
102 void set_print_inconsistency(
bool b =
true) {m_print_inconsistency = b;}
103 void set_free_parton_exception(
bool b =
true) {m_free_parton_exception = b;}
104 void set_convert_gluon_to_0(
bool b =
false) {m_convert_gluon_to_0 = b;}
105 void set_store_pdf(
bool b =
true) {m_store_pdf = b;}
106 void set_store_proc(
bool b =
true) {m_store_proc = b;}
107 void set_store_xsec(
bool b =
true) {m_store_xsec = b;}
112 virtual bool fill_next_event( GenEvent* ) {
return 0; }
113 virtual void write_event(
const GenEvent* ) {;}
116 Pythia8ToHepMC(
const Pythia8ToHepMC& ) : IO_BaseClass() {;}
119 int m_internal_event_number;
120 bool m_print_inconsistency, m_free_parton_exception, m_convert_gluon_to_0,
121 m_store_pdf, m_store_proc, m_store_xsec;
131 inline bool Pythia8ToHepMC::fill_next_event(
Pythia8::Event& pyev,
138 std::cout <<
" Pythia8ToHepMC::fill_next_event error: passed null event."
146 evt->set_event_number(ievnum);
147 m_internal_event_number = ievnum;
149 evt->set_event_number(m_internal_event_number);
150 ++m_internal_event_number;
155 double momFac = HepMC::Units::conversion_factor(HepMC::Units::GEV,
156 evt->momentum_unit());
157 double lenFac = HepMC::Units::conversion_factor(HepMC::Units::MM,
165 std::cout <<
" Pythia8ToHepMC::fill_next_event error: passed null "
166 <<
"root particle in append mode." << std::endl;
170 newBarcode = (iBarcode > -1) ? iBarcode : evt->particles_size();
172 GenVertex* prod_vtx0 =
new GenVertex();
173 prod_vtx0->add_particle_in( rootParticle );
174 evt->add_vertex( prod_vtx0 );
179 std::vector<GenParticle*> hepevt_particles( pyev.size() );
180 for (
int i = iStart; i < pyev.size(); ++i) {
183 hepevt_particles[i] =
new GenParticle(
184 FourVector( momFac * pyev[i].px(), momFac * pyev[i].py(),
185 momFac * pyev[i].pz(), momFac * pyev[i].e() ),
186 pyev[i].
id(), pyev[i].statusHepMC() );
187 if (iBarcode != 0) ++newBarcode;
188 hepevt_particles[i]->suggest_barcode( (append) ? newBarcode : i );
189 hepevt_particles[i]->set_generated_mass( momFac * pyev[i].m() );
192 int colType = pyev[i].colType();
193 if (colType == 1 || colType == 2)
194 hepevt_particles[i]->set_flow(1, pyev[i].col());
195 if (colType == -1 || colType == 2)
196 hepevt_particles[i]->set_flow(2, pyev[i].acol());
202 evt->set_beam_particles( hepevt_particles[1], hepevt_particles[2] );
207 for (
int i = iStart; i < pyev.size(); ++i) {
208 GenParticle* p = hepevt_particles[i];
211 std::vector<int> mothers = pyev[i].motherList();
212 unsigned int imother = 0;
214 if ( !mothers.empty() ) mother = mothers[imother];
215 GenVertex* prod_vtx = p->production_vertex();
216 while ( !prod_vtx && mother > 0 ) {
217 prod_vtx = (append && mother == 1) ? rootParticle->end_vertex()
218 : hepevt_particles[mother]->end_vertex();
219 if (prod_vtx) prod_vtx->add_particle_out( p );
220 mother = ( ++imother < mothers.size() ) ? mothers[imother] : -1;
225 FourVector prod_pos( lenFac * pyev[i].xProd(), lenFac * pyev[i].yProd(),
226 lenFac * pyev[i].zProd(), lenFac * pyev[i].tProd() );
227 if ( !prod_vtx && ( mothers.size() > 0 || prod_pos != FourVector() ) ) {
228 prod_vtx =
new GenVertex();
229 prod_vtx->add_particle_out( p );
230 evt->add_vertex( prod_vtx );
234 if ( prod_vtx && prod_vtx->position() == FourVector() )
235 prod_vtx->set_position( prod_pos );
240 if ( !mothers.empty() ) mother = mothers[imother];
241 while ( prod_vtx && mother > 0 ) {
244 GenParticle* ppp = (append && mother == 1) ? rootParticle
245 : hepevt_particles[mother];
246 if ( !ppp->end_vertex() ) {
247 prod_vtx->add_particle_in( ppp );
254 }
else if (ppp->end_vertex() != prod_vtx ) {
255 if ( m_print_inconsistency ) std::cout
256 <<
" Pythia8ToHepMC::fill_next_event: inconsistent mother/daugher "
257 <<
"information in Pythia8 event " << std::endl
258 <<
"i = " << i <<
" mother = " << mother
259 <<
"\n This warning can be turned off with the "
260 <<
"Pythia8ToHepMC::print_inconsistency switch." << std::endl;
264 mother = ( ++imother < mothers.size() ) ? mothers[imother] : -1;
269 bool doHadr = (pyset == 0) ? m_free_parton_exception
270 : pyset->flag(
"HadronLevel:all") && pyset->flag(
"HadronLevel:Hadronize");
275 for (
int i = iStart; i < pyev.size(); ++i) {
276 if ( !hepevt_particles[i]->end_vertex() &&
277 !hepevt_particles[i]->production_vertex() ) {
278 std::cout <<
" Pythia8ToHepMC::fill_next_event error: "
279 <<
"hanging particle " << i << std::endl;
280 GenVertex* prod_vtx =
new GenVertex();
281 prod_vtx->add_particle_out( hepevt_particles[i] );
282 evt->add_vertex( prod_vtx );
286 if ( doHadr && m_free_parton_exception ) {
287 int pdg_tmp = hepevt_particles[i]->pdg_id();
288 if ( (abs(pdg_tmp) <= 6 || pdg_tmp == 21)
289 && !hepevt_particles[i]->end_vertex() )
290 throw PartonEndVertexException(i, pdg_tmp);
295 if (append)
return true;
299 if (m_store_pdf && pyinfo != 0) {
300 int id1pdf = pyinfo->id1pdf();
301 int id2pdf = pyinfo->id2pdf();
302 if ( m_convert_gluon_to_0 ) {
303 if (id1pdf == 21) id1pdf = 0;
304 if (id2pdf == 21) id2pdf = 0;
308 evt->set_pdf_info( PdfInfo( id1pdf, id2pdf, pyinfo->x1pdf(),
309 pyinfo->x2pdf(), pyinfo->QFac(), pyinfo->pdf1(), pyinfo->pdf2() ) );
313 if (m_store_proc && pyinfo != 0) {
314 evt->set_signal_process_id( pyinfo->code() );
315 evt->set_event_scale( pyinfo->QRen() );
316 if (evt->alphaQED() <= 0) evt->set_alphaQED( pyinfo->alphaEM() );
317 if (evt->alphaQCD() <= 0) evt->set_alphaQCD( pyinfo->alphaS() );
322 if (m_store_xsec && pyinfo != 0) {
325 pyinfo->sigmaErr() * 1e9);
326 evt->set_cross_section(xsec);
327 for (
int iweight = 0; iweight < pyinfo->numberOfWeights();
329 std::string name = pyinfo->weightNameByIndex(iweight);
330 double value = pyinfo->weightValueByIndex(iweight);
331 evt->weights()[name] = value;
334 std::vector<double> xsecVec = pyinfo->weightContainerPtr->getTotalXsec();
335 if (xsecVec.size() > 0) {
337 evt->set_cross_section(xsec);
350 #endif // end Pythia8_HepMC2_H
void set_cross_section(double xs, double xs_err)
Set cross section and error in pb.
The GenCrossSection class stores the generated cross section.