HepMC event record
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  */
5 #include "HepMC/LHEFAttributes.h"
6 #include "HepMC/ReaderAscii.h"
7 #include "HepMC/WriterAscii.h"
8 #include "HepMC/GenEvent.h"
9 #include "HepMC/GenParticle.h"
10 #include "HepMC/GenVertex.h"
11 #include <iomanip>
12 
13 using namespace HepMC;
14 using namespace LHEF;
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  shared_ptr<HEPRUPAttribute> hepr = 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 = 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  shared_ptr<GenRunInfo> runinfo = 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  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  shared_ptr<HEPEUPAttribute> hepe = make_shared<HEPEUPAttribute>();
71  if ( reader.outsideBlock.length() )
72  hepe->tags = 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  make_shared<DoubleAttribute>(hepe->hepeup.AQCDUP));
82  ev.add_attribute("AlphaEM",
83  make_shared<DoubleAttribute>(hepe->hepeup.AQEDUP));
84  ev.add_attribute("NUP",
85  make_shared<IntAttribute>(hepe->hepeup.NUP));
86  ev.add_attribute("IDPRUP",
87  make_shared<LongAttribute>(hepe->hepeup.IDPRUP));
88 
89  // Now add the Particles from the LHE event to HepMC
90  GenParticlePtr p1 = make_shared<GenParticle>(hepe->momentum(0),
91  hepe->hepeup.IDUP[0],
92  hepe->hepeup.ISTUP[0]);
93  GenParticlePtr p2 = make_shared<GenParticle>(hepe->momentum(1),
94  hepe->hepeup.IDUP[1],
95  hepe->hepeup.ISTUP[1]);
96  GenVertexPtr vx = 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(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  // And then we are done and can write out the GenEvent.
114  output.write_event(ev);
115 
116  }
117 
118  output.close();
119 
120  // Now we wnat to make sure we can read in the HepMC file and
121  // recreate the same info. To check this we try to reconstruct the
122  // LHC file we read in above.
123  ReaderAscii input("LHEF_example.hepmc3");
124  LHEF::Writer writer("LHEF_example_out.lhe");
125  hepr = shared_ptr<HEPRUPAttribute>();
126 
127  // The loop over all events in the HepMC file.
128  while ( true ) {
129 
130  // Read in the next event.
131  GenEvent ev(Units::GEV, Units::MM);
132  if ( !input.read_event(ev) || ev.event_number() == 0 ) break;
133 
134  // Make sure the weight names are the same.
135  if ( input.run_info()->weight_names() != weightnames ) return 2;
136 
137  // For the first event we also go in and reconstruct the HEPRUP
138  // information, and write it out to the new LHE file.
139  if ( !hepr ) {
140  hepr = ev.attribute<HEPRUPAttribute>("HEPRUP");
141 
142  // Here we also keep track of the additional non-standard info
143  // we found in the original LHE file.
144  for ( int i = 0, N = hepr->tags.size(); i < N; ++i )
145  if ( hepr->tags[i]->name != "init" )
146  hepr->tags[i]->print(writer.headerBlock());
147 
148  // This is just a test that we can access other attributes
149  // included in the GenRunInfo.
150  hepr->heprup.NPRUP =
151  int(input.run_info()->
152  attribute<FloatAttribute>("NPRUP")->value());
153 
154  // Then we write out the HEPRUP object.
155  writer.heprup = hepr->heprup;
156  writer.init();
157 
158  }
159 
160  // Now we can access the HEPEUP attribute of the current event.
161  shared_ptr<HEPEUPAttribute> hepe =
162  ev.attribute<HEPEUPAttribute>("HEPEUP");
163 
164  // Again, there may be addisional non-standard information we want
165  // to keep.
166  for ( int i = 0, N = hepe->tags.size(); i < N; ++i )
167  if ( hepe->tags[i]->name != "event" &&
168  hepe->tags[i]->name != "eventgroup" )
169  hepe->tags[i]->print(writer.eventComments());
170 
171  // This is just a test that we can access other attributes
172  // included in the GenRunInfo.
173  hepe->hepeup.AQCDUP =
174  ev.attribute<DoubleAttribute>("AlphaQCD")->value();
175  hepe->hepeup.AQEDUP =
176  ev.attribute<DoubleAttribute>("AlphaEM")->value();
177  hepe->hepeup.NUP =
178  ev.attribute<IntAttribute>("NUP")->value();
179  hepe->hepeup.IDPRUP =
180  ev.attribute<LongAttribute>("IDPRUP")->value();
181 
182  // And then we can write out the HEPEUP object.
183  writer.hepeup = hepe->hepeup;
184  writer.hepeup.heprup = &writer.heprup;
185  writer.writeEvent();
186 
187  }
188 
189 }
string description
Other information about how the tool was used in the run.
Attribute that holds a real number as a double.
Attribute that holds an Integer implemented as an int.
std::vector< LHEF::XMLTag * > tags
The parsed XML-tags.
Stores event-related information.
Class for storing data for LHEF run information.
GenEvent I/O serialization for structured text files.
Class for storing data for LHEF run information.
int main(int argc, char **argv)
Definition of template class SmartPointer.
GenEvent I/O parsing for structured text files.
Interrnal struct for keeping track of tools.
std::vector< LHEF::XMLTag * > tags
The parsed XML-tags.