13 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
15 spatialTrkGridSize, temporalTrkGridSize>::getBinCenter(
int bin,
17 return bin * binExtent;
20 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
22 spatialTrkGridSize, temporalTrkGridSize>::getBin(
float value,
24 return static_cast<int>(std::floor(value / binExtent - 0.5) + 1);
27 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
29 spatialTrkGridSize, temporalTrkGridSize>::DensityMap::const_iterator
32 auto maxEntry = std::max_element(
34 [](
const auto& densityEntry1,
const auto& densityEntry2) {
35 return densityEntry1.second < densityEntry2.second;
40 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
42 spatialTrkGridSize, temporalTrkGridSize>::ZTPosition>
45 if (densityMap.empty()) {
46 return VertexingError::EmptyInput;
50 if (!
m_cfg.useHighestSumZPosition) {
51 bin = highestDensityEntry(densityMap)->first;
55 bin = highestDensitySumBin(densityMap);
59 float maxZ = getBinCenter(bin.first,
m_cfg.spatialBinExtent);
61 ZTPosition maxValues = std::make_pair(maxZ, 0.);
64 if constexpr (temporalTrkGridSize > 1) {
65 float maxT = getBinCenter(bin.second,
m_cfg.temporalBinExtent);
66 maxValues.second = maxT;
72 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
74 spatialTrkGridSize, temporalTrkGridSize>::ZTPositionAndWidth>
78 auto maxZTRes = getMaxZTPosition(densityMap);
79 if (not maxZTRes.ok()) {
80 return maxZTRes.error();
85 auto widthRes = estimateSeedWidth(densityMap, maxZT);
86 if (not widthRes.ok()) {
87 return widthRes.error();
89 float width = *widthRes;
94 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
96 temporalTrkGridSize>::DensityMap
104 int centralDBin = getBin(impactParams(0),
m_cfg.spatialBinExtent);
106 if (std::abs(centralDBin) > (spatialTrkGridSize - 1) / 2.) {
108 return emptyTrackDensityMap;
111 int centralZBin = getBin(impactParams(1),
m_cfg.spatialBinExtent);
114 Bin centralBin = std::make_pair(centralZBin, 0.);
117 if constexpr (temporalTrkGridSize > 1) {
118 int centralTBin = getBin(impactParams(2),
m_cfg.temporalBinExtent);
119 centralBin.second = centralTBin;
122 DensityMap trackDensityMap = createTrackGrid(impactParams, centralBin, cov);
124 for (
const auto& densityEntry : trackDensityMap) {
125 Bin bin = densityEntry.first;
126 float trackDensity = densityEntry.second;
128 if (mainDensityMap.count(bin) == 1) {
129 mainDensityMap.at(bin) += trackDensity;
131 mainDensityMap[bin] = trackDensity;
135 return trackDensityMap;
138 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
142 for (
auto it = trackDensityMap.begin();
it != trackDensityMap.end();
it++) {
143 mainDensityMap.at(
it->first) -=
it->second;
147 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
149 temporalTrkGridSize>::DensityMap
155 int halfSpatialTrkGridSize = (spatialTrkGridSize - 1) / 2;
156 int firstZBin = centralBin.first - halfSpatialTrkGridSize;
159 int halfTemporalTrkGridSize = (temporalTrkGridSize - 1) / 2;
160 int firstTBin = centralBin.second - halfTemporalTrkGridSize;
163 for (
int i = 0;
i < temporalTrkGridSize;
i++) {
164 int tBin = firstTBin +
i;
168 if constexpr (temporalTrkGridSize > 1) {
169 t = getBinCenter(tBin,
m_cfg.temporalBinExtent);
171 for (
int j = 0;
j < spatialTrkGridSize;
j++) {
172 int zBin = firstZBin +
j;
173 float z = getBinCenter(zBin,
m_cfg.spatialBinExtent);
177 binCoords -= impactParams;
178 Bin bin = std::make_pair(zBin, tBin);
179 if constexpr (temporalTrkGridSize == 1) {
180 trackDensityMap[bin] = multivariateGaussian<2>(
181 binCoords.head<2>(), cov.topLeftCorner<2, 2>());
183 trackDensityMap[bin] = multivariateGaussian<3>(binCoords,
cov);
187 return trackDensityMap;
190 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
193 temporalTrkGridSize>::estimateSeedWidth(
const DensityMap& densityMap,
195 if (densityMap.empty()) {
196 return VertexingError::EmptyInput;
200 int zMaxBin = getBin(maxZT.first,
m_cfg.spatialBinExtent);
203 if constexpr (temporalTrkGridSize > 1) {
204 tMaxBin = getBin(maxZT.second,
m_cfg.temporalBinExtent);
206 const float maxValue = densityMap.at(std::make_pair(zMaxBin, tMaxBin));
208 int rhmBin = zMaxBin;
209 float gridValue = maxValue;
212 bool binFilled =
true;
213 while (gridValue > maxValue / 2) {
215 if (densityMap.count(std::make_pair(rhmBin + 1, tMaxBin)) == 0) {
220 gridValue = densityMap.at(std::make_pair(rhmBin, tMaxBin));
224 float rightDensity = 0;
226 rightDensity = densityMap.at(std::make_pair(rhmBin, tMaxBin));
228 float leftDensity = densityMap.at(std::make_pair(rhmBin - 1, tMaxBin));
229 float deltaZ1 =
m_cfg.spatialBinExtent * (maxValue / 2 - leftDensity) /
230 (rightDensity - leftDensity);
232 int lhmBin = zMaxBin;
233 gridValue = maxValue;
235 while (gridValue > maxValue / 2) {
237 if (densityMap.count(std::make_pair(lhmBin - 1, tMaxBin)) == 0) {
242 gridValue = densityMap.at(std::make_pair(lhmBin, tMaxBin));
246 rightDensity = densityMap.at(std::make_pair(lhmBin + 1, tMaxBin));
248 leftDensity = densityMap.at(std::make_pair(lhmBin, tMaxBin));
252 float deltaZ2 =
m_cfg.spatialBinExtent * (rightDensity - maxValue / 2) /
253 (rightDensity - leftDensity);
255 float fwhm = (rhmBin - lhmBin) *
m_cfg.spatialBinExtent - deltaZ1 - deltaZ2;
258 float width = fwhm / 2.355f;
263 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
264 template <
unsigned int nDim>
268 float expo = -0.5 * args.transpose().dot(cov.inverse() *
args);
269 float gaussianDensity =
safeExp(expo) / std::sqrt(cov.determinant());
270 return gaussianDensity;
273 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
275 temporalTrkGridSize>::Bin
279 auto firstMax = highestDensityEntry(densityMap);
280 Bin binFirstMax = firstMax->first;
281 float valueFirstMax = firstMax->second;
282 float firstSum = getDensitySum(densityMap, binFirstMax);
285 float densityDeviation = valueFirstMax *
m_cfg.maxRelativeDensityDev;
288 densityMap.at(binFirstMax) = 0;
289 auto secondMax = highestDensityEntry(densityMap);
290 Bin binSecondMax = secondMax->first;
291 float valueSecondMax = secondMax->second;
293 if (valueFirstMax - valueSecondMax < densityDeviation) {
294 secondSum = getDensitySum(densityMap, binSecondMax);
298 densityMap.at(binFirstMax) = valueFirstMax;
303 densityMap.at(binSecondMax) = 0;
304 auto thirdMax = highestDensityEntry(densityMap);
305 Bin binThirdMax = thirdMax->first;
306 float valueThirdMax = thirdMax->second;
308 if (valueFirstMax - valueThirdMax < densityDeviation) {
309 thirdSum = getDensitySum(densityMap, binThirdMax);
313 densityMap.at(binFirstMax) = valueFirstMax;
314 densityMap.at(binSecondMax) = valueSecondMax;
317 if (secondSum > firstSum && secondSum > thirdSum) {
320 if (thirdSum > secondSum && thirdSum > firstSum) {
326 template <
int spatialTrkGr
idSize,
int temporalTrkGr
idSize>
330 float sum = densityMap.at(bin);
335 Bin binShifted = bin;
337 binShifted.first -= 1;
338 if (densityMap.count(binShifted) == 1) {
339 sum += densityMap.at(binShifted);
343 binShifted.first += 2;
344 if (densityMap.count(binShifted) == 1) {
345 sum += densityMap.at(binShifted);