diff --git a/PULP/Makefile b/PULP/Makefile index 0f1c0b8..53d84fa 100755 --- a/PULP/Makefile +++ b/PULP/Makefile @@ -1,15 +1,16 @@ PULP_APP = delineation_app PULP_APP_FC_SRCS = main.c \ adaptive_Rpeak_detection/adaptiveRpeakDetection.c \ Morph_filt/morpho_filtering.c \ REWARD_R_peak_detection/relativeEnergy.c \ REWARD_R_peak_detection/peakDetection.c \ + error_detection/error_detection.c \ profiling/profile.c CORES ?= 1 CTARGET ?= 0 PULP_CFLAGS += -DTARGET=$(CTARGET) -DNUM_CORES=$(CORES) -O3 -g3 -w PULP_LDFLAGS = -lm #-lg #uncomment -lg for pulpissimo include $(PULP_SDK_HOME)/install/rules/pulp_rt.mk diff --git a/PULP/adaptive_Rpeak_detection/adaptiveRpeakDetection.c b/PULP/adaptive_Rpeak_detection/adaptiveRpeakDetection.c index 1db778d..1591381 100755 --- a/PULP/adaptive_Rpeak_detection/adaptiveRpeakDetection.c +++ b/PULP/adaptive_Rpeak_detection/adaptiveRpeakDetection.c @@ -1,300 +1,255 @@ #include "adaptiveRpeakDetection.h" #include "../defines.h" #include "../profiling/profile.h" #include "../data/signal.h" #include "../Morph_filt/morpho_filtering.h" #include "../Morph_filt/defines_globals.h" +#include "../error_detection/error_detection.h" #define N_WINDOWS (int) (2*((ECG_VECTOR_SIZE-LONG_WINDOW)/dim)+1)// Counting the worst case scenario when overlap is dim RT_L2_DATA int16_t ecg_buff[(LONG_WINDOW+dim)*(NLEADS+1)]; RT_L2_DATA rt_perf_t perf[NUM_CORES]; #ifdef MODULE_MF RT_L2_DATA int32_t *argMF[4]; RT_L2_DATA int32_t buffSize_windowMF; #endif #ifdef MODULE_RELEN RT_L2_DATA int32_t *argRelEn[4]; RT_L2_DATA int32_t start_RelEn = 1; RT_L2_DATA int32_t buffSize_windowRelEn; #endif #ifdef MODULE_RPEAK_REWARD RT_L2_DATA int32_t *argRW_Rpeak[2]; RT_L2_DATA int32_t indicesRpeaks[H_B+1]; #endif #ifdef MODULE_ERROR_DETECTION -RT_L2_DATA int32_t *argErrDet[4]; +RT_L2_DATA int32_t *argErrDet[6]; RT_L2_DATA int32_t lastRpeak = 0; RT_L2_DATA int32_t lastRR = 0; RT_L2_DATA int32_t error_RWindow = 0; #endif RT_L2_DATA int32_t overlap; RT_L2_DATA int32_t rWindow; void clearRelEn() { clearAndResetRelEn(); resetPeakDetection(); } -int errorDetection(int32_t *arg[]){ - int32_t *indRpeaks = arg[0]; - int32_t *r_counter = arg[1]; - int32_t *lastPeak = arg[2]; - int32_t *lastRRp = arg[3]; - int32_t RR_intervals[H_B+2]; - int32_t ratioConsecutiveRR = 0; - int32_t offset_ind_rr = 1; - - for(int32_t ix_rr = 0; ix_rr < H_B ; ix_rr++) { - RR_intervals[ix_rr] = 0; - } - - if(*r_counter>0){ - - if(!(rWindow == 1 && *r_counter == 1)){ - if(*lastRRp = 0){ - RR_intervals[0] = (FACTOR_MS*(indRpeaks[0] - *lastPeak))/ECG_SAMPLING_FREQUENCY; - offset_ind_rr = 0; - } - else{ - RR_intervals[0] = *lastRRp; - RR_intervals[1] = (FACTOR_MS*(indRpeaks[0] - *lastPeak))/ECG_SAMPLING_FREQUENCY; - offset_ind_rr = 1; - } - printf("RR[0]: %d\n",RR_intervals[0] ); - printf("RR[1]: %d\n",RR_intervals[1] ); - } - - for(int32_t ix_rp = 1; ix_rp < *r_counter; ix_rp++) { - RR_intervals[ix_rp+offset_ind_rr] = (FACTOR_MS*(indRpeaks[ix_rp]-indRpeaks[ix_rp-1]))/ECG_SAMPLING_FREQUENCY; - } - - for(int32_t ix_rr = 1; ix_rr < *r_counter; ix_rr++){ - ratioConsecutiveRR = (FACTOR_RATIO_RR*RR_intervals[ix_rr])/RR_intervals[ix_rr-1]; - if(ratioConsecutiveRRPERCENTILE_LOO_HIGH) - return 1; - } - - *lastPeak = indRpeaks[*r_counter-1]; - *lastRRp = RR_intervals[*r_counter-1]; - }else{ - return 1; - } - - return 0; -} - void adaptiveRpeakDetection(){ int32_t count_sample = 0; int32_t offset_window = 0; int32_t offset_ind = LONG_WINDOW/2+1; int32_t tot_overlap = 0; overlap = 0; #ifdef MODULE_MF int32_t flagMF = 0; int32_t i_lead = 0; buffSize_windowMF = LONG_WINDOW+dim; argMF[0] = (int32_t*) ecg_buff; argMF[1] = &flagMF; argMF[2] = &i_lead; argMF[3] = &buffSize_windowMF; init_filtering(); #endif #ifdef MODULE_RELEN buffSize_windowRelEn = LONG_WINDOW+dim; argRelEn[0] = (int32_t*) ecg_buff; argRelEn[1] = (int32_t*) &ecg_buff[(LONG_WINDOW+dim)*NLEADS]; argRelEn[2] = &start_RelEn; argRelEn[3] = &buffSize_windowRelEn; clearRelEn(); #endif #ifdef MODULE_RPEAK_REWARD int32_t rpeaks_counter = 0; argRW_Rpeak[0] = (int32_t*) &ecg_buff[LONG_WINDOW+(LONG_WINDOW + dim)*NLEADS]; argRW_Rpeak[1] = indicesRpeaks; #endif for(rWindow=0; rWindow= ECG_VECTOR_SIZE){ return; } if(rWindow > 0){ offset_window = LONG_WINDOW; } else{ offset_window = 0; } if (rWindow > 0) { for(int32_t i=0; i 0) start_RelEn = 0; argRelEn[0] = (int32_t*) &ecg_buff[offset_window + overlap]; argRelEn[1] = (int32_t*) &ecg_buff[offset_window + (LONG_WINDOW + dim)*NLEADS+overlap]; buffSize_windowRelEn = LONG_WINDOW - offset_window + dim-overlap; #endif relEn_w(argRelEn); #ifdef HWPERF_MODULES profile_stop(perf); #endif #ifdef PRINT_RELEN for(int32_t sample = offset_window + (LONG_WINDOW + dim)*NLEADS; sample< (LONG_WINDOW + dim)*(NLEADS+1); sample++) { printf("%d\n", ecg_buff[sample]); } #endif #endif #ifdef MODULE_RPEAK_REWARD #ifdef HWPERF_MODULE_RPEAK_REWARD || HWPERF_MODULES profile_start(perf); #endif getPeaks_w(argRW_Rpeak); rpeaks_counter = 0; while(indicesRpeaks[rpeaks_counter]!=0) { rpeaks_counter++; } #ifdef HWPERF_MODULE_RPEAK_REWARD || HWPERF_MODULES profile_stop(perf); #endif #ifdef PRINT_RPEAKS for(int32_t indR=0; indR0){ +#ifdef PRINT_DEBUG_ERRDET + printf("rWindow: %d r_counter: %d\n", *rWindow,*r_counter ); +#endif + if(!(*rWindow == 0)){ + if(*lastRRp == 0){ + RR_intervals[0] = (FACTOR_MS*(indRpeaks[0] + *offset_ind_r - *lastPeak))/ECG_SAMPLING_FREQUENCY; + offset_ind_rr = 0; +#ifdef PRINT_DEBUG_ERRDET + printf("R[0]: %d RR[0]: %d\n", (FACTOR_MS*(indRpeaks[0] + *offset_ind_r))/ECG_SAMPLING_FREQUENCY, RR_intervals[0]); +#endif + } + else{ + RR_intervals[0] = *lastRRp; + RR_intervals[1] = (FACTOR_MS*(indRpeaks[0] + *offset_ind_r - *lastPeak))/ECG_SAMPLING_FREQUENCY; + offset_ind_rr = 1; +#ifdef PRINT_DEBUG_ERRDET + printf("R[0]: %d RR[0]: %d RR[1]: %d\n", (FACTOR_MS*(indRpeaks[0] + *offset_ind_r))/ECG_SAMPLING_FREQUENCY, RR_intervals[0], RR_intervals[1]); +#endif + } + } + + for(int32_t ix_rp = 1; ix_rp < *r_counter; ix_rp++) { + RR_intervals[ix_rp+offset_ind_rr] = (FACTOR_MS*(indRpeaks[ix_rp]-indRpeaks[ix_rp-1]))/ECG_SAMPLING_FREQUENCY; +#ifdef PRINT_DEBUG_ERRDET + printf("R[%d]: %d RR[%d]: %d\n", ix_rp,(FACTOR_MS*(indRpeaks[ix_rp] + *offset_ind_r))/ECG_SAMPLING_FREQUENCY,ix_rp+offset_ind_rr,RR_intervals[ix_rp+offset_ind_rr]); +#endif + } + + *lastPeak = indRpeaks[*r_counter-1] + *offset_ind_r; + *lastRRp = RR_intervals[*r_counter-1]; +#ifdef PRINT_DEBUG_ERRDET + printf("lastPeak: %d lastRR: %d\n",(FACTOR_MS*(*lastPeak))/ECG_SAMPLING_FREQUENCY,*lastRRp ); +#endif + + if(*rWindow==0) + rr_counter = *r_counter-1; + else + rr_counter = *r_counter; + + for(int32_t ix_rr = 1; ix_rr < rr_counter; ix_rr++){ + ratioConsecutiveRR = (FACTOR_RATIO_RR*RR_intervals[ix_rr])/RR_intervals[ix_rr-1]; +#ifdef PRINT_DEBUG_ERRDET + printf("ratioConsecutiveRR: %d\n", ratioConsecutiveRR); +#endif + if(ratioConsecutiveRRPERCENTILE_LOO_HIGH) + return 1; + } + }else{ + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/PULP/error_detection/error_detection.h b/PULP/error_detection/error_detection.h new file mode 100644 index 0000000..0cff7b0 --- /dev/null +++ b/PULP/error_detection/error_detection.h @@ -0,0 +1,16 @@ +#ifndef ERROR_DETECTION_H_ +#define ERROR_DETECTION_H_ + +#include +#include +#include +#include "../defines.h" + +#define FACTOR_MS 1000 +#define FACTOR_RATIO_RR 1000 +#define PERCENTILE_LOO_LOW 641 //This is the 0.5th percentile of the RR distribution detected by the clustering using the leave-one-out approach for each subject (it is subject-specific) +#define PERCENTILE_LOO_HIGH 1492 //This is the 99.5th percentile of the RR distribution detected by the clustering using the leave-one-out approach for each subject (it is subject-specific) + +int errorDetection(int32_t *arg[]); + +#endif // ERROR_DETECTION_H_ \ No newline at end of file