Belle II Software  release-08-01-10
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 
16 /* ROOT headers. */
17 #include <Math/VectorUtil.h>
18 
19 /* C++ headers. */
20 #include <algorithm>
21 
22 using namespace Belle2;
23 
24 REG_MODULE(KLMClustersReconstructor);
25 
27  m_PositionMode(c_FirstLayer),
28  m_ClusterMode(c_AnyHit)
29 {
30  setDescription("Unified BKLM/EKLM module for the reconstruction of KLMClusters.");
32  addParam("ClusteringAngle", m_ClusteringAngle, "Clustering angle (rad).",
33  0.26);
34  addParam("PositionMode", m_PositionModeString,
35  "Vertex position calculation mode ('FullAverage' or 'FirstLayer').",
36  std::string("FirstLayer"));
37  addParam("ClusterMode", m_ClusterModeString,
38  "Clusterization mode ('AnyHit' or 'FirstHit').",
39  std::string("AnyHit"));
40 }
41 
43 {
44 }
45 
47 {
48  m_KLMClusters.registerInDataStore();
49  m_Hit2ds.isRequired();
50  m_KLMClusters.registerRelationTo(m_Hit2ds);
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().R() < hit2->getPosition().R();
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  layerHitsBKLM = new int[nLayersBKLM];
87  layerHitsEKLM = new int[nLayersEKLM];
88  /* Fill vector of 2d hits. */
89  nHits = m_Hit2ds.getEntries();
90  for (i = 0; i < nHits; i++) {
91  if (m_Hit2ds[i]->isOutOfTime())
92  continue;
93  klmHit2ds.push_back(m_Hit2ds[i]);
94  }
95  /* Sort by the distance from center. */
96  sort(klmHit2ds.begin(), klmHit2ds.end(), compareDistance);
97  /* Clustering. */
98  while (klmHit2ds.size() > 0) {
99  klmClusterHits.clear();
100  it = klmHit2ds.begin();
101  klmClusterHits.push_back(*it);
102  it = klmHit2ds.erase(it);
103  while (it != klmHit2ds.end()) {
104  it2 = klmClusterHits.begin();
105  switch (m_ClusterMode) {
106  case c_AnyHit:
107  while (it2 != klmClusterHits.end()) {
108  if (ROOT::Math::VectorUtil::Angle(
109  (*it)->getPosition(), (*it2)->getPosition()) <
111  klmClusterHits.push_back(*it);
112  it = klmHit2ds.erase(it);
113  goto clusterFound;
114  } else
115  ++it2;
116  }
117  break;
118  case c_FirstHit:
119  if (ROOT::Math::VectorUtil::Angle(
120  (*it)->getPosition(), (*it2)->getPosition()) <
122  klmClusterHits.push_back(*it);
123  it = klmHit2ds.erase(it);
124  goto clusterFound;
125  }
126  break;
127  }
128  ++it;
129 clusterFound:;
130  }
131  ROOT::Math::XYZVector clusterPosition{0, 0, 0};
132  for (i = 0; i < nLayersBKLM; i++)
133  layerHitsBKLM[i] = 0;
134  for (i = 0; i < nLayersEKLM; i++)
135  layerHitsEKLM[i] = 0;
136  /* Find minimal time, fill layer array, find hit position. */
137  it0 = klmClusterHits.begin();
138  nHits = 0;
139  for (it = klmClusterHits.begin(); it != klmClusterHits.end(); ++it) {
140  if (((*it)->getSubdetector() == (*it0)->getSubdetector() &&
141  (*it)->getLayer() == (*it0)->getLayer()) ||
143  clusterPosition = clusterPosition + (*it)->getPosition();
144  nHits++;
145  }
146  if (minTime < 0 || (*it)->getTime() < minTime)
147  minTime = (*it)->getTime();
148  if ((*it)->getSubdetector() == KLMElementNumbers::c_BKLM)
149  layerHitsBKLM[(*it)->getLayer() - 1]++;
150  else
151  layerHitsEKLM[(*it)->getLayer() - 1]++;
152  }
153  clusterPosition = clusterPosition * (1.0 / nHits);
154  /* Find innermost layer. */
155  nLayers = 0;
156  innermostLayer = -1;
157  for (i = 0; i < nLayersBKLM; i++) {
158  if (layerHitsBKLM[i] > 0) {
159  nLayers++;
160  if (innermostLayer < 0)
161  innermostLayer = i + 1;
162  }
163  }
164  for (i = 0; i < nLayersEKLM; i++) {
165  if (layerHitsEKLM[i] > 0) {
166  nLayers++;
167  if (innermostLayer < 0)
168  innermostLayer = i + 1;
169  }
170  }
171  /* Calculate energy. */
172  //if (it0->inBKLM()) {
173  /*
174  * TODO: The constant is from BKLM K0L reconstructor,
175  * it must be recalculated.
176  */
177  p = klmClusterHits.size() * 0.215;
178  /* FIXME: Reimplement time calculation after completion of time calibration.
179  } else {
180  v = clusterPosition.R() / minTime / Const::speedOfLight;
181  if (v < 0.999999)
182  p = mass * v / sqrt(1.0 - v * v);
183  else
184  p = 0;
185  }*/
186  klmCluster = m_KLMClusters.appendNew(
187  clusterPosition.X(), clusterPosition.Y(), clusterPosition.Z(), minTime, nLayers,
188  innermostLayer, p);
189  for (it = klmClusterHits.begin(); it != klmClusterHits.end(); ++it)
190  klmCluster->addRelationTo(*it);
191  }
192  delete[] layerHitsBKLM;
193  delete[] layerHitsEKLM;
194 }
195 
197 {
198 }
199 
201 {
202 }
203 
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
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.
void beginRun() override
Called when entering a new run.
StoreArray< KLMCluster > m_KLMClusters
KLM clusters.
StoreArray< KLMHit2d > m_Hit2ds
Two-dimensional hits.
KLM 2d hit.
Definition: KLMHit2d.h:33
ROOT::Math::XYZVector getPosition() const
Get hit global position.
Definition: KLMHit2d.h:321
Base class for Modules.
Definition: Module.h:72
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
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
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).
REG_MODULE(arichBtest)
Register the Module.
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:560
Abstract base class for different kinds of events.