Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
//g++ cpp_smoothing.cpp -I/usr/include/python3.8 -lpython3.8
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <algorithm> //for replace
#include <vector>
#include <tuple>
#include <math.h>
#include <list>
#include "matplotlibcpp.h"
namespace plt = matplotlibcpp;
//------------------------
#define DATA_CHUNK_LENGTH 64
//------------------------
//---------------------------------------------------------------------------------------
std::tuple<double, double> computeSTD(std::vector<double> vec)
{
double dataMean{0};
double dataSum{0};
double dataLength = vec.size();
double dataVariance{0};
double dataStd{0};
for (auto &ii : vec)
{
dataSum += ii;
}
dataMean = dataSum / dataLength;
for (auto &jj : vec)
{
dataVariance += pow((jj - dataMean), 2);
}
dataVariance = dataVariance * (1 / (dataLength - 1));
dataStd = sqrt(dataVariance);
std::cout << "mean :" << dataMean << " variance : " << dataVariance << " STD : " << dataStd << std::endl;
return std::make_tuple(dataMean, dataStd);
}
//---------------------------------------------------------------------------------------
std::tuple<std::vector<double>, std::vector<double>> readCSV()
{
std::ifstream infile;
infile.open("data_csv100.csv");
int numberOfLines{0};
std::vector<double> time;
std::vector<double> sensor;
std::vector<double> sensor100;
std::string line;
while (std::getline(infile, line))
{
std::replace(line.begin(), line.end(), ',', ' ');
std::istringstream iss(line);
std::string str;
double value1, value2, value3;
int i = 0;
if (iss)
{
//iss.peek() == ',';
iss >> value1 >> value2 >> value3;
time.push_back(value1);
sensor.push_back(value2);
sensor100.push_back(value3);
numberOfLines++;
}
}
std::cout << "number of line in the file : " << numberOfLines << std::endl;
return std::make_tuple(time, sensor);
}
//---------------------------------------------------------------------------------------
void plotData(std::tuple<std::vector<double>, std::vector<double>> data)
{
std::vector<double> xx = std::get<0>(data);
std::vector<double> valueND = std::get<1>(data);
plt::figure_size(1200, 780);
plt::title("Data set ");
plt::plot(xx, valueND);
plt::xlabel("time");
plt::ylabel("value");
plt::show();
}
//---------------------------------------------------------------------------------------
void plotData2(std::tuple<std::vector<double>, std::vector<double>> data1, std::tuple<std::vector<double>, std::vector<double>> data2)
{
std::vector<double> time1 = std::get<0>(data1);
std::vector<double> sensor1 = std::get<1>(data1);
std::vector<double> time2 = std::get<0>(data2);
std::vector<double> sensor2 = std::get<1>(data2);
plt::figure_size(1200, 780);
plt::plot(time1, sensor1);
plt::plot(time2, sensor2);
plt::xlabel("time");
plt::ylabel("value");
plt::title("Custom filer");
plt::show();
}
//Removing outlier using standard deviation
//---------------------------------------------------------------------------------------
std::tuple<std::vector<double>, std::vector<double>> applyFilterB(std::tuple<std::vector<double>, std::vector<double>> data, double dataMean, double dataStd)
{
std::vector<double> time = std::get<0>(data);
std::vector<double> sensor = std::get<1>(data);
std::vector<double> buffer;
std::vector<double> timeFiltered;
double upperLimit = dataMean + 3*dataStd;
double lowerLimit = dataMean - 3*dataStd;
for (int ii = 0; ii < sensor.size(); ii++)
{
if ((sensor[ii] > upperLimit))
{
buffer.push_back(dataMean+dataStd);
}
else
{
buffer.push_back(sensor[ii]);
}
timeFiltered.push_back(ii);
}
return std::make_tuple(timeFiltered,buffer);
}
//---------------------------------------------------------------------------------------
std::tuple<std::vector<double>, std::vector<double>> rollingMeanFilterB(std::tuple<std::vector<double>, std::vector<double>> data)
{
double WINDOW = 6;
std::vector<double> time = std::get<0>(data);
std::vector<double> sensor = std::get<1>(data);
std::list<double> input;
std::vector<double> output_time;
std::vector<double> output_sensor;
for (int ii = 0; ii < sensor.size() - WINDOW; ii++)
{
if (ii > WINDOW)
{
double sensor_jj = 0.0;
for (int jj = 0;jj <= WINDOW ; ++jj)
{
sensor_jj += sensor[ii - jj];
}
output_sensor.push_back(sensor_jj/WINDOW);
output_time.push_back(ii - WINDOW);
}
}
return std::make_tuple(output_time, output_sensor);
}
//custom filter
//---------------------------------------------------------------------------------------
std::tuple<std::vector<double>, std::vector<double>> applyFilterA(std::tuple<std::vector<double>, std::vector<double>> data, double dataMean, double dataStd)
{
std::vector<double> time = std::get<0>(data);
std::vector<double> sensor = std::get<1>(data);
std::vector<int> buffer;
std::vector<double> timeFiltered;
std::vector<double> sensorFiltered;
double upperLimit = dataMean + 2*dataStd;
double lowerLimit = dataMean - 2*dataStd;
for (int ii = 0; ii < sensor.size() - 2; ii++)
{
if ((sensor[ii] > upperLimit) && (sensor[ii + 1] > upperLimit) && (sensor[ii + 2] > upperLimit) && (sensor[ii + 3] > upperLimit))
{
for (int ij = 0; ij < 4; ij++)
{
buffer.push_back(1);
timeFiltered.push_back(ii);
sensorFiltered.push_back(dataMean+dataStd);
}
ii += 4;
}
else
{
buffer.push_back(0);
timeFiltered.push_back(ii);
sensorFiltered.push_back(sensor[ii]);
}
}
int position{0};
for (auto &jj : buffer)
{
if (jj == 1)
{
std::cout << "peak 2 : " << position << std::endl;
}
position++;
}
return std::make_tuple(timeFiltered, sensorFiltered);
}
//---------------------------------------------------------------------------------------
int main()
{
std::tuple<std::vector<double>, std::vector<double>> outputDataX;
outputDataX = readCSV();
plotData(outputDataX);
std::tuple<double, double> dataMeanSTD = computeSTD(std::get<1>(outputDataX));
std::tuple<std::vector<double>, std::vector<double>> outputDataFilterB;
outputDataFilterB = rollingMeanFilterB(outputDataX);
plotData2(outputDataX, outputDataFilterB);
std::tuple<std::vector<double>, std::vector<double>> filtreredDataA = applyFilterA(outputDataX, std::get<0>(dataMeanSTD), std::get<1>(dataMeanSTD));
plotData2(outputDataX, filtreredDataA);
std::tuple<std::vector<double>, std::vector<double>> filtreredDataB = applyFilterB(outputDataX, std::get<0>(dataMeanSTD), std::get<1>(dataMeanSTD));
plotData2(outputDataX, filtreredDataB);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment