9 #include <framework/gearbox/Unit.h>
10 #include <framework/gearbox/Const.h>
11 #include <framework/logging/Logger.h>
12 #include <generators/hepevt/HepevtReader.h>
15 #include <boost/lexical_cast.hpp>
16 #include <boost/algorithm/string.hpp>
17 #include <boost/foreach.hpp>
18 #include <boost/format.hpp>
20 #include <Math/Vector4D.h>
25 const boost::char_separator<char> HepevtReader::sep(
",; \t");
27 void HepevtReader::open(
const string& filename)
30 m_input.open(filename.c_str());
31 if (!m_input)
throw(HepEvtCouldNotOpenFileError() << filename);
38 int nparticles = readEventHeader(eventID, eventWeight);
39 if (nparticles <= 0) {
40 throw (HepEvtEmptyEventError() << m_lineNr << nparticles);
43 int first = graph.
size();
45 for (
int i = 0; i < nparticles; i++) {
49 for (
int i = 0; i < nparticles; ++i) {
54 ROOT::Math::PxPyPzEVector p4 = p.get4Vector();
55 p4.SetPz(-1.0 * p4.Pz());
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);
65 if (d1 == 0) p.addStatus(MCParticle::c_StableInGenerator);
67 for (
int index = d1; index <= d2; ++index) {
68 if (index > 0) p.decaysInto(graph[first + index - 1]);
79 bool HepevtReader::skipEvents(
int n)
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();
96 std::string HepevtReader::getLine()
100 getline(m_input, line);
102 size_t commentPos = line.find_first_of(
'#');
103 if (commentPos != string::npos) {
104 line = line.substr(0, commentPos);
107 }
while (line ==
"" && !m_input.eof());
112 int HepevtReader::readEventHeader(
int& eventID,
double& eventWeight)
116 string line = getLine();
117 if (line ==
"" || m_input.eof())
return -1;
119 vector<double> fields;
125 BOOST_FOREACH(
const string & tok, tokens) {
128 fields.push_back(boost::lexical_cast<double>(tok));
129 }
catch (boost::bad_lexical_cast& e) {
130 throw (HepEvtConvertFieldError() << m_lineNr << index << tok);
134 switch (fields.size()) {
136 nparticles =
static_cast<int>(fields[0]);
139 nparticles =
static_cast<int>(fields[1]);
140 eventID =
static_cast<int>(fields[0]);
143 nparticles =
static_cast<int>(fields[1]);
144 eventID =
static_cast<int>(fields[0]);
145 eventWeight = fields[2];
148 nparticles =
static_cast<int>(fields[0]);
157 string line = getLine();
158 vector<double> fields;
164 BOOST_FOREACH(
const string & tok, tokens) {
167 fields.push_back(boost::lexical_cast<double>(tok));
168 }
catch (boost::bad_lexical_cast& e) {
169 throw (HepEvtConvertFieldError() << m_lineNr << index << tok);
173 switch (fields.size()) {
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]);
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]);
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]);
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]));
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);
216 const double&
E = particle.getEnergy();
217 double dE = fabs(fields[9] -
E) /
E;
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));
226 throw (HepEvtParticleFormatError() << m_lineNr << fields.size());
boost::tokenizer< boost::char_separator< char > > tokenizer
Just a typedef for simple use of the boost::tokenizer to split the lines.
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.
GraphParticle & addParticle()
Add new particle to the graph.
Abstract base class for different kinds of events.