Skip to content

Commit 79f7ee2

Browse files
committed
Add OrderByDepth to NeuropixelsV2e
1 parent 5a605c0 commit 79f7ee2

File tree

7 files changed

+115
-82
lines changed

7 files changed

+115
-82
lines changed

OpenEphys.Onix1/ConfigureNeuropixelsV2e.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
174174
// disconnect i2c bus from both probes to prevent digital interference during acquisition
175175
SelectProbe(serializer, NeuropixelsV2e.NoProbeSelected);
176176

177-
var deviceInfo = new NeuropixelsV2eDeviceInfo(context, DeviceType, deviceAddress, gainCorrectionA, gainCorrectionB, invertPolarity, probeAMetadata, probeBMetadata);
177+
var deviceInfo = new NeuropixelsV2eDeviceInfo(context, DeviceType, deviceAddress, gainCorrectionA, gainCorrectionB, invertPolarity, probeAMetadata, probeBMetadata, ProbeConfigurationA, ProbeConfigurationB);
178178
var shutdown = Disposable.Create(() =>
179179
{
180180
serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.Gpio10, NeuropixelsV2e.DefaultGPO10Config);

OpenEphys.Onix1/ConfigureNeuropixelsV2eBeta.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ public override IObservable<ContextTask> Process(IObservable<ContextTask> source
214214
// Still its good to get them roughly (i.e. within 10 PCLKs) started at the same time.
215215
SyncProbes(serializer, gpo10Config);
216216

217-
var deviceInfo = new NeuropixelsV2eDeviceInfo(context, DeviceType, deviceAddress, gainCorrectionA, gainCorrectionB, invertPolarity, probeAMetadata, probeBMetadata);
217+
var deviceInfo = new NeuropixelsV2eDeviceInfo(context, DeviceType, deviceAddress, gainCorrectionA, gainCorrectionB, invertPolarity, probeAMetadata, probeBMetadata, ProbeConfigurationA, ProbeConfigurationB);
218218
var shutdown = Disposable.Create(() =>
219219
{
220220
serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.Gpio10, NeuropixelsV2eBeta.DefaultGPO10Config);

OpenEphys.Onix1/NeuropixelsV2eBetaData.cs

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ public class NeuropixelsV2eBetaData : Source<NeuropixelsV2eBetaDataFrame>
4141
[Category(DeviceFactory.ConfigurationCategory)]
4242
public NeuropixelsV2Probe ProbeIndex { get; set; }
4343

44+
/// <summary>
45+
/// Gets or sets a boolean value that controls if the channels are ordered by depth.
46+
/// </summary>
47+
/// <remarks>
48+
/// If <see cref="OrderByDepth"/> is false, then channels are ordered from 0 to 383.
49+
/// If <see cref="OrderByDepth"/> is true, then channels are ordered based on the depth
50+
/// of the electrodes.
51+
/// </remarks>
52+
[Description("Determines if the channels are returned ordered by depth.")]
53+
[Category(DeviceFactory.ConfigurationCategory)]
54+
public bool OrderByDepth { get; set; } = false;
55+
4456
/// <summary>
4557
/// Generates a sequence of <see cref="NeuropixelsV2eDataFrame"/> objects.
4658
/// </summary>
@@ -51,10 +63,10 @@ public unsafe override IObservable<NeuropixelsV2eBetaDataFrame> Generate()
5163
return DeviceManager.GetDevice(DeviceName).SelectMany(deviceInfo =>
5264
{
5365
var info = (NeuropixelsV2eDeviceInfo)deviceInfo;
54-
var (metadata, gainCorrection) = ProbeIndex switch
66+
var (gainCorrection, probeConfiguration, metadata) = ProbeIndex switch
5567
{
56-
NeuropixelsV2Probe.ProbeA => (info.ProbeMetadataA, info.GainCorrectionA),
57-
NeuropixelsV2Probe.ProbeB => (info.ProbeMetadataB, info.GainCorrectionB),
68+
NeuropixelsV2Probe.ProbeA => (info.GainCorrectionA, info.ProbeConfigurationA, info.ProbeMetadataA),
69+
NeuropixelsV2Probe.ProbeB => (info.GainCorrectionB, info.ProbeConfigurationB, info.ProbeMetadataB),
5870
_ => throw new InvalidEnumArgumentException($"Unexpected {nameof(ProbeIndex)} value: {ProbeIndex}")
5971
};
6072

@@ -73,6 +85,7 @@ public unsafe override IObservable<NeuropixelsV2eBetaDataFrame> Generate()
7385
.GetDeviceFrames(passthrough.Address)
7486
.Where(frame => NeuropixelsV2eBetaDataFrame.GetProbeIndex(frame) == (int)ProbeIndex);
7587
var invertPolarity = info.InvertPolarity;
88+
var orderByDepth = OrderByDepth;
7689

7790
return Observable.Create<NeuropixelsV2eBetaDataFrame>(observer =>
7891
{
@@ -81,12 +94,13 @@ public unsafe override IObservable<NeuropixelsV2eBetaDataFrame> Generate()
8194
var frameCounter = new int[NeuropixelsV2eBeta.FramesPerSuperFrame * bufferSize];
8295
var hubClockBuffer = new ulong[bufferSize];
8396
var clockBuffer = new ulong[bufferSize];
97+
int[,] channelOrder = orderByDepth ? Neuropixels.OrderChannelsByDepth(probeConfiguration.ChannelMap, RawToChannel) : RawToChannel;
8498

8599
var frameObserver = Observer.Create<oni.Frame>(
86100
frame =>
87101
{
88102
var payload = (NeuropixelsV2BetaPayload*)frame.Data.ToPointer();
89-
NeuropixelsV2eBetaDataFrame.CopyAmplifierBuffer(payload->SuperFrame, amplifierBuffer, frameCounter, sampleIndex, gainCorrection.Value, invertPolarity);
103+
NeuropixelsV2eBetaDataFrame.CopyAmplifierBuffer(payload->SuperFrame, amplifierBuffer, frameCounter, sampleIndex, gainCorrection.Value, invertPolarity, channelOrder);
90104
hubClockBuffer[sampleIndex] = payload->HubClock;
91105
clockBuffer[sampleIndex] = frame.Clock;
92106
if (++sampleIndex >= bufferSize)
@@ -110,5 +124,35 @@ public unsafe override IObservable<NeuropixelsV2eBetaDataFrame> Generate()
110124
});
111125
});
112126
}
127+
128+
// ADC & frame-index to channel mapping
129+
// First dimension: data index
130+
// Second dimension: frame index within super frame
131+
private static readonly int[,] RawToChannel = {
132+
{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 }, // Data Index 9, ADC 1
133+
{ 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126 }, // Data Index 10, ADC 7
134+
{ 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222 }, // Data Index 11, ADC 13
135+
{ 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318 }, // Data Index 12, ADC 19
136+
{ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 }, // Data Index 13, ADC 2
137+
{ 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127 }, // Data Index 14, ADC 8
138+
{ 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223 }, // Data Index 15, ADC 14
139+
{ 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319 }, // Data Index 16, ADC 20
140+
{ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62 }, // Data Index 17, ADC 3
141+
{ 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158 }, // Data Index 18, ADC 9
142+
{ 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254 }, // Data Index 19, ADC 15
143+
{ 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350 }, // Data Index 20, ADC 21
144+
{ 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63 }, // Data Index 21, ADC 4
145+
{ 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159 }, // Data Index 22, ADC 10
146+
{ 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 }, // Data Index 23, ADC 16
147+
{ 321, 323, 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351 }, // Data Index 24, ADC 22
148+
{ 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94 }, // Data Index 25, ADC 5
149+
{ 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190 }, // Data Index 26, ADC 11
150+
{ 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286 }, // Data Index 27, ADC 17
151+
{ 352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 376, 378, 380, 382 }, // Data Index 28, ADC 23
152+
{ 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95 }, // Data Index 29, ADC 6
153+
{ 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191 }, // Data Index 30, ADC 12
154+
{ 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287 }, // Data Index 31, ADC 18
155+
{ 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381, 383 } // Data Index 32, ADC 24
156+
};
113157
}
114158
}

OpenEphys.Onix1/NeuropixelsV2eBetaDataFrame.cs

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ internal static unsafe ushort GetProbeIndex(oni.Frame frame)
5555
return data->ProbeIndex;
5656
}
5757

58-
internal static unsafe void CopyAmplifierBuffer(ushort* superFrame, ushort[,] amplifierBuffer, int[] frameCounter, int index, double gainCorrection, bool invertPolarity)
58+
internal static unsafe void CopyAmplifierBuffer(ushort* superFrame, ushort[,] amplifierBuffer, int[] frameCounter, int index, double gainCorrection, bool invertPolarity, int[,] channelOrder)
5959
{
6060
if (invertPolarity)
6161
{
@@ -75,7 +75,7 @@ internal static unsafe void CopyAmplifierBuffer(ushort* superFrame, ushort[,] am
7575
// Loop over ADC samples within each "frame" and map to channel position
7676
for (var k = 0; k < NeuropixelsV2eBeta.ADCsPerProbe; k++)
7777
{
78-
amplifierBuffer[RawToChannel[k, i], index] = (ushort)(inversionOffset - gainCorrection * superFrame[adcDataOffset + k]);
78+
amplifierBuffer[channelOrder[k, i], index] = (ushort)(inversionOffset - gainCorrection * superFrame[adcDataOffset + k]);
7979
}
8080
}
8181
}
@@ -94,41 +94,11 @@ internal static unsafe void CopyAmplifierBuffer(ushort* superFrame, ushort[,] am
9494
// Loop over ADC samples within each "frame" and map to channel position
9595
for (var k = 0; k < NeuropixelsV2eBeta.ADCsPerProbe; k++)
9696
{
97-
amplifierBuffer[RawToChannel[k, i], index] = (ushort)(gainCorrection * superFrame[adcDataOffset + k]);
97+
amplifierBuffer[channelOrder[k, i], index] = (ushort)(gainCorrection * superFrame[adcDataOffset + k]);
9898
}
9999
}
100100
}
101101
}
102-
103-
// ADC & frame-index to channel mapping
104-
// First dimension: data index
105-
// Second dimension: frame index within super frame
106-
private static readonly int[,] RawToChannel = {
107-
{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 }, // Data Index 9, ADC 1
108-
{ 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126 }, // Data Index 10, ADC 7
109-
{ 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222 }, // Data Index 11, ADC 13
110-
{ 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318 }, // Data Index 12, ADC 19
111-
{ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 }, // Data Index 13, ADC 2
112-
{ 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127 }, // Data Index 14, ADC 8
113-
{ 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223 }, // Data Index 15, ADC 14
114-
{ 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319 }, // Data Index 16, ADC 20
115-
{ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62 }, // Data Index 17, ADC 3
116-
{ 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158 }, // Data Index 18, ADC 9
117-
{ 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254 }, // Data Index 19, ADC 15
118-
{ 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350 }, // Data Index 20, ADC 21
119-
{ 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63 }, // Data Index 21, ADC 4
120-
{ 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159 }, // Data Index 22, ADC 10
121-
{ 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 }, // Data Index 23, ADC 16
122-
{ 321, 323, 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351 }, // Data Index 24, ADC 22
123-
{ 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94 }, // Data Index 25, ADC 5
124-
{ 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190 }, // Data Index 26, ADC 11
125-
{ 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286 }, // Data Index 27, ADC 17
126-
{ 352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 376, 378, 380, 382 }, // Data Index 28, ADC 23
127-
{ 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95 }, // Data Index 29, ADC 6
128-
{ 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191 }, // Data Index 30, ADC 12
129-
{ 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287 }, // Data Index 31, ADC 18
130-
{ 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381, 383 } // Data Index 32, ADC 24
131-
};
132102
}
133103

134104
[StructLayout(LayoutKind.Sequential, Pack = 1)]

0 commit comments

Comments
 (0)