Belle II Software development
KLMClusterEfficiencyModule.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 <klm/modules/KLMClusterEfficiency/KLMClusterEfficiencyModule.h>
11
12/* KLM headers. */
13#include <klm/dataobjects/KLMHit2d.h>
14
15/* Basf2 headers. */
16#include <framework/gearbox/Const.h>
17
18/* ROOT headers. */
19#include <Math/VectorUtil.h>
20#include <TCanvas.h>
21#include <TH2F.h>
22#include <TMarker.h>
23#include <TStyle.h>
24
25using namespace Belle2;
26
27REG_MODULE(KLMClusterEfficiency);
28
30 m_OutputFile(nullptr), m_ClusterTree(nullptr), m_ReconstructionTree(nullptr),
36 m_ReconstructedKL02Clusters{0, 0, 0, 0, 0, 0},
38{
39 setDescription("Module for KLM cluster reconstruction efficiency studies.");
40 addParam("SaveClusterData", m_SaveClusterData,
41 "Whether to save cluster data or not.", false);
42 addParam("SaveReconstructionData", m_SaveReconstructionData,
43 "Whether to save reconstruction data or not.", true);
44 addParam("OutputFile", m_OutputFileName, "Output file.",
45 std::string("KLMClusterEfficiency.root"));
46 addParam("EventsClusterHistograms", m_EventsClusterHistograms,
47 "Draw cluster histograms for this number of events.", 0);
48}
49
53
55{
57 m_OutputFile = new TFile(m_OutputFileName.c_str(), "recreate");
59 m_ClusterTree = new TTree("klm_cluster", "");
60 m_ClusterTree->Branch("DecayVertexX", &m_DecayVertexX, "DecayVertexX/F");
61 m_ClusterTree->Branch("DecayVertexY", &m_DecayVertexY, "DecayVertexY/F");
62 m_ClusterTree->Branch("DecayVertexZ", &m_DecayVertexZ, "DecayVertexZ/F");
63 m_ClusterTree->Branch("MaxDecayVertexHitAngle", &m_MaxDecayVertexHitAngle,
64 "MaxDecayVertexHitAngle/F");
65 m_ClusterTree->Branch("ClusterX", &m_ClusterX, "ClusterX/F");
66 m_ClusterTree->Branch("ClusterY", &m_ClusterY, "ClusterY/F");
67 m_ClusterTree->Branch("ClusterZ", &m_ClusterZ, "ClusterZ/F");
68 m_ClusterTree->Branch("MaxClusterHitAngle", &m_MaxClusterHitAngle,
69 "MaxClusterHitAngle/F");
70 }
72 m_ReconstructionTree = new TTree("klm_reconstruction", "");
73 m_ReconstructionTree->Branch("KL0Clusters", &m_KL0Clusters,
74 "KL0Clusters/I");
75 m_ReconstructionTree->Branch("PartlyKL0Clusters", &m_PartlyKL0Clusters,
76 "PartlyKL0Clusters/I");
77 m_ReconstructionTree->Branch("OtherClusters", &m_OtherClusters,
78 "OtherClusters/I");
79 m_ReconstructionTree->Branch("NonreconstructedKL0", &m_NonreconstructedKL0,
80 "NonreconstructedKL0/I");
81 m_ReconstructionTree->Branch("ReconstructedKL01Cluster",
83 "ReconstructedKL01Cluster[3]/I");
84 m_ReconstructionTree->Branch("ReconstructedKL02Clusters",
86 "ReconstructedKL02Clusters[6]/I");
87 m_ReconstructionTree->Branch("ReconstructedKL03Clusters",
89 "ReconstructedKL03Clusters/I");
90 }
91 gStyle->SetOptStat(0);
92}
93
95{
96 static int nevent = 0;
97 /* cppcheck-suppress variableScope */
98 char str[128];
99 int i1, i2, i3, n1, n2, n3;
100 int bs1, bs2, es1, es2;
101 ROOT::Math::XYZVector clusterPosition;
102 ROOT::Math::XYZVector decayVertex, hitPosition;
103 float angle;
104 /* cppcheck-suppress variableScope */
105 bool haveKL0;
106 n1 = m_KLMClusters.getEntries();
107 for (i1 = 0; i1 < n1; i1++) {
108 haveKL0 = false;
109 RelationVector<MCParticle> clusterMCParticles =
110 m_KLMClusters[i1]->getRelationsTo<MCParticle>();
111 n2 = clusterMCParticles.size();
112 for (i2 = 0; i2 < n2; i2++) {
113 if (clusterMCParticles[i2]->getPDG() == Const::Klong.getPDGCode())
114 haveKL0 = true;
115 }
116 if (haveKL0) {
117 if (n2 == 1)
119 else
121 } else
123 }
124 if (nevent < m_EventsClusterHistograms) {
125 static TH2F* hzx = new TH2F("hzx", "", 100, -300, 420, 100, -320, 320);
126 static TH2F* hzy = new TH2F("hzy", "", 100, -300, 420, 100, -320, 320);
127 static TH2F* hxy = new TH2F("hxy", "", 100, -320, 320, 100, -320, 320);
128 static TCanvas* c1 = new TCanvas();
129 static TMarker* clusterMarker = new TMarker(0, 0, 20);
130 static TMarker* hitMarker = new TMarker(0, 0, 21);
131 if (nevent == 0) {
132 hzx->GetXaxis()->SetTitle("z, cm");
133 hzx->GetYaxis()->SetTitle("x, cm");
134 hzy->GetXaxis()->SetTitle("z, cm");
135 hzy->GetYaxis()->SetTitle("y, cm");
136 hxy->GetXaxis()->SetTitle("x, cm");
137 hxy->GetYaxis()->SetTitle("y, cm");
138 }
139 hzx->Draw();
140 for (i1 = 0; i1 < n1; i1++) {
141 clusterMarker->SetMarkerColor(i1 + 1);
142 hitMarker->SetMarkerColor(i1 + 1);
143 clusterPosition = m_KLMClusters[i1]->getClusterPosition();
144 clusterMarker->DrawMarker(clusterPosition.Z(), clusterPosition.X());
145 RelationVector<KLMHit2d> klmHit2ds =
146 m_KLMClusters[i1]->getRelationsTo<KLMHit2d>();
147 n2 = klmHit2ds.size();
148 for (i2 = 0; i2 < n2; i2++) {
149 hitPosition = klmHit2ds[i2]->getPosition();
150 hitMarker->DrawMarker(hitPosition.Z(), hitPosition.X());
151 }
152 }
153 snprintf(str, 128, "clusters%dzx.eps", nevent);
154 c1->Print(str);
155 hzy->Draw();
156 for (i1 = 0; i1 < n1; i1++) {
157 clusterMarker->SetMarkerColor(i1 + 1);
158 hitMarker->SetMarkerColor(i1 + 1);
159 clusterPosition = m_KLMClusters[i1]->getClusterPosition();
160 clusterMarker->DrawMarker(clusterPosition.Z(), clusterPosition.Y());
161 RelationVector<KLMHit2d> klmHit2ds =
162 m_KLMClusters[i1]->getRelationsTo<KLMHit2d>();
163 n2 = klmHit2ds.size();
164 for (i2 = 0; i2 < n2; i2++) {
165 hitPosition = klmHit2ds[i2]->getPosition();
166 hitMarker->DrawMarker(hitPosition.Z(), hitPosition.Y());
167 }
168 }
169 snprintf(str, 128, "clusters%dzy.eps", nevent);
170 c1->Print(str);
171 hxy->Draw();
172 for (i1 = 0; i1 < n1; i1++) {
173 clusterMarker->SetMarkerColor(i1 + 1);
174 hitMarker->SetMarkerColor(i1 + 1);
175 clusterPosition = m_KLMClusters[i1]->getClusterPosition();
176 clusterMarker->DrawMarker(clusterPosition.X(), clusterPosition.Y());
177 RelationVector<KLMHit2d> klmHit2ds =
178 m_KLMClusters[i1]->getRelationsTo<KLMHit2d>();
179 n2 = klmHit2ds.size();
180 for (i2 = 0; i2 < n2; i2++) {
181 hitPosition = klmHit2ds[i2]->getPosition();
182 hitMarker->DrawMarker(hitPosition.X(), hitPosition.Y());
183 }
184 }
185 snprintf(str, 128, "clusters%dxy.eps", nevent);
186 c1->Print(str);
187 nevent++;
188 }
189 n1 = m_MCParticles.getEntries();
190 for (i1 = 0; i1 < n1; i1++) {
191 if (m_MCParticles[i1]->getPDG() != Const::Klong.getPDGCode())
192 continue;
193 decayVertex = m_MCParticles[i1]->getDecayVertex();
194 m_DecayVertexX = decayVertex.X();
195 m_DecayVertexY = decayVertex.Y();
196 m_DecayVertexZ = decayVertex.Z();
198 RelationVector<KLMHit2d> mcKLMHit2ds =
199 m_MCParticles[i1]->getRelationsFrom<KLMHit2d>();
200 n2 = mcKLMHit2ds.size();
201 for (i2 = 0; i2 < n2; i2++) {
202 hitPosition = mcKLMHit2ds[i2]->getPosition();
203 angle = ROOT::Math::VectorUtil::Angle(decayVertex, hitPosition);
204 if (angle > m_MaxDecayVertexHitAngle)
206 }
207 RelationVector<KLMCluster> kl0Clusters =
208 m_MCParticles[i1]->getRelationsFrom<KLMCluster>();
209 n2 = kl0Clusters.size();
210 if (n2 == 0)
212 else if (n2 == 1) {
213 RelationVector<KLMHit2d> klmHit2ds =
214 kl0Clusters[0]->getRelationsTo<KLMHit2d>();
215 bs1 = 0;
216 es1 = 0;
217 for (const KLMHit2d& hit2d : klmHit2ds) {
218 if (hit2d.getSubdetector() == KLMElementNumbers::c_BKLM)
219 bs1++;
220 else
221 es1++;
222 }
223 if (bs1 > 0) {
224 if (es1 > 0)
226 else
228 } else if (es1 > 0)
230 RelationVector<MCParticle> m_MCParticles2 =
231 kl0Clusters[0]->getRelationsTo<MCParticle>();
232 if (m_MCParticles2.size() == 1) {
233 if (m_MCParticles2.weight(0) == 1)
235 }
236 } else if (n2 == 2) {
237 RelationVector<KLMHit2d> klmHit2ds1 =
238 kl0Clusters[0]->getRelationsTo<KLMHit2d>();
239 RelationVector<KLMHit2d> klmHit2ds2 =
240 kl0Clusters[1]->getRelationsTo<KLMHit2d>();
241 bs1 = 0;
242 bs2 = 0;
243 es1 = 0;
244 es2 = 0;
245 for (const KLMHit2d& hit2d : klmHit2ds1) {
246 if (hit2d.getSubdetector() == KLMElementNumbers::c_BKLM)
247 bs1++;
248 else
249 es1++;
250 }
251 for (const KLMHit2d& hit2d : klmHit2ds2) {
252 if (hit2d.getSubdetector() == KLMElementNumbers::c_BKLM)
253 bs2++;
254 else
255 es2++;
256 }
257 if (bs1 > 0 && bs2 > 0) {
258 if (es1 > 0 && es2 > 0) {
260 } else if ((es1 > 0 && es2 == 0) || (es1 == 0 && es2 > 0)) {
262 } else if (es1 == 0 && es2 == 0) {
264 }
265 } else if (bs1 > 0 && bs2 == 0) {
266 if (es1 > 0 && es2 > 0) {
268 } else if (es1 == 0 && es2 > 0) {
270 }
271 } else if (bs1 == 0 && bs2 > 0) {
272 if (es1 > 0 && es2 > 0) {
274 } else if (es1 > 0 && es2 == 0) {
276 }
277 } else if (bs1 == 0 && bs2 == 0) {
278 if (es1 > 0 && es2 > 0) {
280 }
281 }
282 } else if (n2 >= 3)
284 if (m_SaveClusterData) {
285 for (i2 = 0; i2 < n2; i2++) {
286 clusterPosition = kl0Clusters[i2]->getClusterPosition();
287 m_ClusterX = clusterPosition.X();
288 m_ClusterY = clusterPosition.Y();
289 m_ClusterZ = clusterPosition.Z();
291 RelationVector<KLMHit2d> klmHit2ds =
292 kl0Clusters[i2]->getRelationsTo<KLMHit2d>();
293 n3 = klmHit2ds.size();
294 for (i3 = 0; i3 < n3; i3++) {
295 hitPosition = klmHit2ds[i3]->getPosition();
296 angle = ROOT::Math::VectorUtil::Angle(clusterPosition, hitPosition);
297 if (angle > m_MaxClusterHitAngle)
298 m_MaxClusterHitAngle = angle;
299 }
300 m_ClusterTree->Fill();
301 }
302 }
303 }
304}
305
307{
308 int i, rec1Cluster, rec2Clusters;
309 rec1Cluster = 0;
310 rec2Clusters = 0;
311 for (i = 0; i < 3; i++)
312 rec1Cluster = rec1Cluster + m_ReconstructedKL01Cluster[i];
313 for (i = 0; i < 6; i++)
314 rec2Clusters = rec2Clusters + m_ReconstructedKL02Clusters[i];
315 /* Always printed once, not necessary to use LogVar. */
316 B2INFO("Total number of KLM clusters: " << m_KL0Clusters +
318 B2INFO("K_L0 clusters: " << m_KL0Clusters);
319 B2INFO("(K_L0+other) clusters: " << m_PartlyKL0Clusters);
320 B2INFO("Other clusters: " << m_OtherClusters);
321 B2INFO("Total number of generated K_L0: " << m_NonreconstructedKL0 +
322 rec1Cluster + rec2Clusters + m_ReconstructedKL03Clusters);
323 B2INFO("Nonreconstructed K_L0: " << m_NonreconstructedKL0);
324 B2INFO("K_L0 reconstructed as 1 cluster (total): " << rec1Cluster);
325 B2INFO("K_L0 reconstructed as 1 cluster (BKLM): " <<
327 B2INFO("K_L0 reconstructed as 1 cluster (BKLM/EKLM): " <<
329 B2INFO("K_L0 reconstructed as 1 cluster (EKLM): " <<
331 B2INFO("K_L0 reconstructed as 1 cluster (exact reconstruction): " <<
333 B2INFO("K_L0 reconstructed as 2 clusters (total): " << rec2Clusters);
334 B2INFO("K_L0 reconstructed as 2 clusters (2 * BKLM): " <<
336 B2INFO("K_L0 reconstructed as 2 clusters (BKLM + BKLM/EKLM): " <<
338 B2INFO("K_L0 reconstructed as 2 clusters (BKLM + EKLM): " <<
340 B2INFO("K_L0 reconstructed as 2 clusters (2 * BKLM/EKLM): " <<
342 B2INFO("K_L0 reconstructed as 2 clusters (BKLM/EKLM + EKLM): " <<
344 B2INFO("K_L0 reconstructed as 2 clusters (2 * EKLM): " <<
346 B2INFO("K_L0 reconstructed as 3 or more clusters: " <<
349 m_ReconstructionTree->Fill();
350 m_OutputFile->cd();
351 m_ReconstructionTree->Write();
353 }
354 if (m_SaveClusterData) {
355 m_OutputFile->cd();
356 m_ClusterTree->Write();
357 delete m_ClusterTree;
358 }
360 delete m_OutputFile;
361}
362
static const ParticleType Klong
K^0_L particle.
Definition Const.h:679
bool m_SaveClusterData
Whether to save cluster data or not.
float m_DecayVertexZ
MCParticle decay vertex Z coordinate.
float m_DecayVertexX
MCParticle decay vertex X coordinate.
float m_MaxClusterHitAngle
Maximal angle between KLM cluster and its hits.
void event() override
This method is called for each event.
int m_KL0Clusters
Number of clusters from a K_L0.
void terminate() override
This method is called at the end of the event processing.
int m_ReconstructedKL03Clusters
Number of K_L0 reconstructed as >= 2 clusters.
int m_EventsClusterHistograms
Draw cluster histograms for this number of events.
bool m_SaveReconstructionData
Whether to save reconstruction data or not.
int m_OtherClusters
Number of clusters from other particles.
int m_ExactlyReconstructedKL0
Number of K_L0 reconstructed as 1 cluster, and this cluster should be related only to 1 (K_L0 ) MCPar...
int m_PartlyKL0Clusters
Number of clusters from a K_L0 + other particles.
TTree * m_ReconstructionTree
Reconstruction tree.
StoreArray< KLMCluster > m_KLMClusters
KLM clusters.
int m_ReconstructedKL02Clusters[6]
Number of K_L0 reconstructed as 2 clusters in (2 * BKLM, BKLM + BKLM/EKLM, BKLM + EKLM,...
int m_ReconstructedKL01Cluster[3]
Number of K_L0 reconstructed as 1 cluster in (BKLM, BKLM/EKLM, EKLM).
float m_MaxDecayVertexHitAngle
Maximal angle between MCParticle decay vertex and its hits.
std::string m_OutputFileName
Output file name.
float m_DecayVertexY
MCParticle decay vertex Y coordinate.
StoreArray< MCParticle > m_MCParticles
MC particles.
int m_NonreconstructedKL0
Number of nonreconstructed K_L0.
KLM cluster data.
Definition KLMCluster.h:29
KLM 2d hit.
Definition KLMHit2d.h:33
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
float weight(int index) const
Get weight with index.
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
Abstract base class for different kinds of events.