18 mValues.reserve(maxValues);
19 mWeights.reserve(maxValues);
24 if (mValues.empty()) {
25 return std::pair<float, float>(0, 0);
40 const auto upper = mValues.begin() + mValues.size() * interQuartileRange;
41 const auto lower = mValues.begin() + mValues.size() * (1 - interQuartileRange);
44 const float median = mValues[mValues.size() / 2];
47 return std::pair<float, float>(median, 0);
51 const float stdev = getStdDev(median, lower, upper);
54 return std::pair<float, float>(getFilteredMean(median, stdev, sigma), stdev);
59 if (mValues.empty()) {
67 const float median = mValues[mValues.size() / 2];
70 const auto upperV0 = std::upper_bound(mValues.begin(), mValues.end(), median + maxAbsMedian);
71 const auto lowerV0 = std::lower_bound(mValues.begin(), mValues.end(), median - maxAbsMedian);
73 if (upperV0 == lowerV0) {
78 const float stdev = getStdDev(median, lowerV0, upperV0);
81 const float sigmastddev = sigma * stdev;
82 const float minVal = median - sigmastddev;
83 const float maxVal = median + sigmastddev;
84 const auto upper = std::upper_bound(mValues.begin(), mValues.end(), maxVal);
85 const auto lower = std::lower_bound(mValues.begin(), mValues.end(), minVal);
91 const int indexUp = upper - mValues.begin();
92 const int indexLow = lower - mValues.begin();
95 const float medianFilterd = mValues[(indexUp - indexLow) / 2 + indexLow];
98 const auto upperW = mWeights.begin() + indexUp;
99 const auto lowerW = mWeights.begin() + indexLow;
100 const float wMean = mUseWeights ? getWeightedMean(lower, upper, lowerW, upperW) : getMean(lower, upper);
103 const int nEntries = indexUp - indexLow;
105 return {medianFilterd, wMean, stdev, nEntries};
111 const size_t nVals = mValues.size();
112 if (mValues.size() != mWeights.size()) {
113 LOGP(warning,
"values and errors haave different size");
116 std::vector<std::size_t> tmpIdx(nVals);
117 std::iota(tmpIdx.begin(), tmpIdx.end(), 0);
118 std::sort(tmpIdx.begin(), tmpIdx.end(), [&](std::size_t
i, std::size_t
j) { return (mValues[i] < mValues[j]); });
120 std::vector<float> mValues_tmp;
121 std::vector<float> mWeights_tmp;
122 mValues_tmp.reserve(nVals);
123 mWeights_tmp.reserve(nVals);
124 for (
int i = 0;
i < nVals; ++
i) {
125 const int idx = tmpIdx[
i];
126 mValues_tmp.emplace_back(mValues[idx]);
127 mWeights_tmp.emplace_back(mWeights[idx]);
129 mValues.swap(mValues_tmp);
130 mWeights.swap(mWeights_tmp);
132 std::sort(mValues.begin(), mValues.end());
142 mTmpValues.resize(
size);
143 std::transform(
begin,
end, mTmpValues.begin(), [mean](
const float val) { return val - mean; });
144 const float sqsum = std::inner_product(mTmpValues.begin(), mTmpValues.end(), mTmpValues.begin(),
decltype(mTmpValues)::value_type(0));
145 const float stdev = std::sqrt(sqsum /
size);
149float o2::tpc::RobustAverage::getFilteredMean(
const float mean,
const float stdev,
const float sigma)
const
151 const float sigmastddev = sigma * stdev;
152 const float minVal = mean - sigmastddev;
153 const float maxVal = mean + sigmastddev;
154 const auto upper = std::upper_bound(mValues.begin(), mValues.end(), maxVal);
155 const auto lower = std::lower_bound(mValues.begin(), mValues.end(), minVal);
156 return getMean(lower, upper);
161 LOGP(info,
"PRINTING STORED VALUES");
162 for (
auto val : mValues) {
163 LOGP(info,
"{}",
val);
169 return std::accumulate(
begin,
end,
decltype(mValues)::value_type(0)) / std::distance(
begin,
end);
174 if (mValues.empty()) {
177 size_t n = mValues.size() / 2;
178 std::nth_element(mValues.begin(), mValues.begin() +
n, mValues.end());
182float o2::tpc::RobustAverage::getWeightedMean(std::vector<float>::const_iterator beginValues, std::vector<float>::const_iterator endValues, std::vector<float>::const_iterator beginWeight, std::vector<float>::const_iterator endWeight)
const
184 return std::inner_product(beginValues, endValues, beginWeight,
decltype(mValues)::value_type(0)) / std::accumulate(beginWeight, endWeight,
decltype(mWeights)::value_type(0));
195 mValues.emplace_back(
value);
197 mWeights.emplace_back(
weight);
204 LOGP(warning,
"low {} should be higher than high {}", low, high);
207 const int startInd =
static_cast<int>(low * mValues.size());
208 const int endInd =
static_cast<int>(high * mValues.size());
209 if ((endInd <= startInd) || (startInd < 0) || (endInd >= mValues.size())) {
215 std::nth_element(mValues.begin(), mValues.begin() + startInd, mValues.end());
216 const float valMin = mValues[startInd];
218 std::nth_element(mValues.begin(), mValues.begin() + endInd, mValues.end());
219 const float valMax = mValues[endInd];
222 for (
auto val : mValues) {
223 if (
val >= valMin &&
val < valMax) {
227 const int count = endInd - startInd;
232 return getMean(mValues.begin() + startInd, mValues.begin() + endInd);
239 if (mValues.empty() || (quantile > 1) || (quantile < 0)) {
244 const int n = mValues.size();
245 const float vIdx =
type ? (quantile * (
n + 1 / 3.) - 2 / 3.) : (quantile * (
n - 1));
246 const int idxL = vIdx;
247 const float frac = vIdx - idxL;
249 if ((frac == 0) || (idxL >= mValues.size() - 1)) {
250 return mValues[idxL];
253 const int idxR = idxL + 1;
256 const float val = mValues[idxL] + (mValues[idxR] - mValues[idxL]) * frac;
class for performing robust averaging and outlier filtering
void addValue(const float value, const float weight=1)
float getTrunctedMean(float low, float high)
float getQuantile(float quantile, int type)
float getWeightedMean() const
void reserve(const unsigned int maxValues)
void print() const
values which will be averaged and filtered
std::pair< float, float > getFilteredAverage(const float sigma=3, const float interQuartileRange=0.9)
void clear()
clear the stored values
std::tuple< float, float, float, unsigned int > filterPointsMedian(const float maxAbsMedian, const float sigma=5)
remove all the point which are abs(val - val_median)>maxAbsMedian
GLuint GLuint GLfloat weight
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
Enum< T >::Iterator begin(Enum< T >)
DataT sum(const Vector< DataT, N > &a)