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