Skip to content

Commit

Permalink
1D signal Fourier and Inverse Fourier transform filter.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArminTaheri committed Aug 1, 2017
1 parent a996c28 commit d4871bd
Show file tree
Hide file tree
Showing 8 changed files with 2,774 additions and 168 deletions.
2,800 changes: 2,653 additions & 147 deletions dist/pixpipe.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/pixpipe.js.map

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
"file-saver": "^1.3.3",
"geotiff": "^0.4.1",
"js-md5": "^0.4.2",
"ndarray": "^1.0.18",
"ndarray-fft": "^1.0.3",
"pako": "^1.0.4",
"qeegmodfileparser": "github:jonathanlurie/qeegmodfileparser",
"qeegmodfile": "github:jonathanlurie/qeegmodfile",
"rollup-plugin-bundle-worker": "^0.1.0"
},
"devDependencies": {
Expand Down
20 changes: 10 additions & 10 deletions src/core/Filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Filter extends PixpipeObject {
this._timer = {};

this._isOutputReady = false;

this.setMetadata("time", true);

}
Expand Down Expand Up @@ -247,15 +247,15 @@ class Filter extends PixpipeObject {
var that = this;
var inputCategories = Object.keys( this._inputValidator );
var valid = true;

if(inputCategories.length == 0){
valid = false;
console.warn("No input validator was added. Filter cannot run. Use addInputValidator(...) to specify input types.");
}

inputCategories.forEach( function(key){
var inputOfCategory = that._getInput( key );

if(inputOfCategory){
if("isOfType" in inputOfCategory){
valid = valid && inputOfCategory.isOfType( that._inputValidator[ key ] )
Expand All @@ -266,13 +266,13 @@ class Filter extends PixpipeObject {
valid = false;
}
}

}
// input simply not existing!
else{
valid = false;
}

});

if(!valid){
Expand Down Expand Up @@ -316,7 +316,7 @@ class Filter extends PixpipeObject {
* @param {String} recordName - name of the record
*/
addTimeRecord( recordName ){
this._timer[ recordName ] = performance.now();
this._timer[ recordName ] = 0;
}


Expand Down Expand Up @@ -356,24 +356,24 @@ class Filter extends PixpipeObject {
*/
triggerEvent( eventName /* any other arguments to follow */ ){
var returnValue = null;

if(this.hasEvent(eventName)){
if( arguments.length > 1 ){

// a-la-mano slicing argument array to comply with V8 JS engine optimization...
var argToSend = [];
for(var i=1; i<arguments.length; i++){
argToSend.push( arguments[i] );
}

returnValue = this._events[eventName].apply(this, argToSend )
}else{
returnValue = this._events[eventName].call(this);
}
}else{
console.warn("The event " + eventName + " does not exist.");
}

return returnValue;
}

Expand Down
44 changes: 44 additions & 0 deletions src/core/Signal1D.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { PixpipeContainer } from './PixpipeContainer';

class Signal1D extends PixpipeContainer {
constructor() {
super();
this._type = Signal1D.TYPE();
this.setMetadata('length', 0);
}

static TYPE() {
return 'SIGNAL1D';
}

getData() {
return this._data;
}

setData(array, deepCopy = false) {
if (deepCopy) {
this._data = new array.constructor(array);
} else {
this._data = array;
}

this.setMetadata('length', array.length);
}

clone(){
const copy = new Signal1D();
if (this._data) {
copy.setData(this._data, true);
}
return copy;
}

hollowClone(){
const copy = new Signal1D();
const length = this.getMetadata('length');
copy.setData( new Float32Array(length).fill(0) );
return copy
}
}

export { Signal1D }
16 changes: 8 additions & 8 deletions src/decoder/EegModDecoder.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
import { Filter } from '../core/Filter.js';
import QeegModFileParser from 'qeegmodfileparser';
import { QeegModFileParser } from 'qeegmodfile';


class EegModDecoder extends Filter {

constructor() {
super();
this.addInputValidator(0, ArrayBuffer);
this.setMetadata("debug", false);

// a soon-to-be DataView to read the input buffer
this._view = null;
}

_run(){
var inputBuffer = this._getInput(0);

if(!inputBuffer){
console.warn("EegModDecoder requires an ArrayBuffer as input \"0\". Unable to continue.");
return;
}

var modParser = new QeegModFileParser();
modParser.setRawData( inputBuffer );
var qeegData = modParser.parse();

if( qeegData ){
this._output[0] = qeegData;
}

}

} /* END of class EegModDecoder */

export { EegModDecoder }
52 changes: 52 additions & 0 deletions src/filter/FourierSignalFilters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import ndarray from 'ndarray';
import ft from 'ndarray-fft';

import { Filter } from '../core/Filter';
import { Signal1D } from '../core/Signal1D';

const DIRECTIONS = {
'FORWARD': 1,
'INVERSE': -1,
};

class BaseFourierSignalFilter extends Filter {
constructor(direction) {
super();
this.direction = direction;
if (DIRECTIONS[this.direction] === undefined) {
throw new Error(`${this.direction} is not a valid fourier transform direction. Please try one of: ${Object.keys(DIRECTIONS)}`);
}
this.addInputValidator(0, Signal1D);
}
_run() {
if( ! this.hasValidInput()){
console.warn("A filter of type BaseFourierSignalFilter requires 1 input of Signal1D.");
return;
}
const inputSignal = this._getInput(0);
const length = inputSignal.getMetadata('length');
const real = ndarray(inputSignal.clone().getData(), [length]);
const img = ndarray(inputSignal.hollowClone().getData(), [length]);
this.setMetadata('direction', this.direction);

ft(DIRECTIONS[this.direction], real, img);
this._output[0] = new Signal1D();
this._output[0].setData(real.data);
this._output[1] = new Signal1D();
this._output[1].setData(img.data);
}
}

class ForwardFourierSignalFilter extends BaseFourierSignalFilter {
constructor() {
super('FORWARD');
}
}

class InverseFourerSignalFilter extends BaseFourierSignalFilter {
constructor() {
super('INVERSE');
}
}

export { ForwardFourierSignalFilter, InverseFourerSignalFilter }
4 changes: 3 additions & 1 deletion src/pixpipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// core classes
export { PixpipeObject } from './core/PixpipeObject.js';
export { Filter } from './core/Filter.js';
export { Signal1D } from './core/Signal1D.js'
export { Image2D } from './core/Image2D.js';
export { Image3D } from './core/Image3D.js';
export { ImageToImageFilter } from './core/ImageToImageFilter.js';
Expand All @@ -30,7 +31,8 @@ export { EegModDecoder } from './decoder/EegModDecoder.js';
export { PixBinEncoder } from './decoder/PixBinEncoder.js';
export { PixBinDecoder } from './decoder/PixBinDecoder.js';

// filters - processing of Images2D
// filters - processing of Images2D and Signal1D
export { ForwardFourierSignalFilter, InverseFourerSignalFilter } from './filter/FourierSignalFilters.js';
export { ForEachPixelImageFilter } from './filter/ForEachPixelImageFilter.js';
export { SpectralScaleImageFilter } from './filter/SpectralScaleImageFilter.js';
export { ImageBlendExpressionFilter } from './filter/ImageBlendExpressionFilter.js';
Expand Down

0 comments on commit d4871bd

Please sign in to comment.