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