Belle II Software  release-05-02-19
BelleMCOutputModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2021 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Kirill Chilikin *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 /* Own header. */
12 #include <b2bii/modules/BelleMCOutput/BelleMCOutputModule.h>
13 
14 /* Belle2 headers. */
15 #include <framework/gearbox/Unit.h>
16 #include <framework/logging/Logger.h>
17 
18 /* Belle headers. */
19 #include <belle_legacy/tables/belletdf.h>
20 #include <belle_legacy/tables/hepevt.h>
21 #include <belle_legacy/tables/filespec.h>
22 
23 /* ROOT headers. */
24 #include <TMatrixD.h>
25 
26 using namespace Belle2;
27 
28 REG_MODULE(BelleMCOutput)
29 
31  Module()
32 {
33  setDescription("Output of MC particle list in Belle format.");
34  setPropertyFlags(c_Output);
35  addParam("outputFileName", m_OutputFileName,
36  "Output file name.", std::string("belle_mc.mdst"));
37  addParam("decayKsInGenerator", m_DecayKsInGenerator,
38  "Decay K_S0 in generator.", false);
39  addParam("decayLambdaInGenerator", m_DecayLambdaInGenerator,
40  "Decay Lambda in generator.", false);
41 }
42 
44 {
45 }
46 
48 {
49  m_BelleFile = new Belle::Panther_FileIO(m_OutputFileName.c_str(), BBS_WRITE);
50  m_BelleFile->write(BBS_FORMAT, 0);
51  m_BelleFile->save_br("BELLE_FILE_SPECIFICATION");
52  m_BelleFile->save_br("BELLE_RUNHEAD");
53  m_BelleFile->save_br("BELLE_NOMINAL_BEAM");
54  m_BelleFile->save("GEN_HEPEVT");
55  B2WARNING(
56  "************ ATTENTION! ************\n"
57  "\n"
58  " Belle MC generation differs from Belle II. In order to generate MC "
59  "correctly, you must do the following:\n"
60  "\n"
61  " 1. Use global tag with smearing of beam parameters and generation "
62  "flags: b2bii_beamParameters_with_smearing (there are no smearing data "
63  "or generation flags in the tags B2BII or B2BII_MC).\n"
64  " 2. Disable smearing in Belle simulation by removing the module "
65  "\"bpsmear\" from basf gsim scripts.\n"
66  "\n"
67  "It is also necessary to consider the following differences:\n"
68  "\n"
69  " 1. When converting the simulation result back to Belle II format, "
70  "it is recommended to disable conversion of beam parameters "
71  "(convertBeamParameters = False). Since the format of the table "
72  "BELLE_NOMINAL_BEAM is not sufficient to store an arbitrary covariance "
73  "matrix, the covariance matrix of IP position (BeamSpot) is not guaranteed "
74  "to be exactly the same after conversion.\n"
75  " 2. By default, decays of long-lived particles are removed and particles "
76  "are declared to be stable in generator (ISTHEP == 1 in basf) because "
77  "such decays are simulated by GEANT3 in basf. However, you may choose "
78  "to decay such particles via module parameters. This results in direct "
79  "passing of the decay products to simulation, i.e. material effects are "
80  "ignored. In this case, you may need to perform an additional study "
81  "of the difference between data and MC.\n"
82  "\n"
83  "************************************\n"
84  );
85 }
86 
88 {
89  Belle::Belle_file_specification_Manager& fileManager =
90  Belle::Belle_file_specification_Manager::get_manager();
91  fileManager.remove();
92  int position = 0;
93  int length = m_OutputFileName.size();
94  do {
95  Belle::Belle_file_specification& file = fileManager.add();
96  file.Spec(m_OutputFileName.substr(position, std::min(length, 8)).c_str());
97  position += 8;
98  length -= 8;
99  } while (length > 0);
100  Belle::Belle_runhead_Manager& runheadManager =
101  Belle::Belle_runhead_Manager::get_manager();
102  runheadManager.remove();
103  Belle::Belle_runhead& runhead = runheadManager.add();
104  runhead.ExpMC(2);
105  runhead.ExpNo(m_EventMetaData->getExperiment());
106  runhead.RunNo(m_EventMetaData->getRun());
107  runhead.Time(time(nullptr));
108  runhead.Type(0);
109  TLorentzVector momentumLER = m_BeamParameters->getLER();
110  TLorentzVector momentumHER = m_BeamParameters->getHER();
111  runhead.ELER(momentumLER.E());
112  runhead.EHER(momentumHER.E());
113  Belle::Belle_nominal_beam_Manager& beamManager =
114  Belle::Belle_nominal_beam_Manager::get_manager();
115  beamManager.remove();
116  Belle::Belle_nominal_beam& beam = beamManager.add();
117  beam.px_high(momentumHER.X());
118  beam.py_high(momentumHER.Y());
119  beam.pz_high(momentumHER.Z());
120  beam.px_low(momentumLER.X());
121  beam.py_low(momentumLER.Y());
122  beam.pz_low(momentumLER.Z());
123  TMatrixDSym herCovariance = m_BeamParameters->getCovHER();
124  beam.sigma_p_high(sqrt(herCovariance[0][0]));
125  TMatrixDSym lerCovariance = m_BeamParameters->getCovLER();
126  beam.sigma_p_low(sqrt(lerCovariance[0][0]));
127  /*
128  * The vertex parameters are in cm, as in basf2.
129  * The unit is not the same as for particles in GEN_HEPEVT.
130  */
131  TVector3 vertex = m_BeamParameters->getVertex();
132  beam.ip_x(vertex.X());
133  beam.ip_y(vertex.Y());
134  beam.ip_z(vertex.Z());
135  TMatrixDSym vertexCovariance = m_BeamParameters->getCovVertex();
136  beam.cang_high(momentumHER.Vect().Theta());
137  beam.cang_low(M_PI - momentumLER.Vect().Theta());
138  double angleIPZX = momentumHER.Vect().Theta() / 2;
139  beam.angle_ip_zx(angleIPZX);
140  /*
141  * Transformation of error matrix. It is inverse to the transformation in
142  * belle_legacy/ip/IpProfile.cc.
143  */
144  TRotation rotationY;
145  rotationY.RotateY(-angleIPZX);
146  TMatrixD rotationMatrix(3, 3);
147  rotationMatrix[0][0] = rotationY.XX();
148  rotationMatrix[0][1] = rotationY.XY();
149  rotationMatrix[0][2] = rotationY.XZ();
150  rotationMatrix[1][0] = rotationY.YX();
151  rotationMatrix[1][1] = rotationY.YY();
152  rotationMatrix[1][2] = rotationY.YZ();
153  rotationMatrix[2][0] = rotationY.ZX();
154  rotationMatrix[2][1] = rotationY.ZY();
155  rotationMatrix[2][2] = rotationY.ZZ();
156  TMatrixDSym vertexCovariance2 = vertexCovariance.Similarity(rotationMatrix);
157  beam.sigma_ip_x(sqrt(vertexCovariance2[0][0]));
158  beam.sigma_ip_y(sqrt(vertexCovariance2[1][1]));
159  beam.sigma_ip_z(sqrt(vertexCovariance2[2][2]));
160  m_BelleFile->write(BBS_BEGIN_RUN, 0);
161 }
162 
164  const MCParticle* particle, MCParticleGraph::GraphParticle* mother)
165 {
167  part = *particle;
168  if (mother != nullptr)
169  part.comesFrom(*mother);
170  int pdg = abs(particle->getPDG());
171  if ((pdg == Const::muon.getPDGCode()) ||
172  (pdg == Const::pion.getPDGCode()) ||
173  (pdg == Const::kaon.getPDGCode()) ||
174  ((pdg == Const::Kshort.getPDGCode()) && !m_DecayKsInGenerator) ||
175  (pdg == Const::Klong.getPDGCode()) ||
176  (pdg == Const::neutron.getPDGCode()) ||
177  ((pdg == Const::Lambda.getPDGCode()) && !m_DecayLambdaInGenerator) ||
178  (pdg == 3222) || // Sigma+
179  (pdg == 3112) || // Sigma-
180  (pdg == 3322) || // Xi0
181  (pdg == 3312) || // Xi-
182  (pdg == 3334)) { // Omega-
183  part.addStatus(MCParticle::c_StableInGenerator);
184  return;
185  }
186  std::vector<MCParticle*> daughters = particle->getDaughters();
187  for (const MCParticle* daughter : daughters)
188  addParticle(daughter, &part);
189 }
190 
192 {
193  Belle::Gen_hepevt_Manager& hepevtManager =
194  Belle::Gen_hepevt_Manager::get_manager();
195  hepevtManager.remove();
196  /*
197  * The time shift applied by basf module "evtgen" (file beam.cc) is
198  * vertex z coordinate [mm] / (2.0 * 2.99792458).
199  * The vertex coordinate is calculated relative to the IP position.
200  * The position correction happens at the simulation stage (bpsmear) in basf.
201  */
202  double timeShift = (m_MCInitialParticles->getVertex().Z() -
203  m_BeamParameters->getVertex().Z()) /
204  Unit::mm / (2.0 * 0.1 * Const::speedOfLight);
205  /*
206  * Regeneration of MCParticle array. It is necesary because in basf the
207  * long-lived particles (K_S0, K_L0, Lambda, neutron, pi, K, mu)
208  * are decayed by GEANT3.
209  */
211  for (const MCParticle& particle : m_MCParticles) {
212  if (particle.getMother() == nullptr)
213  addParticle(&particle, nullptr);
214  }
218  for (const MCParticle& particle : m_MCParticles) {
219  Belle::Gen_hepevt& hepevt = hepevtManager.add();
220  if (particle.hasStatus(MCParticle::c_Initial))
221  hepevt.isthep(3);
222  else if (particle.hasStatus(MCParticle::c_StableInGenerator))
223  hepevt.isthep(1);
224  else
225  hepevt.isthep(2);
226  hepevt.idhep(particle.getPDG());
227  hepevt.reset_mother();
228  const MCParticle* mother = particle.getMother();
229  int motherIndex = 0;
230  if (mother != nullptr)
231  motherIndex = mother->getIndex();
232  hepevt.moFirst(motherIndex);
233  hepevt.moLast(motherIndex);
234  hepevt.daFirst(particle.getFirstDaughter());
235  hepevt.daLast(particle.getLastDaughter());
236  TLorentzVector momentum = particle.get4Vector();
237  hepevt.PX(momentum.Px());
238  hepevt.PY(momentum.Py());
239  hepevt.PZ(momentum.Pz());
240  hepevt.E(momentum.E());
241  hepevt.M(particle.getMass());
242  TVector3 vertex = particle.getVertex();
243  hepevt.VX(vertex.X() / Unit::mm);
244  hepevt.VY(vertex.Y() / Unit::mm);
245  hepevt.VZ(vertex.Z() / Unit::mm);
246  hepevt.T(particle.getProductionTime() / Unit::mm * Const::speedOfLight +
247  timeShift);
248  }
249  m_BelleFile->write(BBS_EVENT, m_EventMetaData->getEvent());
250 }
251 
253 {
254 }
255 
257 {
258  delete m_BelleFile;
259 }
Belle2::MCParticleGraph::generateList
void generateList(const std::string &name="", int options=c_setNothing)
Generates the MCParticle list and stores it in the StoreArray with the given name.
Definition: MCParticleGraph.cc:211
Belle2::ProcType::c_Output
@ c_Output
Output Process.
Belle2::BelleMCOutputModule::m_MCInitialParticles
StoreObjPtr< MCInitialParticles > m_MCInitialParticles
Initial particles.
Definition: BelleMCOutputModule.h:110
Belle2::BelleMCOutputModule::endRun
virtual void endRun() override
This method is called if the current run ends.
Definition: BelleMCOutputModule.cc:252
Belle2::Const::Kshort
static const ParticleType Kshort
K^0_S particle.
Definition: Const.h:550
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::Const::Klong
static const ParticleType Klong
K^0_L particle.
Definition: Const.h:551
Belle2::MCParticleGraph::c_checkCyclic
@ c_checkCyclic
Check for cyclic dependencies.
Definition: MCParticleGraph.h:75
Belle2::BelleMCOutputModule::m_OutputFileName
std::string m_OutputFileName
Output file name.
Definition: BelleMCOutputModule.h:98
Belle2::Const::kaon
static const ChargedStable kaon
charged kaon particle
Definition: Const.h:536
Belle2::MCParticleGraph::c_setDecayInfo
@ c_setDecayInfo
Set decay time and vertex.
Definition: MCParticleGraph.h:74
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::BelleMCOutputModule::m_DecayLambdaInGenerator
bool m_DecayLambdaInGenerator
Decay Lambda in generator.
Definition: BelleMCOutputModule.h:104
Belle2::BelleMCOutputModule::event
virtual void event() override
This method is called for each event.
Definition: BelleMCOutputModule.cc:191
Belle2::Const::speedOfLight
static const double speedOfLight
[cm/ns]
Definition: Const.h:568
Belle2::Const::pion
static const ChargedStable pion
charged pion particle
Definition: Const.h:535
Belle2::BelleMCOutputModule::m_DecayKsInGenerator
bool m_DecayKsInGenerator
Decay K_S0 in generator.
Definition: BelleMCOutputModule.h:101
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::MCParticle::c_Initial
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
Definition: MCParticle.h:68
Belle2::MCParticleGraph::addParticle
GraphParticle & addParticle()
Add new particle to the graph.
Definition: MCParticleGraph.h:305
Belle2::Const::neutron
static const ParticleType neutron
neutron particle
Definition: Const.h:549
Belle2::BelleMCOutputModule::terminate
virtual void terminate() override
This method is called at the end of the event processing.
Definition: BelleMCOutputModule.cc:256
Belle2::BelleMCOutputModule::addParticle
void addParticle(const MCParticle *particle, MCParticleGraph::GraphParticle *mother)
Add particle to graph.
Definition: BelleMCOutputModule.cc:163
Belle2::MCParticleGraph::c_clearParticles
@ c_clearParticles
Clear the particle list before adding the graph.
Definition: MCParticleGraph.h:76
Belle2::MCParticle::c_StableInGenerator
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
Definition: MCParticle.h:60
Belle2::Unit::mm
static const double mm
[millimeters]
Definition: Unit.h:80
Belle2::BelleMCOutputModule
KLM digitization module.
Definition: BelleMCOutputModule.h:47
Belle2::BelleMCOutputModule::m_MCParticleGraph
MCParticleGraph m_MCParticleGraph
MC particle graph.
Definition: BelleMCOutputModule.h:119
Belle2::BelleMCOutputModule::beginRun
virtual void beginRun() override
Called when entering a new run.
Definition: BelleMCOutputModule.cc:87
Belle2::Const::muon
static const ChargedStable muon
muon particle
Definition: Const.h:534
Belle2::MCParticle
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:43
Belle2::BelleMCOutputModule::m_BeamParameters
DBObjPtr< BeamParameters > m_BeamParameters
Beam parameters.
Definition: BelleMCOutputModule.h:116
Belle2::MCParticleGraph::clear
void clear()
Reset particles and decay information to make the class reusable.
Definition: MCParticleGraph.h:298
Belle2::BelleMCOutputModule::~BelleMCOutputModule
virtual ~BelleMCOutputModule()
Destructor.
Definition: BelleMCOutputModule.cc:43
Belle2::BelleMCOutputModule::m_BelleFile
Belle::Panther_FileIO * m_BelleFile
Belle file input-output handler.
Definition: BelleMCOutputModule.h:122
Belle2::MCParticleGraph::GraphParticle
Class to represent Particle data in graph.
Definition: MCParticleGraph.h:86
Belle2::BelleMCOutputModule::m_MCParticles
StoreArray< MCParticle > m_MCParticles
MC particles.
Definition: BelleMCOutputModule.h:107
Belle2::Const::Lambda
static const ParticleType Lambda
Lambda particle.
Definition: Const.h:552
Belle2::BelleMCOutputModule::m_EventMetaData
StoreObjPtr< EventMetaData > m_EventMetaData
Event metadata.
Definition: BelleMCOutputModule.h:113
Belle2::BelleMCOutputModule::initialize
virtual void initialize() override
Initializer.
Definition: BelleMCOutputModule.cc:47