Belle II Software  release-06-02-00
KLMClustersReconstructorModule.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/KLMClustersReconstructor/KLMClustersReconstructorModule.h>
11 
12 /* KLM headers. */
13 #include <klm/dataobjects/bklm/BKLMElementNumbers.h>
14 #include <klm/dataobjects/eklm/EKLMElementNumbers.h>
15 #include <klm/modules/KLMClustersReconstructor/KLMHit2d.h>
16 
17 /* C++ headers. */
18 #include <algorithm>
19 
20 using namespace Belle2;
21 
22 REG_MODULE(KLMClustersReconstructor)
23 
25  m_PositionMode(c_FirstLayer),
26  m_ClusterMode(c_AnyHit)
27 {
28  setDescription("Unified BKLM/EKLM module for the reconstruction of KLMClusters.");
29  setPropertyFlags(c_ParallelProcessingCertified);
30  addParam("ClusteringAngle", m_ClusteringAngle, "Clustering angle (rad).",
31  0.26);
32  addParam("PositionMode", m_PositionModeString,
33  "Vertex position calculation mode ('FullAverage' or 'FirstLayer').",
34  std::string("FirstLayer"));
35  addParam("ClusterMode", m_ClusterModeString,
36  "Clusterization mode ('AnyHit' or 'FirstHit').",
37  std::string("AnyHit"));
38 }
39 
41 {
42 }
43 
45 {
46  m_KLMClusters.registerInDataStore();
47  m_BKLMHit2ds.isRequired();
48  m_EKLMHit2ds.isRequired();
49  m_KLMClusters.registerRelationTo(m_BKLMHit2ds);
50  m_KLMClusters.registerRelationTo(m_EKLMHit2ds);
51  if (m_PositionModeString == "FullAverage")
53  else if (m_PositionModeString == "FirstLayer")
55  else
56  B2FATAL("Incorrect PositionMode argument.");
57  if (m_ClusterModeString == "AnyHit")
59  else if (m_ClusterModeString == "FirstHit")
61  else
62  B2FATAL("Incorrect ClusterMode argument.");
63 }
64 
66 {
67 }
68 
69 static bool compareDistance(const KLMHit2d& hit1, const KLMHit2d& hit2)
70 {
71  return hit1.getPosition().Mag() < hit2.getPosition().Mag();
72 }
73 
75 {
76  //static double mass = Const::Klong.getMass();
77  int i, nLayers, innermostLayer, nHits;
80  int* layerHitsBKLM, *layerHitsEKLM;
81  float minTime = -1;
82  double p;//, v;
83  std::vector<KLMHit2d> klmHit2ds, klmClusterHits;
84  std::vector<KLMHit2d>::iterator it, it0, it2;
85  KLMCluster* klmCluster;
86  TVector3 hitPos;
87  layerHitsBKLM = new int[nLayersBKLM];
88  layerHitsEKLM = new int[nLayersEKLM];
89  /* Fill vector of 2d hits. */
90  int nHitsBKLM = m_BKLMHit2ds.getEntries();
91  for (i = 0; i < nHitsBKLM; i++) {
92  if (m_BKLMHit2ds[i]->isOutOfTime())
93  continue;
94  klmHit2ds.push_back(KLMHit2d(m_BKLMHit2ds[i]));
95  }
96  int nHitsEKLM = m_EKLMHit2ds.getEntries();
97  for (i = 0; i < nHitsEKLM; i++) {
98  klmHit2ds.push_back(KLMHit2d(m_EKLMHit2ds[i]));
99  }
100  /* Sort by the distance from center. */
101  sort(klmHit2ds.begin(), klmHit2ds.end(), compareDistance);
102  /* Clustering. */
103  while (klmHit2ds.size() > 0) {
104  klmClusterHits.clear();
105  it = klmHit2ds.begin();
106  klmClusterHits.push_back(*it);
107  it = klmHit2ds.erase(it);
108  while (it != klmHit2ds.end()) {
109  it2 = klmClusterHits.begin();
110  switch (m_ClusterMode) {
111  case c_AnyHit:
112  while (it2 != klmClusterHits.end()) {
113  if (it->getPosition().Angle(it2->getPosition()) <
115  klmClusterHits.push_back(*it);
116  it = klmHit2ds.erase(it);
117  goto clusterFound;
118  } else
119  ++it2;
120  }
121  break;
122  case c_FirstHit:
123  if (it->getPosition().Angle(it2->getPosition()) <
125  klmClusterHits.push_back(*it);
126  it = klmHit2ds.erase(it);
127  goto clusterFound;
128  }
129  break;
130  }
131  ++it;
132 clusterFound:;
133  }
134  hitPos.SetX(0);
135  hitPos.SetY(0);
136  hitPos.SetZ(0);
137  for (i = 0; i < nLayersBKLM; i++)
138  layerHitsBKLM[i] = 0;
139  for (i = 0; i < nLayersEKLM; i++)
140  layerHitsEKLM[i] = 0;
141  /* Find minimal time, fill layer array, find hit position. */
142  it0 = klmClusterHits.begin();
143  nHits = 0;
144  for (it = klmClusterHits.begin(); it != klmClusterHits.end(); ++it) {
145  if ((it->getLayer() == it0->getLayer() &&
146  it->inBKLM() == it0->inBKLM()) || m_PositionMode == c_FullAverage) {
147  hitPos = hitPos + it->getPosition();
148  nHits++;
149  }
150  if (minTime < 0 || it->getTime() < minTime)
151  minTime = it->getTime();
152  if (it->inBKLM())
153  layerHitsBKLM[it->getLayer() - 1]++;
154  else
155  layerHitsEKLM[it->getLayer() - 1]++;
156  }
157  hitPos = hitPos * (1.0 / nHits);
158  /* Find innermost layer. */
159  nLayers = 0;
160  innermostLayer = -1;
161  for (i = 0; i < nLayersBKLM; i++) {
162  if (layerHitsBKLM[i] > 0) {
163  nLayers++;
164  if (innermostLayer < 0)
165  innermostLayer = i + 1;
166  }
167  }
168  for (i = 0; i < nLayersEKLM; i++) {
169  if (layerHitsEKLM[i] > 0) {
170  nLayers++;
171  if (innermostLayer < 0)
172  innermostLayer = i + 1;
173  }
174  }
175  /* Calculate energy. */
176  //if (it0->inBKLM()) {
177  /*
178  * TODO: The constant is from BKLM K0L reconstructor,
179  * it must be recalculated.
180  */
181  p = klmClusterHits.size() * 0.215;
182  /* FIXME: Reimplement time calculation after completion of time calibration.
183  } else {
184  v = hitPos.Mag() / minTime / Const::speedOfLight;
185  if (v < 0.999999)
186  p = mass * v / sqrt(1.0 - v * v);
187  else
188  p = 0;
189  }*/
190  klmCluster = m_KLMClusters.appendNew(
191  hitPos.x(), hitPos.y(), hitPos.z(), minTime, nLayers,
192  innermostLayer, p);
193  for (it = klmClusterHits.begin(); it != klmClusterHits.end(); ++it) {
194  if (it->inBKLM())
195  klmCluster->addRelationTo(it->getBKLMHit2d());
196  else
197  klmCluster->addRelationTo(it->getEKLMHit2d());
198  }
199  }
200  delete[] layerHitsBKLM;
201  delete[] layerHitsEKLM;
202 }
203 
205 {
206 }
207 
209 {
210 }
211 
static constexpr int getMaximalLayerNumber()
Get maximal layer number (1-based).
static constexpr int getMaximalLayerNumber()
Get maximal layer number.
KLM cluster data.
Definition: KLMCluster.h:28
Module KLMClustersReconstructorModule.
enum ClusterMode m_ClusterMode
Clusterization mode.
void event() override
This method is called for each event.
void endRun() override
This method is called if the current run ends.
void terminate() override
This method is called at the end of the event processing.
std::string m_PositionModeString
Vertex position calculation mode.
enum PositionMode m_PositionMode
Vertex position calculation mode.
StoreArray< BKLMHit2d > m_BKLMHit2ds
BKLM 2d hits.
void beginRun() override
Called when entering a new run.
StoreArray< EKLMHit2d > m_EKLMHit2ds
EKLM 2d hits.
StoreArray< KLMCluster > m_KLMClusters
KLM clusters.
Class for simultaneous handling of the BKLM and EKLM 2d hits.
Definition: KLMHit2d.h:24
TVector3 getPosition() const
Get hit position.
Definition: KLMHit2d.cc:32
Base class for Modules.
Definition: Module.h:72
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.