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) const
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) const
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) const
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) const
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) const
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) const
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) const
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) const
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
295int Belle2::PXD::PXDClusterPositionEstimator::getSectorIndex(double thetaU, double thetaV) const
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...
void initialize()
Initialize PXDClusterPositionEstimator from DB.
PXDClusterPositionEstimatorPar m_positionEstimatorPar
Current valid PXDClusterPositionEstimatorPar.
const std::string getFullName(const std::set< Pixel > &pixels, int uStart, int vStart) const
Return a name for the pixel set.
static PXDClusterPositionEstimator & getInstance()
Main (and only) way to access the PXDClusterPositionEstimator.
int getSectorIndex(double thetaU, double thetaV) const
Get sector index from angles.
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.
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.
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.
const PXDClusterOffsetPar * getClusterOffset(const PXDCluster &cluster, double tu, double tv) const
Return pointer to cluster offsets, can be nullptr.
PXDClusterShapeIndexPar m_shapeIndexPar
Current valid PXDClusterShapeIndex.
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...
float getShapeLikelyhood(const PXDCluster &cluster, double tu, double tv) const
Return cluster shape likelihood.
std::unique_ptr< DBObjPtr< PXDClusterPositionEstimatorPar > > m_positionEstimatorFromDB
PXDClusterPositionEstimatorPar retrieved from DB.
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.
void setPositionEstimatorFromDB()
Set PositionEstimator from DB.
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.
int getClusterkind(const PXDCluster &cluster) const
Return kind of cluster needed to find cluster position correction.
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.
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.
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.