Belle II Software  release-05-01-25
PXDClusterPositionEstimator.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Benjamin Schwenker *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <framework/logging/Logger.h>
12 #include <pxd/reconstruction/PXDClusterPositionEstimator.h>
13 #include <vxd/dataobjects/VxdID.h>
14 #include <pxd/geometry/SensorInfo.h>
15 #include <vxd/geometry/GeoCache.h>
16 
17 #include <cmath>
18 #include <numeric>
19 
20 using namespace std;
21 
22 //namespace Belle2 {
23 // namespace PXD {
24 
26 {
27  m_shapeIndexFromDB = unique_ptr<Belle2::DBObjPtr<Belle2::PXDClusterShapeIndexPar>>(new
29  m_positionEstimatorFromDB = unique_ptr<Belle2::DBObjPtr<Belle2::PXDClusterPositionEstimatorPar>>
31 
32  if ((*m_shapeIndexFromDB).isValid() && (*m_positionEstimatorFromDB).isValid()) {
33  setShapeIndexFromDB();
34  (*m_shapeIndexFromDB).addCallback(this, &Belle2::PXD::PXDClusterPositionEstimator::setShapeIndexFromDB);
35 
36  setPositionEstimatorFromDB();
37  (*m_positionEstimatorFromDB).addCallback(this, &Belle2::PXD::PXDClusterPositionEstimator::setPositionEstimatorFromDB);
38  }
39 }
40 
42 {
43  m_shapeIndexPar = **m_shapeIndexFromDB;
44 }
45 
47 {
48  m_positionEstimatorPar = **m_positionEstimatorFromDB;
49 }
50 
52 {
53  static std::unique_ptr<Belle2::PXD::PXDClusterPositionEstimator> instance(new Belle2::PXD::PXDClusterPositionEstimator());
54  return *instance;
55 }
56 
57 
59  double tu,
60  double tv) const
61 {
62  double thetaU = TMath::ATan2(tu, 1.0) * 180.0 / M_PI;
63  double thetaV = TMath::ATan2(tv, 1.0) * 180.0 / M_PI;
64  int sector_index = getSectorIndex(thetaU, thetaV);
65 
66  int clusterkind = cluster.getKind();
67  int shape_index = cluster.getSectorShapeIndices().at(sector_index);
68  float eta = cluster.getSectorEtaValues().at(sector_index);
69  return m_positionEstimatorPar.getOffset(shape_index, eta, thetaU, thetaV, clusterkind);
70 }
71 
72 
74 {
75  double thetaU = TMath::ATan2(tu, 1.0) * 180.0 / M_PI;
76  double thetaV = TMath::ATan2(tv, 1.0) * 180.0 / M_PI;
77  int clusterkind = cluster.getKind();
78  int sector_index = getSectorIndex(thetaU, thetaV);
79  int shape_index = cluster.getSectorShapeIndices().at(sector_index);
80  return m_positionEstimatorPar.getShapeLikelyhood(shape_index, thetaU, thetaV, clusterkind);
81 }
82 
83 
84 float Belle2::PXD::PXDClusterPositionEstimator::computeEta(const std::set<Belle2::PXD::Pixel>& pixels, int vStart, int vSize,
85  double thetaU, double thetaV) const
86 {
87  const Belle2::PXD::Pixel& headPixel = getHeadPixel(pixels, vStart, vSize, thetaU, thetaV);
88  const Belle2::PXD::Pixel& tailPixel = getTailPixel(pixels, vStart, vSize, thetaU, thetaV);
89  float eta = 0;
90  if (headPixel.getIndex() != tailPixel.getIndex()) {
91  eta = tailPixel.getCharge();
92  eta /= (tailPixel.getCharge() + headPixel.getCharge());
93  } else {
94  eta = tailPixel.getCharge();
95  }
96  return eta;
97 }
98 
99 const Belle2::PXD::Pixel& Belle2::PXD::PXDClusterPositionEstimator::getHeadPixel(const std::set<Belle2::PXD::Pixel>& pixels,
100  int vStart, int vSize, double thetaU,
101  double thetaV) const
102 {
103  if (thetaV >= 0) {
104  if (thetaU >= 0) {
105  return getLastPixelWithVOffset(pixels, vStart, vSize - 1);
106  } else {
107  return getFirstPixelWithVOffset(pixels, vStart, vSize - 1);
108  }
109  } else {
110  if (thetaU >= 0) {
111  return getLastPixelWithVOffset(pixels, vStart, 0);
112  } else {
113  return getFirstPixelWithVOffset(pixels, vStart, 0);
114  }
115  }
116 }
117 
118 const Belle2::PXD::Pixel& Belle2::PXD::PXDClusterPositionEstimator::getTailPixel(const std::set<Belle2::PXD::Pixel>& pixels,
119  int vStart, int vSize, double thetaU,
120  double thetaV) const
121 {
122  if (thetaV >= 0) {
123  if (thetaU >= 0) {
124  return getFirstPixelWithVOffset(pixels, vStart, 0);
125  } else {
126  return getLastPixelWithVOffset(pixels, vStart, 0);
127  }
128  } else {
129  if (thetaU >= 0) {
130  return getFirstPixelWithVOffset(pixels, vStart, vSize - 1);
131  } else {
132  return getLastPixelWithVOffset(pixels, vStart, vSize - 1);
133  }
134  }
135 }
136 
138  pixels,
139  int vStart, int vOffset) const
140 {
141  for (auto pxit = pixels.cbegin(); pxit != pixels.cend(); ++pxit) {
142  int v = pxit->getV() - vStart;
143  if (vOffset < v) {
144  if (pxit == pixels.cbegin()) {
145  } else {
146  pxit--;
147  return *pxit;
148  }
149  }
150  }
151  if (pixels.empty())
152  B2FATAL("Found cluster with empty pixel set. ");
153 
154  auto pxit = --pixels.cend();
155  return *pxit;
156 }
157 
159  const std::set<Belle2::PXD::Pixel>& pixels,
160  int vStart, int vOffset) const
161 {
162  for (const Belle2::PXD::Pixel& px : pixels) {
163  int v = px.getV() - vStart;
164  if (vOffset == v) {
165  return px;
166  }
167  }
168  if (pixels.empty())
169  B2FATAL("Found cluster with empty pixel set. ");
170 
171  return *pixels.cbegin();
172 }
173 
174 const std::string Belle2::PXD::PXDClusterPositionEstimator::getShortName(const std::set<Belle2::PXD::Pixel>& pixels, int uStart,
175  int vStart, int vSize, double thetaU,
176  double thetaV) const
177 {
178  const Belle2::PXD::Pixel& headPixel = getHeadPixel(pixels, vStart, vSize, thetaU, thetaV);
179  const Belle2::PXD::Pixel& tailPixel = getTailPixel(pixels, vStart, vSize, thetaU, thetaV);
180  std::string name = "S";
181 
182  name += "D" + std::to_string(tailPixel.getV() - vStart) + '.' + std::to_string(tailPixel.getU() - uStart);
183 
184  if (headPixel.getIndex() != tailPixel.getIndex()) {
185  name += "D" + std::to_string(headPixel.getV() - vStart) + '.' + std::to_string(headPixel.getU() - uStart);
186  }
187  return name;
188 }
189 
190 int Belle2::PXD::PXDClusterPositionEstimator::computeShapeIndex(const std::set<Belle2::PXD::Pixel>& pixels, int uStart, int vStart,
191  int vSize, double thetaU,
192  double thetaV) const
193 {
194  // Compute shape name
195  auto shape_name = getShortName(pixels, uStart, vStart, vSize, thetaU, thetaV);
196  // Return shape index
197  return m_shapeIndexPar.getShapeIndex(shape_name);
198 }
199 
200 
201 const std::string Belle2::PXD::PXDClusterPositionEstimator::getMirroredShortName(const std::set<Belle2::PXD::Pixel>& pixels,
202  int uStart,
203  int vStart, int vSize, double thetaU,
204  double thetaV) const
205 {
206  const Belle2::PXD::Pixel& headPixel = getHeadPixel(pixels, vStart, vSize, thetaU, thetaV);
207  const Belle2::PXD::Pixel& tailPixel = getTailPixel(pixels, vStart, vSize, thetaU, thetaV);
208  int vmax = vSize - 1;
209 
210  std::string name = "S";
211  name += "D" + std::to_string(vmax - tailPixel.getV() + vStart) + '.' + std::to_string(tailPixel.getU() - uStart);
212 
213  if (headPixel.getIndex() != tailPixel.getIndex()) {
214  name += "D" + std::to_string(vmax - headPixel.getV() + vStart) + '.' + std::to_string(headPixel.getU() - uStart);
215  }
216  return name;
217 }
218 
219 const std::string Belle2::PXD::PXDClusterPositionEstimator::getFullName(const std::set<Belle2::PXD::Pixel>& pixels, int uStart,
220  int vStart) const
221 {
222  return std::accumulate(pixels.begin(), pixels.end(), std::string("F"),
223  [uStart, vStart](auto name, auto px) {
224  return name + "D" + std::to_string(px.getV() - vStart) + "." + std::to_string(px.getU() - uStart);
225  });
226 }
227 
229 {
230  std::set<int> pixelkinds;
231  bool uEdge = false;
232  bool vEdge = false;
233 
234  Belle2::VxdID sensorID = cluster.getSensorID();
235  const Belle2::PXD::SensorInfo& Info = dynamic_cast<const Belle2::PXD::SensorInfo&>(Belle2::VXD::GeoCache::get(sensorID));
236 
237  for (const Belle2::PXDDigit& digit : cluster.getRelationsTo<Belle2::PXDDigit>("PXDDigits")) {
238  int pixelkind = Info.getPixelKindNew(sensorID, digit.getVCellID());
239  pixelkinds.insert(pixelkind);
240 
241  // Cluster at v sensor edge
242  if (digit.getVCellID() == 0 or digit.getVCellID() >= 767)
243  vEdge = true;
244  // Cluster at u sensor edge
245  if (digit.getUCellID() == 0 or digit.getUCellID() >= 249)
246  uEdge = true;
247  }
248 
249  // In most cases, clusterkind is just pixelkind of first digit
250  int clusterkind = *pixelkinds.begin();
251 
252  // Clusters with different pixelkinds or edge digits are special
253  // TODO: At the moment, clusterkind >3 will not be corrected
254  if (pixelkinds.size() > 1 || uEdge || vEdge)
255  clusterkind = 4;
256 
257  return clusterkind;
258 }
259 
260 int Belle2::PXD::PXDClusterPositionEstimator::getClusterkind(const std::vector<Belle2::PXD::Pixel>& pixels,
261  const Belle2::VxdID& sensorID) const
262 {
263  std::set<int> pixelkinds;
264  bool uEdge = false;
265  bool vEdge = false;
266 
267  const Belle2::PXD::SensorInfo& Info = dynamic_cast<const Belle2::PXD::SensorInfo&>(Belle2::VXD::GeoCache::get(sensorID));
268 
269  for (const Belle2::PXD::Pixel& pix : pixels) {
270  int pixelkind = Info.getPixelKindNew(sensorID, pix.getV());
271  pixelkinds.insert(pixelkind);
272 
273  // Cluster at v sensor edge
274  if (pix.getV() == 0 or pix.getV() >= 767)
275  vEdge = true;
276  // Cluster at u sensor edge
277  if (pix.getU() == 0 or pix.getU() >= 249)
278  uEdge = true;
279  }
280 
281  // In most cases, clusterkind is just pixelkind of first digit
282  int clusterkind = *pixelkinds.begin();
283 
284  // Clusters with different pixelkinds or edge digits are special
285  // TODO: At the moment, clusterkind >3 will not be corrected
286  if (pixelkinds.size() > 1 || uEdge || vEdge)
287  clusterkind = 4;
288 
289  return clusterkind;
290 }
291 
292 int Belle2::PXD::PXDClusterPositionEstimator::getSectorIndex(double thetaU, double thetaV) const
293 {
294  int sectorIndex = 0;
295  if (thetaU >= 0) {
296  if (thetaV >= 0) {
297  sectorIndex = 0;
298  } else {
299  sectorIndex = 3;
300  }
301  } else {
302  if (thetaV >= 0) {
303  sectorIndex = 1;
304  } else {
305  sectorIndex = 2;
306  }
307  }
308  return sectorIndex;
309 }
310 
311 
312 
313 // }
314 //}
Belle2::PXD::PXDClusterPositionEstimator::getHeadPixel
const Pixel & getHeadPixel(const std::set< Pixel > &pixels, int vStart, int vSize, double thetaU, double thetaV) const
Return reference to the head pixel in pixel set.
Definition: PXDClusterPositionEstimator.cc:99
Belle2::VxdID
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:43
Belle2::PXD::Pixel::getCharge
float getCharge() const
Return the Charge of the Pixel.
Definition: Pixel.h:81
Belle2::PXDClusterOffsetPar
The class for PXD cluster position offset payload.
Definition: PXDClusterOffsetPar.h:32
Belle2::VXD::GeoCache::get
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:141
Belle2::PXD::PXDClusterPositionEstimator::getLastPixelWithVOffset
const Pixel & getLastPixelWithVOffset(const std::set< Pixel > &pixels, int vStart, int vOffset) const
Return reference to the last pixel in pixel set with given vOffset from vStart.
Definition: PXDClusterPositionEstimator.cc:137
Belle2::PXD::PXDClusterPositionEstimator::computeShapeIndex
int computeShapeIndex(const std::set< Pixel > &pixels, int uStart, int vStart, int vSize, double thetaU, double thetaV) const
Return the shape index of the pixels.
Definition: PXDClusterPositionEstimator.cc:190
Belle2::PXD::Pixel
Class to represent one pixel, used in clustering for fast access.
Definition: Pixel.h:47
Belle2::PXD::PXDClusterPositionEstimator::getFirstPixelWithVOffset
const Pixel & getFirstPixelWithVOffset(const std::set< Pixel > &pixels, int vStart, int vOffset) const
Return reference to the first pixel in pixel set with given vOffset from vStart.
Definition: PXDClusterPositionEstimator.cc:158
Belle2::PXD::PXDClusterPositionEstimator::getShortName
const std::string getShortName(const std::set< Pixel > &pixels, int uStart, int vStart, int vSize, double thetaU, double thetaV) const
Return the name for the pixel set.
Definition: PXDClusterPositionEstimator.cc:174
Belle2::PXD::SensorInfo::getPixelKindNew
int getPixelKindNew(const VxdID &sensorID, int vID) const
Return pixel kind ID.
Definition: SensorInfo.cc:76
Belle2::PXD::PXDClusterPositionEstimator::getSectorIndex
int getSectorIndex(double thetaU, double thetaV) const
Get sector index from angles.
Definition: PXDClusterPositionEstimator.cc:292
Belle2::PXDDigit
The PXD digit class.
Definition: PXDDigit.h:38
Belle2::DBObjPtr< Belle2::PXDClusterShapeIndexPar >
Belle2::PXD::PXDClusterPositionEstimator::getInstance
static PXDClusterPositionEstimator & getInstance()
Main (and only) way to access the PXDClusterPositionEstimator.
Definition: PXDClusterPositionEstimator.cc:51
Belle2::PXD::PXDClusterPositionEstimator::getMirroredShortName
const std::string getMirroredShortName(const std::set< Pixel > &pixels, int uStart, int vStart, int vSize, double thetaU, double thetaV) const
Return the mirrored name for the pixel set.
Definition: PXDClusterPositionEstimator.cc:201
Belle2::PXD::SensorInfo
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
Definition: SensorInfo.h:34
Belle2::PXD::PXDClusterPositionEstimator::getClusterkind
int getClusterkind(const PXDCluster &cluster) const
Return kind of cluster needed to find cluster position correction.
Definition: PXDClusterPositionEstimator.cc:228
Belle2::PXD::PXDClusterPositionEstimator::setPositionEstimatorFromDB
void setPositionEstimatorFromDB()
Set PositionEstimator from DB.
Definition: PXDClusterPositionEstimator.cc:46
Belle2::PXD::PXDClusterPositionEstimator::getShapeLikelyhood
float getShapeLikelyhood(const PXDCluster &cluster, double tu, double tv) const
Return cluster shape likelyhood.
Definition: PXDClusterPositionEstimator.cc:73
Belle2::PXD::PXDClusterPositionEstimator::getClusterOffset
const PXDClusterOffsetPar * getClusterOffset(const PXDCluster &cluster, double tu, double tv) const
Return pointer to cluster offsets, can be nullptr.
Definition: PXDClusterPositionEstimator.cc:58
Belle2::PXDCluster
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:41
Belle2::PXD::Pixel::getIndex
unsigned int getIndex() const
Return the Index of the digit.
Definition: Pixel.h:83
Belle2::PXD::PXDClusterPositionEstimator::setShapeIndexFromDB
void setShapeIndexFromDB()
Set ShapeIndex from DB.
Definition: PXDClusterPositionEstimator.cc:41
Belle2::PXD::Pixel::getV
unsigned short getV() const
Return the CellID in v.
Definition: Pixel.h:79
Belle2::PXD::Pixel::getU
unsigned short getU() const
Return the CellID in u.
Definition: Pixel.h:77
Belle2::PXD::PXDClusterPositionEstimator::computeEta
float computeEta(const std::set< Pixel > &pixels, int vStart, int vSize, double thetaU, double thetaV) const
Return the normed charge ratio between head and tail pixels (size>=2) or the charge of the seed (size...
Definition: PXDClusterPositionEstimator.cc:84
Belle2::PXD::PXDClusterPositionEstimator::getFullName
const std::string getFullName(const std::set< Pixel > &pixels, int uStart, int vStart) const
Return a name for the pixel set.
Definition: PXDClusterPositionEstimator.cc:219
Belle2::PXD::PXDClusterPositionEstimator::getTailPixel
const Pixel & getTailPixel(const std::set< Pixel > &pixels, int vStart, int vSize, double thetaU, double thetaV) const
Return reference to the tail pixel in pixel set.
Definition: PXDClusterPositionEstimator.cc:118
Belle2::PXD::PXDClusterPositionEstimator
Singleton class that estimates cluster positions taking into account the estimated track incidence an...
Definition: PXDClusterPositionEstimator.h:43
Belle2::PXD::PXDClusterPositionEstimator::initialize
void initialize()
Initialize PXDClusterPositionEstimator from DB.
Definition: PXDClusterPositionEstimator.cc:25