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
41{
42 m_shapeIndexPar = **m_shapeIndexFromDB;
43}
44
46{
47 m_positionEstimatorPar = **m_positionEstimatorFromDB;
48}
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.
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.
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 likelyhood.
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:66
unsigned int getIndex() const
Return the Index of the digit.
Definition: Pixel.h:72
float getCharge() const
Return the Charge of the Pixel.
Definition: Pixel.h:70
unsigned short getV() const
Return the CellID in v.
Definition: Pixel.h:68
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
Definition: SensorInfo.h:23
int getPixelKindNew(const VxdID &sensorID, int vID) const
Return pixel kind ID.
Definition: SensorInfo.cc:78
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne 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.