HepMC3 event record library
LHEF_example_cat.cc
1/**
2 * @example LHEF_example_cat.cc
3 * @brief Basic example of use of LHEF for reading and writing LHE files
4 */
8#include "HepMC3/GenEvent.h"
10#include "HepMC3/GenVertex.h"
12#include <iomanip>
13
14using namespace HepMC3;
15
16int main(int /*argc*/, char ** /*argv*/) {
17
18 // Create Reader to read the example LHE file.
19 LHEF::Reader reader("LHEF_example.lhe");
20
21 // Create a HEPRUP attribute and initialize it from the reader.
22 std::shared_ptr<HEPRUPAttribute> hepr = std::make_shared<HEPRUPAttribute>();
23 hepr->heprup = reader.heprup;
24
25 // There may be some XML tags in the LHE file which are
26 // non-standard, but we can save them as well.
27 hepr->tags = LHEF::XMLTag::findXMLTags(reader.headerBlock + reader.initComments);
28
29 // Nowwe want to create a GenRunInfo object for the HepMC file, and
30 // we add the LHEF attribute to that.
31 std::shared_ptr<GenRunInfo> runinfo = std::make_shared<GenRunInfo>();
32 runinfo->add_attribute("HEPRUP", hepr);
33
34 // This is just a test to make sure we can add other attributes as
35 // well.
36 runinfo->add_attribute("NPRUP",
37 std::make_shared<FloatAttribute>(hepr->heprup.NPRUP));
38
39 // We want to be able to convey the different event weights to
40 // HepMC. In particular we need to add the names of the weights to
41 // the GenRunInfo object.
42 std::vector<std::string> weightnames;
43 weightnames.push_back("0"); // The first weight is always the
44 // default weight with name "0".
45 for ( int i = 0, N = hepr->heprup.weightinfo.size(); i < N; ++i )
46 weightnames.push_back(hepr->heprup.weightNameHepMC(i));
47 runinfo->set_weight_names(weightnames);
48
49 // We also want to convey the information about which generators was
50 // used to HepMC.
51 for ( int i = 0, N = hepr->heprup.generators.size(); i < N; ++i ) {
53 tool.name = hepr->heprup.generators[i].name;
54 tool.version = hepr->heprup.generators[i].version;
55 tool.description = hepr->heprup.generators[i].contents;
56 runinfo->tools().push_back(tool);
57 }
58
59 // Now we want to start reading events from the LHE file and
60 // translate them to HepMC.
61 WriterAscii output("LHEF_example.hepmc3", runinfo);
62 int neve = 0;
63 while ( reader.readEvent() ) {
64 ++neve;
65
66 // To each GenEvent we want to add an attribute corresponding to
67 // the HEPEUP. Also here there may be additional non-standard
68 // information outside the LHEF <event> tags, which we may want to
69 // add.
70 std::shared_ptr<HEPEUPAttribute> hepe = std::make_shared<HEPEUPAttribute>();
71 if ( reader.outsideBlock.length() )
72 hepe->tags = LHEF:: XMLTag::findXMLTags(reader.outsideBlock);
73 hepe->hepeup = reader.hepeup;
74 GenEvent ev(runinfo, Units::GEV, Units::MM);
75 ev.set_event_number(neve);
76
77 // This is just a text to check that we can add additional
78 // attributes to each event.
79 ev.add_attribute("HEPEUP", hepe);
80 ev.add_attribute("AlphaQCD",
81 std:: make_shared<DoubleAttribute>(hepe->hepeup.AQCDUP));
82 ev.add_attribute("AlphaEM",
83 std::make_shared<DoubleAttribute>(hepe->hepeup.AQEDUP));
84 ev.add_attribute("NUP",
85 std::make_shared<IntAttribute>(hepe->hepeup.NUP));
86 ev.add_attribute("IDPRUP",
87 std::make_shared<LongAttribute>(hepe->hepeup.IDPRUP));
88
89 // Now add the Particles from the LHE event to HepMC
90 GenParticlePtr p1 = std::make_shared<GenParticle>(hepe->momentum(0),
91 hepe->hepeup.IDUP[0],
92 hepe->hepeup.ISTUP[0]);
93 GenParticlePtr p2 = std::make_shared<GenParticle>(hepe->momentum(1),
94 hepe->hepeup.IDUP[1],
95 hepe->hepeup.ISTUP[1]);
96 GenVertexPtr vx = std::make_shared<GenVertex>();
97 vx->add_particle_in(p1);
98 vx->add_particle_in(p2);
99
100 for ( int i = 2; i < hepe->hepeup.NUP; ++i )
101 vx->add_particle_out(std::make_shared<GenParticle>
102 (hepe->momentum(i),
103 hepe->hepeup.IDUP[i],
104 hepe->hepeup.ISTUP[i]));
105 ev.add_vertex(vx);
106
107 // And we also want to add the weights.
108 std::vector<double> wts;
109 for ( int i = 0, N = hepe->hepeup.weights.size(); i < N; ++i )
110 wts.push_back(hepe->hepeup.weights[i].first);
111 ev.weights() = wts;
112
113 // Let's see if we can associate p1 and p2.
114 ev.add_attribute("OtherIncoming",
115 std::make_shared<AssociatedParticle>(p2), p1->id());
116
117
118 // And then we are done and can write out the GenEvent.
119 output.write_event(ev);
120
121 }
122
123 output.close();
124
125 // Now we wnat to make sure we can read in the HepMC file and
126 // recreate the same info. To check this we try to reconstruct the
127 // LHC file we read in above.
128 ReaderAscii input("LHEF_example.hepmc3");
129 LHEF::Writer writer("LHEF_example_out.lhe");
130 hepr = std::shared_ptr<HEPRUPAttribute>();
131
132 // The loop over all events in the HepMC file.
133 while ( true ) {
134
135 // Read in the next event.
136 GenEvent ev(Units::GEV, Units::MM);
137 if ( !input.read_event(ev) || ev.event_number() == 0 ) break;
138
139 // Check that the first incoming particle still refers to the second.
140 std::shared_ptr<AssociatedParticle> assoc =
141 ev.attribute<AssociatedParticle>("OtherIncoming", 1);
142 if ( !assoc || !assoc->associated() ||
143 assoc->associated() != ev.particles()[1] ) return 3;
144
145 // Make sure the weight names are the same.
146 if ( input.run_info()->weight_names() != weightnames ) return 2;
147
148 // For the first event we also go in and reconstruct the HEPRUP
149 // information, and write it out to the new LHE file.
150 if ( !hepr ) {
151 hepr = ev.attribute<HEPRUPAttribute>("HEPRUP");
152
153 // Here we also keep track of the additional non-standard info
154 // we found in the original LHE file.
155 for ( int i = 0, N = hepr->tags.size(); i < N; ++i )
156 if ( hepr->tags[i]->name != "init" )
157 hepr->tags[i]->print(writer.headerBlock());
158
159 // This is just a test that we can access other attributes
160 // included in the GenRunInfo.
161 hepr->heprup.NPRUP =
162 int(input.run_info()->
163 attribute<FloatAttribute>("NPRUP")->value());
164
165 // Then we write out the HEPRUP object.
166 writer.heprup = hepr->heprup;
167 if ( writer.heprup.eventfiles.size() >= 2 ) {
168 writer.heprup.eventfiles[0].filename = "LHEF_example_1_out.plhe";
169 writer.heprup.eventfiles[1].filename = "LHEF_example_2_out.plhe";
170 }
171 writer.init();
172
173 }
174
175 // Now we can access the HEPEUP attribute of the current event.
176 std::shared_ptr<HEPEUPAttribute> hepe =
177 ev.attribute<HEPEUPAttribute>("HEPEUP");
178
179 // Again, there may be addisional non-standard information we want
180 // to keep.
181 for ( int i = 0, N = hepe->tags.size(); i < N; ++i )
182 if ( hepe->tags[i]->name != "event" &&
183 hepe->tags[i]->name != "eventgroup" )
184 hepe->tags[i]->print(writer.eventComments());
185
186 // This is just a test that we can access other attributes
187 // included in the GenRunInfo.
188 hepe->hepeup.AQCDUP =
189 ev.attribute<DoubleAttribute>("AlphaQCD")->value();
190 hepe->hepeup.AQEDUP =
191 ev.attribute<DoubleAttribute>("AlphaEM")->value();
192 hepe->hepeup.NUP =
193 ev.attribute<IntAttribute>("NUP")->value();
194 hepe->hepeup.IDPRUP =
195 ev.attribute<LongAttribute>("IDPRUP")->value();
196
197 // And then we can write out the HEPEUP object.
198 writer.hepeup = hepe->hepeup;
199 writer.hepeup.heprup = &writer.heprup;
200 writer.writeEvent();
201
202 }
203
204}
Definition of class AssociatedParticle,.
Definition of class GenEvent.
Definition of class GenParticle.
Definition of class GenVertex.
Definition of class HEPRUPAttribute and class HEPEUAttribute.
Definition of class ReaderAscii.
Definition of class WriterAscii.
Attribute class allowing eg. a GenParticle to refer to another GenParticle.
Attribute that holds a real number as a double.
Definition: Attribute.h:243
Stores event-related information.
Definition: GenEvent.h:41
Class for storing data for LHEF run information.
std::vector< LHEF::XMLTag * > tags
The parsed XML-tags.
Class for storing data for LHEF run information.
std::vector< LHEF::XMLTag * > tags
The parsed XML-tags.
Attribute that holds an Integer implemented as an int.
Definition: Attribute.h:159
Attribute that holds an Integer implemented as an int.
Definition: Attribute.h:200
GenEvent I/O parsing for structured text files.
Definition: ReaderAscii.h:29
GenEvent I/O serialization for structured text files.
Definition: WriterAscii.h:25
HepMC3 main namespace.
int main(int argc, char **argv)
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