Belle II Software light-2607-kasei
BelleMCOutputModule.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 <b2bii/modules/BelleMCOutput/BelleMCOutputModule.h>
11
12/* Basf2 headers. */
13#include <framework/gearbox/Unit.h>
14#include <framework/logging/Logger.h>
15
16/* Belle headers. */
17#include <belle_legacy/tables/belletdf.h>
18#include <belle_legacy/tables/hepevt.h>
19#include <belle_legacy/tables/filespec.h>
20
21/* ROOT headers. */
22#include <TMatrixD.h>
23#include <Math/RotationY.h>
24#include <Math/Rotation3D.h>
25
26using namespace Belle2;
27
28REG_MODULE(BelleMCOutput);
29
31 Module()
32{
33 setDescription("Output of MC particle list in Belle format.");
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
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#if defined(__GNUC__) && !defined(__clang__)
97#pragma GCC diagnostic push
98#pragma GCC diagnostic ignored "-Wstringop-truncation"
99#endif
100 file.Spec(m_OutputFileName.substr(position, std::min(length, 8)).c_str());
101#if defined(__GNUC__) && !defined(__clang__)
102#pragma GCC diagnostic pop
103#endif
104 position += 8;
105 length -= 8;
106 } while (length > 0);
107 Belle::Belle_runhead_Manager& runheadManager =
108 Belle::Belle_runhead_Manager::get_manager();
109 runheadManager.remove();
110 Belle::Belle_runhead& runhead = runheadManager.add();
111 runhead.ExpMC(2);
112 runhead.ExpNo(m_EventMetaData->getExperiment());
113 runhead.RunNo(m_EventMetaData->getRun());
114 runhead.Time(time(nullptr));
115 runhead.Type(0);
116 ROOT::Math::PxPyPzEVector momentumLER = m_BeamParameters->getLER();
117 ROOT::Math::PxPyPzEVector momentumHER = m_BeamParameters->getHER();
118 runhead.ELER(momentumLER.E());
119 runhead.EHER(momentumHER.E());
120 Belle::Belle_nominal_beam_Manager& beamManager =
121 Belle::Belle_nominal_beam_Manager::get_manager();
122 beamManager.remove();
123 Belle::Belle_nominal_beam& beam = beamManager.add();
124 beam.px_high(momentumHER.X());
125 beam.py_high(momentumHER.Y());
126 beam.pz_high(momentumHER.Z());
127 beam.px_low(momentumLER.X());
128 beam.py_low(momentumLER.Y());
129 beam.pz_low(momentumLER.Z());
130 TMatrixDSym herCovariance = m_BeamParameters->getCovHER();
131 beam.sigma_p_high(sqrt(herCovariance[0][0]));
132 TMatrixDSym lerCovariance = m_BeamParameters->getCovLER();
133 beam.sigma_p_low(sqrt(lerCovariance[0][0]));
134 /*
135 * The vertex parameters are in cm, as in basf2.
136 * The unit is not the same as for particles in GEN_HEPEVT.
137 */
138 ROOT::Math::XYZVector vertex = m_BeamParameters->getVertex();
139 beam.ip_x(vertex.X());
140 beam.ip_y(vertex.Y());
141 beam.ip_z(vertex.Z());
142 TMatrixDSym vertexCovariance = m_BeamParameters->getCovVertex();
143 beam.cang_high(momentumHER.Theta());
144 beam.cang_low(M_PI - momentumLER.Theta());
145 double angleIPZX = momentumHER.Theta() / 2;
146 beam.angle_ip_zx(angleIPZX);
147 /*
148 * Transformation of error matrix. It is inverse to the transformation in
149 * belle_legacy/ip/IpProfile.cc.
150 */
151 ROOT::Math::RotationY rotationY(-angleIPZX);
152 ROOT::Math::Rotation3D rotation(rotationY);
153 TMatrixD rotationMatrix(3, 3);
154 rotation.GetRotationMatrix(rotationMatrix);
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-
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 necessary because in basf the
206 * long-lived particles (K_S0, K_L0, Lambda, neutron, pi, K, mu)
207 * are decayed by GEANT3.
208 */
209 m_MCParticleGraph.clear();
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 ROOT::Math::PxPyPzEVector 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 ROOT::Math::XYZVector 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
254
256{
257 delete m_BelleFile;
258}
void addParticle(const MCParticle *particle, MCParticleGraph::GraphParticle *mother)
Add particle to graph.
StoreObjPtr< MCInitialParticles > m_MCInitialParticles
Initial particles.
virtual void initialize() override
Initializer.
bool m_DecayKsInGenerator
Decay K_S0 in generator.
virtual void event() override
This method is called for each event.
Belle::Panther_FileIO * m_BelleFile
Belle file input-output handler.
virtual void endRun() override
This method is called if the current run ends.
virtual void terminate() override
This method is called at the end of the event processing.
virtual void beginRun() override
Called when entering a new run.
DBObjPtr< BeamParameters > m_BeamParameters
Beam parameters.
virtual ~BelleMCOutputModule()
Destructor.
bool m_DecayLambdaInGenerator
Decay Lambda in generator.
std::string m_OutputFileName
Output file name.
StoreObjPtr< EventMetaData > m_EventMetaData
Event metadata.
StoreArray< MCParticle > m_MCParticles
MC particles.
MCParticleGraph m_MCParticleGraph
MC particle graph.
static const ParticleType neutron
neutron particle
Definition Const.h:676
static const ParticleType Lambda
Lambda particle.
Definition Const.h:680
static const ChargedStable muon
muon particle
Definition Const.h:661
static const ChargedStable pion
charged pion particle
Definition Const.h:662
static const ParticleType Klong
K^0_L particle.
Definition Const.h:679
static const double speedOfLight
[cm/ns]
Definition Const.h:696
static const ParticleType Kshort
K^0_S particle.
Definition Const.h:678
static const ChargedStable kaon
charged kaon particle
Definition Const.h:663
Class to represent Particle data in graph.
void comesFrom(GraphParticle &mother)
Tells the graph that this particle is a decay product of mother.
@ c_checkCyclic
Check for cyclic dependencies.
@ c_clearParticles
Clear the particle list before adding the graph.
@ c_setDecayInfo
Set decay time and vertex.
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
Definition MCParticle.h:57
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
Definition MCParticle.h:49
int getIndex() const
Get 1-based index of the particle in the corresponding MCParticle list.
Definition MCParticle.h:219
void addStatus(unsigned short int bitmask)
Add bitmask to current status.
Definition MCParticle.h:343
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
Definition MCParticle.cc:50
int getPDG() const
Return PDG code of particle.
Definition MCParticle.h:101
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
Module()
Constructor.
Definition Module.cc:30
@ c_Output
This module is an output module (writes data).
Definition Module.h:79
static const double mm
[millimeters]
Definition Unit.h:70
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
MCParticle * getMother() const
Returns a pointer to the mother particle.
Definition MCParticle.h:591
Abstract base class for different kinds of events.