File indexing completed on 2025-01-18 09:11:32
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Vertexing/GaussianGridTrackDensity.hpp"
0010
0011 #include "Acts/Utilities/AlgebraHelpers.hpp"
0012 #include "Acts/Vertexing/VertexingError.hpp"
0013
0014 #include <algorithm>
0015
0016 namespace Acts {
0017
0018 Result<float> GaussianGridTrackDensity::getMaxZPosition(
0019 MainGridVector& mainGrid) const {
0020 if (mainGrid.isZero()) {
0021 return VertexingError::EmptyInput;
0022 }
0023
0024 int zbin = -1;
0025 if (!m_cfg.useHighestSumZPosition) {
0026
0027 mainGrid.maxCoeff(&zbin);
0028 } else {
0029
0030
0031 zbin = getHighestSumZPosition(mainGrid);
0032 }
0033
0034
0035 return (zbin - m_cfg.mainGridSize / 2.0f + 0.5f) * m_cfg.binSize;
0036 }
0037
0038 Result<std::pair<float, float>>
0039 GaussianGridTrackDensity::getMaxZPositionAndWidth(
0040 MainGridVector& mainGrid) const {
0041
0042 auto maxZRes = getMaxZPosition(mainGrid);
0043 if (!maxZRes.ok()) {
0044 return maxZRes.error();
0045 }
0046 float maxZ = *maxZRes;
0047
0048
0049 auto widthRes = estimateSeedWidth(mainGrid, maxZ);
0050 if (!widthRes.ok()) {
0051 return widthRes.error();
0052 }
0053 float width = *widthRes;
0054 std::pair<float, float> returnPair{maxZ, width};
0055 return returnPair;
0056 }
0057
0058 std::pair<int, GaussianGridTrackDensity::TrackGridVector>
0059 GaussianGridTrackDensity::addTrack(const BoundTrackParameters& trk,
0060 MainGridVector& mainGrid) const {
0061 SquareMatrix2 cov = trk.spatialImpactParameterCovariance().value();
0062 float d0 = trk.parameters()[0];
0063 float z0 = trk.parameters()[1];
0064
0065
0066 int dOffset = static_cast<int>(std::floor(d0 / m_cfg.binSize - 0.5) + 1);
0067
0068
0069 if (std::abs(dOffset) > (m_cfg.trkGridSize - 1) / 2.) {
0070
0071
0072 return {-1, TrackGridVector::Zero(m_cfg.trkGridSize)};
0073 }
0074
0075
0076 int zBin = static_cast<int>(z0 / m_cfg.binSize + m_cfg.mainGridSize / 2.);
0077
0078 if (zBin < 0 || zBin >= m_cfg.mainGridSize) {
0079 return {-1, TrackGridVector::Zero(m_cfg.trkGridSize)};
0080 }
0081
0082 float binCtrZ = (zBin + 0.5f) * m_cfg.binSize - m_cfg.zMinMax;
0083
0084
0085
0086 float distCtrZ = z0 - binCtrZ;
0087
0088
0089 TrackGridVector trackGrid = createTrackGrid(d0, distCtrZ, cov);
0090
0091 addTrackGridToMainGrid(zBin, trackGrid, mainGrid);
0092
0093 return {zBin, trackGrid};
0094 }
0095
0096 void GaussianGridTrackDensity::addTrackGridToMainGrid(
0097 int zBin, const TrackGridVector& trkGrid, MainGridVector& mainGrid) const {
0098 modifyMainGridWithTrackGrid(zBin, trkGrid, mainGrid, +1);
0099 }
0100
0101 void GaussianGridTrackDensity::removeTrackGridFromMainGrid(
0102 int zBin, const TrackGridVector& trkGrid, MainGridVector& mainGrid) const {
0103 modifyMainGridWithTrackGrid(zBin, trkGrid, mainGrid, -1);
0104 }
0105
0106 void GaussianGridTrackDensity::modifyMainGridWithTrackGrid(
0107 int zBin, const TrackGridVector& trkGrid, MainGridVector& mainGrid,
0108 int modifyModeSign) const {
0109 int width = (m_cfg.trkGridSize - 1) / 2;
0110
0111 int leftOL = zBin - width;
0112
0113 int rightOL = zBin + width - m_cfg.mainGridSize + 1;
0114 if (leftOL < 0) {
0115 int totalTrkSize = m_cfg.trkGridSize + leftOL;
0116 mainGrid.segment(0, totalTrkSize) +=
0117 modifyModeSign * trkGrid.segment(-leftOL, totalTrkSize);
0118 return;
0119 }
0120 if (rightOL > 0) {
0121 int totalTrkSize = m_cfg.trkGridSize - rightOL;
0122 mainGrid.segment(m_cfg.mainGridSize - totalTrkSize, totalTrkSize) +=
0123 modifyModeSign * trkGrid.segment(0, totalTrkSize);
0124 return;
0125 }
0126
0127 mainGrid.segment(zBin - width, m_cfg.trkGridSize) += modifyModeSign * trkGrid;
0128 }
0129
0130 GaussianGridTrackDensity::TrackGridVector
0131 GaussianGridTrackDensity::createTrackGrid(float d0, float distCtrZ,
0132 const SquareMatrix2& cov) const {
0133 TrackGridVector trackGrid(TrackGridVector::Zero(m_cfg.trkGridSize));
0134 float floorHalfTrkGridSize = static_cast<float>(m_cfg.trkGridSize) / 2 - 0.5f;
0135
0136
0137 for (int j = 0; j < m_cfg.trkGridSize; j++) {
0138 float z = (j - floorHalfTrkGridSize) * m_cfg.binSize;
0139 trackGrid(j) = normal2D(-d0, z - distCtrZ, cov);
0140 }
0141 return trackGrid;
0142 }
0143
0144 Result<float> GaussianGridTrackDensity::estimateSeedWidth(
0145 MainGridVector& mainGrid, float maxZ) const {
0146 if (mainGrid.isZero()) {
0147 return VertexingError::EmptyInput;
0148 }
0149
0150 int zBin = static_cast<int>(maxZ / m_cfg.binSize + m_cfg.mainGridSize / 2.);
0151
0152 const float maxValue = mainGrid(zBin);
0153 float gridValue = mainGrid(zBin);
0154
0155
0156 int rhmBin = zBin;
0157 while (gridValue > maxValue / 2) {
0158 rhmBin += 1;
0159 gridValue = mainGrid(rhmBin);
0160 }
0161
0162
0163 float deltaZ1 = m_cfg.binSize * (maxValue / 2 - mainGrid(rhmBin - 1)) /
0164 (mainGrid(rhmBin) - mainGrid(rhmBin - 1));
0165
0166
0167 int lhmBin = zBin;
0168 gridValue = mainGrid(zBin);
0169 while (gridValue > maxValue / 2) {
0170 lhmBin -= 1;
0171 gridValue = mainGrid(lhmBin);
0172 }
0173
0174
0175 float deltaZ2 = m_cfg.binSize * (mainGrid(lhmBin + 1) - maxValue / 2) /
0176 (mainGrid(lhmBin + 1) - mainGrid(lhmBin));
0177
0178
0179 float fwhm =
0180 rhmBin * m_cfg.binSize - deltaZ1 - lhmBin * m_cfg.binSize - deltaZ2;
0181
0182
0183 float width = fwhm / 2.355f;
0184
0185 return std::isnormal(width) ? width : 0.0f;
0186 }
0187
0188 float GaussianGridTrackDensity::normal2D(float d, float z,
0189 const SquareMatrix2& cov) const {
0190 float det = cov.determinant();
0191 float coef = 1 / std::sqrt(det);
0192 float expo =
0193 -1 / (2 * det) *
0194 (cov(1, 1) * d * d - (cov(0, 1) + cov(1, 0)) * d * z + cov(0, 0) * z * z);
0195 return coef * safeExp(expo);
0196 }
0197
0198 int GaussianGridTrackDensity::getHighestSumZPosition(
0199 MainGridVector& mainGrid) const {
0200
0201
0202
0203
0204 int zbin = -1;
0205 mainGrid.maxCoeff(&zbin);
0206 int zFirstMax = zbin;
0207 double firstDensity = mainGrid(zFirstMax);
0208 double firstSum = getDensitySum(mainGrid, zFirstMax);
0209
0210
0211 mainGrid[zFirstMax] = 0;
0212 mainGrid.maxCoeff(&zbin);
0213 int zSecondMax = zbin;
0214 double secondDensity = mainGrid(zSecondMax);
0215 double secondSum = 0;
0216 if (firstDensity - secondDensity <
0217 firstDensity * m_cfg.maxRelativeDensityDev) {
0218 secondSum = getDensitySum(mainGrid, zSecondMax);
0219 }
0220
0221
0222 mainGrid[zSecondMax] = 0;
0223 mainGrid.maxCoeff(&zbin);
0224 int zThirdMax = zbin;
0225 double thirdDensity = mainGrid(zThirdMax);
0226 double thirdSum = 0;
0227 if (firstDensity - thirdDensity <
0228 firstDensity * m_cfg.maxRelativeDensityDev) {
0229 thirdSum = getDensitySum(mainGrid, zThirdMax);
0230 }
0231
0232
0233 mainGrid[zFirstMax] = firstDensity;
0234 mainGrid[zSecondMax] = secondDensity;
0235
0236
0237 if (secondSum > firstSum && secondSum > thirdSum) {
0238 return zSecondMax;
0239 }
0240 if (thirdSum > secondSum && thirdSum > firstSum) {
0241 return zThirdMax;
0242 }
0243 return zFirstMax;
0244 }
0245
0246 double GaussianGridTrackDensity::getDensitySum(const MainGridVector& mainGrid,
0247 int pos) const {
0248 double sum = mainGrid(pos);
0249
0250
0251 if (pos - 1 >= 0) {
0252 sum += mainGrid(pos - 1);
0253 }
0254 if (pos + 1 <= mainGrid.size() - 1) {
0255 sum += mainGrid(pos + 1);
0256 }
0257 return sum;
0258 }
0259
0260 }