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  */
6 #include "HepMC3/ReaderAscii.h"
7 #include "HepMC3/WriterAscii.h"
8 #include "HepMC3/GenEvent.h"
9 #include "HepMC3/GenParticle.h"
10 #include "HepMC3/GenVertex.h"
12 #include <iomanip>
13 
14 using namespace HepMC3;
15 
16 int 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 HEPRUPAttribute and class HEPEUAttribute.
std::string version
The version of the tool.
Definition: GenRunInfo.h:44
HepMC3 main namespace.
static std::vector< XMLTag * > findXMLTags(std::string str, std::string *leftover=0)
Definition: LHEF.h:198
GenEvent I/O parsing for structured text files.
Definition: ReaderAscii.h:29
Definition of class GenParticle.
Class for storing data for LHEF run information.
Definition of class GenVertex.
std::string description
Other information about how the tool was used in the run.
Definition: GenRunInfo.h:48
Definition of class WriterAscii.
Class for storing data for LHEF run information.
std::vector< LHEF::XMLTag * > tags
The parsed XML-tags.
Stores event-related information.
Definition: GenEvent.h:41
Attribute that holds a real number as a double.
Definition: Attribute.h:243
Interrnal struct for keeping track of tools.
Definition: GenRunInfo.h:38
Definition of class ReaderAscii.
int main(int argc, char **argv)
std::vector< LHEF::XMLTag * > tags
The parsed XML-tags.
Attribute that holds an Integer implemented as an int.
Definition: Attribute.h:200
std::string name
The name of the tool.
Definition: GenRunInfo.h:41
Definition of class GenEvent.
Definition of class AssociatedParticle,.
Attribute class allowing eg. a GenParticle to refer to another GenParticle.
Attribute that holds an Integer implemented as an int.
Definition: Attribute.h:159
GenEvent I/O serialization for structured text files.
Definition: WriterAscii.h:25