Belle II Software  release-05-01-25
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. Enable vertex and beam-momentum smearing by adding the module "
62  "\"OverrideGenerationFlags\" before the generator.\n"
63  " 2. Disable smearing in Belle simulation by removing the module "
64  "\"bpsmear\" from basf gsim scripts.\n"
65  "\n"
66  "It is also necessary to consider the following differences:\n"
67  "\n"
68  " 1. When converting the simulation result back to Belle II format, "
69  "it is recommended to disable conversion of beam parameters "
70  "(convertBeamParameters = False). Since the format of the table "
71  "BELLE_NOMINAL_BEAM is not sufficient to store an arbitrary covariance "
72  "matrix, the covariance matrix of IP position (BeamSpot) is not guaranteed "
73  "to be exactly the same after conversion.\n"
74  " 2. By default, decays of long-lived particles are removed and particles "
75  "are declared to be stable in generator (ISTHEP == 1 in basf) because "
76  "such decays are simulated by GEANT3 in basf. However, you may choose "
77  "to decay such particles via module parameters. This results in direct "
78  "passing of the decay products to simulation, i.e. material effects are "
79  "ignored. In this case, you may need to perform an additional study "
80  "of the difference between data and MC.\n"
81  "\n"
82  "************************************\n"
83  );
84 }
85 
87 {
88  Belle::Belle_file_specification_Manager& fileManager =
89  Belle::Belle_file_specification_Manager::get_manager();
90  fileManager.remove();
91  int position = 0;
92  int length = m_OutputFileName.size();
93  do {
94  Belle::Belle_file_specification& file = fileManager.add();
95  file.Spec(m_OutputFileName.substr(position, std::min(length, 8)).c_str());
96  position += 8;
97  length -= 8;
98  } while (length > 0);
99  Belle::Belle_runhead_Manager& runheadManager =
100  Belle::Belle_runhead_Manager::get_manager();
101  runheadManager.remove();
102  Belle::Belle_runhead& runhead = runheadManager.add();
103  runhead.ExpMC(2);
104  runhead.ExpNo(m_EventMetaData->getExperiment());
105  runhead.RunNo(m_EventMetaData->getRun());
106  runhead.Time(time(nullptr));
107  runhead.Type(0);
108  TLorentzVector momentumLER = m_BeamParameters->getLER();
109  TLorentzVector momentumHER = m_BeamParameters->getHER();
110  runhead.ELER(momentumLER.E());
111  runhead.EHER(momentumHER.E());
112  Belle::Belle_nominal_beam_Manager& beamManager =
113  Belle::Belle_nominal_beam_Manager::get_manager();
114  beamManager.remove();
115  Belle::Belle_nominal_beam& beam = beamManager.add();
116  beam.px_high(momentumHER.X());
117  beam.py_high(momentumHER.Y());
118  beam.pz_high(momentumHER.Z());
119  beam.px_low(momentumLER.X());
120  beam.py_low(momentumLER.Y());
121  beam.pz_low(momentumLER.Z());
122  TMatrixDSym herCovariance = m_BeamParameters->getCovHER();
123  beam.sigma_p_high(sqrt(herCovariance[0][0]));
124  TMatrixDSym lerCovariance = m_BeamParameters->getCovLER();
125  beam.sigma_p_low(sqrt(lerCovariance[0][0]));
126  /*
127  * The vertex parameters are in cm, as in basf2.
128  * The unit is not the same as for particles in GEN_HEPEVT.
129  */
130  TVector3 vertex = m_BeamParameters->getVertex();
131  beam.ip_x(vertex.X());
132  beam.ip_y(vertex.Y());
133  beam.ip_z(vertex.Z());
134  TMatrixDSym vertexCovariance = m_BeamParameters->getCovVertex();
135  beam.cang_high(momentumHER.Vect().Theta());
136  beam.cang_low(M_PI - momentumLER.Vect().Theta());
137  double angleIPZX = momentumHER.Vect().Theta() / 2;
138  beam.angle_ip_zx(angleIPZX);
139  /*
140  * Transformation of error matrix. It is inverse to the transformation in
141  * belle_legacy/ip/IpProfile.cc.
142  */
143  TRotation rotationY;
144  rotationY.RotateY(-angleIPZX);
145  TMatrixD rotationMatrix(3, 3);
146  rotationMatrix[0][0] = rotationY.XX();
147  rotationMatrix[0][1] = rotationY.XY();
148  rotationMatrix[0][2] = rotationY.XZ();
149  rotationMatrix[1][0] = rotationY.YX();
150  rotationMatrix[1][1] = rotationY.YY();
151  rotationMatrix[1][2] = rotationY.YZ();
152  rotationMatrix[2][0] = rotationY.ZX();
153  rotationMatrix[2][1] = rotationY.ZY();
154  rotationMatrix[2][2] = rotationY.ZZ();
155  TMatrixDSym vertexCovariance2 = vertexCovariance.Similarity(rotationMatrix);
156  beam.sigma_ip_x(sqrt(vertexCovariance2[0][0]));
157  beam.sigma_ip_y(sqrt(vertexCovariance2[1][1]));
158  beam.sigma_ip_z(sqrt(vertexCovariance2[2][2]));
159  m_BelleFile->write(BBS_BEGIN_RUN, 0);
160 }
161 
163  const MCParticle* particle, MCParticleGraph::GraphParticle* mother)
164 {
166  part = *particle;
167  if (mother != nullptr)
168  part.comesFrom(*mother);
169  int pdg = abs(particle->getPDG());
170  if ((pdg == Const::muon.getPDGCode()) ||
171  (pdg == Const::pion.getPDGCode()) ||
172  (pdg == Const::kaon.getPDGCode()) ||
173  ((pdg == Const::Kshort.getPDGCode()) && !m_DecayKsInGenerator) ||
174  (pdg == Const::Klong.getPDGCode()) ||
175  (pdg == Const::neutron.getPDGCode()) ||
176  ((pdg == Const::Lambda.getPDGCode()) && !m_DecayLambdaInGenerator) ||
177  (pdg == 3222) || // Sigma+
178  (pdg == 3112) || // Sigma-
179  (pdg == 3322) || // Xi0
180  (pdg == 3312) || // Xi-
181  (pdg == 3334)) { // Omega-
182  part.addStatus(MCParticle::c_StableInGenerator);
183  return;
184  }
185  std::vector<MCParticle*> daughters = particle->getDaughters();
186  for (const MCParticle* daughter : daughters)
187  addParticle(daughter, &part);
188 }
189 
191 {
192  Belle::Gen_hepevt_Manager& hepevtManager =
193  Belle::Gen_hepevt_Manager::get_manager();
194  hepevtManager.remove();
195  /*
196  * The time shift applied by basf module "evtgen" (file beam.cc) is
197  * vertex z coordinate [mm] / (2.0 * 2.99792458).
198  * The vertex coordinate is calculated relative to the IP position.
199  * The position correction happens at the simulation stage (bpsmear) in basf.
200  */
201  double timeShift = (m_MCInitialParticles->getVertex().Z() -
202  m_BeamParameters->getVertex().Z()) /
203  Unit::mm / (2.0 * 0.1 * Const::speedOfLight);
204  /*
205  * Regeneration of MCParticle array. It is necesary because in basf the
206  * long-lived particles (K_S0, K_L0, Lambda, neutron, pi, K, mu)
207  * are decayed by GEANT3.
208  */
210  for (const MCParticle& particle : m_MCParticles) {
211  if (particle.getMother() == nullptr)
212  addParticle(&particle, nullptr);
213  }
217  for (const MCParticle& particle : m_MCParticles) {
218  Belle::Gen_hepevt& hepevt = hepevtManager.add();
219  if (particle.hasStatus(MCParticle::c_Initial))
220  hepevt.isthep(3);
221  else if (particle.hasStatus(MCParticle::c_StableInGenerator))
222  hepevt.isthep(1);
223  else
224  hepevt.isthep(2);
225  hepevt.idhep(particle.getPDG());
226  hepevt.reset_mother();
227  const MCParticle* mother = particle.getMother();
228  int motherIndex = 0;
229  if (mother != nullptr)
230  motherIndex = mother->getIndex();
231  hepevt.moFirst(motherIndex);
232  hepevt.moLast(motherIndex);
233  hepevt.daFirst(particle.getFirstDaughter());
234  hepevt.daLast(particle.getLastDaughter());
235  TLorentzVector momentum = particle.get4Vector();
236  hepevt.PX(momentum.Px());
237  hepevt.PY(momentum.Py());
238  hepevt.PZ(momentum.Pz());
239  hepevt.E(momentum.E());
240  hepevt.M(particle.getMass());
241  TVector3 vertex = particle.getVertex();
242  hepevt.VX(vertex.X() / Unit::mm);
243  hepevt.VY(vertex.Y() / Unit::mm);
244  hepevt.VZ(vertex.Z() / Unit::mm);
245  hepevt.T(particle.getProductionTime() / Unit::mm * Const::speedOfLight +
246  timeShift);
247  }
248  m_BelleFile->write(BBS_EVENT, m_EventMetaData->getEvent());
249 }
250 
252 {
253 }
254 
256 {
257  delete m_BelleFile;
258 }
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:251
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:190
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:255
Belle2::BelleMCOutputModule::addParticle
void addParticle(const MCParticle *particle, MCParticleGraph::GraphParticle *mother)
Add particle to graph.
Definition: BelleMCOutputModule.cc:162
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:86
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