Belle II Software development
HepevtReader.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/hepevt/HepevtReader.h>
13
14#include <string>
15#include <boost/lexical_cast.hpp>
16#include <boost/algorithm/string.hpp>
17#include <boost/format.hpp>
18
19#include <Math/Vector4D.h>
20
21using namespace std;
22using namespace Belle2;
23
24const boost::char_separator<char> HepevtReader::sep(",; \t");
25
26void HepevtReader::open(const string& filename)
27{
28 m_lineNr = 0;
29 m_input.open(filename.c_str());
30 if (!m_input) throw(HepEvtCouldNotOpenFileError() << filename);
31}
32
33
34int HepevtReader::getEvent(MCParticleGraph& graph, double& eventWeight)
35{
36 int eventID = -1;
37 int nparticles = readEventHeader(eventID, eventWeight);
38 if (nparticles <= 0) {
39 throw (HepEvtEmptyEventError() << m_lineNr << nparticles);
40 }
41
42 int first = graph.size();
43 //Make list of particles
44 for (int i = 0; i < nparticles; i++) {
45 graph.addParticle();
46 }
47 //Read particles from file
48 for (int i = 0; i < nparticles; ++i) {
49 MCParticleGraph::GraphParticle& p = graph[first + i];
50 readParticle(p);
51
52 if (m_wrongSignPz) { // this means we have to mirror Pz
53 ROOT::Math::PxPyPzEVector p4 = p.get4Vector();
54 p4.SetPz(-1.0 * p4.Pz());
55 p.set4Vector(p4);
56 }
57
58 //Check for sensible daughter indices
59 int d1 = p.getFirstDaughter();
60 int d2 = p.getLastDaughter();
61 if (d1 < 0 || d1 > nparticles || d2 < d1 || d2 > nparticles) {
62 throw (HepEvtInvalidDaughterIndicesError() << m_lineNr << d1 << d2 << nparticles);
63 }
64 if (d1 == 0) p.addStatus(MCParticle::c_StableInGenerator);
65 //Add decays
66 for (int index = d1; index <= d2; ++index) {
67 if (index > 0) p.decaysInto(graph[first + index - 1]);
68 }
69
70 //check if particle should be made virtual according to steering options:
71 if (i < m_nVirtual)
72 p.setVirtual();
73 }
74 return eventID;
75}
76
77
79{
80 int eventID;
81 double weight;
82 for (int i = 0; i < n; i++) {
83 int nparticles = readEventHeader(eventID, weight);
84 if (nparticles < 0) return false;
85 for (int j = 0; j < nparticles; j++) getLine();
86 }
87 return true;
88}
89
90
91//===================================================================
92// Protected methods
93//===================================================================
94
96{
97 std::string line;
98 do {
99 getline(m_input, line);
100 m_lineNr++;
101 size_t commentPos = line.find_first_of('#');
102 if (commentPos != string::npos) {
103 line = line.substr(0, commentPos);
104 }
105 boost::trim(line);
106 } while (line == "" && !m_input.eof());
107 return line;
108}
109
110
111int HepevtReader::readEventHeader(int& eventID, double& eventWeight)
112{
113 //Get number of particles from file
114 int nparticles = -1;
115 string line = getLine();
116 if (line == "" || m_input.eof()) return -1;
117
118 vector<double> fields;
119 fields.reserve(15);
120
121 tokenizer tokens(line, sep);
122 int index(0);
123
124 for (const string& tok : tokens) {
125 ++index;
126 try {
127 fields.push_back(boost::lexical_cast<double>(tok));
128 } catch (boost::bad_lexical_cast& e) {
129 throw (HepEvtConvertFieldError() << m_lineNr << index << tok);
130 }
131 }
132
133 switch (fields.size()) {
134 case 1:
135 nparticles = static_cast<int>(fields[0]);
136 break;
137 case 2:
138 nparticles = static_cast<int>(fields[1]);
139 eventID = static_cast<int>(fields[0]);
140 break;
141 case 3:
142 nparticles = static_cast<int>(fields[1]);
143 eventID = static_cast<int>(fields[0]);
144 eventWeight = fields[2];
145 break;
146 default:
147 nparticles = static_cast<int>(fields[0]);
148 break;
149 }
150 return nparticles;
151}
152
153
155{
156 string line = getLine();
157 vector<double> fields;
158 fields.reserve(15);
159
160 tokenizer tokens(line, sep);
161 int index(0);
162
163 for (const string& tok : tokens) {
164 ++index;
165 try {
166 fields.push_back(boost::lexical_cast<double>(tok));
167 } catch (boost::bad_lexical_cast& e) {
168 throw (HepEvtConvertFieldError() << m_lineNr << index << tok);
169 }
170 }
171
172 switch (fields.size()) {
173 case 8:
174 particle.setStatus(MCParticle::c_PrimaryParticle);
175 particle.setPDG(static_cast<int>(fields[1]));
176 particle.setFirstDaughter(static_cast<int>(fields[2]));
177 particle.setLastDaughter(static_cast<int>(fields[3]));
178 particle.setMomentum(ROOT::Math::XYZVector(fields[4], fields[5], fields[6]));
179 particle.setMass(fields[7]);
180 break;
181 case 6:
182 particle.setStatus(MCParticle::c_PrimaryParticle);
183 particle.setPDG(static_cast<int>(fields[5]));
184 particle.setFirstDaughter(0);
185 particle.setLastDaughter(0);
186 particle.setMomentum(ROOT::Math::XYZVector(fields[0], fields[1], fields[2]));
187 particle.setMass(fields[4]);
188 particle.setEnergy(fields[3]);
189 break;
190 //modified Pit
191 case 9:
192 particle.setStatus(MCParticle::c_PrimaryParticle);
193 particle.setPDG(static_cast<int>(fields[8]));
194 particle.setFirstDaughter(0);
195 particle.setLastDaughter(0);
196 particle.setProductionVertex(ROOT::Math::XYZVector(fields[0], fields[1], fields[2])*Unit::mm);
197 particle.setMomentum(ROOT::Math::XYZVector(fields[3], fields[4], fields[5]));
198 particle.setMass(fields[6]);
199 particle.setEnergy(fields[7]);
200 break;
201 //end modified Pit
202 case 15:
203 particle.setStatus(MCParticle::c_PrimaryParticle);
204 particle.setPDG(static_cast<int>(fields[1]));
205 particle.setFirstDaughter(static_cast<int>(fields[4]));
206 particle.setLastDaughter(static_cast<int>(fields[5]));
207 particle.setMomentum(ROOT::Math::XYZVector(fields[6], fields[7], fields[8]));
208 //particle.setEnergy(fields[9]);
209 particle.setMass(fields[10]);
210 particle.setProductionVertex(ROOT::Math::XYZVector(fields[11], fields[12], fields[13])*Unit::mm);
211 particle.setProductionTime(fields[14]*Unit::mm / Const::speedOfLight);
212 particle.setValidVertex(true);
213 {
214 //Warn if energy in Hepevt file differs from calculated energy by more than 0.1%
215 const double& E = particle.getEnergy();
216 double dE = fabs(fields[9] - E) / E;
217 if (dE > 1e-3) {
218 B2WARNING(boost::format("line %d: Energy of particle does not match with expected energy: %.6e != %.6e")
219 % m_lineNr % fields[9] % E);
220 B2WARNING(boost::format("delta E = %.2f%% -> ignoring given value") % (dE * 100));
221 }
222 }
223 break;
224 default:
225 throw (HepEvtParticleFormatError() << m_lineNr << fields.size());
226 }
227}
R E
internal precision of FFTW codelets
static const double speedOfLight
[cm/ns]
Definition: Const.h:695
bool skipEvents(int n)
Skips a given number of events.
Definition: HepevtReader.cc:78
std::string getLine()
Returns the current line from the Hepevt ascii file.
Definition: HepevtReader.cc:95
static const boost::char_separator< char > sep
The characters at which to split, defaults to ",; \t".
Definition: HepevtReader.h:95
int m_lineNr
The current line number within the ascii file.
Definition: HepevtReader.h:97
void open(const std::string &filename)
Opens an ascii file and prepares it for reading.
Definition: HepevtReader.cc:26
std::ifstream m_input
The input stream of the ascii file.
Definition: HepevtReader.h:98
boost::tokenizer< boost::char_separator< char > > tokenizer
Just a typedef for simple use of the boost::tokenizer to split the lines.
Definition: HepevtReader.h:93
int readEventHeader(int &eventID, double &eventWeight)
Reads the event header from the hepevt file.
int getEvent(MCParticleGraph &graph, double &weight)
Reads the next event and stores the result in the given MCParticle graph.
Definition: HepevtReader.cc:34
bool m_wrongSignPz
Bool to indicate that HER and LER were swapped.
Definition: HepevtReader.h:89
void readParticle(MCParticleGraph::GraphParticle &particle)
Reads the information for a single particle from the Hepevt file.
int m_nVirtual
The number of particles in each event with a set Virtual flag.
Definition: HepevtReader.h:88
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_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
Definition: MCParticle.h:49
static const double mm
[millimeters]
Definition: Unit.h:70
GraphParticle & addParticle()
Add new particle to the graph.
Abstract base class for different kinds of events.
STL namespace.