Giter VIP home page Giter VIP logo

bci.js's Introduction

Brain Computer Interfaces (BCIs) with JavaScript

Version Downloads CDN License


Getting Started

Latest release is v1.8.0. You can view the release notes at releases

Documentation is available at https://bci.js.org/docs/

Node.js

npm install bcijs

Browser

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/bci.min.js"></script>

Feature Overview

For a complete list of methods, see the docs.

Signal Processing Machine Learning Data Management
Bandpower Feature extraction Load and save CSVs (Node.js only)
Welch's method Linear discriminant analysis Load from EDF (Node.js only)
Periodogram Confusion matrices Epoch / window data
Independent component analysis Metrics (precision, recall, F1, MCC, etc.) Partition datasets
Common spatial pattern Array subscripting (colon notation)
Signal generation

Tutorials

Examples

More examples can be found in the examples directory

Bandpower

const bci = require('bcijs');

// Generate 1 second of sample data at 512 Hz
// Contains 8 μV / 8 Hz and 4 μV / 17 Hz
let samplerate = 512;
let signal = bci.generateSignal([8, 4], [8, 17], samplerate, 1);

// Compute relative power in each frequency band
let bandpowers = bci.bandpower(signal, samplerate, ['alpha', 'beta'], {relative: true});

console.log(bandpowers); // [ 0.6661457715567836, 0.199999684787573 ]

Epoch data

let samples = [[1,2], [3,4], ...] // 2D array where rows are samples and columns are channels
let samplerate = 256; // 256 Hz

// Epoch data into epochs of 256 samples with a step of 64 (75% overlap)
// Then find the average alpha and beta powers in each epoch.
let powers = bci.windowApply(
	samples,
	epoch => bci.bandpower(epoch, samplerate, ['alpha', 'beta'], {average: true}),
	256,
	64
);

Subscript

const bci = require('bcijs');

// 5 samples of data from 3 channels 
let signal = [[1,2,3], [5,3,4], [4,5,6], [7,5,8], [4,4,2]];

// Select the first 3 samples from channels 1 and 3
let subset = bci.subscript(signal, '1:3', '1 3'); // [ [ 1, 3 ], [ 5, 4 ], [ 4, 6 ] ]

Linear discriminant analysis

const bci = require('bcijs');

// Training set
let class1 = [[0, 0], [1, 2], [2, 2], [1.5, 0.5]];
let class2 = [[8, 8], [9, 10], [7, 8], [9, 9]];

// Testing set
let unknownPoints = [[-1, 0], [1.5, 2],	[7, 9], [10, 12]];

// Learn an LDA classifier
let ldaParams = bci.ldaLearn(class1, class2);

// Test classifier
let predictions = bci.ldaClassify(ldaParams, unknownPoints);

console.log(predictions); // [ 0, 0, 1, 1 ]

Check out https://bci.js.org/examples/lda for a visual demo of how LDA works

Usage in the web

BCI.js can be loaded from the jsDelivr CDN with

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/bci.min.js"></script>

You can also find bci.js and bci.min.js at releases.

BCI.js methods are accessible via the global object bci.

If building a web distributable using a tool such as browserify or webpack, require bcijs/browser.js to load only methods that are browser compatible. Node.js specific methods such as networking and file system methods will not be included.

const bci = require('bcijs/browser.js');

Requiring specific methods

You can require specific methods as well. For example, if you only need fastICA, you can use

const fastICA = require('bcijs/lib/math/fastICA.js');

BCI.js methods can be found in the src/ directory.

Files are transpiled from ES6 import/export (in src/) to CommonJS (generated lib/) on npm install.

Documentation

Documentation can be found at https://bci.js.org/docs or by viewing api.md

Deprecated methods can be found at deprecated.md

Building

See dev.md for info on how to modify and build BCI.js

Reference

BCI.js began as WebBCI, a library developed to aid in my research at the Human Technology Interaction Lab at the University of Alabama Department of Computer Science. If you use BCI.js in a published work, please reference this paper

P. Stegman, C. Crawford, and J. Gray, "WebBCI: An Electroencephalography Toolkit Built on Modern Web Technologies," in Augmented Cognition: Intelligent Technologies, 2018, pp. 212–221.

Logo uses icon from Font Awesome.

Contact

If you have a commercial use case for BCI.js and would like to discuss working together, contact me at [email protected]

bci.js's People

Contributors

pwstegman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bci.js's Issues

Average bandpower with single band

This computes average power across channels as expected:

let power = bci.bandpower(samples, samplerate, ['alpha'], {average: true});

But this does not average across channels ({average: true} is ignored)

let power = bci.bandpower(samples, samplerate, 'alpha', {average: true});

Multitaper method

Multitaper method for power spectral density estimation.

Implemented in v1.8. Need to add unit tests.

Edit: Moved to v1.9

For computation of discrete prolate spheroidal (Slepian) sequences, a length up to 128 is calculated. Lengths past 128 are linearly interpolated up.

For tapers with near-unity eigenvalues for common time half bandwidths (2.5, 4, etc.) the curves are smooth enough that linear interpolation works well. A more efficient eigenvector method will help remove the need to interpolate.

[dev] PSD on small FFT size

When using a small FFT size, the PSD returns NaN.

Steps to reproduce.

bci.signalBandPower([1, 2, 3, 4, 5, 6, 7], 8, 256, 'alpha')
=> NaN
bci.signalBandPower([1, 2, 3, 4, 5, 6, 7], 16, 256, 'alpha')
=> NaN
bci.signalBandPower([1, 2, 3, 4, 5, 6, 7], 32, 256, 'alpha')
=> 26.416893639442556

Packing with webpack causes an error.

When attempting to pack this code for use on a browser-only solution, webbci's dependence on node-osc causes webpack to error due to node-only dependencies.

ERROR in ./node_modules/node-osc/lib/safeDgram.js
Module not found: Error: Can't resolve 'dgram' in './node_modules/node-osc/lib'
 @ ./node_modules/node-osc/lib/safeDgram.js 3:12-28
 @ ./node_modules/node-osc/lib/Server.js
 @ ./node_modules/node-osc/lib/index.js
 @ ./node_modules/webbci/lib/network.js
 @ ./node_modules/webbci/index.js

If you don't expect for this code to run on the browser side only, then this is probably expected behavior.

Welch's method

Welch's method for power spectral density estimation.

Implemented and set for release in v1.8. Need to add unit tests.

Cannot read property 'length' of undefined (Average Band Powers)

I am loading an edf using:
bci.loadEDF
In return I am getting an object that contains a channel property. Each channel contains samples, I am passing each of these samples to bci.averageBandPowers but getting this error:
TypeError: Cannot read property 'length' of undefined
at signalBandPower (C:\Users\HP\Desktop\projects\driverDrowsiness\node_modules\bcijs\lib\math\signalBandPower.js:49:41)
at Object.averageBandPowers (C:\Users\HP\Desktop\projects\driverDrowsiness\node_modules\bcijs\lib\math\averageBandPowers.js:25:29)
at getData (C:\Users\HP\Desktop\projects\driverDrowsiness\index.js:11:37)
at process._tickCallback (internal/process/next_tick.js:68:7)
at Function.Module.runMain (internal/modules/cjs/loader.js:834:11)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)

P.S In channels.sample I am getting a 1d array rather than the 2d one in bci.loadedf
This is my edf file

Band power per second

Hello Pierce!
My name is Anton and I’m using your js package called BCI.js but I can’t understand one thing and I believe you can help me :)
I have an array of signals from EEG session which lasted for 30 seconds and I want to get average alpha band power for every second.
I divide my signals by 30 and on each subarray I’m using signalBandPower method. Is this correct or I’m doing something wrong?

Thank you in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.