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