Belle II Software prerelease-11-00-00a
LHEReader.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <framework/gearbox/Unit.h>
10#include <framework/gearbox/Const.h>
11#include <framework/logging/Logger.h>
12#include <generators/lhe/LHEReader.h>
13#include <mdst/dataobjects/MCParticle.h>
14
15#include <string>
16#include <boost/lexical_cast.hpp>
17#include <boost/algorithm/string.hpp>
18#include <boost/format.hpp>
19
20using namespace std;
21using namespace Belle2;
22
23const boost::char_separator<char> LHEReader::sep(",; \t");
24
25void LHEReader::open(const string& filename)
26{
27 m_lineNr = 0;
28 m_input.open(filename.c_str());
29 if (!m_input) throw(LHECouldNotOpenFileError() << filename);
30}
31
32int LHEReader::getEvent(MCParticleGraph& graph, double& eventWeight)
33{
34 int nparticles = readEventHeader(eventWeight);
35 if (nparticles <= 0) {
36 throw (LHEEmptyEventError() << m_lineNr << nparticles);
37 }
38
39 int first = graph.size();
40 //Make list of particles
41 for (int i = 0; i < nparticles; i++) {
42 graph.addParticle();
43 }
44
45 //Read particles from file
46 for (int i = 0; i < nparticles; ++i) {
47 MCParticleGraph::GraphParticle& p = graph[first + i];
48 int mother = readParticle(p);
49
50 // add the mother
51 if (mother > 0) {
52 MCParticleGraph::GraphParticle* q = &graph[mother - 1];
53 p.comesFrom(*q);
54 }
55
56 // if positron goes to positive z-direction, we have to rotate along y-axis by 180deg
57 if (m_wrongSignPz) {
58 ROOT::Math::PxPyPzEVector p4 = p.get4Vector();
59 p4.SetPz(-1.0 * p4.Pz());
60 p4.SetPx(-1.0 * p4.Px());
61 p.set4Vector(p4);
62 }
63
64 // initial 2 (e+/e-), virtual 3 (Z/gamma*)
65 // check if particle should be made virtual according to steering options:
66 if (i < m_indexVirtual && i >= m_indexInitial)
67 p.addStatus(MCParticle::c_IsVirtual);
68
69 if (i < m_indexInitial)
70 p.addStatus(MCParticle::c_Initial);
71
72 if (m_indexVirtual < m_indexInitial) B2WARNING("IsVirtual particle requested but is overwritten by Initial");
73
74 }
75 return -1;
76}
77
78
80{
81 double weight;
82 for (int i = 0; i < n; i++) {
83 int nparticles = readEventHeader(weight);
84 if (nparticles < 0) return false;
85 for (int j = 0; j < nparticles; j++) getLine();
86 }
87 return true;
88}
89
90int LHEReader::countEvents(const std::string& filename)
91{
92 std::ifstream input(filename.c_str());
93 if (!input) throw(LHECouldNotOpenFileError() << filename);
94
95 int count = 0;
96 int lineNr = 0;
97 std::string line;
98
99 auto countEvent = [&]() {
100 count++;
101 while (std::getline(input, line)) {
102 lineNr++;
103 boost::trim(line);
104 if (line == "</event>" || line.empty()) break;
105 }
106 };
107
108 while (std::getline(input, line)) {
109 lineNr++;
110 boost::trim(line);
111 if (line == "<event>") {
112 countEvent();
113 }
114 }
115
116 B2INFO("Counted " << count << " events in " << filename << ".");
117 return count;
118}
119
120//===================================================================
121// Protected methods
122//===================================================================
123
125{
126 std::string line;
127 do {
128 getline(m_input, line);
129 m_lineNr++;
130 size_t commentPos = line.find_first_of('#');
131 if (commentPos != string::npos) {
132 line = line.substr(0, commentPos);
133 }
134 boost::trim(line);
135
136 } while (line == "" && !m_input.eof());
137
138 return line;
139}
140
141int LHEReader::readEventHeader(double& eventWeight)
142{
143
144 // Search for next <event>
145 std::string line2;
146 do {
147 getline(m_input, line2);
148 m_lineNr++;
149 size_t commentPos = line2.find_first_of('#');
150 if (commentPos != string::npos) {
151 line2 = line2.substr(0, commentPos);
152 }
153 boost::trim(line2);
154
155 } while (line2 != "<event>" && !m_input.eof());
156
157 //Get number of particles from file
158 int nparticles = -1;
159 string line = getLine();
160
161 if (line == "" || m_input.eof()) return -1;
162
163 vector<double> fields;
164 fields.reserve(15);
165
166 tokenizer tokens(line, sep);
167 int index(0);
168
169 for (const string& tok : tokens) {
170 ++index;
171 try {
172 fields.push_back(boost::lexical_cast<double>(tok));
173 } catch (boost::bad_lexical_cast& e) {
174 throw (LHEConvertFieldError() << m_lineNr << index << tok);
175 }
176 }
177
178 if (fields.size() < 3) {
179 nparticles = static_cast<int>(fields[0]);
180 eventWeight = 1.0;
181 } else {
182 nparticles = static_cast<int>(fields[0]);
183 eventWeight = static_cast<double>(fields[2]);
184 }
185 return nparticles;
186}
187
189{
190 int mother = -1;
191
192 string line = getLine();
193 vector<double> fields;
194 fields.reserve(15);
195
196 tokenizer tokens(line, sep);
197 int index(0);
198
199 for (const string& tok : tokens) {
200 ++index;
201 try {
202 fields.push_back(boost::lexical_cast<double>(tok));
203 } catch (boost::bad_lexical_cast& e) {
204 throw (LHEConvertFieldError() << m_lineNr << index << tok);
205 }
206 }
207
208 switch (fields.size()) {
209 case 13:
210 particle.addStatus(MCParticle::c_PrimaryParticle);
211 particle.setPDG(static_cast<int>(fields[0]));
212 mother = static_cast<int>(fields[2]);
213 particle.setMomentum(ROOT::Math::XYZVector(fields[6], fields[7], fields[8]));
214 particle.setEnergy(fields[9]);
215 particle.setMass(fields[10]);
216 break;
217 default:
218 throw (LHEParticleFormatError() << m_lineNr << fields.size());
219 }
220
221 return mother;
222}
int readParticle(MCParticleGraph::GraphParticle &particle)
Reads the information for a single particle from the LHE file.
Definition LHEReader.cc:188
bool skipEvents(int n)
Skips a given number of events.
Definition LHEReader.cc:79
std::string getLine()
Returns the current line from the LHE ascii file.
Definition LHEReader.cc:124
int countEvents(const std::string &filename)
Count events in the file by reading through it.
Definition LHEReader.cc:90
static const boost::char_separator< char > sep
The characters at which to split, defaults to ",; \t".
Definition LHEReader.h:115
int m_lineNr
The current line number within the ascii file.
Definition LHEReader.h:117
int m_indexVirtual
Maximum index of particles in each event that must be set as c_IsVirtual (1-based).
Definition LHEReader.h:141
void open(const std::string &filename)
Opens an ascii file and prepares it for reading.
Definition LHEReader.cc:25
std::ifstream m_input
The input stream of the ascii file.
Definition LHEReader.h:118
boost::tokenizer< boost::char_separator< char > > tokenizer
Just a typedef for simple use of the boost::tokenizer to split the lines.
Definition LHEReader.h:113
int m_indexInitial
Maximum index of particles in each event that must be set as c_Initial (1-based).
Definition LHEReader.h:139
int getEvent(MCParticleGraph &graph, double &weight)
Reads the next event and stores the result in the given MCParticle graph.
Definition LHEReader.cc:32
bool m_wrongSignPz
Bool to indicate that HER and LER were swapped.
Definition LHEReader.h:109
int readEventHeader(double &eventWeight)
Reads the event header from the hepevt file.
Definition LHEReader.cc:141
Class to represent Particle data in graph.
Class to build, validate and sort a particle decay chain.
size_t size() const
Return the number of particles in the graph.
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
Definition MCParticle.h:57
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition MCParticle.h:47
@ c_IsVirtual
bit 4: Particle is virtual and not going to Geant4.
Definition MCParticle.h:55
GraphParticle & addParticle()
Add new particle to the graph.
Abstract base class for different kinds of events.
STL namespace.