Belle II Software  release-06-00-14
KKGenInterface.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 /* Own header. */
10 #include <generators/kkmc/KKGenInterface.h>
11 
12 /* Belle 2 headers. */
13 #include <framework/gearbox/Const.h>
14 #include <framework/gearbox/Unit.h>
15 #include <framework/logging/Logger.h>
16 #include <framework/particledb/EvtGenDatabasePDG.h>
17 #include <mdst/dataobjects/MCParticleGraph.h>
18 
19 /* ROOT headers. */
20 #include <THashList.h>
21 #include <TLorentzVector.h>
22 
23 /* C++ headers. */
24 #include <cmath>
25 #include <string>
26 #include <utility>
27 
28 using namespace Belle2;
29 
30 int KKGenInterface::setup(const std::string& KKdefaultFileName, const std::string& tauinputFileName,
31  const std::string& taudecaytableFileName, const std::string& KKMCOutputFileName)
32 {
33  B2DEBUG(20, "Begin initialisation of KKGen Interface.");
34 
35  // This is to avoid character corruption of TAUOLA output
36  char DatX_d[132], DatX_u[132], DatX_p[132], DatX_o[132];
37  for (int i = 0; i < 132; ++i) {
38  DatX_d[i] = ' ';
39  DatX_u[i] = ' ';
40  DatX_p[i] = ' ';
41  DatX_o[i] = ' ';
42  }
43  strcpy(DatX_d, KKdefaultFileName.c_str());
44  int length = strlen(DatX_d);
45  DatX_d[length] = ' ';
46  strcpy(DatX_u, tauinputFileName.c_str());
47  length = strlen(DatX_u);
48  DatX_u[length] = ' ';
49  strcpy(DatX_p, taudecaytableFileName.c_str());
50  length = strlen(DatX_p);
51  DatX_p[length] = ' ';
52  strcpy(DatX_o, KKMCOutputFileName.c_str());
53  length = strlen(DatX_o);
54  DatX_o[length] = ' ';
55  int irand = 0;
56  kk_init_(DatX_d, DatX_u, DatX_p, &irand, DatX_o);
57 
58  // seed of random generator should be set here
59  kk_init_seed_();
60 
61  // create mapping from pythia id to pdg code
62  auto particlelist = EvtGenDatabasePDG::Instance()->ParticleList();
63  m_mapPythiaIDtoPDG.reserve(particlelist->GetEntries());
64  for (TObject* object : *particlelist) {
65  EvtGenParticlePDG* particle = dynamic_cast<EvtGenParticlePDG*>(object);
66  if (!particle) {
67  B2FATAL("Something is wrong with the EvtGenDatabasePDG, got object not inheriting from EvtGenParticlePDG");
68  }
69  m_mapPythiaIDtoPDG[particle->PythiaID()] = particle->PdgCode();
70  }
71 
72  B2DEBUG(20, "End initialisation of KKGen Interface.");
73 
74  return 0;
75 }
76 
77 void KKGenInterface::set_beam_info(TLorentzVector P4_LER, double Espread_LER, TLorentzVector P4_HER, double Espread_HER)
78 {
79 
80  // Beam 4 momenta settings
81 // double crossing_angle = 0.;
82  double ph = P4_HER.Vect().Mag();
83  double pl = P4_LER.Vect().Mag();
84  double eh = P4_HER.E();
85  double el = P4_LER.E();
86  if (ph > 0. && pl > 0. && eh > 0. && el > 0.) {
87 
88  double pxh, pyh, pzh, pxl, pyl, pzl;
89  pxh = P4_HER.Px();
90  pyh = P4_HER.Py();
91  pzh = P4_HER.Pz();
92 
93  pxl = P4_LER.Px();
94  pyl = P4_LER.Py();
95  pzl = P4_LER.Pz();
96 
97  char buf[200];
98  sprintf(buf,
99  "Set Beam info: (%9.4f, %9.4f, %9.4f, %9.4f), (%9.4f, %9.4f, %9.4f, %9.4f)", pxh, pyh, pzh, eh, pxl, pyl, pzl, el);
100  B2DEBUG(100, buf);
101 
102  kk_putbeam_(&pxh, &pyh, &pzh, &eh, &pxl, &pyl, &pzl, &el);
103 
104  B2DEBUG(20, "Espread_LER=" << Espread_LER);
105  B2DEBUG(20, "Espread_HER=" << Espread_HER);
106  double Espread_CM = 0.0;
107 
108  sprintf(buf,
109  "Set Beam Energy spread: %9.4f", Espread_CM);
110  B2DEBUG(100, buf);
111  kk_begin_run_(&Espread_CM);
112  } else {
113  char buf[200];
114  sprintf(buf,
115  "Wrongly Set Beam info: Eh=%9.4f, Ph=%9.4f, El=%9.4f, Pl=%9.4f",
116  eh, ph, el, pl);
117  B2DEBUG(100, buf);
118  }
119 
120 }
121 
122 int KKGenInterface::simulateEvent(MCParticleGraph& graph, TVector3 vertex)
123 {
124  B2DEBUG(20, "Start simulation of KKGen Interface.");
125  int status = 0;
126  kk_event_(&status);
127 
128  // before storing event to MCParticle, check /hepevt/ common block
129  B2DEBUG(100, "HepEVT table:");
130 
131  for (int i = 0; i < hepevt_.nhep; ++i) {
132  char buf[200];
133  sprintf(buf,
134  "IntA: %3d %4d %8d %4d %4d %4d %9.4f %9.4f %9.4f %9.4f %9.4f",
135  i + 1, hepevt_.isthep[i], hepevt_.idhep[i],
136  hepevt_.jmohep[i][0], hepevt_.jdahep[i][0],
137  hepevt_.jdahep[i][1], hepevt_.phep[i][0],
138  hepevt_.phep[i][1], hepevt_.phep[i][2],
139  hepevt_.phep[i][3], hepevt_.phep[i][4]);
140  B2DEBUG(100, buf);
141  }
142 
143  int npar = addParticles2Graph(graph, vertex);
145  B2DEBUG(100, "GraphParticles:");
146 
147  // check MCParticleGraph
148  for (int i = 0; i < npar; ++i) {
149  MCParticleGraph::GraphParticle* p = &graph[i];
150  int moID = 0;
151  char buf[200];
152  sprintf(buf, "IntB: %3d %4u %8d %4d %4d %4d %9.4f %9.4f %9.4f %9.4f",
153  p->getIndex() , p->getStatus() , p->getPDG() , moID ,
154  p->getFirstDaughter() , p->getLastDaughter() ,
155  p->get4Vector().Px() , p->get4Vector().Py() ,
156  p->get4Vector().Pz() , p->get4Vector().E());
157  B2DEBUG(100, buf);
158 
159  }
160 
161  B2DEBUG(20, "End simulation of KKGen Interface.");
162  return hepevt_.nhep; //returns the number of generated particles from KKMC
163 }
164 
165 
166 
168 {
169  // KKMC generates at least five particles:
170  // beam (e+ e-), intermediate gamma/Z, f+ f- (f=mu, tau, ...)
171  if (hepevt_.nhep < 5) {
172  B2ERROR("KKMC-generated event has not been produced correctty!");
173  return hepevt_.nhep;
174  }
175 
176  std::vector <MCParticleGraph::GraphParticle*> MCPList;
177 
178  //Fill top particle in the tree & starting the queue:
179  for (int i = 1; i <= hepevt_.nhep; ++i) {
180  int position = graph.size();
181  graph.addParticle();
182  MCParticleGraph::GraphParticle* p = &graph[position];
183  updateGraphParticle(i, p, vertex);
184  MCPList.push_back(p);
185  }
186 
187  // From produced particles, its mother is assigned
188  for (int i = 4; i <= hepevt_.nhep; ++i) {
189  MCParticleGraph::GraphParticle* p = MCPList[i - 1];
190  if (hepevt_.jmohep[i - 1][0] > 0 && hepevt_.jmohep[i - 1][0] <= hepevt_.nhep) {
191  int j = hepevt_.jmohep[i - 1][0];
192  MCParticleGraph::GraphParticle* q = MCPList[j - 1];
193  p->comesFrom((*q));
194  }
195  }
196  return hepevt_.nhep;
197 }
198 
199 
200 void KKGenInterface::updateGraphParticle(int index, MCParticleGraph::GraphParticle* gParticle, TVector3 vertex)
201 {
202  if (index < 1 || index > hepevt_.nhep)
203  return;
204  //updating the GraphParticle information from /hepevt/ common block information
205 
206  // convert PYTHIA ID to PDG ID
207  auto iter = m_mapPythiaIDtoPDG.find(hepevt_.idhep[index - 1]);
208  if (iter != end(m_mapPythiaIDtoPDG)) {
209  gParticle->setPDG(iter->second);
210  } else {
211  //not in the map, set pythia id directly
212  gParticle->setPDG(hepevt_.idhep[index - 1]);
213  }
214 
215  //all(!) particles from the generator have to be primary
217 
218  // initial beam electron and positron should be Initial.
219  if (abs(hepevt_.idhep[index - 1]) == 11 &&
220  hepevt_.jmohep[index - 1][0] == 0 &&
221  hepevt_.jmohep[index - 1][1] == 0 &&
222  hepevt_.isthep[index - 1] == 3 &&
223  index < 3) {
224  gParticle->addStatus(MCParticle::c_Initial);
225  }
226 
227  // Z0 or W+/W- must be flagged as virtual
228  if (hepevt_.idhep[index - 1] == 23 || std::abs(hepevt_.idhep[index - 1]) == 24) {
230  } else if (hepevt_.isthep[index - 1] == 1) {
232  }
233 
234  // set photon flags (for now: set ISR and FSR (CEEX is undefined by definition, unsure about IFI))
235  // PHOTOS could be called by TAUOLA, not sure what to do about that
236  if (hepevt_.idhep[index - 1] == 22) {
237  if (hepevt_.jmohep[index - 1][0] == 1) {
240  }
241  }
242 
243  TLorentzVector p4(hepevt_.phep[index - 1][0],
244  hepevt_.phep[index - 1][1],
245  hepevt_.phep[index - 1][2],
246  hepevt_.phep[index - 1][3]);
247  gParticle->setMass(hepevt_.phep[index - 1][4]);
248  gParticle->set4Vector(p4);
249 
250  //set vertex including smearing (if user requested)
251  TVector3 pProductionVertex(hepevt_.vhep[index - 1][0]*Unit::mm,
252  hepevt_.vhep[index - 1][1]*Unit::mm,
253  hepevt_.vhep[index - 1][2]*Unit::mm);
254  if (!gParticle->hasStatus(MCParticle::c_Initial)) {
255  pProductionVertex = pProductionVertex + vertex;
256  }
257  gParticle->setProductionVertex(pProductionVertex);
258  gParticle->setProductionTime(hepevt_.vhep[index - 1][3]*Unit::mm / Const::speedOfLight);
259  gParticle->setValidVertex(true);
260 }
261 
263 {
264  double xsec = 0.;
265  double xsecerr = 0.;
266  kk_term_(&xsec, &xsecerr);
267 }
static const double speedOfLight
[cm/ns]
Definition: Const.h:575
static EvtGenDatabasePDG * Instance()
Instance method that loads the EvtGen table.
Helper class for setting additional TParticlePDG members and storing the ones it doesn't have yet.
int simulateEvent(MCParticleGraph &graph, TVector3 vertex)
Simulate the events.
std::unordered_map< int, int > m_mapPythiaIDtoPDG
Map between PYTHIA id and PDG codes.
void term()
Terminate the generator.
int addParticles2Graph(MCParticleGraph &graph, TVector3 vertex)
Add particles to the MCParticleGraph.
void set_beam_info(TLorentzVector P4_LER, double Espread_LER, TLorentzVector P4_HER, double Espread_HER)
Setup for beams information.
int setup(const std::string &KKdefaultFileName, const std::string &tauinputFileName, const std::string &taudecaytableFileName, const std::string &KKMCOutputFileName)
Setup for KKMC and TAUOLA.
void updateGraphParticle(int, MCParticleGraph::GraphParticle *gParticle, TVector3 vertex)
Update the MCParticleGraph.
Class to represent Particle data in graph.
Class to build, validate and sort a particle decay chain.
@ c_checkCyclic
Check for cyclic dependencies.
@ c_setDecayInfo
Set decay time and vertex.
size_t size() const
Return the number of particles in the graph.
void generateList(const std::string &name="", int options=c_setNothing)
Generates the MCParticle list and stores it in the StoreArray with the given name.
@ c_IsFSRPhoton
bit 7: Particle is from finial state radiation
Definition: MCParticle.h:61
@ 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
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
Definition: MCParticle.h:49
@ c_IsISRPhoton
bit 6: Particle is from initial state radiation
Definition: MCParticle.h:59
void set4Vector(const TLorentzVector &p4)
Sets the 4Vector of particle.
Definition: MCParticle.h:435
void setMass(float mass)
Set particle mass.
Definition: MCParticle.h:363
void setProductionVertex(const TVector3 &vertex)
Set production vertex position.
Definition: MCParticle.h:393
void addStatus(unsigned short int bitmask)
Add bitmask to current status.
Definition: MCParticle.h:350
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
Definition: MCParticle.h:129
void setValidVertex(bool valid)
Set indication wether vertex and time information is valid or just default.
Definition: MCParticle.h:375
void setPDG(int pdg)
Set PDG code of the particle.
Definition: MCParticle.h:332
void setProductionTime(float time)
Set production time.
Definition: MCParticle.h:381
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.
int jmohep[nmxhep][2]
parent particles.
int isthep[nmxhep]
status code.
double vhep[nmxhep][4]
vertex [mm].
int jdahep[nmxhep][2]
childreen particles.
double phep[nmxhep][5]
four-momentum, mass [GeV].
int idhep[nmxhep]
particle ident KF.
int nhep
number of particles.