Skip to content

Commit af51f5e

Browse files
author
AJ Keller
committed
Over hauling sample parseing
1 parent a680dd6 commit af51f5e

File tree

5 files changed

+189
-1
lines changed

5 files changed

+189
-1
lines changed

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
* Could not use 'daisy' with sample rate setter.
66

7+
### New Features
8+
9+
* Add function in utilities for making daisy packets.
10+
711

812
# 0.0.5
913

openBCIConstants.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ const obciBoardCyton = 'cyton';
239239
const obciBoardDaisy = 'daisy';
240240
const obciBoardDefault = 'default';
241241
const obciBoardGanglion = 'ganglion';
242+
const obciBoardNone = 'none';
242243

243244
/** Possible Simulator Line Noise injections */
244245
const obciSimulatorLineNoiseHz60 = '60Hz';
@@ -885,12 +886,16 @@ module.exports = {
885886
OBCIBoardDaisy: obciBoardDaisy,
886887
OBCIBoardDefault: obciBoardDefault,
887888
OBCIBoardGanglion: obciBoardGanglion,
889+
OBCIBoardNone: obciBoardNone,
888890
numberOfChannelsForBoardType: boardType => {
889891
switch (boardType) {
890892
case obciBoardDaisy:
891893
return obciNumberOfChannelsDaisy;
892894
case obciBoardGanglion:
893895
return obciNumberOfChannelsGanglion;
896+
case obciBoardNone:
897+
return 0;
898+
case obciBoardCyton:
894899
default:
895900
return obciNumberOfChannelsDefault;
896901
}

openBCIUtilities.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ var utilitiesModule = {
489489
return new Buffer([0xA0, 0x00, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, makeTailByteFromPacketType(k.OBCIStreamPacketUserDefinedType)]);
490490
},
491491
makeDaisySampleObject,
492+
makeDaisySampleObjectWifi,
492493
getChannelDataArray,
493494
isEven,
494495
isOdd,
@@ -1394,6 +1395,57 @@ function makeDaisySampleObject (lowerSampleObject, upperSampleObject) {
13941395
return daisySampleObject;
13951396
}
13961397

1398+
/**
1399+
* @description Used to make one sample object from two sample objects. The sample number of the new daisy sample will
1400+
* be the upperSampleObject's sample number divded by 2. This allows us to preserve consecutive sample numbers that
1401+
* flip over at 127 instead of 255 for an 8 channel. The daisySampleObject will also have one `channelData` array
1402+
* with 16 elements inside it, with the lowerSampleObject in the lower indices and the upperSampleObject in the
1403+
* upper set of indices. The auxData from both channels shall be captured in an object called `auxData` which
1404+
* contains two arrays referenced by keys `lower` and `upper` for the `lowerSampleObject` and `upperSampleObject`,
1405+
* respectively. The timestamps shall be averaged and moved into an object called `timestamp`. Further, the
1406+
* un-averaged timestamps from the `lowerSampleObject` and `upperSampleObject` shall be placed into an object called
1407+
* `_timestamps` which shall contain two keys `lower` and `upper` which contain the original timestamps for their
1408+
* respective sampleObjects.
1409+
* @param lowerSampleObject {Object} - Lower 8 channels with odd sample number
1410+
* @param upperSampleObject {Object} - Upper 8 channels with even sample number
1411+
* @returns {Object} - The new merged daisy sample object
1412+
*/
1413+
function makeDaisySampleObjectWifi (lowerSampleObject, upperSampleObject) {
1414+
var daisySampleObject = {};
1415+
1416+
if (lowerSampleObject.hasOwnProperty('channelData')) {
1417+
daisySampleObject['channelData'] = lowerSampleObject.channelData.concat(upperSampleObject.channelData);
1418+
}
1419+
1420+
if (lowerSampleObject.hasOwnProperty('channelDataCounts')) {
1421+
daisySampleObject['channelDataCounts'] = lowerSampleObject.channelDataCounts.concat(upperSampleObject.channelDataCounts);
1422+
}
1423+
1424+
daisySampleObject['sampleNumber'] = upperSampleObject.sampleNumber;
1425+
1426+
daisySampleObject['auxData'] = {
1427+
'lower': lowerSampleObject.auxData,
1428+
'upper': upperSampleObject.auxData
1429+
};
1430+
1431+
if (lowerSampleObject.hasOwnProperty('timestamp')) {
1432+
daisySampleObject['timestamp'] = lowerSampleObject.timestamp;
1433+
}
1434+
1435+
daisySampleObject['_timestamps'] = {
1436+
'lower': lowerSampleObject.timestamp,
1437+
'upper': upperSampleObject.timestamp
1438+
};
1439+
1440+
if (lowerSampleObject.accelData) {
1441+
daisySampleObject['accelData'] = lowerSampleObject.accelData;
1442+
} else if (upperSampleObject.accelData) {
1443+
daisySampleObject['accelData'] = upperSampleObject.accelData;
1444+
}
1445+
1446+
return daisySampleObject;
1447+
}
1448+
13971449
/**
13981450
* @description Used to test a number to see if it is even
13991451
* @param a {Number} - The number to test

test/openBCIConstants-test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,34 @@ describe('OpenBCIConstants', function () {
967967
expect(k.OBCIRadioPollTimeMin).to.be.equal(0);
968968
});
969969
});
970+
describe('Board Types', function () {
971+
it('should get right name for chan daisy', function () {
972+
expect(k.OBCIBoardDaisy).to.equal("daisy");
973+
});
974+
it('should get right name for chan cyton', function () {
975+
expect(k.OBCIBoardCyton).to.equal("cyton");
976+
});
977+
it('should get right name for chan ganglion', function () {
978+
expect(k.OBCIBoardGanglion).to.equal("ganglion");
979+
});
980+
it('should get right name for chan none', function () {
981+
expect(k.OBCIBoardNone).to.equal("none");
982+
});
983+
});
984+
describe('numberOfChannelsForBoardTypes', function () {
985+
it('should get right num chan for daisy board', function () {
986+
expect(k.numberOfChannelsForBoardType(k.OBCIBoardDaisy)).to.equal(16);
987+
});
988+
it('should get right num chan for cyton board', function () {
989+
expect(k.numberOfChannelsForBoardType(k.OBCIBoardCyton)).to.equal(8);
990+
});
991+
it('should get right num chan for ganglion', function () {
992+
expect(k.numberOfChannelsForBoardType(k.OBCIBoardGanglion)).to.equal(4);
993+
});
994+
it('should get right num chan for none', function () {
995+
expect(k.numberOfChannelsForBoardType(k.OBCIBoardNone)).to.equal(0);
996+
});
997+
});
970998
describe('#getChannelSetter', function () {
971999
// 'channel 1, power on, gain 24, inputType normal, bias include, srb2 connect, srb1 dissconnect'
9721000
describe('channel input selection works', function () {

test/openBCIUtilities-test.js

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ describe('openBCIUtilities', function () {
917917
});
918918
describe('#makeDaisySampleObject', function () {
919919
let lowerSampleObject, upperSampleObject, daisySampleObject;
920+
let lowerSampleObjectNoScale, upperSampleObjectNoScale, daisySampleObjectNoScale;
920921
before(() => {
921922
// Make the lower sample (channels 1-8)
922923
lowerSampleObject = openBCIUtilities.newSample(1);
@@ -930,37 +931,135 @@ describe('openBCIUtilities', function () {
930931
upperSampleObject.auxData = [3, 4, 5];
931932
upperSampleObject.timestamp = 8;
932933

933-
// Call the function under test
934934
daisySampleObject = openBCIUtilities.makeDaisySampleObject(lowerSampleObject, upperSampleObject);
935+
936+
// lowerSampleObjectNoScale = openBCIUtilities.newSample(1);
937+
// lowerSampleObjectNoScale.channelDataCounts = [1, 2, 3, 4, 5, 6, 7, 8];
938+
// lowerSampleObjectNoScale.auxData = [0, 1, 2];
939+
// lowerSampleObjectNoScale.timestamp = 4;
940+
// lowerSampleObjectNoScale.accelData = [0.5, -0.5, 1];
941+
// // Make the upper sample (channels 9-16)
942+
// upperSampleObjectNoScale = openBCIUtilities.newSample(2);
943+
// upperSampleObjectNoScale.channelDataCounts = [9, 10, 11, 12, 13, 14, 15, 16];
944+
// upperSampleObjectNoScale.auxData = [3, 4, 5];
945+
// upperSampleObjectNoScale.timestamp = 8;
946+
//
947+
// // Call the function under test
948+
// daisySampleObjectNoScale = openBCIUtilities.makeDaisySampleObject(lowerSampleObjectNoScale, upperSampleObjectNoScale);
935949
});
936950
it('should make a channelData array 16 elements long', function () {
937951
expect(daisySampleObject.channelData).to.have.length(k.OBCINumberOfChannelsDaisy);
952+
// expect(daisySampleObjectNoScale.channelDataCounts).to.have.length(k.OBCINumberOfChannelsDaisy);
938953
});
939954
it('should make a channelData array with lower array in front of upper array', function () {
940955
for (let i = 0; i < 16; i++) {
941956
expect(daisySampleObject.channelData[i]).to.equal(i + 1);
957+
// expect(daisySampleObjectNoScale.channelDataCounts[i]).to.equal(i + 1);
942958
}
943959
});
944960
it('should make the sample number equal to the second packet divided by two', function () {
945961
expect(daisySampleObject.sampleNumber).to.equal(upperSampleObject.sampleNumber / 2);
962+
// expect(daisySampleObjectNoScale.sampleNumber).to.equal(upperSampleObject.sampleNumber / 2);
946963
});
947964
it('should put the aux packets in an object', function () {
948965
expect(daisySampleObject.auxData).to.have.property('lower');
949966
expect(daisySampleObject.auxData).to.have.property('upper');
967+
// expect(daisySampleObjectNoScale.auxData).to.have.property('lower');
968+
// expect(daisySampleObjectNoScale.auxData).to.have.property('upper');
950969
});
951970
it('should put the aux packets in an object in the right order', function () {
952971
for (let i = 0; i < 3; i++) {
953972
expect(daisySampleObject.auxData['lower'][i]).to.equal(i);
954973
expect(daisySampleObject.auxData['upper'][i]).to.equal(i + 3);
974+
// expect(daisySampleObjectNoScale.auxData['lower'][i]).to.equal(i);
975+
// expect(daisySampleObjectNoScale.auxData['upper'][i]).to.equal(i + 3);
955976
}
956977
});
957978
it('should average the two timestamps together', function () {
958979
let expectedAverage = (upperSampleObject.timestamp + lowerSampleObject.timestamp) / 2;
959980
expect(daisySampleObject.timestamp).to.equal(expectedAverage);
981+
// expect(daisySampleObjectNoScale.timestamp).to.equal(expectedAverage);
982+
});
983+
it('should place the old timestamps in an object', function () {
984+
expect(daisySampleObject._timestamps.lower).to.equal(lowerSampleObject.timestamp);
985+
expect(daisySampleObject._timestamps.upper).to.equal(upperSampleObject.timestamp);
986+
// expect(upperSampleObjectNoScale._timestamps.lower).to.equal(upperSampleObjectNoScale.timestamp);
987+
// expect(upperSampleObjectNoScale._timestamps.upper).to.equal(upperSampleObjectNoScale.timestamp);
988+
});
989+
it('should store an accelerometer value if present', function () {
990+
expect(daisySampleObject).to.have.property('accelData');
991+
});
992+
});
993+
994+
describe('#makeDaisySampleObjectWifi', function () {
995+
let lowerSampleObject, upperSampleObject, daisySampleObject;
996+
let lowerSampleObjectNoScale, upperSampleObjectNoScale, daisySampleObjectNoScale;
997+
before(() => {
998+
// Make the lower sample (channels 1-8)
999+
lowerSampleObject = openBCIUtilities.newSample(1);
1000+
lowerSampleObject.channelData = [1, 2, 3, 4, 5, 6, 7, 8];
1001+
lowerSampleObject.auxData = [0, 1, 2];
1002+
lowerSampleObject.timestamp = 4;
1003+
lowerSampleObject.accelData = [0.5, -0.5, 1];
1004+
// Make the upper sample (channels 9-16)
1005+
upperSampleObject = openBCIUtilities.newSample(2);
1006+
upperSampleObject.channelData = [9, 10, 11, 12, 13, 14, 15, 16];
1007+
upperSampleObject.auxData = [3, 4, 5];
1008+
upperSampleObject.timestamp = 8;
1009+
1010+
daisySampleObject = openBCIUtilities.makeDaisySampleObjectWifi(lowerSampleObject, upperSampleObject);
1011+
1012+
lowerSampleObjectNoScale = openBCIUtilities.newSample(1);
1013+
lowerSampleObjectNoScale.channelDataCounts = [1, 2, 3, 4, 5, 6, 7, 8];
1014+
lowerSampleObjectNoScale.auxData = [0, 1, 2];
1015+
lowerSampleObjectNoScale.timestamp = 4;
1016+
lowerSampleObjectNoScale.accelData = [0.5, -0.5, 1];
1017+
// Make the upper sample (channels 9-16)
1018+
upperSampleObjectNoScale = openBCIUtilities.newSample(2);
1019+
upperSampleObjectNoScale.channelDataCounts = [9, 10, 11, 12, 13, 14, 15, 16];
1020+
upperSampleObjectNoScale.auxData = [3, 4, 5];
1021+
upperSampleObjectNoScale.timestamp = 8;
1022+
1023+
// Call the function under test
1024+
daisySampleObjectNoScale = openBCIUtilities.makeDaisySampleObjectWifi(lowerSampleObjectNoScale, upperSampleObjectNoScale);
1025+
});
1026+
it('should make a channelData array 16 elements long', function () {
1027+
expect(daisySampleObject.channelData).to.have.length(k.OBCINumberOfChannelsDaisy);
1028+
expect(daisySampleObjectNoScale.channelDataCounts).to.have.length(k.OBCINumberOfChannelsDaisy);
1029+
});
1030+
it('should make a channelData array with lower array in front of upper array', function () {
1031+
for (let i = 0; i < 16; i++) {
1032+
expect(daisySampleObject.channelData[i]).to.equal(i + 1);
1033+
expect(daisySampleObjectNoScale.channelDataCounts[i]).to.equal(i + 1);
1034+
}
1035+
});
1036+
it('should make the sample number equal to the second packet divided by two', function () {
1037+
expect(daisySampleObject.sampleNumber).to.equal(upperSampleObject.sampleNumber);
1038+
expect(daisySampleObjectNoScale.sampleNumber).to.equal(upperSampleObject.sampleNumber);
1039+
});
1040+
it('should put the aux packets in an object', function () {
1041+
expect(daisySampleObject.auxData).to.have.property('lower');
1042+
expect(daisySampleObject.auxData).to.have.property('upper');
1043+
expect(daisySampleObjectNoScale.auxData).to.have.property('lower');
1044+
expect(daisySampleObjectNoScale.auxData).to.have.property('upper');
1045+
});
1046+
it('should put the aux packets in an object in the right order', function () {
1047+
for (let i = 0; i < 3; i++) {
1048+
expect(daisySampleObject.auxData['lower'][i]).to.equal(i);
1049+
expect(daisySampleObject.auxData['upper'][i]).to.equal(i + 3);
1050+
expect(daisySampleObjectNoScale.auxData['lower'][i]).to.equal(i);
1051+
expect(daisySampleObjectNoScale.auxData['upper'][i]).to.equal(i + 3);
1052+
}
1053+
});
1054+
it('should take the lower timestamp', function () {
1055+
expect(daisySampleObject.timestamp).to.equal(lowerSampleObject.timestamp);
1056+
expect(daisySampleObjectNoScale.timestamp).to.equal(lowerSampleObject.timestamp);
9601057
});
9611058
it('should place the old timestamps in an object', function () {
9621059
expect(daisySampleObject._timestamps.lower).to.equal(lowerSampleObject.timestamp);
9631060
expect(daisySampleObject._timestamps.upper).to.equal(upperSampleObject.timestamp);
1061+
expect(daisySampleObjectNoScale._timestamps.lower).to.equal(lowerSampleObjectNoScale.timestamp);
1062+
expect(daisySampleObjectNoScale._timestamps.upper).to.equal(upperSampleObjectNoScale.timestamp);
9641063
});
9651064
it('should store an accelerometer value if present', function () {
9661065
expect(daisySampleObject).to.have.property('accelData');

0 commit comments

Comments
 (0)