Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion .github/workflows/run_unix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ jobs:
- name: Install dotnet
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.0.x'
dotnet-version: |
7.0.x
8.0.x
- name: Install Python 3.10
uses: actions/setup-python@v5
with:
Expand Down Expand Up @@ -378,6 +380,27 @@ jobs:
run: sudo -H python3 $GITHUB_WORKSPACE/python_package/examples/tests/band_power.py
- name: BandPowerAll Python
run: sudo -H python3 $GITHUB_WORKSPACE/python_package/examples/tests/band_power_all.py
- name: Band Power Regression Python
run: sudo -H python3 $GITHUB_WORKSPACE/python_package/examples/tests/band_power_regression.py
- name: Signal Processing Regression Python
run: |
sudo -H python3 $GITHUB_WORKSPACE/python_package/examples/tests/signal_processing_regression.py
sudo -H python3 $GITHUB_WORKSPACE/python_package/examples/tests/decomposition_regression.py
sudo -H python3 $GITHUB_WORKSPACE/python_package/examples/tests/signal_metrics_regression.py
sudo -H python3 $GITHUB_WORKSPACE/python_package/examples/tests/binding_validation_regression.py
- name: Signal Processing Regression Cpp
run: $GITHUB_WORKSPACE/cpp_package/examples/signal_processing/build/signal_processing_regression
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/installed/lib
- name: Signal Processing Regression Csharp
run: dotnet run --project $GITHUB_WORKSPACE/csharp_package/brainflow/examples/signal_processing_regression
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/installed/lib
- name: Signal Processing Regression Rust
run: cargo test --manifest-path $GITHUB_WORKSPACE/rust_package/brainflow/Cargo.toml data_filter::tests
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/installed/lib
DYLD_LIBRARY_PATH: ${{ github.workspace }}/installed/lib
- name: Activity Index Python
run: sudo -H python3 $GITHUB_WORKSPACE/python_package/examples/tests/activity_index.py
- name: Denoising Cpp
Expand Down Expand Up @@ -456,6 +479,12 @@ jobs:
mvn exec:java -Dexec.mainClass="brainflow.examples.BandPower"
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/installed/lib
- name: Binding Validation Java
run: |
cd $GITHUB_WORKSPACE/java_package/brainflow
mvn test-compile exec:java -Dexec.mainClass="brainflow.BindingValidationRegression" -Dexec.classpathScope=test
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/installed/lib
- name: EEG Metrics Python
run: sudo -H python3 $GITHUB_WORKSPACE/python_package/examples/tests/eeg_metrics.py --board-id -1
- name: EEG Metrics Custom Python
Expand Down Expand Up @@ -485,6 +514,10 @@ jobs:
run: |
cd $GITHUB_WORKSPACE/nodejs_package/tests
npm run signal_filtering
- name: Binding Validation Node
run: |
cd $GITHUB_WORKSPACE/nodejs_package/tests
npx ts-node binding_validation_regression.ts
- name: Serialization Node
run: |
cd $GITHUB_WORKSPACE/nodejs_package/tests
Expand Down
19 changes: 18 additions & 1 deletion .github/workflows/run_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ jobs:
- name: Install dotnet
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.0.x'
dotnet-version: |
7.0.x
8.0.x
- name: Setup Python
uses: actions/setup-python@v4
with:
Expand Down Expand Up @@ -241,6 +243,21 @@ jobs:
- name: PSD Welch Nyquist Overlap Python Test
run: python %GITHUB_WORKSPACE%\python_package\examples\tests\psd_welch_nyquist_overlap.py
shell: cmd
- name: Signal Processing Regression Python
run: |
python python_package\examples\tests\band_power_regression.py
python python_package\examples\tests\signal_processing_regression.py
python python_package\examples\tests\decomposition_regression.py
python python_package\examples\tests\signal_metrics_regression.py
python python_package\examples\tests\binding_validation_regression.py
shell: cmd
- name: Signal Processing Regression Csharp
run: dotnet run --project csharp_package\brainflow\examples\signal_processing_regression
- name: Signal Processing Regression Rust
run: cargo test --manifest-path rust_package\brainflow\Cargo.toml data_filter::tests
- name: Signal Processing Regression Cpp
run: .\cpp_package\examples\signal_processing\build\Release\signal_processing_regression.exe
shell: cmd
- name: Wavelet Buffer Size Python Test
run: python %GITHUB_WORKSPACE%\python_package\examples\tests\wavelet_buffer_size.py
shell: cmd
Expand Down
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,18 @@ ASALocalRun/
*.pickle
*.onnx

# Reviewed classifier release artifacts (raw recordings and work caches stay ignored).
!src/ml/train/logreg_mindfulness.onnx
!src/ml/train/svm_mindfulness.onnx
!src/ml/train/forest_mindfulness.onnx
!src/ml/train/knn_mindfulness.onnx
!src/ml/train/mlp_mindfulness.onnx
!src/ml/train/stacking_mindfulness.onnx
!src/ml/train/extra_trees_mindfulness.onnx
!src/ml/train/hist_gradient_boosting_mindfulness.onnx
!src/ml/train/polynomial_logreg_mindfulness.onnx
!src/ml/train/gradient_boosting_mindfulness.onnx

#Environment file
.env
.vscode/
Expand Down
8 changes: 7 additions & 1 deletion cpp_package/examples/signal_processing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ find_package (
brainflow CONFIG REQUIRED
)

add_executable (signal_processing_regression src/signal_processing_regression.cpp)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Commit the referenced regression test assets

The repository tree contains no src/signal_processing_regression.cpp, so both Unix and Windows fail while configuring the signal-processing examples before this target can run. The new workflow steps likewise reference five absent Python scripts, an absent C# project, and an absent Java regression class, so merely fixing this C++ source still leaves both CI workflows guaranteed to fail; add the regression assets or remove their targets and invocations.

Useful? React with 👍 / 👎.

target_include_directories (signal_processing_regression PUBLIC ${brainflow_INCLUDE_DIRS})
target_link_libraries (signal_processing_regression PUBLIC ${BrainflowPath} ${DataHandlerPath} ${BoardControllerPath})
enable_testing ()
add_test (NAME signal_processing_regression COMMAND signal_processing_regression)

##############################
## Demo for read write file ##
##############################
Expand Down Expand Up @@ -290,4 +296,4 @@ target_link_libraries (
${MLModulePath}
${DataHandlerPath}
${BoardControllerPath}
)
)
73 changes: 21 additions & 52 deletions cpp_package/examples/signal_processing/src/ica.cpp
Original file line number Diff line number Diff line change
@@ -1,64 +1,33 @@
#include <cmath>
#include <iostream>
#include <stdlib.h>
#include <string>

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

#include "board_shim.h"
#include "data_filter.h"

using namespace std;


int main (int argc, char *argv[])
int main ()
{
BoardShim::enable_dev_board_logger ();

struct BrainFlowInputParams params;
int res = 0;
int board_id = (int)BoardIds::SYNTHETIC_BOARD;
std::vector<int> eeg_channels = BoardShim::get_eeg_channels (board_id);
int channel_to_use = eeg_channels[4];
// use synthetic board for demo
BoardShim *board = new BoardShim (board_id, params);

// Two simultaneous mixtures of non-Gaussian sources: rows are channels, columns are samples.
const int samples = 1024;
const double pi = std::acos (-1.0);
BrainFlowArray<double, 2> data (2, samples);
for (int i = 0; i < samples; i++)
{
double t = i / 256.0;
double first = std::sin (2.0 * pi * 7.0 * t);
double second = std::pow (std::sin (2.0 * pi * 13.0 * t), 3);
data.at (0, i) = first + 0.3 * second;
data.at (1, i) = 0.2 * first + second;
}
try
{
board->prepare_session ();
board->start_stream ();

#ifdef _WIN32
Sleep (10000);
#else
sleep (10);
#endif

board->stop_stream ();
BrainFlowArray<double, 2> data =
board->get_board_data (500, (int)BrainFlowPresets::DEFAULT_PRESET);
board->release_session ();

BrainFlowArray<double, 2> data_reshaped (data.get_address (channel_to_use), 5, 100);
std::tuple<BrainFlowArray<double, 2>, BrainFlowArray<double, 2>, BrainFlowArray<double, 2>,
BrainFlowArray<double, 2>>
returned_matrixes = DataFilter::perform_ica (data_reshaped, 2);
std::cout << std::get<3> (returned_matrixes) << std::endl;
auto result = DataFilter::perform_ica (data, 2);
// Component order and sign are arbitrary.
std::cout << "Recovered " << std::get<3> (result).get_size (0) << " sources from "
<< samples << " samples" << std::endl;
}
catch (const BrainFlowException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
std::cerr << err.what () << std::endl;
return err.exit_code;
}

delete board;

return res;
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <cmath>
#include <functional>
#include <iostream>
#include <limits>
#include <stdexcept>

#include "data_filter.h"

static void reject (const std::function<void ()> &action)
{
try
{
action ();
}
catch (const BrainFlowException &)
{
return;
}
throw std::runtime_error ("Expected invalid input to be rejected");
}

int main ()
{
BrainFlowArray<double, 2> data (2, 256);
reject ([&] { data.at (-1, 0); });
reject ([&] { data.at (0, 256); });
reject ([&] { data.get_address (-1); });
reject ([&] { data[-1]; });
reject ([&] { BrainFlowArray<double, 2> invalid (-1, 256); });
reject (
[&] {
DataFilter::get_csp (
BrainFlowArray<double, 3> (2, 2, 8), BrainFlowArray<double, 1> (1));
});
reject ([&] { DataFilter::perform_ica (data, 2, {-1, 1}); });
reject ([&] { DataFilter::get_avg_band_powers (data, {-1}, 256, false); });
reject ([&] { DataFilter::perform_fft (data.get_raw_ptr (), 256, 0, nullptr); });
reject ([&] { DataFilter::get_psd (data.get_raw_ptr (), 256, 256, 0, nullptr); });
reject ([&] { DataFilter::perform_wavelet_transform (data.get_raw_ptr (), 256, 3, -1); });
reject (
[&] {
DataFilter::perform_inverse_wavelet_transform (
std::vector<double> (4), {2, 2}, 8, 3, 2);
});
for (int original_length :
{4, std::numeric_limits<int>::max () / 2, std::numeric_limits<int>::max ()})
reject (
[&]
{
DataFilter::perform_inverse_wavelet_transform (
std::vector<double> (2), {1, 1}, original_length, 0, 1);
});

std::vector<double> input (256);
for (size_t i = 0; i < input.size (); ++i)
input[i] = std::sin (0.1 * i);
auto transform =
DataFilter::perform_wavelet_transform (input.data (), (int)input.size (), 3, 3);
std::vector<int> lengths (transform.second, transform.second + 4);
int total = 0;
for (int length : lengths)
total += length;
std::vector<double> coefficients (transform.first, transform.first + total);
delete[] transform.first;
delete[] transform.second;
auto restored =
DataFilter::perform_inverse_wavelet_transform (coefficients, lengths, 256, 3, 3);
for (size_t i = 0; i < input.size (); ++i)
if (std::abs (input[i] - restored[i]) > 1e-10)
throw std::runtime_error ("Wavelet round trip failed");
lengths[0]++;
reject (
[&] { DataFilter::perform_inverse_wavelet_transform (coefficients, lengths, 256, 3, 3); });
std::cout << "Signal-processing binding validation passed." << std::endl;
}
Loading
Loading