11 #ifndef Pythia8_HepMC3_H 12 #define Pythia8_HepMC3_H 14 #ifdef Pythia8_HepMC2_H 15 #error Cannot include HepMC3.h if HepMC2.h has already been included. 19 #include "Pythia8/Pythia.h" 20 #include "Pythia8/HIInfo.h" 21 #include "HepMC3/GenVertex.h" 22 #include "HepMC3/GenParticle.h" 23 #include "HepMC3/GenEvent.h" 24 #include "HepMC3/WriterAscii.h" 25 #include "HepMC3/WriterAsciiHepMC2.h" 26 #include "HepMC3/GenHeavyIon.h" 27 #include "HepMC3/GenPdfInfo.h" 39 m_free_parton_warnings(true), m_crash_on_problem(false),
40 m_convert_gluon_to_0(false), m_store_pdf(true), m_store_proc(true),
41 m_store_xsec(true), m_store_weights(true) {}
60 std::cerr <<
"Pythia8ToHepMC3::fill_next_event error - " 61 <<
"passed null event." << std::endl;
67 evt->set_event_number(ievnum);
68 m_internal_event_number = ievnum;
71 evt->set_event_number(m_internal_event_number);
72 ++m_internal_event_number;
76 evt->set_units(Units::GEV,Units::MM);
79 if ( pyinfo && pyinfo->hiInfo ) {
80 auto ion = make_shared<HepMC3::GenHeavyIon>();
81 ion->Ncoll_hard = pyinfo->hiInfo->nCollNDTot();
82 ion->Ncoll = pyinfo->hiInfo->nAbsProj() +
83 pyinfo->hiInfo->nDiffProj() +
84 pyinfo->hiInfo->nAbsTarg() +
85 pyinfo->hiInfo->nDiffTarg() -
86 pyinfo->hiInfo->nCollND() -
87 pyinfo->hiInfo->nCollDD();
88 ion->Npart_proj = pyinfo->hiInfo->nAbsProj() +
89 pyinfo->hiInfo->nDiffProj();
90 ion->Npart_targ = pyinfo->hiInfo->nAbsTarg() +
91 pyinfo->hiInfo->nDiffTarg();
92 ion->impact_parameter = pyinfo->hiInfo->b();
93 evt->set_heavy_ion(ion);
97 std::vector<GenParticlePtr> hepevt_particles;
98 hepevt_particles.reserve( pyev.
size() );
99 for(
int i = 0; i < pyev.
size(); ++i) {
100 hepevt_particles.push_back( std::make_shared<GenParticle>(
101 FourVector( pyev[i].px(), pyev[i].py(), pyev[i].pz(), pyev[i].e() ),
102 pyev[i].
id(), pyev[i].statusHepMC() ) );
103 hepevt_particles[i]->set_generated_mass( pyev[i].m() );
107 std::vector<GenVertexPtr> vertex_cache;
108 for (
int i = 3; i < pyev.
size(); ++i) {
109 std::vector<int> mothers = pyev[i].motherList();
110 if (mothers.size()) {
111 GenVertexPtr prod_vtx = hepevt_particles[mothers[0]]->end_vertex();
113 prod_vtx = make_shared<GenVertex>();
114 vertex_cache.push_back(prod_vtx);
115 for (
unsigned int j = 0; j < mothers.size(); ++j)
116 prod_vtx->add_particle_in( hepevt_particles[mothers[j]] );
118 FourVector prod_pos( pyev[i].xProd(), pyev[i].yProd(),pyev[i].zProd(),
122 if (!prod_pos.is_zero() && prod_vtx->position().is_zero())
123 prod_vtx->set_position( prod_pos );
124 prod_vtx->add_particle_out( hepevt_particles[i] );
129 evt->reserve( hepevt_particles.size(), vertex_cache.size() );
132 vector<GenParticlePtr> beam_particles;
133 beam_particles.push_back(hepevt_particles[1]);
134 beam_particles.push_back(hepevt_particles[2]);
137 evt->add_tree( beam_particles );
139 for (
int i = 0; i < pyev.
size(); ++i) {
142 int colType = pyev[i].colType();
143 if (colType == -1 ||colType == 1 || colType == 2) {
144 int flow1 = 0, flow2 = 0;
145 if (colType == 1 || colType == 2) flow1 = pyev[i].col();
146 if (colType == -1 || colType == 2) flow2 = pyev[i].acol();
147 hepevt_particles[i]->add_attribute(
"flow1",
148 make_shared<IntAttribute>(flow1));
149 hepevt_particles[i]->add_attribute(
"flow2",
150 make_shared<IntAttribute>(flow2));
155 bool doHadr = (pyset == 0) ? m_free_parton_warnings
156 : pyset->flag(
"HadronLevel:all") && pyset->flag(
"HadronLevel:Hadronize");
161 for (
int i = 1; i < pyev.
size(); ++i) {
166 if ( !hepevt_particles[i] ) {
167 std::cerr <<
"hanging particle " << i << std::endl;
168 GenVertexPtr prod_vtx = make_shared<GenVertex>();
169 prod_vtx->add_particle_out( hepevt_particles[i] );
170 evt->add_vertex(prod_vtx);
174 if ( doHadr && m_free_parton_warnings ) {
175 if ( hepevt_particles[i]->pid() == 21
176 && !hepevt_particles[i]->end_vertex() ) {
177 std::cerr <<
"gluon without end vertex " << i << std::endl;
178 if ( m_crash_on_problem ) exit(1);
180 if ( std::abs(hepevt_particles[i]->pid()) <= 6
181 && !hepevt_particles[i]->end_vertex() ) {
182 std::cerr <<
"quark without end vertex " << i << std::endl;
183 if ( m_crash_on_problem ) exit(1);
190 if (m_store_pdf && pyinfo != 0) {
191 int id1pdf = pyinfo->id1pdf();
192 int id2pdf = pyinfo->id2pdf();
193 if ( m_convert_gluon_to_0 ) {
194 if (id1pdf == 21) id1pdf = 0;
195 if (id2pdf == 21) id2pdf = 0;
199 GenPdfInfoPtr pdfinfo = make_shared<GenPdfInfo>();
200 pdfinfo->set(id1pdf, id2pdf, pyinfo->x1pdf(), pyinfo->x2pdf(),
201 pyinfo->QFac(), pyinfo->pdf1(), pyinfo->pdf2() );
202 evt->set_pdf_info( pdfinfo );
206 if (m_store_proc && pyinfo != 0) {
207 evt->add_attribute(
"signal_process_id",
208 std::make_shared<IntAttribute>( pyinfo->code()));
209 evt->add_attribute(
"event_scale",
210 std::make_shared<DoubleAttribute>(pyinfo->QRen()));
211 evt->add_attribute(
"alphaQCD",
212 std::make_shared<DoubleAttribute>(pyinfo->alphaS()));
213 evt->add_attribute(
"alphaQED",
214 std::make_shared<DoubleAttribute>(pyinfo->alphaEM()));
218 if (m_store_weights && pyinfo != 0) {
219 evt->weights().clear();
220 for (
int iWeight = 0; iWeight < pyinfo->numberOfWeights(); ++iWeight)
221 evt->weights().push_back(pyinfo->weightValueByIndex(iWeight));
225 if (m_store_xsec && pyinfo != 0) {
229 GenCrossSectionPtr xsec = make_shared<GenCrossSection>();
230 evt->set_cross_section(xsec);
231 xsec->set_cross_section( pyinfo->sigmaGen() * 1e9,
232 pyinfo->sigmaErr() * 1e9);
234 vector<double> xsecVec = pyinfo->weightContainerPtr->getTotalXsec();
235 if (xsecVec.size() > 0) {
236 for (
unsigned int iXsec = 0; iXsec < xsecVec.size(); ++iXsec) {
237 xsec->set_xsec(iXsec, xsecVec[iXsec]*1e9);
248 bool free_parton_warnings()
const {
return m_free_parton_warnings; }
249 bool crash_on_problem()
const {
return m_crash_on_problem; }
250 bool convert_gluon_to_0()
const {
return m_convert_gluon_to_0; }
251 bool store_pdf()
const {
return m_store_pdf; }
252 bool store_proc()
const {
return m_store_proc; }
253 bool store_xsec()
const {
return m_store_xsec; }
254 bool store_weights()
const {
return m_store_weights; }
258 void set_free_parton_warnings(
bool b =
true) { m_free_parton_warnings = b; }
259 void set_crash_on_problem(
bool b =
false) { m_crash_on_problem = b; }
260 void set_convert_gluon_to_0(
bool b =
false) { m_convert_gluon_to_0 = b; }
261 void set_store_pdf(
bool b =
true) { m_store_pdf = b; }
262 void set_store_proc(
bool b =
true) { m_store_proc = b; }
263 void set_store_xsec(
bool b =
true) { m_store_xsec = b; }
264 void set_store_weights(
bool b =
true) { m_store_weights = b; }
270 virtual void write_event(
const GenEvent* ) {}
276 int m_internal_event_number;
277 bool m_print_inconsistency, m_free_parton_warnings, m_crash_on_problem,
278 m_convert_gluon_to_0, m_store_pdf, m_store_proc, m_store_xsec,
306 typedef shared_ptr<GenEvent> EventPtr;
307 typedef HepMC3::Writer Writer;
308 typedef shared_ptr<Writer> WriterPtr;
315 : runinfo(make_shared<
HepMC3::GenRunInfo>()) {
316 setNewFile(filename, ft);
323 writerPtr = make_shared<HepMC3::WriterAscii>(filename);
326 writerPtr = make_shared<HepMC3::WriterAsciiHepMC2>(filename);
331 return writerPtr !=
nullptr;
337 geneve = make_shared<HepMC3::GenEvent>(runinfo);
338 if (runinfo->weight_names().size() == 0)
339 setWeightNames(pythia.
info.weightNameVector());
345 writerPtr->write_event(*geneve);
352 if ( !fillNextEvent(pythia) )
return false;
354 return !writerPtr->failed();
379 auto xsecptr = geneve->cross_section();
381 xsecptr = make_shared<HepMC3::GenCrossSection>();
382 geneve->set_cross_section(xsecptr);
384 xsecptr->set_cross_section(xsec, xsecerr);
389 geneve->weights() = wv;
394 runinfo->set_weight_names(wnv);
399 double scale,
double xf1,
double xf2,
400 int pdf1 = 0,
int pdf2 = 0) {
401 auto pdf = make_shared<HepMC3::GenPdfInfo>();
402 pdf->set(id1, id2, x1, x2, scale, xf1, xf2, pdf1, pdf2);
403 geneve->set_pdf_info(pdf);
410 shared_ptr<HepMC3::Attribute> att = make_shared<T>(attribute);
411 geneve->add_attribute(name, att);
415 template<
class T=
double>
417 auto dAtt = HepMC3::DoubleAttribute(attribute);
418 shared_ptr<HepMC3::Attribute> att =
419 make_shared<HepMC3::DoubleAttribute>(dAtt);
420 geneve->add_attribute(name, att);
425 geneve->remove_attribute(name);
431 EventPtr geneve =
nullptr;
434 WriterPtr writerPtr =
nullptr;
437 shared_ptr<HepMC3::GenRunInfo> runinfo;
void addAttribute(const string &name, double &attribute)
Add an attribute of double type.
Definition: HepMC3.h:416
void setWeightNames(const vector< string > &wnv)
Set all weight names in the current run.
Definition: HepMC3.h:393
GenEvent & event()
Get a reference to the current GenEvent.
Definition: HepMC3.h:358
The Event class holds all info on the generated event.
Definition: Event.h:453
void setPdfInfo(int id1, int id2, double x1, double x2, double scale, double xf1, double xf2, int pdf1=0, int pdf2=0)
Update the PDF information in the current GenEvent.
Definition: HepMC3.h:398
bool fill_next_event(Pythia8::Event &pyev, GenEvent *evt, int ievnum=-1, const Pythia8::Info *pyinfo=0, Pythia8::Settings *pyset=0)
Definition: HepMC3.h:55
bool setNewFile(string filename, OutputType ft=ascii3)
Open a new external output stream.
Definition: HepMC3.h:320
Settings settings
Settings: databases of flags/modes/parms/words to control run.
Definition: Pythia.h:332
void removeAttribute(const string &name)
Remove an attribute from the current event.
Definition: HepMC3.h:424
bool writeNextEvent(Pythia &pythia)
Definition: HepMC3.h:351
Event event
The event record for the complete event history.
Definition: Pythia.h:323
void setXSec(double xsec, double xsecerr)
Set cross section information in the current GenEvent.
Definition: HepMC3.h:378
Pythia8ToHepMC3()
Constructor and destructor.
Definition: HepMC3.h:38
void writeEvent()
Write out the current GenEvent to the internal stream.
Definition: HepMC3.h:344
Pythia8ToHepMC(string filename, OutputType ft=ascii3)
Construct an object with an internal output stream.
Definition: HepMC3.h:314
EventPtr getEventPtr()
Get a pointer to the current GenEvent.
Definition: HepMC3.h:363
void set_print_inconsistency(bool b=true)
Set values for some switches.
Definition: HepMC3.h:257
Pythia8ToHepMC()
The empty constructor does not creat an aoutput stream.
Definition: HepMC3.h:311
void addAtribute(const string &name, T &attribute)
Definition: HepMC3.h:409
int size() const
Event record size.
Definition: Event.h:504
HepMC3::GenEvent GenEvent
Typedef for the version 3 specific classes used.
Definition: HepMC3.h:305
WriterPtr outputPtr()
Get a pointer to the internal stream.
Definition: HepMC3.h:373
void setWeights(const vector< double > &wv)
Update all weights in the current GenEvent.
Definition: HepMC3.h:388
bool fill_next_event(Pythia8::Pythia &pythia, GenEvent *evt, int ievnum=-1)
The recommended method to convert Pythia events into HepMC3 ones.
Definition: HepMC3.h:45
bool fill_next_event(Pythia8::Event &pyev, GenEvent &evt, int ievnum=-1, const Pythia8::Info *pyinfo=0, Pythia8::Settings *pyset=0)
Alternative method to convert Pythia events into HepMC3 ones.
Definition: HepMC3.h:52
OutputType
We can either have standard ascii output or none at all.
Definition: HepMC2.h:413
bool print_inconsistency() const
Read out values for some switches.
Definition: HepMC3.h:247
Header for classes to set beam momentum and interaction vertex spread.
Definition: Analysis.h:20
The Pythia class contains the top-level routines to generate an event.
Definition: Pythia.h:71
bool fillNextEvent(Pythia &pythia)
Definition: HepMC3.h:336
const Info & info
Public information and statistic on the generation.
Definition: Pythia.h:326
Writer & output()
Get a reference to the internal stream.
Definition: HepMC3.h:368
Definition: Settings.h:195