Belle II Software development
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/foreach.hpp>
19#include <boost/format.hpp>
20
21#include <TF1.h>
22
23using namespace std;
24using namespace Belle2;
25
26const boost::char_separator<char> LHEReader::sep(",; \t");
27
28void LHEReader::open(const string& filename)
29{
30 m_lineNr = 0;
31 m_input.open(filename.c_str());
32 if (!m_input) throw(LHECouldNotOpenFileError() << filename);
33}
34
35
36int LHEReader::getEvent(MCParticleGraph& graph, double& eventWeight)
37{
38 int nparticles = readEventHeader(eventWeight);
39 if (nparticles <= 0) {
40 throw (LHEEmptyEventError() << 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
49 double r, x = 0, y = 0, z = 0, t = 0;
50 //Read particles from file
51 for (int i = 0; i < nparticles; ++i) {
52 MCParticleGraph::GraphParticle& p = graph[first + i];
53 int mother = readParticle(p);
54
55 // add the mother
56 if (mother > 0) {
57 MCParticleGraph::GraphParticle* q = &graph[mother - 1];
58 p.comesFrom(*q);
59 }
60
61 // if positron goes to positive z-direction, we have to rotate along y-axis by 180deg
62 if (m_wrongSignPz) {
63 ROOT::Math::PxPyPzEVector p4 = p.get4Vector();
64 p4.SetPz(-1.0 * p4.Pz());
65 p4.SetPx(-1.0 * p4.Px());
66 p.set4Vector(p4);
67 }
68
69 //move vertex position of selected particle and its daughters
70 if (m_meanDecayLength > 0) {
71 if (p.getPDG() == m_pdgDisplaced) {
72 TF1 fr("fr", "exp(-x/[0])", 0, 1000000);
73 ROOT::Math::PxPyPzEVector p4 = p.get4Vector();
74 fr.SetRange(m_Rmin, m_Rmax);
75 fr.SetParameter(0, m_meanDecayLength * p4.Gamma());
76 r = fr.GetRandom();
77 x = r * p4.Px() / p4.P();
78 y = r * p4.Py() / p4.P();
79 z = r * p4.Pz() / p4.P();
80 p.setDecayVertex(x, y, z);
81 t = (r / Const::speedOfLight) * (p4.E() / p4.P());
82 p.setDecayTime(t);
83 p.setValidVertex(true);
84 }
85
86 if (mother > 0) {
87 if (graph[mother - 1].getPDG() == m_pdgDisplaced) {
88 p.setProductionVertex(x, y, z);
89 p.setProductionTime(t);
90 p.setValidVertex(true);
91 }
92 }
93 }
94
95
96 // initial 2 (e+/e-), virtual 3 (Z/gamma*)
97 // check if particle should be made virtual according to steering options:
98 if (i < m_indexVirtual && i >= m_indexInitial)
99 p.addStatus(MCParticle::c_IsVirtual);
100
101 if (i < m_indexInitial)
102 p.addStatus(MCParticle::c_Initial);
103
104 if (m_indexVirtual < m_indexInitial) B2WARNING("IsVirtual particle requested but is overwritten by Initial");
105
106 }
107// return eventID;
108 return -1;
109}
110
111
113{
114// int eventID;
115 double weight;
116 for (int i = 0; i < n; i++) {
117// int nparticles = readEventHeader(eventID, weight);
118 int nparticles = readEventHeader(weight);
119 if (nparticles < 0) return false;
120 for (int j = 0; j < nparticles; j++) getLine();
121 }
122 return true;
123}
124
125
126//===================================================================
127// Protected methods
128//===================================================================
129
131{
132 std::string line;
133 do {
134 getline(m_input, line);
135 m_lineNr++;
136 size_t commentPos = line.find_first_of('#');
137 if (commentPos != string::npos) {
138 line = line.substr(0, commentPos);
139 }
140 boost::trim(line);
141
142 } while (line == "" && !m_input.eof());
143
144 return line;
145}
146
147
148// int LHEReader::readEventHeader(int& eventID, double& eventWeight)
149int LHEReader::readEventHeader(double& eventWeight)
150{
151
152 // Search for next <event>
153 std::string line2;
154 do {
155 getline(m_input, line2);
156 m_lineNr++;
157 size_t commentPos = line2.find_first_of('#');
158 if (commentPos != string::npos) {
159 line2 = line2.substr(0, commentPos);
160 }
161 boost::trim(line2);
162
163 } while (line2 != "<event>" && !m_input.eof());
164
165 //Get number of particles from file
166 int nparticles = -1;
167 string line = getLine();
168
169 if (line == "" || m_input.eof()) return -1;
170
171 vector<double> fields;
172 fields.reserve(15);
173
174 tokenizer tokens(line, sep);
175 int index(0);
176
177 BOOST_FOREACH(const string & tok, tokens) {
178 ++index;
179 try {
180 fields.push_back(boost::lexical_cast<double>(tok));
181 } catch (boost::bad_lexical_cast& e) {
182 throw (LHEConvertFieldError() << m_lineNr << index << tok);
183 }
184 }
185
186 switch (fields.size()) {
187 default:
188 eventWeight = 1.0;
189 nparticles = static_cast<int>(fields[0]); //other fields in LHE contain effective couplings
190 break;
191 }
192 return nparticles;
193}
194
195
197{
198 int mother = -1;
199
200 string line = getLine();
201 vector<double> fields;
202 fields.reserve(15);
203
204 tokenizer tokens(line, sep);
205 int index(0);
206
207 BOOST_FOREACH(const string & tok, tokens) {
208 ++index;
209 try {
210 fields.push_back(boost::lexical_cast<double>(tok));
211 } catch (boost::bad_lexical_cast& e) {
212 throw (LHEConvertFieldError() << m_lineNr << index << tok);
213 }
214 }
215
216 switch (fields.size()) {
217 case 13:
218 particle.addStatus(MCParticle::c_PrimaryParticle);
219 particle.setPDG(static_cast<int>(fields[0]));
220 mother = static_cast<int>(fields[2]);
221 particle.setMomentum(ROOT::Math::XYZVector(fields[6], fields[7], fields[8]));
222 particle.setEnergy(fields[9]);
223 particle.setMass(fields[10]);
224 break;
225 default:
226 throw (LHEParticleFormatError() << m_lineNr << fields.size());
227 }
228
229 return mother;
230}
static const double speedOfLight
[cm/ns]
Definition: Const.h:695
int readParticle(MCParticleGraph::GraphParticle &particle)
Reads the information for a single particle from the LHE file.
Definition: LHEReader.cc:196
bool skipEvents(int n)
Skips a given number of events.
Definition: LHEReader.cc:112
std::string getLine()
Returns the current line from the LHE ascii file.
Definition: LHEReader.cc:130
double m_Rmin
Minimum of vertex distance to IP.
Definition: LHEReader.h:104
int m_pdgDisplaced
PDG code of the displaced particle being studied.
Definition: LHEReader.h:106
static const boost::char_separator< char > sep
The characters at which to split, defaults to ",; \t".
Definition: LHEReader.h:112
int m_lineNr
The current line number within the ascii file.
Definition: LHEReader.h:114
int m_indexVirtual
Maximum index of particles in each event that must be set as c_IsVirtual (1-based).
Definition: LHEReader.h:142
double m_Rmax
Maximum of vertex distance to IP.
Definition: LHEReader.h:105
void open(const std::string &filename)
Opens an ascii file and prepares it for reading.
Definition: LHEReader.cc:28
std::ifstream m_input
The input stream of the ascii file.
Definition: LHEReader.h:115
boost::tokenizer< boost::char_separator< char > > tokenizer
Just a typedef for simple use of the boost::tokenizer to split the lines.
Definition: LHEReader.h:110
int m_indexInitial
Maximum index of particles in each event that must be set as c_Initial (1-based).
Definition: LHEReader.h:140
int getEvent(MCParticleGraph &graph, double &weight)
Reads the next event and stores the result in the given MCParticle graph.
Definition: LHEReader.cc:36
bool m_wrongSignPz
Bool to indicate that HER and LER were swapped.
Definition: LHEReader.h:102
int readEventHeader(double &eventWeight)
Reads the event header from the hepevt file.
Definition: LHEReader.cc:149
double m_meanDecayLength
Mean lifetime*c of displaced particle.
Definition: LHEReader.h:103
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.