Belle II Software  release-06-02-00
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 #include <TLorentzVector.h>
23 
24 using namespace std;
25 using namespace Belle2;
26 
27 const boost::char_separator<char> LHEReader::sep(",; \t");
28 
29 void LHEReader::open(const string& filename)
30 {
31  m_lineNr = 0;
32  m_input.open(filename.c_str());
33  if (!m_input) throw(LHECouldNotOpenFileError() << filename);
34 }
35 
36 
37 int LHEReader::getEvent(MCParticleGraph& graph, double& eventWeight)
38 {
39  int nparticles = readEventHeader(eventWeight);
40  if (nparticles <= 0) {
41  throw (LHEEmptyEventError() << m_lineNr << nparticles);
42  }
43 
44  int first = graph.size();
45  //Make list of particles
46  for (int i = 0; i < nparticles; i++) {
47  graph.addParticle();
48  }
49 
50  double r, x = 0, y = 0, z = 0, t = 0;
51  //Read particles from file
52  for (int i = 0; i < nparticles; ++i) {
53  MCParticleGraph::GraphParticle& p = graph[first + i];
54  int mother = readParticle(p);
55 
56  // add the mother
57  if (mother > 0) {
58  MCParticleGraph::GraphParticle* q = &graph[mother - 1];
59  p.comesFrom(*q);
60  }
61 
62  //move vertex position of selected particle and its daughters
63  if (m_meanDecayLength > 0) {
64  if (p.getPDG() == m_pdgDisplaced) {
65  TF1 fr("fr", "exp(-x/[0])", 0, 1000000);
66  TLorentzVector p4 = p.get4Vector();
67  fr.SetRange(m_Rmin, m_Rmax);
68  fr.SetParameter(0, m_meanDecayLength * p4.Gamma());
69  r = fr.GetRandom();
70  x = r * p4.Px() / p4.P();
71  y = r * p4.Py() / p4.P();
72  z = r * p4.Pz() / p4.P();
73  p.setDecayVertex(TVector3(x, y, z));
74  t = (r / Const::speedOfLight) * (p4.E() / p4.P());
75  p.setDecayTime(t);
76  p.setValidVertex(true);
77  }
78 
79  if (mother > 0) {
80  if (graph[mother - 1].getPDG() == m_pdgDisplaced) {
81  p.setProductionVertex(TVector3(x, y, z));
82  p.setProductionTime(t);
83  p.setValidVertex(true);
84  }
85  }
86  }
87 
88  if (m_wrongSignPz) { // this means we have to mirror Pz
89  TLorentzVector p4 = p.get4Vector();
90  p4.SetPz(-1.0 * p4.Pz());
91  p.set4Vector(p4);
92  }
93 
94  // initial 2 (e+/e-), virtual 3 (Z/gamma*)
95  // check if particle should be made virtual according to steering options:
96  if (i < m_indexVirtual && i >= m_indexInitial)
97  p.addStatus(MCParticle::c_IsVirtual);
98 
99  if (i < m_indexInitial)
100  p.addStatus(MCParticle::c_Initial);
101 
102  if (m_indexVirtual < m_indexInitial) B2WARNING("IsVirtual particle requested but is overwritten by Initial");
103 
104  }
105 // return eventID;
106  return -1;
107 }
108 
109 
110 bool LHEReader::skipEvents(int n)
111 {
112 // int eventID;
113  double weight;
114  for (int i = 0; i < n; i++) {
115 // int nparticles = readEventHeader(eventID, weight);
116  int nparticles = readEventHeader(weight);
117  if (nparticles < 0) return false;
118  for (int j = 0; j < nparticles; j++) getLine();
119  }
120  return true;
121 }
122 
123 
124 //===================================================================
125 // Protected methods
126 //===================================================================
127 
128 std::string LHEReader::getLine()
129 {
130  std::string line;
131  do {
132  getline(m_input, line);
133  m_lineNr++;
134  size_t commentPos = line.find_first_of('#');
135  if (commentPos != string::npos) {
136  line = line.substr(0, commentPos);
137  }
138  boost::trim(line);
139 
140  } while (line == "" && !m_input.eof());
141 
142  return line;
143 }
144 
145 
146 // int LHEReader::readEventHeader(int& eventID, double& eventWeight)
147 int LHEReader::readEventHeader(double& eventWeight)
148 {
149 
150  // Search for next <event>
151  std::string line2;
152  do {
153  getline(m_input, line2);
154  m_lineNr++;
155  size_t commentPos = line2.find_first_of('#');
156  if (commentPos != string::npos) {
157  line2 = line2.substr(0, commentPos);
158  }
159  boost::trim(line2);
160 
161  } while (line2 != "<event>" && !m_input.eof());
162 
163  //Get number of particles from file
164  int nparticles = -1;
165  string line = getLine();
166 
167  if (line == "" || m_input.eof()) return -1;
168 
169  vector<double> fields;
170  fields.reserve(15);
171 
172  tokenizer tokens(line, sep);
173  int index(0);
174 
175  BOOST_FOREACH(const string & tok, tokens) {
176  ++index;
177  try {
178  fields.push_back(boost::lexical_cast<double>(tok));
179  } catch (boost::bad_lexical_cast& e) {
180  throw (LHEConvertFieldError() << m_lineNr << index << tok);
181  }
182  }
183 
184  switch (fields.size()) {
185  default:
186  eventWeight = 1.0;
187  nparticles = static_cast<int>(fields[0]); //other fields in LHE contain effective couplings
188  break;
189  }
190  return nparticles;
191 }
192 
193 
194 int LHEReader::readParticle(MCParticleGraph::GraphParticle& particle)
195 {
196  int mother = -1;
197 
198  string line = getLine();
199  vector<double> fields;
200  fields.reserve(15);
201 
202  tokenizer tokens(line, sep);
203  int index(0);
204 
205  BOOST_FOREACH(const string & tok, tokens) {
206  ++index;
207  try {
208  fields.push_back(boost::lexical_cast<double>(tok));
209  } catch (boost::bad_lexical_cast& e) {
210  throw (LHEConvertFieldError() << m_lineNr << index << tok);
211  }
212  }
213 
214  switch (fields.size()) {
215  case 13:
216  particle.addStatus(MCParticle::c_PrimaryParticle);
217  particle.setPDG(static_cast<int>(fields[0]));
218  mother = static_cast<int>(fields[2]);
219  particle.setMomentum(TVector3(&fields[6]));
220  particle.setMass(fields[10]);
221  break;
222  default:
223  throw (LHEParticleFormatError() << m_lineNr << fields.size());
224  }
225 
226  return mother;
227 }
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
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.