3#define _USE_MATH_DEFINES
40 if(time.size() != vals.size()){
41 std::cerr<<
"TIME VECTOR SIZE DIFFERENT THAN VALUE VECTOR" << endl;
44 for(
int idx = 0; idx < time.size(); idx++){
58 return (v1 - v3)/((t1 - t2)*2);
63 return (v1 - 2*v2 + v3) / ((t1-t2)*(t1-t2));
67 return (v1 + v2) * (t1 - t2) * 0.5;
87 std::cerr <<
"THE CHOSEN DATA TABLE HAS AT LEAST A ROW MISSING" << endl;
90 std::cerr <<
"TOOO FEW SAMPLES PRE ANALYZER TERMINATE" << endl;
97 unsigned int row_index = 0;
102 double max_amp = current_val;
103 double min_amp = current_val;
107 double last_val = current_val;
108 double last_time = current_time;
117 if(last_time > current_time){
118 std::cerr <<
"CORRUPTED DATA " << row_index << endl;
123 double current_dvBdt =
_dvBdt(last_val, next_val, last_time, current_time);
124 double current_dv2Bdt2 =
_dv2Bdt2(last_val,current_val,next_val, current_time, last_time);
126 vdt +=
_vdt(last_val, current_val, current_time, last_time);
133 last_val = current_val;
134 last_time = current_time;
141 vdt +=
_vdt(last_val, current_val, current_time, last_time);
156 unsigned int index = 1;
158 int last_firstDeriv_sign = current_firstDeriv_sign;
165 for(index = 2; index < (
analytics.samples_num - 2); index++){
169 if((last_firstDeriv_sign != current_firstDeriv_sign)){
173 last_firstDeriv_sign = current_firstDeriv_sign;
174 if((last_firstDeriv_sign !=
zero)){
176 if(current_firstDeriv_sign ==
positive){
179 unsigned int i = index + ridx;
181 for(i; i < (index + 1); i++){
190 else if(current_firstDeriv_sign ==
negative){
194 unsigned int i = index + ridx;
196 for(i; i < (index + 1); i++){
206 else if(current_firstDeriv_sign ==
zero){
209 unsigned int i = index + ridx;
211 for(i; i < (index + 1); i++){
220 else if(last_firstDeriv_sign ==
positive){
223 unsigned int i = index + ridx;
225 for(i; i < (index + 1); i++){
305 double sum_maxes = 0;
327 double sum_ptp = max_ptp;
329 for(
int i = 1; i < ptp_num; i++){
334 }
else if(ptp > max_ptp){
343 std::cerr <<
"NOT ENOUGH PEAKS " << endl;
352 double sumFrequency_maximaBased = 0;
353 double sumFrequency_minimaBased = 0;
354 std::vector<double> _minima_periods;
355 std::vector<double> _maxima_periods;
356 bool maxima_periodic;
357 bool minima_periodic;
358 for(
int i = 0; i < least_extrema_num; i++){
360 sumFrequency_maximaBased += maxima_subPeriod;
363 double base_frequency_maximaBased = sumFrequency_maximaBased/(least_extrema_num);
365 for(
int i = 0; i < least_extrema_num; i++){
367 sumFrequency_minimaBased += minima_subPeriod;
371 double base_frequency_minimaBased = sumFrequency_minimaBased/(least_extrema_num);
374 if(_maxima_periods.size() > 1){
376 maxima_periodic =
true;
377 for(
int i = 0; i < (_maxima_periods.size() - 1); i++){
379 maxima_periodic =
false;
383 maxima_periodic =
true;
385 if(_minima_periods.size() > 1){
386 minima_periodic =
true;
387 for(
int i = 0; i < (_minima_periods.size() - 1); i++){
389 minima_periodic =
false;
393 minima_periodic =
true;
399 if(maxima_periodic && minima_periodic){
401 analytics.base_frequency = (base_frequency_maximaBased + base_frequency_minimaBased)/2;
407 unsigned int idx = 0;
411 for(idx; idx < least_extrema_num; idx++){
414 sumDuty += t_on/(t_on + t_off);
427 double rise_trigger_time = 0;
428 double fall_trigger_time = 0;
429 double last_rise_trigger_time = 0;
430 double last_fall_trigger_time = 0;
431 unsigned int idx = 0;
441 for(idx ; idx < this->
analytics.samples_num; idx++){
452 last_value = current_value;
456 double sum_rise_periods = 0;
457 double sum_fall_periods = 0;
460 unsigned int idx_periods = 0;
467 double avg_rise_period = sum_rise_periods/(idx_periods - 1);
474 double avg_fall_period = sum_fall_periods/(idx_periods - 1);
476 this->
analytics.periodic_time = (avg_fall_period + avg_rise_period)/2 ;
487 unsigned int idx = 0;
489 bool last_hyster_state = current_hyster_state;
498 for(idx; idx < this->
analytics.samples_num; idx++){
500 if(last_hyster_state != current_hyster_state && current_hyster_state ==
true){
503 last_hyster_state = current_hyster_state;
506 double periods_sum = 0;
507 unsigned int rise_idx = 1;
513 this->
analytics.periodic_time = periods_sum/(rise_idx - 1);
542 double startTime_stamp =
analytics.timeStart;
543 double endTime_stamp = 0;
546 endTime_stamp =
analytics.periodic_time * floor(
analytics.periods_num) + startTime_stamp ;
551 unsigned int index = 0;
552 double currentTime = 0;
554 double currentVal = 0;
560 for(index; (currentTime <= (endTime_stamp)) && (index <
analytics.samples_num); index++){
563 vdt +=
_vdt(currentVal, lastVal, currentTime, lastTime);
564 v2dt +=
_vdt((currentVal*currentVal), (lastVal*lastVal), currentTime, lastTime);
565 lastTime = currentTime;
566 lastVal = currentVal;
568 analytics.avg = vdt/(endTime_stamp - startTime_stamp);
569 analytics.rms = sqrt( v2dt/(endTime_stamp - startTime_stamp) );
599 unsigned int rise_idx = 1;
600 unsigned int pattern_idx = 0;
607 unsigned int transients_count = 0;
608 unsigned int unique_periods_count = 0;
630 unique_periods_count++;
703 sig.subSignals.clear();
704 for(
int i = 0; i <
pattern.size(); i++){
736 std::vector<double> time;
738 std::vector<double> values;
750 std::ofstream file(fileLocation+name, std::ios::out | std::ios::binary);
753 double startTime = this->
analytics.timeStart;
754 double endTime = this->
analytics.timeEnd;
755 double t_sample = this->
analytics.avg_sample_time;
756 double time_comp[] = {startTime , t_sample, endTime};
758 std::vector<double> values;
760 std::vector<float> down_scaled(values.begin(),values.end());
761 file.write(
reinterpret_cast<const char*
>(time_comp) ,
sizeof(
double)*3);
762 file.write(
reinterpret_cast<const char*
>(down_scaled.data()), values.size()*
sizeof(
float));
778 std::ifstream file(fileLocation+name, std::ios::binary);
783 file.seekg(0, std::ios::end);
784 std::streampos fileSize = file.tellg();
785 file.seekg(0, std::ios::beg);
787 std::vector<char> file_data(fileSize);
789 file.read(
reinterpret_cast<char*
>(file_data.data()), fileSize);
794 for(file_idx = 0; file_idx < 3*
sizeof(double) ; file_idx+=8 ){
795 memcpy(&time_comp[file_idx/
sizeof(
double)], (file_data.data() + file_idx),
sizeof(
double));
798 std::vector<float> values;
800 for(file_idx; file_idx < file_data.size() ; file_idx+=
sizeof(float) ){
802 memcpy(&value, &file_data[file_idx],
sizeof(
float));
803 values.push_back(value);
806 double timeStart = time_comp[0];
807 double t_sampling = time_comp[1];
808 double timeEnd = time_comp[2];
811 std::vector<double> upscaled(values.begin(),values.end());
812 std::vector<double> time(values.size());
813 time.at(0) = timeStart;
814 for(
unsigned int idx = 1; idx < values.size() ; idx++){
815 time.at(idx) = timeStart + idx*t_sampling;
847 auto data_val_pair = [&pdf_file](std::string a,
double b){
852 pdf_file.
addText(to_string(b));
857 auto signal_pdf_stream = [&pdf_file, &data_val_pair](
signal &
sig){
861 data_val_pair(
"TIME START :",
sig.analytics.timeStart);
862 data_val_pair(
"TIME END :",
sig.analytics.timeEnd);
863 data_val_pair(
"NUMBER OF PERIODS :",
sig.analytics.periods_num);
864 data_val_pair(
"NUMBER OF SAMPLES :",
sig.analytics.samples_num);
865 data_val_pair(
"AVG SAMPLING TIME :",
sig.analytics.avg_sample_time);
866 data_val_pair(
"ABSOLUTE MAX :",
sig.analytics.max_val);
867 data_val_pair(
"ABSOLUTE MIN :",
sig.analytics.min_val);
868 data_val_pair(
"AVERAGE OF LOCAL MAXIMAS :",
sig.analytics.avg_max_val);
869 data_val_pair(
"AVERAGE OF LOCAL MINIMAS :",
sig.analytics.avg_min_val);
870 data_val_pair(
"AVERAGE :",
sig.analytics.avg);
871 data_val_pair(
"RMS :",
sig.analytics.rms);
872 data_val_pair(
"AVERAGE PERIODIC TIME :",
sig.analytics.periodic_time);
873 data_val_pair(
"AVERAGE FREQUENCY :",
sig.analytics.base_frequency);
880 pdf_file.
init(file_address+name);
887 std::size_t pos = name.find(
'.');
889 if (pos != std::string::npos) {
898 signal_pdf_stream(*
this);
905 pdf_file.
center_text(
"THIS PDF WAS GENERATED BY BIG_ANT OMAR MAGDY X_X");
926 pdf_file.
center_text(name +
" SUBSIGNAL (" + to_string(i) +
") " + type);
933 pdf_file.
center_text(
"THIS PDF WAS GENERATED BY BIG_ANT OMAR_MAGDY X_X");
bool subsignal_time_based(signal &base_sig, signal &sub_sig, double time_start, double time_end)
create subSignal from bigger ones based on time boundaries
bool insertColumn(unsigned int columnNumber, const std::vector< HELD_DATA > &putArray)
inserts a column in the table replacing existing if they exist or adds them
unsigned int get_col_num()
unsigned int get_row_num()
bool extractColumn(unsigned int columnNumber, std::vector< HELD_DATA > &returnArray)
Extracts a row from the dataTable in a vector.
bool update_state(double value)
void init(std::string fileLocation)
void center_text(std::string word)
void setCursor(int x, int y)
void addText(std::string text)
void setFontStyle(float size, int r, int g, int b, int a)
signal class the parent class for every other signal or any form of time-sorted (time,...
struct signal::_subSignals subSignals_period_based
bool exportSignal(std::string name, bool export_all=false, sig_exp expType=sig_exp::csv, std::string fileLocation=settings.get_setting("signal","export_path"))
export the signal data to a specific file
void make_subsignals(std::vector< pattern > &pattern, _subSignals &sig)
a function that keeps generating subsignals based on the pattern provided that holds pattern start ti...
double _vdt(double v1, double v2, double t1, double t2)
bool frequency_triggerHysteresis()
calculate the base_frequency with hysteresis added for noise ignorance
bool smaller_extremas_ignored
bool deduce_avg_rms()
rms and avg based on integer number of signals analysis only
maximas_minimas val_maximas
maximas_minimas val_minimas
bool period_pattern_analysis()
analyse regions of the signal basesd on their periodic times (connected similar periodic times = 1 co...
const _analytics * get_analytics() const
get analytics of the time_domain analysed signal
double _hysteresis_high_threshold
bool deduce_baseFrequency()
deduce base frequency + angular + number of periods for the signal
int minimum_periodic_periodNum
double period_diff_accuracy
void refreshData()
refresh the dataTable that we use
std::vector< double > rising_trigger_times
rising edges detected are stored here mainly used by trigger level frequency calculation and hysteres...
double maxima_diff_rounding
bool frequency_triggerLevel()
calculate frequency based on crossing trigger level times
bool update_local_maximas_minimas()
EVALUATE MAXIMAS/MINIMAS using SLOPE DATA.
bool pdf_export(std::string name, std::string file_address=settings.get_setting("signal","export_path"))
export valuable signal report (images and text)//in the pdf format
_subSignals * subSignal_periodBased()
get the subSignals generated from this signal based on their periodic times pattern
bool pattern_analyze()
analyse changes in the signal and store any continous patterns detected for future interval Based sig...
const v_container * get_signal_data() const
get any values in the signal data table
_subSignals * subSignal_valueBased()
get the subSignals generated from this signal based on their rms for periods times pattern
bool frequency_peakNdtrough()
calculate frequency based on Local maximas and minimas and their times respectively
std::vector< pattern > periods_pattern
double minima_diff_rounding
struct signal::_subSignals subSignals_value_based
void putValue(double val, int row, int col)
easy abstracted values insersion
void set_hysteresis(double upThreshold, double lowThreshold)
sets the hysteresis parameters for the hysteresis trigger frequency calculations
bool pre_analyze()
Makes variable data out of the time-value data such as slopes and areas wrt to time.
bool soft_analyze()
soft time tomain analysis
bool loadData(std::string name, std::string fileLocation=settings.get_setting("signal","import_path"))
load data from a file directly if it has the following format (time,value)
double _dvBdt(double v1, double v2, double t1, double t2)
std::vector< double > falling_trigger_times
rising edges detected are stored here mainly used by trigger level frequency calculation and hysteres...
void set_trigger_level(double v)
sets the trigger level for the trigger level based frequency calculation
bool analyse()
generalized huge analysis in the time domain fetches basic data
bool post_local_maximas_minimas()
filter local MAXIMAS and MINIMAS and update ptp data (only top maximas and lowest minimas)
double _dv2Bdt2(double v1, double v2, double v3, double t1, double t2)
bool importSignal(std::string name, std::string fileLocation=settings.get_setting("signal","import_path"))
import a signal in the .sig binary format
std::vector< double > falling_periods
rising edges detected are stored here mainly used by trigger level frequency calculation and hysteres...
double getValue(int row, int col)
easy abstracted values extraction
std::vector< double > rising_periods
rising edges detected are stored here mainly used by trigger level frequency calculation and hysteres...
double _hysteresis_low_threshold
double _trigger_level
signal value for detecting edges and calculating frequency based on
struct signal::_analytics analytics
bool isNear(double v1, double v2, double acc)
this file includes the base class "signal" for signals modeling and analysing thier time-domain / fre...
this file includes the basic signal_operation class responsible for doing any required manipulation o...
a basic structure that holds basic analysis results
bool data_import(string file_address, dataTable< double > &data, int type)
a function that imports files with supported file formats
bool data_export(string file_address, dataTable< double > &data, int type)
unsigned int transients_count
unsigned int unique_periods_count
std::vector< signal > subSignals
std::vector< double > value
std::vector< double > time
double pattern_start_time