HepMC3 event record library
ReaderLHEF.cc
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of HepMC
4// Copyright (C) 2014-2023 The HepMC collaboration (see AUTHORS for details)
5//
6/**
7 * @file ReaderLHEF.cc
8 * @brief Implementation of \b class ReaderLHEF
9 *
10 */
11#include "HepMC3/ReaderLHEF.h"
12namespace HepMC3
13{
14ReaderLHEF::ReaderLHEF(const std::string& filename)
15{
16 m_reader = std::make_shared<LHEF::Reader>(filename);
17 init();
18}
19ReaderLHEF::ReaderLHEF(std::istream & stream)
20{
21 m_reader = std::make_shared<LHEF::Reader>(stream);
22 init();
23}
24
25ReaderLHEF::ReaderLHEF(std::shared_ptr<std::istream> s_stream)
26 : m_shared_stream(s_stream)
27{
28 m_reader = std::make_shared<LHEF::Reader>(*(m_shared_stream.get()));
29 init();
30}
31
32bool ReaderLHEF::skip(const int n)
33{
34 GenEvent evt;
35 for (int nn = n; nn > 0; --nn)
36 {
37 if (!read_event(evt)) return false;
38 evt.clear();
39 }
40 return !failed();
41}
42
43
45{
46 m_neve = 0;
47 m_failed = false;
48 // Create a HEPRUP attribute and initialize it from the reader.
49 m_hepr = std::make_shared<HEPRUPAttribute>();
50 m_hepr->heprup = m_reader->heprup;
51 // There may be some XML tags in the LHE file which are
52 // non-standard, but we can save them as well.
54 // This code is ugly and should be replaced.
55 size_t nweights = 0;
56 for (auto* t1: m_hepr->tags) {
57 if (t1->name != "header") continue;
58 for (auto* t2: t1->tags) {
59 if (t2->name != "initrwgt") continue;
60 for (auto* t3: t2->tags) {
61 if (t3->name != "weightgroup") continue;
62 for (auto* t4: t3->tags) if (t4->name == "weight") nweights++;
63 //We can have multiple weight groups
64 }
65 break;
66 }
67 break;
68 }
69 //
70 // Now we want to create a GenRunInfo object for the HepMC file, and
71 // we add the LHEF attribute to that.
72 set_run_info(std::make_shared<GenRunInfo>());
73 run_info()->add_attribute("HEPRUP", m_hepr);
74
75 // Other attributes
76 run_info()->add_attribute("NPRUP",std::make_shared<IntAttribute>(m_hepr->heprup.NPRUP));
77 run_info()->add_attribute("XSECUP",std::make_shared<VectorDoubleAttribute>(m_hepr->heprup.XSECUP));
78 run_info()->add_attribute("XERRUP",std::make_shared<VectorDoubleAttribute>(m_hepr->heprup.XERRUP));
79 run_info()->add_attribute("LPRUP",std::make_shared<VectorIntAttribute>(m_hepr->heprup.LPRUP));
80 run_info()->add_attribute("PDFGUP1",std::make_shared<IntAttribute>(m_hepr->heprup.PDFGUP.first));
81 run_info()->add_attribute("PDFGUP2",std::make_shared<IntAttribute>(m_hepr->heprup.PDFGUP.second));
82 run_info()->add_attribute("PDFSUP1",std::make_shared<IntAttribute>(m_hepr->heprup.PDFSUP.first));
83 run_info()->add_attribute("PDFSUP2",std::make_shared<IntAttribute>(m_hepr->heprup.PDFSUP.second));
84 run_info()->add_attribute("IDBMUP1",std::make_shared<IntAttribute>(m_hepr->heprup.IDBMUP.first));
85 run_info()->add_attribute("IDBMUP2",std::make_shared<IntAttribute>(m_hepr->heprup.IDBMUP.second));
86 run_info()->add_attribute("EBMUP1",std::make_shared<DoubleAttribute>(m_hepr->heprup.EBMUP.first));
87 run_info()->add_attribute("EBMUP2",std::make_shared<DoubleAttribute>(m_hepr->heprup.EBMUP.second));
88
89
90
91
92
93
94 // We want to be able to convey the different event weights to
95 // HepMC. In particular we need to add the names of the weights to
96 // the GenRunInfo object.
97
98 std::vector<std::string> weightnames;
99 size_t N = m_hepr->heprup.weightinfo.size();
100 weightnames.reserve(N);
101 for ( size_t i = 0; i < N; ++i ) weightnames.emplace_back(m_hepr->heprup.weightNameHepMC(i));
102 if (nweights == 0) {
103 HEPMC3_WARNING("ReaderLHEF::init: no weights in the LHEF file.")
104 nweights=1;
105 }
106 if (weightnames.empty()) {
107 HEPMC3_WARNING("ReaderLHEF::init: empty weightinfo in the LHEF file.")
108 for ( size_t i = weightnames.size(); i < nweights; ++i ) weightnames.emplace_back(std::to_string(i));
109 }
110 run_info()->set_weight_names(weightnames);
111
112 // We also want to convey the information about which generators was
113 // used.
114 for ( int i = 0, N = m_hepr->heprup.generators.size(); i < N; ++i )
115 {
117 tool.name = m_hepr->heprup.generators[i].name;
118 tool.version = m_hepr->heprup.generators[i].version;
119 tool.description = m_hepr->heprup.generators[i].contents;
120 run_info()->tools().emplace_back(tool);
121 }
122}
123/// @brief Destructor
125
127{
128 if (!m_storage.empty())
129 {
130 ev = m_storage.front();
131 m_storage.pop_front();
132 return true;
133 }
134 bool read_result = m_reader->readEvent();
135 if (!read_result) {
136 return false;
137 }
138 // To each GenEvent we want to add an attribute corresponding to
139 // the HEPEUP. Also here there may be additional non-standard
140 // information outside the LHEF <event> tags, which we may want to
141 // add.
142 std::shared_ptr<HEPEUPAttribute> hepe = std::make_shared<HEPEUPAttribute>();
143 if ( m_reader->outsideBlock.length() ) {
145 }
146 hepe->hepeup = m_reader->hepeup;
147 std::vector<LHEF::HEPEUP*> input;
148 if (!m_reader->hepeup.subevents.empty()) { input.insert(input.end(), hepe->hepeup.subevents.begin(), hepe->hepeup.subevents.end()); }
149 else { input.emplace_back(&m_reader->hepeup);}
150 int first_group_event = m_neve;
151 m_neve++;
152 for (auto* ahepeup: input)
153 {
154 GenEvent evt;
155 evt.set_event_number(first_group_event);
156 evt.add_attribute("AlphaQCD", std::make_shared<DoubleAttribute>(ahepeup->AQCDUP));
157 evt.add_attribute("AlphaEM", std::make_shared<DoubleAttribute>(ahepeup->AQEDUP));
158 evt.add_attribute("NUP", std::make_shared<IntAttribute>(ahepeup->NUP));
159 evt.add_attribute("IDPRUP", std::make_shared<LongAttribute>(ahepeup->IDPRUP));
160 // Now add the Particles from the LHE event to HepMC
161 std::vector<GenParticlePtr> particles;
162 if (ahepeup->NUP>0) particles.reserve(ahepeup->NUP);
163 std::map< std::pair<int, int>, GenVertexPtr> vertices;
164 for ( int i = 0; i < ahepeup->NUP; ++i )
165 {
166 FourVector mom((ahepeup->PUP)[i][0], (ahepeup->PUP)[i][1], (ahepeup->PUP)[i][2], (ahepeup->PUP)[i][3]);
167 particles.emplace_back(std::make_shared<GenParticle>(mom, ahepeup->IDUP[i], ahepeup->ISTUP[i]));
168 if ( i < 2 ) continue;
169 std::pair<int, int> vertex_index(ahepeup->MOTHUP[i].first, ahepeup->MOTHUP[i].second);
170 if (vertices.count(vertex_index) == 0) vertices[vertex_index] = std::make_shared<GenVertex>();
171 vertices[vertex_index]->add_particle_out(particles.back());
172 }
173 for ( auto& v: vertices )
174 {
175 std::pair<int, int> vertex_index = v.first;
176 GenVertexPtr vertex = v.second;
177 for (int i = vertex_index.first-1; i < vertex_index.second; ++i) {
178 if ( i >= 0 && i < (int)particles.size()) {
179 vertex->add_particle_in(particles[i]);
180 }
181 }
182 }
183 std::pair<int, int> vertex_index(0, 0);
184 if (vertices.count(vertex_index) == 0) vertices[vertex_index] = std::make_shared<GenVertex>();
185 for (size_t i = 0; i < particles.size(); ++i) {
186 if (!particles[i]->end_vertex() && !particles[i]->production_vertex())
187 {
188 if ( i < 2 ) { vertices[vertex_index]->add_particle_in(particles[i]); }
189 else { vertices[vertex_index]->add_particle_out(particles[i]);}
190 }
191 }
192 for ( auto v: vertices ) {
193 if (!v.second->particles_out().empty() && !v.second->particles_in().empty()) {
194 evt.add_vertex(v.second);
195 }
196 }
197 if (particles.size() > 1)
198 {
199 particles[0]->set_status(4);
200 particles[1]->set_status(4);
201 evt.set_beam_particles(particles[0], particles[1]);
202 }
203 // And we also want to add the weights.
204
205
206 std::vector<double> wts;
207 size_t N = ahepeup->weights.size();
208 wts.reserve(N);
209 for ( size_t i = 0; i < N; ++i )
210 {
211 wts.emplace_back(ahepeup->weights[i].first);
212 }
213 evt.weights() = wts;
214 /// Cross-section
215 std::shared_ptr<GenCrossSection> xs = std::make_shared<GenCrossSection>();
216 evt.add_attribute("GenCrossSection", xs);
217 /// In this order the number of cross-sections will match the number of weights
218 xs->set_cross_section(m_hepr->heprup.XSECUP, m_hepr->heprup.XERRUP);
219 /// PDF info
220 std::shared_ptr<GenPdfInfo> pi = std::make_shared<GenPdfInfo>();
221 pi->parton_id[0] = particles[0]->pdg_id();
222 pi->parton_id[1] = particles[1]->pdg_id();
223 pi->x[0] = std::abs(particles[0]->momentum().pz()/m_hepr->heprup.EBMUP.first);
224 pi->x[1] = std::abs(particles[1]->momentum().pz()/m_hepr->heprup.EBMUP.second);
225 pi->scale = ahepeup->pdfinfo.scale;
226 pi->xf[0] = 1;
227 pi->xf[1] = 1;
228 /*
229 pi->parton_id[0] = ahepeup->pdfinfo.p1;
230 pi->parton_id[1] = ahepeup->pdfinfo.p2;
231 pi->x[0] = ahepeup->pdfinfo.x1;
232 pi->x[1] = ahepeup->pdfinfo.x2;
233 pi->scale = ahepeup->pdfinfo.scale;
234 pi->xf[0] = ahepeup->pdfinfo.xf1;
235 pi->xf[1] = ahepeup->pdfinfo.xf2;
236 */
237 pi->pdf_id[0] = m_hepr->heprup.PDFSUP.first;
238 pi->pdf_id[1] = m_hepr->heprup.PDFSUP.second;
239 evt.add_attribute("GenPdfInfo", pi);
240 m_storage.emplace_back(evt);
241 }
242 ev = m_storage.front();
243 m_storage.pop_front();
244 return true;
245}
246/// @brief Return status of the stream
247bool ReaderLHEF::failed() { return ((m_reader->initfile_rdstate()!=std::ifstream::goodbit)||(m_reader->file_rdstate()!=std::ifstream::goodbit)) && (m_storage.empty()); }
248
249/// @brief Close file stream
251} // namespace HepMC3
#define HEPMC3_WARNING(MESSAGE)
Macro for printing HEPMC3_HEPMC3_WARNING messages.
Definition Errors.h:27
Definition of class ReaderLHEF.
Generic 4-vector.
Definition FourVector.h:36
Stores event-related information.
Definition GenEvent.h:41
void add_vertex(GenVertexPtr v)
Add vertex.
Definition GenEvent.cc:97
void set_event_number(const int &num)
Set event number.
Definition GenEvent.h:150
void add_attribute(const std::string &name, const std::shared_ptr< Attribute > &att, const int &id=0)
Definition GenEvent.cc:810
const std::vector< double > & weights() const
Get event weight values as a vector.
Definition GenEvent.h:98
void clear()
Remove contents of this event.
Definition GenEvent.cc:598
void set_beam_particles(GenParticlePtr p1, GenParticlePtr p2)
Set incoming beam particles.
Definition GenEvent.cc:766
~ReaderLHEF()
Destructor.
void init()
Init helper.
Definition ReaderLHEF.cc:44
bool failed() override
State.
bool read_event(GenEvent &ev) override
Reading event.
bool skip(const int) override
skip events
Definition ReaderLHEF.cc:32
std::shared_ptr< HEPRUPAttribute > m_hepr
Holder of attributes.
Definition ReaderLHEF.h:57
void close() override
Close.
bool m_failed
State of reader.
Definition ReaderLHEF.h:59
std::deque< GenEvent > m_storage
storage used for subevents.
Definition ReaderLHEF.h:60
ReaderLHEF(std::istream &)
The ctor to read from stream.
Definition ReaderLHEF.cc:19
std::shared_ptr< std::istream > m_shared_stream
Holds temporary stream.
Definition ReaderLHEF.h:55
std::shared_ptr< LHEF::Reader > m_reader
The actual reader.
Definition ReaderLHEF.h:56
int m_neve
Event counter.
Definition ReaderLHEF.h:58
virtual void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
Definition Reader.h:56
virtual std::shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
Definition Reader.h:44
EventGroup subevents
Definition LHEF.h:2688
std::string outsideBlock
Definition LHEF.h:3011
std::ios_base::iostate file_rdstate() const
Definition LHEF.h:3000
HEPEUP hepeup
Definition LHEF.h:3031
HEPRUP heprup
Definition LHEF.h:3021
bool readEvent()
Definition LHEF.h:2868
std::string headerBlock
Definition LHEF.h:3016
std::string initComments
Definition LHEF.h:3026
std::ios_base::iostate initfile_rdstate() const
Definition LHEF.h:2996
HepMC3 main namespace.
Interrnal struct for keeping track of tools.
Definition GenRunInfo.h:38
std::string description
Other information about how the tool was used in the run.
Definition GenRunInfo.h:48
std::string version
The version of the tool.
Definition GenRunInfo.h:44
std::string name
The name of the tool.
Definition GenRunInfo.h:41
static std::vector< XMLTag * > findXMLTags(std::string str, std::string *leftover=0)
Definition LHEF.h:198