File indexing completed on 2025-01-18 09:11:32
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Vertexing/FsmwMode1dFinder.hpp"
0010
0011 #include "Acts/Vertexing/VertexingError.hpp"
0012
0013 #include <algorithm>
0014 #include <cmath>
0015 #include <limits>
0016
0017 Acts::FsmwMode1dFinder::FsmwMode1dFinder(double firstFraction, double fraction)
0018 : m_firstFraction(firstFraction), m_fraction(fraction) {}
0019
0020 Acts::Result<double> Acts::FsmwMode1dFinder::getMode(
0021 std::vector<std::pair<double, double>> inputVector) const {
0022 if (inputVector.empty()) {
0023 return VertexingError::EmptyInput;
0024 }
0025 if (inputVector.size() == 1) {
0026 return inputVector.begin()->first;
0027 }
0028
0029
0030
0031 std::ranges::sort(inputVector, {}, [](const auto& i) { return i.first; });
0032
0033
0034 auto begin = inputVector.begin();
0035 auto end = inputVector.end();
0036
0037 double overallweight(0.);
0038 auto best_begin = begin;
0039 auto best_end = end;
0040
0041 double last_value = std::numeric_limits<double>::max();
0042
0043 bool isthelast = false;
0044
0045 int counter = 0;
0046 double fraction = m_firstFraction;
0047 while (!isthelast) {
0048 counter += 1;
0049 if (counter == 2) {
0050 fraction = m_fraction;
0051 }
0052 int step = static_cast<int>(std::floor(fraction * (end - begin + 1)));
0053 overallweight = 0.;
0054 {
0055 auto i = begin;
0056 if (step > 0) {
0057 auto j_end = i + step - 1;
0058 for (auto j = i; j != j_end; j++) {
0059 overallweight += j->second;
0060 }
0061 }
0062 }
0063 auto i_last = begin + step - 1;
0064
0065 for (auto i = begin; i != (end - step + 1); ++i, ++i_last) {
0066
0067 overallweight += i_last->second;
0068
0069 double new_value = ((i + step - 1)->first - i->first) / overallweight;
0070 if (new_value < last_value) {
0071 last_value = ((i + step - 1)->first - i->first) / overallweight;
0072 best_begin = i;
0073 best_end = i + step - 1;
0074 }
0075 overallweight -= i->second;
0076 }
0077
0078
0079 begin = best_begin;
0080 end = best_end;
0081 last_value = std::numeric_limits<double>::max();
0082
0083
0084 if (best_end - best_begin <= 2) {
0085 isthelast = true;
0086 }
0087 }
0088
0089 if (best_end - best_begin == 2) {
0090 auto medium = begin;
0091 medium++;
0092 return (begin->first * begin->second + medium->first * medium->second +
0093 end->first * end->second) /
0094 (begin->second + medium->second + end->second);
0095 }
0096
0097 return (begin->first * begin->second + end->first * end->second) /
0098 (begin->second + end->second);
0099 }