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.
53 m_hepr->tags = LHEF::XMLTag::findXMLTags(m_reader->headerBlock + m_reader->initComments);
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 // We want to be able to convey the different event weights to
90 // HepMC. In particular we need to add the names of the weights to
91 // the GenRunInfo object.
92
93 std::vector<std::string> weightnames;
94 size_t N = m_hepr->heprup.weightinfo.size();
95 weightnames.reserve(N);
96 for ( size_t i = 0; i < N; ++i ) weightnames.emplace_back(m_hepr->heprup.weightNameHepMC(i));
97 if (nweights == 0) {
98 HEPMC3_WARNING_LEVEL(600,"ReaderLHEF::init: no weights in the LHEF file.")
99 nweights=1;
100 }
101 if (weightnames.empty()) {
102 HEPMC3_WARNING_LEVEL(600,"ReaderLHEF::init: empty weightinfo in the LHEF file.")
103 for ( size_t i = weightnames.size(); i < nweights; ++i ) weightnames.emplace_back(std::to_string(i));
104 }
105 run_info()->set_weight_names(weightnames);
106
107 // We also want to convey the information about which generators was
108 // used.
109 for ( int i = 0, NN = m_hepr->heprup.generators.size(); i < NN; ++i )
110 {
112 tool.name = m_hepr->heprup.generators[i].name;
113 tool.version = m_hepr->heprup.generators[i].version;
114 tool.description = m_hepr->heprup.generators[i].contents;
115 run_info()->tools().emplace_back(tool);
116 }
117}
118/// @brief Destructor
120
122{
123 if (!m_storage.empty())
124 {
125 ev = m_storage.front();
126 m_storage.pop_front();
127 return true;
128 }
129 bool read_result = m_reader->readEvent();
130 if (!read_result) {
131 return false;
132 }
133 // To each GenEvent we want to add an attribute corresponding to
134 // the HEPEUP. Also here there may be additional non-standard
135 // information outside the LHEF <event> tags, which we may want to
136 // add.
137 std::shared_ptr<HEPEUPAttribute> hepe = std::make_shared<HEPEUPAttribute>();
138 if ( m_reader->outsideBlock.length() ) {
139 hepe->tags = LHEF::XMLTag::findXMLTags(m_reader->outsideBlock);
140 }
141 hepe->hepeup = m_reader->hepeup;
142 std::vector<LHEF::HEPEUP*> input;
143 if (!m_reader->hepeup.subevents.empty()) { input.insert(input.end(), hepe->hepeup.subevents.begin(), hepe->hepeup.subevents.end()); }
144 else { input.emplace_back(&m_reader->hepeup);}
145 int first_group_event = m_neve;
146 m_neve++;
147 for (auto* ahepeup: input)
148 {
149 GenEvent evt;
150 evt.set_event_number(first_group_event);
151 evt.add_attribute("AlphaQCD", std::make_shared<DoubleAttribute>(ahepeup->AQCDUP));
152 evt.add_attribute("AlphaEM", std::make_shared<DoubleAttribute>(ahepeup->AQEDUP));
153 evt.add_attribute("NUP", std::make_shared<IntAttribute>(ahepeup->NUP));
154 evt.add_attribute("IDPRUP", std::make_shared<LongAttribute>(ahepeup->IDPRUP));
155 // Now add the Particles from the LHE event to HepMC
156 std::vector<GenParticlePtr> particles;
157 if (ahepeup->NUP>0) particles.reserve(ahepeup->NUP);
158 std::map< std::pair<int, int>, GenVertexPtr> vertices;
159 for ( int i = 0; i < ahepeup->NUP; ++i )
160 {
161 FourVector mom((ahepeup->PUP)[i][0], (ahepeup->PUP)[i][1], (ahepeup->PUP)[i][2], (ahepeup->PUP)[i][3]);
162 particles.emplace_back(std::make_shared<GenParticle>(mom, ahepeup->IDUP[i], ahepeup->ISTUP[i]));
163 if ( i < 2 ) continue;
164 std::pair<int, int> vertex_index(ahepeup->MOTHUP[i].first, ahepeup->MOTHUP[i].second);
165 if (vertices.count(vertex_index) == 0) vertices[vertex_index] = std::make_shared<GenVertex>();
166 vertices[vertex_index]->add_particle_out(particles.back());
167 }
168 for ( auto& v: vertices )
169 {
170 std::pair<int, int> vertex_index = v.first;
171 GenVertexPtr vertex = v.second;
172 for (int i = vertex_index.first-1; i < vertex_index.second; ++i) {
173 if ( i >= 0 && i < static_cast<int>(particles.size())) {
174 vertex->add_particle_in(particles[i]);
175 }
176 }
177 }
178 std::pair<int, int> vertex_index(0, 0);
179 if (vertices.count(vertex_index) == 0) vertices[vertex_index] = std::make_shared<GenVertex>();
180 for (size_t i = 0; i < particles.size(); ++i) {
181 if (!particles[i]->end_vertex() && !particles[i]->production_vertex())
182 {
183 if ( i < 2 ) { vertices[vertex_index]->add_particle_in(particles[i]); }
184 else { vertices[vertex_index]->add_particle_out(particles[i]);}
185 }
186 }
187 for ( auto& v: vertices ) {
188 if (!v.second->particles_out().empty() && !v.second->particles_in().empty()) {
189 evt.add_vertex(v.second);
190 }
191 }
192 if (particles.size() > 1)
193 {
194 particles[0]->set_status(4);
195 particles[1]->set_status(4);
196 evt.set_beam_particles(particles[0], particles[1]);
197 }
198 // And we also want to add the weights.
199
200
201 std::vector<double> wts;
202 size_t N = ahepeup->weights.size();
203 wts.reserve(N);
204 for ( size_t i = 0; i < N; ++i )
205 {
206 wts.emplace_back(ahepeup->weights[i].first);
207 }
208 evt.weights() = wts;
209 /// Cross-section
210 std::shared_ptr<GenCrossSection> xs = std::make_shared<GenCrossSection>();
211 evt.add_attribute("GenCrossSection", xs);
212 /// In this order the number of cross-sections will match the number of weights
213 xs->set_cross_section(m_hepr->heprup.XSECUP, m_hepr->heprup.XERRUP);
214 /// PDF info
215 std::shared_ptr<GenPdfInfo> pi = std::make_shared<GenPdfInfo>();
216 pi->parton_id[0] = particles[0]->pdg_id();
217 pi->parton_id[1] = particles[1]->pdg_id();
218 pi->x[0] = std::abs(particles[0]->momentum().pz()/m_hepr->heprup.EBMUP.first);
219 pi->x[1] = std::abs(particles[1]->momentum().pz()/m_hepr->heprup.EBMUP.second);
220 pi->scale = ahepeup->pdfinfo.scale;
221 pi->xf[0] = 1;
222 pi->xf[1] = 1;
223 /*
224 pi->parton_id[0] = ahepeup->pdfinfo.p1;
225 pi->parton_id[1] = ahepeup->pdfinfo.p2;
226 pi->x[0] = ahepeup->pdfinfo.x1;
227 pi->x[1] = ahepeup->pdfinfo.x2;
228 pi->scale = ahepeup->pdfinfo.scale;
229 pi->xf[0] = ahepeup->pdfinfo.xf1;
230 pi->xf[1] = ahepeup->pdfinfo.xf2;
231 */
232 pi->pdf_id[0] = m_hepr->heprup.PDFSUP.first;
233 pi->pdf_id[1] = m_hepr->heprup.PDFSUP.second;
234 evt.add_attribute("GenPdfInfo", pi);
235 m_storage.emplace_back(evt);
236 }
237 ev = m_storage.front();
238 m_storage.pop_front();
239 return true;
240}
241/// @brief Return status of the stream
242bool ReaderLHEF::failed() { return ((m_reader->initfile_rdstate()!=std::ifstream::goodbit)||(m_reader->file_rdstate()!=std::ifstream::goodbit)) && (m_storage.empty()); }
243
244/// @brief Close file stream
246} // namespace HepMC3
#define HEPMC3_WARNING_LEVEL(LEVEL, MESSAGE)
Macro for printing HEPMC3_HEPMC3_WARNING messages.
Definition Errors.h:34
Definition of class ReaderLHEF.
Generic 4-vector.
Definition FourVector.h:36
Stores event-related information.
Definition GenEvent.h:47
void add_vertex(GenVertexPtr v)
Add vertex.
Definition GenEvent.cc:99
void set_event_number(const int &num)
Set event number.
Definition GenEvent.h:157
void add_attribute(const std::string &name, const std::shared_ptr< Attribute > &att, const int &id=0)
Definition GenEvent.cc:797
const std::vector< double > & weights() const
Get event weight values as a vector.
Definition GenEvent.h:105
void clear()
Remove contents of this event.
Definition GenEvent.cc:592
void set_beam_particles(GenParticlePtr p1, GenParticlePtr p2)
Set incoming beam particles.
Definition GenEvent.cc:753
~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
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=nullptr)
Definition LHEF.h:200