7#ifndef RLDeconvolutor_H
8#define RLDeconvolutor_H
10#include "FairLogger.h"
23 const std::vector<float>& kernel_,
24 const float R2threshold_,
25 const int max_iterations_)
47 LOG(debug4) <<
"RLDeconvolutor : calculating error " << iter;
49 LOG(debug4) <<
"RLDeconvolutor : recalculating deconvolved " << iter;
56 LOG(debug4) <<
"RLDeconvolutor : estimated error R2 " <<
R2.back();
60 LOG(debug4) <<
"RLDeconvolutor : coverged at iter " << iter;
67 LOG(debug4) <<
"RLDeconvolutor : did not converge.";
70 LOG(debug4) <<
"RLDeconvolutor : findCamelPoints";
74 LOG(debug4) <<
"RLDeconvolutor : extracting";
91 const std::vector<float>&
getR2()
const {
return R2; }
99 std::vector<float>
R2;
110 std::vector<float>
convolution(
const std::vector<float>& signal,
const std::vector<float>& kern)
const
114 size_t signal_size = signal.size();
115 size_t kernel_size = kern.size();
116 size_t padding = kernel_size / 2;
118 std::vector<float> padded_signal(signal_size + 2 * padding, 0.0);
119 std::copy(signal.begin(), signal.end(), padded_signal.begin() + padding);
121 std::vector<float> result(signal_size, 0.0);
123 for (
size_t i = 0;
i < signal_size; ++
i)
124 for (
size_t j = 0; j < kernel_size; ++j)
125 result.at(
i) += padded_signal.at(
i + kernel_size - 1 - j) * kern.at(j);
132 std::vector<float> out_array(data_array.size(), 0.0);
135 auto condition = [](
float number) {
return number > 0.0; };
138 for (
size_t i = 0;
i < data_array.size(); ++
i) {
139 if (condition(data_array.at(
i)))
140 out_array.at(
i) = data_array.at(
i);
142 out_array.at(
i) = 0.0;
149 std::vector<float> result(vec1.size());
150 assert(vec1.size() == vec2.size());
152 for (
size_t i = 0;
i < vec1.size(); ++
i)
153 result.at(
i) = vec1.at(
i) * vec2.at(
i);
158 std::vector<float>
elementwiseDivision(
const std::vector<float>& vec1,
const std::vector<float>& vec2)
const
160 std::vector<float> result(vec1.size());
161 assert(vec1.size() == vec2.size());
163 for (
size_t i = 0;
i < vec1.size(); ++
i)
164 result.at(
i) = vec1.at(
i) / (vec2.at(
i) + std::numeric_limits<float>::min());
169 float R2score(
const std::vector<float>& true_values,
const std::vector<float>& predicted_values)
const
171 assert(true_values.size() == predicted_values.size());
172 if (true_values.empty())
175 float mean_true = std::accumulate(true_values.begin(), true_values.end(), 0.0) / true_values.size();
176 float ss_total = 0.0;
177 float ss_residual = 0.0;
179 for (
size_t i = 0;
i < true_values.size(); ++
i) {
180 ss_total += std::pow(true_values.at(
i) - mean_true, 2);
181 ss_residual += std::pow(true_values.at(
i) - predicted_values.at(
i), 2);
184 return ss_residual / (ss_total + std::numeric_limits<float>::min());
189 std::vector<size_t> maxima_indices;
191 return maxima_indices;
193 for (
size_t i = 1;
i <
vec.size() - 1; ++
i) {
195 maxima_indices.push_back(
i);
199 return maxima_indices;
205 std::vector<size_t> c_points;
207 LOG(debug4) <<
"RLDeconvolutor : findCamelPoints between total maxima " << maxima_indices.size();
208 if (!maxima_indices.empty()) {
209 for (
size_t i = 0;
i < maxima_indices.size() - 1; ++
i) {
212 if (!camel_area.empty()) {
215 + std::distance(camel_area.begin(), std::min_element(camel_area.begin(), camel_area.end()));
216 c_points.push_back(camel_point);
220 c_points.insert(c_points.begin(), 0);
222 for (
auto it : c_points)
223 LOG(debug4) <<
"RLDeconvolutor : found CamelPoints " << it;
228 std::vector<float>
getSubvector(
const std::vector<float>&
vec,
size_t start,
size_t end)
const
230 return std::vector<float>(
vec.begin() + start,
vec.begin() + end);
246 std::vector<float> thisVector(
deconvolved.size(), 0.0);
247 std::copy(subvector.begin(), subvector.end(), thisVector.begin() + start_index);
255 auto max_amplitude_iter = std::max_element(reconstructed_signal.begin(), reconstructed_signal.end());
256 float max_amplitude = *max_amplitude_iter;
257 int max_amplitude_position = std::distance(reconstructed_signal.begin(), max_amplitude_iter);
260 signal_info.push_back(std::make_pair(max_amplitude_position, max_amplitude));
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
const std::vector< float > & getR2() const
RLDeconvolutor(const std::vector< float > &y, const std::vector< float > &kernel_, const float R2threshold_, const int max_iterations_)
std::vector< float > getWfmApproximation() const
std::vector< std::vector< float > > signal_deconvolved
const std::vector< std::vector< float > > & getSignalDeconvolution() const
float R2score(const std::vector< float > &true_values, const std::vector< float > &predicted_values) const
std::vector< float > constrainOperator(const std::vector< float > &data_array)
std::vector< std::vector< float > > signal_decomposed
std::vector< float > getSubvector(const std::vector< float > &vec, size_t start, size_t end) const
std::vector< float > blurred_signal
std::vector< float > elementwiseMultiplication(const std::vector< float > &vec1, const std::vector< float > &vec2) const
std::vector< float > deconvolved
std::vector< float > reversed_kernel
std::vector< float > elementwiseDivision(const std::vector< float > &vec1, const std::vector< float > &vec2) const
std::vector< float > convolution(const std::vector< float > &signal, const std::vector< float > &kern) const
std::vector< float > kernel
std::vector< std::pair< size_t, float > > signal_info
const std::vector< std::pair< size_t, float > > & getSignalInfo() const
std::vector< size_t > findCamelPoints() const
static constexpr float R2default
const std::vector< std::vector< float > > & getSignalDecomposition() const
void setMaxIterations(int max)
std::vector< size_t > findMaximaIndices(const std::vector< float > &vec) const
std::vector< size_t > camel_points
void setR2threshold(float thr)