Skip to content

Commit 1086513

Browse files
authored
Merge pull request #433 from open-ephys/issue-422
Map Rhd2164 ephys channels into Intan order
2 parents 8e0803e + cddbed5 commit 1086513

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed

OpenEphys.Onix1/BufferHelper.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using OpenCV.Net;
1+
using System;
2+
using OpenCV.Net;
23

34
namespace OpenEphys.Onix1
45
{
@@ -47,5 +48,35 @@ public static Mat CopyTranspose<TBuffer>(
4748
CV.Mul(transposeBuffer, scale, data);
4849
return data;
4950
}
51+
52+
public static Mat CopyTranspose<TBuffer>(
53+
TBuffer[] buffer,
54+
int sampleCount,
55+
int channelCount,
56+
Depth depth,
57+
int[] channelMap)
58+
where TBuffer : unmanaged
59+
{
60+
if (channelMap == null || channelMap.Length != channelCount)
61+
{
62+
return CopyTranspose(buffer, sampleCount, channelCount, depth);
63+
}
64+
65+
using var bufferHeader = Mat.CreateMatHeader(
66+
buffer,
67+
sampleCount,
68+
channelCount,
69+
depth,
70+
channels: 1);
71+
var data = new Mat(bufferHeader.Rows, bufferHeader.Cols, depth, 1);
72+
73+
for (int i = 0; i < bufferHeader.Cols; i++)
74+
CV.Copy(bufferHeader.GetCol(channelMap[i]), data.GetCol(i));
75+
76+
var transposeData = new Mat(bufferHeader.Cols, bufferHeader.Rows, depth, 1);
77+
78+
CV.Transpose(data, transposeData);
79+
return transposeData;
80+
}
5081
}
5182
}

OpenEphys.Onix1/Rhd2164Data.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ namespace OpenEphys.Onix1
2020
[Description("Produces a sequence of Rhd2164DataFrame objects with data from an Intan Rhd2164 bioacquisition chip.")]
2121
public class Rhd2164Data : Source<Rhd2164DataFrame>
2222
{
23+
private readonly static int[] EphysChannelMap = new[] {0 , 2, 4, 6, 8, 10, 12, 14,
24+
16, 18, 20, 22, 24, 26, 28, 30,
25+
32, 34, 36, 38, 40, 42, 44, 46,
26+
48, 50, 52, 54, 56, 58, 60, 62,
27+
1 , 3 , 5 , 7 , 9 , 11, 13, 15,
28+
17, 19, 21, 23, 25, 27, 29, 31,
29+
33, 35, 37, 39, 41, 43, 45, 47,
30+
49, 51, 53, 55, 57, 59, 61, 63};
31+
2332
/// <inheritdoc cref = "SingleDeviceFactory.DeviceName"/>
2433
[TypeConverter(typeof(Rhd2164.NameConverter))]
2534
[Description(SingleDeviceFactory.DeviceNameDescription)]
@@ -66,7 +75,7 @@ public unsafe override IObservable<Rhd2164DataFrame> Generate()
6675
clockBuffer[sampleIndex] = frame.Clock;
6776
if (++sampleIndex >= bufferSize)
6877
{
69-
var amplifierData = BufferHelper.CopyTranspose(amplifierBuffer, bufferSize, Rhd2164.AmplifierChannelCount, Depth.U16);
78+
var amplifierData = BufferHelper.CopyTranspose(amplifierBuffer, bufferSize, Rhd2164.AmplifierChannelCount, Depth.U16, EphysChannelMap);
7079
var auxData = BufferHelper.CopyTranspose(auxBuffer, bufferSize, Rhd2164.AuxChannelCount, Depth.U16);
7180
observer.OnNext(new Rhd2164DataFrame(clockBuffer, hubClockBuffer, amplifierData, auxData));
7281
hubClockBuffer = new ulong[bufferSize];

OpenEphys.Onix1/Rhd2164DataFrame.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ public Rhd2164DataFrame(ulong[] clock, ulong[] hubClock, Mat amplifierData, Mat
2727
/// </summary>
2828
/// <remarks>
2929
/// Electrophysiology samples are organized in 64xN matrix with rows representing electrophysiology
30-
/// channel number and N columns representing sample index. Each column is a 64-channel vector of ADC
31-
/// samples whose acquisition time is indicated by the corresponding elements in <see
32-
/// cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>. Each ADC sample is a 16-bit,
33-
/// offset binary value encoded as a <see cref="ushort"/>. The following equation can be used to
34-
/// convert a sample to microvolts:
30+
/// channel number and N columns representing sample index. Channels are ordered in accordance with
31+
/// the Rhd2164 input number specified on its datasheet (channel 0 corresponds to input 0, channel 1
32+
/// corresponds to input 1, and so on). Each column is a 64-channel vector of ADC samples whose
33+
/// acquisition time is indicated by the corresponding elements in <see cref="DataFrame.Clock"/> and
34+
/// <see cref="DataFrame.HubClock"/>. Each ADC sample is a 16-bit, offset binary value encoded as a
35+
/// <see cref="ushort"/>. The following equation can be used to convert a sample to microvolts:
3536
/// <code>
3637
/// Electrode Voltage (µV) = 0.195 × (ADC Sample – 32768)
3738
/// </code>
@@ -42,11 +43,13 @@ public Rhd2164DataFrame(ulong[] clock, ulong[] hubClock, Mat amplifierData, Mat
4243
/// Gets the buffered auxiliary data array.
4344
/// </summary>
4445
/// <remarks>
45-
/// Auxiliary samples are organized in 3xN matrix with rows representing electrophysiology channel
46-
/// number and N columns representing sample index. Each column is a 3-channel vector of ADC samples
47-
/// whose acquisition time is indicated by the corresponding elements in <see cref="DataFrame.Clock"/>
48-
/// and <see cref="DataFrame.HubClock"/>. Each ADC sample is a 16-bit <see cref="ushort"/>. The
49-
/// following equation can be used to convert a sample to volts:
46+
/// Auxiliary samples are organized in 3xN matrix with rows representing auxiliary channel number and N
47+
/// columns representing sample index. Channels are ordered in accordance with the Rhd2164 input
48+
/// number specified on its datasheet (channel 0 corresponds to auxiliary input 0, channel 1
49+
/// corresponds to auxiliary input 1, and channel 2 corresponds to auxiliary input 2). Each column is
50+
/// a 3-channel vector of ADC samples whose acquisition time is indicated by the corresponding
51+
/// elements in <see cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>. Each ADC sample is
52+
/// a 16-bit <see cref="ushort"/>. The following equation can be used to convert a sample to volts:
5053
/// <code>
5154
/// Auxiliary Voltage (V) = 0.0000374 × ADC Sample
5255
/// </code>

0 commit comments

Comments
 (0)