From 9aaec182a85a6edfa9f7ebe264bb4061f0f52c12 Mon Sep 17 00:00:00 2001 From: David Madl Date: Thu, 12 Mar 2026 20:34:54 +0100 Subject: [PATCH] refactor: move test_helpers, RunningQuality --- google-tests/CMakeLists.txt | 3 + google-tests/test2.cpp | 55 +-------- google-tests/test3.cpp | 197 ++++++++++++------------------ google-tests/test3/ssf_t3_acc.npy | Bin 0 -> 314936 bytes google-tests/test_helpers.cpp | 46 +++++++ google-tests/test_helpers.h | 33 +++++ pasada-lib/include/ssf_filter.h | 49 ++++++++ pasada-lib/ssf_filter.cpp | 88 ++++++++++++- 8 files changed, 297 insertions(+), 174 deletions(-) create mode 100644 google-tests/test3/ssf_t3_acc.npy create mode 100644 google-tests/test_helpers.cpp create mode 100644 google-tests/test_helpers.h diff --git a/google-tests/CMakeLists.txt b/google-tests/CMakeLists.txt index d8e648f..68f45da 100644 --- a/google-tests/CMakeLists.txt +++ b/google-tests/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(Google_Tests_run test1.cpp test2.cpp test3.cpp + test_helpers.cpp ) file(COPY test1/data1.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test1) @@ -23,6 +24,8 @@ file(COPY test1/iir_t1_y.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test1) file(COPY test2/ssf_t2_acc.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test2) file(COPY test2/ssf_t2_y_ref.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test2) +file(COPY test3/ssf_t3_acc.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test3) + target_link_libraries(Google_Tests_run pasada) #target_include_directories(Google_Tests_run PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/pasada-lib/include") diff --git a/google-tests/test2.cpp b/google-tests/test2.cpp index 64a3de5..5399cf8 100644 --- a/google-tests/test2.cpp +++ b/google-tests/test2.cpp @@ -6,56 +6,13 @@ #include #include "iir_filter.h" #include "ssf_filter.h" +#include "test_helpers.h" #include #include #define FPS 60 #define MAX_BPM 300 -template static std::vector apply_filter(T& filter, std::vector& x) { - std::vector y; - y.resize(x.size()); - for (int i = 0; i < x.size(); i++) { - y[i] = filter.filter(x[i]); - } - return y; -} - -static void npy_save(std::string path, std::vector& x) { - npy::npy_data_ptr d; - d.data_ptr = x.data(); - d.shape = {(unsigned long) x.size()}; - npy::write_npy(path, d); -} - -static std::vector fetch_y_axis(npy::npy_data& acc) { - // TODO: later on, we should use a vector projection towards gravity - std::vector signal; - const size_t rows_real = acc.shape[0]; -#if DEBUG_IIR == 1 - const size_t rows = 5; -#else - const size_t rows = acc.shape[0]; -#endif - int stride = 3; - int offset = 1; // [x,y,z] per row - fetch y - signal.resize(rows); - if (acc.fortran_order) { - stride = 1; - offset = (int) rows_real; - } - /* - std::cout << "is_fortran=" << acc.fortran_order << std::endl; - for (size_t i = 0; i < 10; i++) { - std::cout << "acc.data[" << i << "]=" << acc.data[i] << std::endl; - } - */ - for (int i = 0; i < rows; i++) { - signal[i] = acc.data[i * stride + offset]; - } - return signal; -} - TEST(HelloTest, Zong_SSF_Stage1) { npy::npy_data acc = npy::read_npy("test2/ssf_t2_acc.npy"); npy::npy_data y_ref = npy::read_npy("test2/ssf_t2_y_ref.npy"); @@ -166,16 +123,6 @@ TEST(HelloTest, Zong_SSF_Stage2) { npy_save("test2/ssf_t2_ssf.npy", ssf); } -/** Returns the ssf_threshold as the filter output for debugging. */ -class DebugSsfStepDetectorThreshold : public SsfStepDetector { -public: - DebugSsfStepDetectorThreshold(size_t len_refr) : SsfStepDetector(len_refr) {} - double filter(double val) { - this->SsfStepDetector::filter(val); - return peek_threshold(); - } -}; - TEST(HelloTest, Zong_SSF_Stage3) { npy::npy_data acc = npy::read_npy("test2/ssf_t2_acc.npy"); diff --git a/google-tests/test3.cpp b/google-tests/test3.cpp index 2577076..49bc59b 100644 --- a/google-tests/test3.cpp +++ b/google-tests/test3.cpp @@ -2,9 +2,12 @@ // Created by david on 04.03.2026. // #include +#include "npy.hpp" //#include #include #include "pd_signal.h" +#include "ssf_filter.h" +#include "test_helpers.h" using namespace pd_signal; @@ -38,123 +41,6 @@ TEST(SignalTest, ranges) { ASSERT_NEAR(2.0, i[2], abs_error); } -/** - * Running signal quality indicator. - */ -class RunningQuality { -protected: - // TODO: make it a filter (output proper samples) - - /** template beat is resampled to this #samples */ - const int BEAT_LEN = 120 /* 2*FPS for 30 bpm lower end */; - - /** threshold for accepting initial beats */ - const double BEAT_CORR_THR_1 = 0.9; - /** threshold for accepting subsequent beats */ - const double BEAT_CORR_THR_2 = 0.8; - /** absolute SSF threshold for accepting any beat */ - const double SSF_THRESHOLD = 5.0; - /** number of recent beats to use for beat template. must be even (alternating feet have different patterns; make it symmetric) */ - const int NUM_BEATS = 4; - - std::deque > beatTemplates; - std::vector beatTemplate; - //std::vector > badBeatRanges; - double beatCorrThr2; - bool justLocked; - int idx; - - /** for debugging only - disable SSF_THRESHOLD */ - bool disableSsf; - - void addTemplate(std::vector& x) { - beatTemplates.emplace_back(x); - while (beatTemplates.size() > NUM_BEATS) { - // sliding window on 'beat_templates', do not use all history - beatTemplates.pop_front(); - } - pd_signal::mean(beatTemplate, beatTemplates); - } - - void replaceTemplate(std::vector& x) { - beatTemplates.clear(); - beatTemplates.emplace_back(x); - // essentially just a copy - pd_signal::mean(beatTemplate, beatTemplates); - } - - virtual void dispatchLocked() { /* implement me, add Listener etc. */ } - virtual void dispatchBeat(int idx, bool good, double posCorr) { /* implement me, add Listener etc. */ } - -public: - RunningQuality(): beatCorrThr2(BEAT_CORR_THR_2), justLocked(false), idx(0), disableSsf(false) {} - explicit RunningQuality(bool disableSsf): beatCorrThr2(BEAT_CORR_THR_2), justLocked(false), idx(0), disableSsf(disableSsf) {} - virtual ~RunningQuality() {} - - // note: arg should be an iterator really, but can do later - /** - * @param beat individual beat accelero signal - */ - void append(std::vector &rawBeat, std::vector &rawSsf) { - // TODO: should ignore crazy-long and very short beats here. (filter up on beat detector) - - std::vector beat; - std::vector ssf; - resample(beat, rawBeat, BEAT_LEN); - resample(ssf, rawSsf, BEAT_LEN); - //std::ranges::copy(rawBeat, std::back_inserter(beat)); - - // check ssf at sample 2 (mid-slope of 4 window of ssf) - // TODO: param upon SsfFilter.upslope_width/2 instead of hardcoding - double checkedSsf = ssf[(int) (2*((double)beat.size())/((double)rawBeat.size()))]; - - double corr = std::numeric_limits::quiet_NaN(); - double posCorr = std::numeric_limits::quiet_NaN(); - bool goodBeat = false; - if (beatTemplates.size() > 0) { - corr = pd_signal::crossCorr(ssf, beatTemplate); - posCorr = pd_signal::clip(corr, 0.0, 1.0); - double corrThreshold = (beatTemplates.size() > 2) ? beatCorrThr2 : BEAT_CORR_THR_1; - goodBeat = (corr > corrThreshold) && (checkedSsf > SSF_THRESHOLD || disableSsf); - } - - if (beatTemplates.size() == 0) { - // cannot correlate the first beat, no template yet - std::cerr << "(0) first beat -> addTemplate()" << std::endl; - addTemplate(beat); - justLocked = false; - } else if (beatTemplates.size() <= 2) { - // restart if there is no clear correlation between beats - if (goodBeat) { - std::cerr << "(2) good initial beat -> addTemplate()" << std::endl; - addTemplate(beat); - if (beatTemplates.size() > 2) - justLocked = true; // TODO why not set? wrong compiler optimization? (is it unaware of member change?) - //std::cerr << " (2) beatTemplates.size()=" << beatTemplates.size() << " justLocked=" << ((int) justLocked) << std::endl; - } else { - std::cerr << "(2) bad initial beat -> replaceTemplate()" << std::endl; - replaceTemplate(beat); - //badBeatRanges.clear(); - justLocked = false; - } - } else { - // running mode: collect bad beats, but may be OK not to restart immediately - - std::cerr << "(3) running mode, good=" << ((int) goodBeat) << " justLocked=" << ((int) justLocked) << std::endl; - if (goodBeat) { - addTemplate(beat); - } else { - // badBeatRanges.add(s, e) - // numNoisy++ - } - // runningCorrs.add(posCorr) - if (justLocked) { dispatchLocked(); justLocked = false; } - dispatchBeat(idx, goodBeat, posCorr); - } - idx++; - } -}; - class DebugRunningQuality : public RunningQuality { protected: virtual void dispatchLocked() { locked = true; } @@ -212,4 +98,79 @@ TEST(SignalTest, RunningQuality_t1) { //ASSERT_NEAR(0.3, sqi.getBeatTemplate()[1], 1e-6); //ASSERT_NEAR(0.7, sqi.getBeatTemplate()[4], 1e-6); // nb. resampled! ASSERT_NEAR(num/norm, sqi.getCorrs()[0], 1e-3); -} \ No newline at end of file +} + +TEST(SignalTest, RunningQuality_t2) { + npy::npy_data acc = npy::read_npy("test3/ssf_t3_acc.npy"); + + std::vector signal = fetch_y_axis(acc); + +#if (FPS != 60) +#error "FPS must currently be 60, as highpass taps are pre-computed for that value" +#endif + + // TODO: SQI: cehck input file + // TODO: SQI: print debug values corr,idx, checkedSsf + + // Butterworth filter: order=5, fc=0.5, fs=60, btype='highpass' + std::vector b {0.91875845, -4.59379227, 9.18758454, -9.18758454, 4.59379227, -0.91875845}; + std::vector a {1. , -4.83056552, 9.33652742, -9.02545247, 4.36360803, -0.8441171}; + IirFilter filter(b, a); + + //std::cerr << "before stage 1" << std::endl; + + // Stage 1: high-pass + auto y = apply_filter(filter, signal); + + Filt f_neg(1, 0, 0, std::vector {-1.0}); + auto y_neg = apply_filter(f_neg, y); + + //std::cerr << "before stage 2" << std::endl; + + // Stage 2: sum slope function + const size_t upslope_width = 4; + SsfFilter f_ssf(upslope_width); + auto ssf = apply_filter(f_ssf, y_neg); + + //std::cerr << "before stage 3" << std::endl; + + // Stage 3: threshold detection + const size_t len_refr = (size_t) (FPS / (MAX_BPM / 60)); + DebugSsfStepDetectorThreshold f_ssd_thr(len_refr); + auto ssf_threshold = apply_filter(f_ssd_thr, ssf); + + //std::cerr << "before writing results 1 and doing step detection" << std::endl; + + npy_save("test2/ssf_t3_ssf_threshold.npy", ssf_threshold); + + SsfStepDetector f_ssd(len_refr); + auto steps = apply_filter(f_ssd, ssf); + + //std::cerr << "before writing results 2" << std::endl; + + npy_save("test2/ssf_t3_steps.npy", steps); + + // Debug SQI + + DebugRunningQuality sqi; + + std::vector beat_buf; + std::vector ssf_buf; + // y, ssf + size_t N = y.size(); + for (size_t i = 0; i < N; i++) { + if (steps[i] == 1.0) { + sqi.append(beat_buf, ssf_buf); + beat_buf.clear(); + ssf_buf.clear(); + } + beat_buf.push_back(y[i]); + ssf_buf.push_back(ssf[i]); + } + + EXPECT_TRUE(sqi.isLocked()); + EXPECT_TRUE(sqi.getCorrs().size() > 50); + + std::vector corrs(sqi.getCorrs()); + npy_save("test3/ssf_t3_sqi_corrs.npy", corrs); +} diff --git a/google-tests/test3/ssf_t3_acc.npy b/google-tests/test3/ssf_t3_acc.npy new file mode 100644 index 0000000000000000000000000000000000000000..e018df059d5194e2bb517f13990275b8e73a146c GIT binary patch literal 314936 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

Rg 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 I4*a& x) { + npy::npy_data_ptr d; + d.data_ptr = x.data(); + d.shape = {(unsigned long) x.size()}; + npy::write_npy(path, d); +} + +std::vector fetch_y_axis(npy::npy_data& acc) { + // TODO: later on, we should use a vector projection towards gravity + std::vector signal; + const size_t rows_real = acc.shape[0]; +#if DEBUG_IIR == 1 + const size_t rows = 5; +#else + const size_t rows = acc.shape[0]; +#endif + int stride = 3; + int offset = 1; // [x,y,z] per row - fetch y + signal.resize(rows); + if (acc.fortran_order) { + stride = 1; + offset = (int) rows_real; + } + /* + std::cout << "is_fortran=" << acc.fortran_order << std::endl; + for (size_t i = 0; i < 10; i++) { + std::cout << "acc.data[" << i << "]=" << acc.data[i] << std::endl; + } + */ + for (int i = 0; i < rows; i++) { + signal[i] = acc.data[i * stride + offset]; + } + return signal; +} + +DebugSsfStepDetectorThreshold::DebugSsfStepDetectorThreshold(size_t len_refr) : SsfStepDetector(len_refr) {} +double DebugSsfStepDetectorThreshold::filter(double val) { + this->SsfStepDetector::filter(val); + return peek_threshold(); +} diff --git a/google-tests/test_helpers.h b/google-tests/test_helpers.h new file mode 100644 index 0000000..9b23828 --- /dev/null +++ b/google-tests/test_helpers.h @@ -0,0 +1,33 @@ +// +// Created by david on 11.03.2026. +// + +#ifndef PASADASUPERPROJECT_TEST_HELPERS_H +#define PASADASUPERPROJECT_TEST_HELPERS_H + +#include "npy.hpp" +#include "ssf_filter.h" +#include +#include + +template static std::vector apply_filter(T& filter, std::vector& x) { + std::vector y; + y.resize(x.size()); + for (int i = 0; i < x.size(); i++) { + y[i] = filter.filter(x[i]); + } + return y; +} + +void npy_save(std::string path, std::vector& x); + +std::vector fetch_y_axis(npy::npy_data& acc); + +/** Returns the ssf_threshold as the filter output for debugging. */ +class DebugSsfStepDetectorThreshold : public SsfStepDetector { +public: + DebugSsfStepDetectorThreshold(size_t len_refr); + double filter(double val); +}; + +#endif //PASADASUPERPROJECT_TEST_HELPERS_H \ No newline at end of file diff --git a/pasada-lib/include/ssf_filter.h b/pasada-lib/include/ssf_filter.h index 9199a1c..11fd9da 100644 --- a/pasada-lib/include/ssf_filter.h +++ b/pasada-lib/include/ssf_filter.h @@ -6,6 +6,7 @@ #define PASADASUPERPROJECT_SSF_FILTER_H #include "iir_filter.h" +#include #define FPS 60 #define MAX_BPM 300 @@ -53,4 +54,52 @@ public: double peek_threshold(); }; +/** + * Running signal quality indicator. + */ +class RunningQuality { +protected: + // TODO: make it a filter (output proper samples) + + /** template beat is resampled to this #samples */ + const int BEAT_LEN = 120 /* 2*FPS for 30 bpm lower end */; + + /** threshold for accepting initial beats */ + const double BEAT_CORR_THR_1 = 0.9; + /** threshold for accepting subsequent beats */ + const double BEAT_CORR_THR_2 = 0.8; + /** absolute SSF threshold for accepting any beat */ + const double SSF_THRESHOLD = 5.0; + /** number of recent beats to use for beat template. must be even (alternating feet have different patterns; make it symmetric) */ + const int NUM_BEATS = 4; + + std::deque > beatTemplates; + std::vector beatTemplate; + //std::vector > badBeatRanges; + double beatCorrThr2; + bool justLocked; + int idx; + + /** for debugging only - disable SSF_THRESHOLD */ + bool disableSsf; + + void addTemplate(std::vector& x); + + void replaceTemplate(std::vector& x); + + virtual void dispatchLocked(); + virtual void dispatchBeat(int idx, bool good, double posCorr); + +public: + RunningQuality(); + explicit RunningQuality(bool disableSsf); + virtual ~RunningQuality(); + + // note: arg should be an iterator really, but can do later + /** + * @param beat individual beat accelero signal + */ + void append(std::vector &rawBeat, std::vector &rawSsf); +}; + #endif //PASADASUPERPROJECT_SSF_FILTER_H \ No newline at end of file diff --git a/pasada-lib/ssf_filter.cpp b/pasada-lib/ssf_filter.cpp index 5b281ee..88556f0 100644 --- a/pasada-lib/ssf_filter.cpp +++ b/pasada-lib/ssf_filter.cpp @@ -2,9 +2,9 @@ // Created by david on 03.03.2026. // -#include "include/ssf_filter.h" +#include "ssf_filter.h" +#include "pd_signal.h" #include -#include #include #include @@ -86,3 +86,87 @@ double SsfStepDetector::filter(double ssf) { double SsfStepDetector::peek_threshold() { return ssf_threshold; } + + +void RunningQuality::addTemplate(std::vector& x) { + beatTemplates.emplace_back(x); + while (beatTemplates.size() > NUM_BEATS) { + // sliding window on 'beat_templates', do not use all history + beatTemplates.pop_front(); + } + pd_signal::mean(beatTemplate, beatTemplates); +} + +void RunningQuality::replaceTemplate(std::vector& x) { + beatTemplates.clear(); + beatTemplates.emplace_back(x); + // essentially just a copy + pd_signal::mean(beatTemplate, beatTemplates); +} + +void RunningQuality::dispatchLocked() { /* implement me, add Listener etc. */ } +void RunningQuality::dispatchBeat(int idx, bool good, double posCorr) { /* implement me, add Listener etc. */ } + +RunningQuality::RunningQuality(): beatCorrThr2(BEAT_CORR_THR_2), justLocked(false), idx(0), disableSsf(false) {} +RunningQuality::RunningQuality(bool disableSsf): beatCorrThr2(BEAT_CORR_THR_2), justLocked(false), idx(0), disableSsf(disableSsf) {} +RunningQuality::~RunningQuality() {} + +// note: arg should be an iterator really, but can do later +void RunningQuality::append(std::vector &rawBeat, std::vector &rawSsf) { + // TODO: should ignore crazy-long and very short beats here. (filter up on beat detector) + + std::vector beat; + std::vector ssf; + pd_signal::resample(beat, rawBeat, BEAT_LEN); + pd_signal::resample(ssf, rawSsf, BEAT_LEN); + //std::ranges::copy(rawBeat, std::back_inserter(beat)); + + // check ssf at sample 2 (mid-slope of 4 window of ssf) + // TODO: param upon SsfFilter.upslope_width/2 instead of hardcoding + double checkedSsf = ssf[(int) (2*((double)beat.size())/((double)rawBeat.size()))]; + + double corr = std::numeric_limits::quiet_NaN(); + double posCorr = std::numeric_limits::quiet_NaN(); + bool goodBeat = false; + if (beatTemplates.size() > 0) { + corr = pd_signal::crossCorr(ssf, beatTemplate); + posCorr = pd_signal::clip(corr, 0.0, 1.0); + double corrThreshold = (beatTemplates.size() > 2) ? beatCorrThr2 : BEAT_CORR_THR_1; + goodBeat = (corr > corrThreshold) && (checkedSsf > SSF_THRESHOLD || disableSsf); + } + + if (beatTemplates.size() == 0) { + // cannot correlate the first beat, no template yet + std::cerr << "(0) first beat -> addTemplate()" << std::endl; + addTemplate(beat); + justLocked = false; + } else if (beatTemplates.size() <= 2) { + // restart if there is no clear correlation between beats + if (goodBeat) { + std::cerr << "(2) good initial beat -> addTemplate()" << std::endl; + addTemplate(beat); + if (beatTemplates.size() > 2) + justLocked = true; // TODO why not set? wrong compiler optimization? (is it unaware of member change?) + //std::cerr << " (2) beatTemplates.size()=" << beatTemplates.size() << " justLocked=" << ((int) justLocked) << std::endl; + } else { + std::cerr << "(2) bad initial beat -> replaceTemplate()" << std::endl; + replaceTemplate(beat); + //badBeatRanges.clear(); + justLocked = false; + } + } else { + // running mode: collect bad beats, but may be OK not to restart immediately + + std::cerr << "(3) running mode, good=" << ((int) goodBeat) << " justLocked=" << ((int) justLocked) << std::endl; + if (goodBeat) { + addTemplate(beat); + } else { + // badBeatRanges.add(s, e) + // numNoisy++ + } + // runningCorrs.add(posCorr) + if (justLocked) { dispatchLocked(); justLocked = false; } + dispatchBeat(idx, goodBeat, posCorr); + } + idx++; +}