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 <vxd/dataobjects/VxdID.h>
12#include <pxd/geometry/SensorInfo.h>
13#include <vxd/geometry/GeoCache.h>
14#include <TMath.h>
15
16#include <cmath>
17#include <numeric>
18
19using namespace std;
20
21//namespace Belle2 {
22// namespace PXD {
23
25{
26 m_shapeIndexFromDB = unique_ptr<Belle2::DBObjPtr<Belle2::PXDClusterShapeIndexPar>>(new
28 m_positionEstimatorFromDB = unique_ptr<Belle2::DBObjPtr<Belle2::PXDClusterPositionEstimatorPar>>
30
31 if ((*m_shapeIndexFromDB).isValid() && (*m_positionEstimatorFromDB).isValid()) {
33 (*m_shapeIndexFromDB).addCallback(this, &Belle2::PXD::PXDClusterPositionEstimator::setShapeIndexFromDB);
34
36 (*m_positionEstimatorFromDB).addCallback(this, &Belle2::PXD::PXDClusterPositionEstimator::setPositionEstimatorFromDB);
37 }
38}
39
44
49
51{
52 static std::unique_ptr<Belle2::PXD::PXDClusterPositionEstimator> instance(new Belle2::PXD::PXDClusterPositionEstimator());
53 return *instance;
54}
55
56
58 double tu,
59 double tv) const
60{
61 double thetaU = TMath::ATan2(tu, 1.0) * 180.0 / M_PI;
62 double thetaV = TMath::ATan2(tv, 1.0) * 180.0 / M_PI;
63 int sector_index = getSectorIndex(thetaU, thetaV);
64
65 int clusterkind = cluster.getKind();
66 int shape_index = cluster.getSectorShapeIndices().at(sector_index);
67 float eta = cluster.getSectorEtaValues().at(sector_index);
68 return m_positionEstimatorPar.getOffset(shape_index, eta, thetaU, thetaV, clusterkind);
69}
70
71
73{
74 double thetaU = TMath::ATan2(tu, 1.0) * 180.0 / M_PI;
75 double thetaV = TMath::ATan2(tv, 1.0) * 180.0 / M_PI;
76 int clusterkind = cluster.getKind();
77 int sector_index = getSectorIndex(thetaU, thetaV);
78 int shape_index = cluster.getSectorShapeIndices().at(sector_index);
79 return m_positionEstimatorPar.getShapeLikelyhood(shape_index, thetaU, thetaV, clusterkind);
80}
81
82
83float Belle2::PXD::PXDClusterPositionEstimator::computeEta(const std::set<Belle2::PXD::Pixel>& pixels, int vStart, int vSize,
84 double thetaU, double thetaV) const
85{
86 const Belle2::PXD::Pixel& headPixel = getHeadPixel(pixels, vStart, vSize, thetaU, thetaV);
87 const Belle2::PXD::Pixel& tailPixel = getTailPixel(pixels, vStart, vSize, thetaU, thetaV);
88 float eta = 0;
89 if (headPixel.getIndex() != tailPixel.getIndex()) {
90 eta = tailPixel.getCharge();
91 eta /= (tailPixel.getCharge() + headPixel.getCharge());
92 } else {
93 eta = tailPixel.getCharge();
94 }
95 return eta;
96}
97
98const Belle2::PXD::Pixel& Belle2::PXD::PXDClusterPositionEstimator::getHeadPixel(const std::set<Belle2::PXD::Pixel>& pixels,
99 int vStart, int vSize, double thetaU,
100 double thetaV) const
101{
102 if (thetaV >= 0) {
103 if (thetaU >= 0) {
104 return getLastPixelWithVOffset(pixels, vStart, vSize - 1);
105 } else {
106 return getFirstPixelWithVOffset(pixels, vStart, vSize - 1);
107 }
108 } else {
109 if (thetaU >= 0) {
110 return getLastPixelWithVOffset(pixels, vStart, 0);
111 } else {
112 return getFirstPixelWithVOffset(pixels, vStart, 0);
113 }
114 }
115}
116
117const Belle2::PXD::Pixel& Belle2::PXD::PXDClusterPositionEstimator::getTailPixel(const std::set<Belle2::PXD::Pixel>& pixels,
118 int vStart, int vSize, double thetaU,
119 double thetaV) const
120{
121 if (thetaV >= 0) {
122 if (thetaU >= 0) {
123 return getFirstPixelWithVOffset(pixels, vStart, 0);
124 } else {
125 return getLastPixelWithVOffset(pixels, vStart, 0);
126 }
127 } else {
128 if (thetaU >= 0) {
129 return getFirstPixelWithVOffset(pixels, vStart, vSize - 1);
130 } else {
131 return getLastPixelWithVOffset(pixels, vStart, vSize - 1);
132 }
133 }
134}
135
137 pixels,
138 int vStart, int vOffset) const
139{
140 for (auto pxit = pixels.cbegin(); pxit != pixels.cend(); ++pxit) {
141 int v = pxit->getV() - vStart;
142 if (vOffset < v) {
143 if (pxit == pixels.cbegin()) {
144 } else {
145 pxit--;
146 return *pxit;
147 }
148 }
149 }
150 if (pixels.empty())
151 B2FATAL("Found cluster with empty pixel set. ");
152
153 auto pxit = --pixels.cend();
154 return *pxit;
155}
156
158 const std::set<Belle2::PXD::Pixel>& pixels,
159 int vStart, int vOffset) const
160{
161 for (const Belle2::PXD::Pixel& px : pixels) {
162 int v = px.getV() - vStart;
163 if (vOffset == v) {
164 return px;
165 }
166 }
167 if (pixels.empty())
168 B2FATAL("Found cluster with empty pixel set. ");
169
170 return *pixels.cbegin();
171}
172
173const std::string Belle2::PXD::PXDClusterPositionEstimator::getShortName(const std::set<Belle2::PXD::Pixel>& pixels, int uStart,
174 int vStart, int vSize, double thetaU,
175 double thetaV) const
176{
177 const Belle2::PXD::Pixel& headPixel = getHeadPixel(pixels, vStart, vSize, thetaU, thetaV);
178 const Belle2::PXD::Pixel& tailPixel = getTailPixel(pixels, vStart, vSize, thetaU, thetaV);
179 std::string name = "S";
180
181 name += "D" + std::to_string(tailPixel.getV() - vStart) + '.' + std::to_string(tailPixel.getU() - uStart);
182
183 if (headPixel.getIndex() != tailPixel.getIndex()) {
184 name += "D" + std::to_string(headPixel.getV() - vStart) + '.' + std::to_string(headPixel.getU() - uStart);
185 }
186 return name;
187}
188
189int Belle2::PXD::PXDClusterPositionEstimator::computeShapeIndex(const std::set<Belle2::PXD::Pixel>& pixels, int uStart, int vStart,
190 int vSize, double thetaU,
191 double thetaV) const
192{
193 // Compute shape name
194 auto shape_name = getShortName(pixels, uStart, vStart, vSize, thetaU, thetaV);
195 // Return shape index
196 return m_shapeIndexPar.getShapeIndex(shape_name);
197}
198
199
200const std::string Belle2::PXD::PXDClusterPositionEstimator::getMirroredShortName(const std::set<Belle2::PXD::Pixel>& pixels,
201 int uStart,
202 int vStart, int vSize, double thetaU,
203 double thetaV) const
204{
205 const Belle2::PXD::Pixel& headPixel = getHeadPixel(pixels, vStart, vSize, thetaU, thetaV);
206 const Belle2::PXD::Pixel& tailPixel = getTailPixel(pixels, vStart, vSize, thetaU, thetaV);
207 int vmax = vSize - 1;
208
209 std::string name = "S";
210 name += "D" + std::to_string(vmax - tailPixel.getV() + vStart) + '.' + std::to_string(tailPixel.getU() - uStart);
211
212 if (headPixel.getIndex() != tailPixel.getIndex()) {
213 name += "D" + std::to_string(vmax - headPixel.getV() + vStart) + '.' + std::to_string(headPixel.getU() - uStart);
214 }
215 return name;
216}
217
218const std::string Belle2::PXD::PXDClusterPositionEstimator::getFullName(const std::set<Belle2::PXD::Pixel>& pixels, int uStart,
219 int vStart) const
220{
221 return std::accumulate(pixels.begin(), pixels.end(), std::string("F"),
222 [uStart, vStart](auto name, auto px) {
223 return name + "D" + std::to_string(px.getV() - vStart) + "." + std::to_string(px.getU() - uStart);
224 });
225}
226
228{
229 std::set<int> pixelkinds;
230 bool uEdge = false;
231 bool vEdge = false;
232
233 Belle2::VxdID sensorID = cluster.getSensorID();
234 const Belle2::PXD::SensorInfo& Info = dynamic_cast<const Belle2::PXD::SensorInfo&>
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
260int 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&>
269
270 for (const Belle2::PXD::Pixel& pix : pixels) {
271 int pixelkind = Info.getPixelKindNew(sensorID, pix.getV());
272 pixelkinds.insert(pixelkind);
273
274 // Cluster at v sensor edge
275 if (pix.getV() == 0 or pix.getV() >= 767)
276 vEdge = true;
277 // Cluster at u sensor edge
278 if (pix.getU() == 0 or pix.getU() >= 249)
279 uEdge = true;
280 }
281
282 // In most cases, clusterkind is just pixelkind of first digit
283 int clusterkind = *pixelkinds.begin();
284
285 // Clusters with different pixelkinds or edge digits are special
286 // TODO: At the moment, clusterkind >3 will not be corrected
287 if (pixelkinds.size() > 1 || uEdge || vEdge)
288 clusterkind = 4;
289
290 return clusterkind;
291}
292
293int Belle2::PXD::PXDClusterPositionEstimator::getSectorIndex(double thetaU, double thetaV) const
294{
295 int sectorIndex = 0;
296 if (thetaU >= 0) {
297 if (thetaV >= 0) {
298 sectorIndex = 0;
299 } else {
300 sectorIndex = 3;
301 }
302 } else {
303 if (thetaV >= 0) {
304 sectorIndex = 1;
305 } else {
306 sectorIndex = 2;
307 }
308 }
309 return sectorIndex;
310}
311
312
313
314// }
315//}
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:33
STL namespace.