Skip to content

Commit a66bd1c

Browse files
authored
Merge pull request #414 from open-ephys/issue-405
Add microvolt conversion equations
2 parents e4d8998 + 131693a commit a66bd1c

File tree

9 files changed

+146
-76
lines changed

9 files changed

+146
-76
lines changed

OpenEphys.Onix1/AnalogInputDataFrame.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,26 @@ public AnalogInputDataFrame(ulong[] clock, ulong[] hubClock, Mat analogData)
2121
}
2222

2323
/// <summary>
24-
/// Get the buffered analog data array.
24+
/// Gets the buffered analog data array.
2525
/// </summary>
26+
/// <remarks>
27+
/// Analog samples are organized in 12xN matrix with rows representing channel number and
28+
/// N columns representing samples acquired at 100 kHz. Each column is a 12-channel vector of ADC
29+
/// samples whose acquisition time is indicated by the corresponding elements in <see
30+
/// cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>. When <see
31+
/// cref="AnalogInput.DataType"/> is set to <see cref="AnalogIODataType.Volts"/>, each sample is
32+
/// internally converted to a voltage value and represented using a <see cref="float"/>. When <see
33+
/// cref="AnalogInput.DataType"/> is set to <see cref="AnalogIODataType.S16"/>, each 16-bit ADC sample
34+
/// is represented as a <see cref="short"/>. In this case, the following equation can be used to
35+
/// convert a sample to volts:
36+
/// <code>
37+
/// Channel Voltage (V) = ADC Sample × (Input Span / 2^16)
38+
/// </code>
39+
/// where <c>Input Span</c> is 5V, 10V, or 20V when the <see cref="AnalogIOVoltageRange"/> is set to
40+
/// ±2.5V, ±5V, or ±10V, respectively. Note that <see cref="AnalogIOVoltageRange"/> can be set
41+
/// independently for each channel in <see cref="ConfigureBreakoutBoard.AnalogIO"/>. Therefore, the
42+
/// conversion factor may be different for each channel.
43+
/// </remarks>
2644
public Mat AnalogData { get; }
2745
}
2846

OpenEphys.Onix1/NeuropixelsV1DataFrame.cs

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,46 @@ public NeuropixelsV1DataFrame(ulong[] clock, ulong[] hubClock, int[] frameCount,
2727
/// Gets the frame count value array.
2828
/// </summary>
2929
/// <remarks>
30-
/// A 20-bit counter on the probe that increments its value for every frame produced.
31-
/// The value ranges from 0 to 1048575 (2^20-1), and should always increment by 1 until it wraps around back to 0.
32-
/// This can be used to detect dropped frames.
30+
/// A 20-bit counter on the probe that increments its value for every "frame" produced by the probe.
31+
/// Thirteen frames are produced for each 384-channel column of samples in <see cref="SpikeData"/>.
32+
/// The value ranges from 0 to 1048575 (2^20-1), and should always increment by 1 until it wraps
33+
/// around back to 0. This can be used to detect dropped frames.
3334
/// </remarks>
3435
public int[] FrameCount { get; }
3536

3637
/// <summary>
37-
/// Gets the spike-band data as a <see cref="Mat"/> object.
38+
/// Gets spike-band electrophysiology data array.
3839
/// </summary>
3940
/// <remarks>
40-
/// Spike-band data has 384 electrodes (rows) with columns representing the samples acquired at 30 kHz.
41-
/// Each sample is a 10-bit, offset binary value encoded as a <see cref="ushort"/>. To convert to
42-
/// microvolts, the following equation can be used:
43-
/// <code>
44-
/// V_electrode (uV) = 1171.875 uV / AP Gain × (ADC result – 512)
41+
/// Spike-band (0.3-10 kHz) samples are organized in 384xN matrix with rows representing
42+
/// channel number and N columns representing samples acquired at 30 kHz. Each column is a 384-channel
43+
/// vector of ADC samples whose acquisition time is indicated by the corresponding elements in <see
44+
/// cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>. Each ADC sample is a 10-bit, offset
45+
/// binary value represented as a <see cref="ushort"/>. The following equation can be used to convert
46+
/// a sample to microvolts:
47+
/// <code>
48+
/// Electrode Voltage (µV) = (1,171.875 / AP Gain) × (ADC Sample – 512)
4549
/// </code>
50+
/// where <c>AP Gain</c> can be 50, 125, 250, 500, 1000, 1500, 2000, or 3000 depending on the value of <see
51+
/// cref="NeuropixelsV1ProbeConfiguration.SpikeAmplifierGain"/>.
4652
/// </remarks>
4753
public Mat SpikeData { get; }
4854

4955
/// <summary>
50-
/// Gets the LFP band data as a <see cref="Mat"/> object.
56+
/// Gets LFP-band electrophysiology data array.
5157
/// </summary>
5258
/// <remarks>
53-
/// LFP-band data has 384 electrodes (rows) with columns representing the samples acquired at 2.5 kHz.
54-
/// Each sample is a 10-bit, offset binary value encoded as a <see cref="ushort"/>. To convert to
55-
/// microvolts, the following equation can be used:
56-
/// <code>
57-
/// V_electrode (uV) = 1171.875 uV / LFP Gain × (ADC result – 512)
59+
/// LFP-band (0.5-500 Hz) samples are organized in 384xN matrix with rows representing channel
60+
/// number and N columns representing samples acquired at 2.5 kHz. Each column is a 384-channel vector
61+
/// of ADC samples whose acquisition time is indicated by the corresponding elements in <see
62+
/// cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>. Each ADC sample is a 10-bit, offset
63+
/// binary value represented as a <see cref="ushort"/>. The following equation can be used to convert
64+
/// a sample to microvolts:
65+
/// <code>
66+
/// Electrode Voltage (µV) = (1,171.875 / LFP Gain) × (ADC Sample – 512)
5867
/// </code>
68+
/// where <c>LFP Gain</c> can be 50, 125, 250, 500, 1000, 1500, 2000, or 3000 depending on the value of <see
69+
/// cref="NeuropixelsV1ProbeConfiguration.LfpAmplifierGain"/>.
5970
/// </remarks>
6071
public Mat LfpData { get; }
6172
}

OpenEphys.Onix1/NeuropixelsV2eBetaDataFrame.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace OpenEphys.Onix1
55
{
66
/// <summary>
7-
/// Buffered data from a NeuropixelsV2e device.
7+
/// Buffered data from a NeuropixelsV2-Beta probe.
88
/// </summary>
99
public class NeuropixelsV2eBetaDataFrame : BufferedDataFrame
1010
{
@@ -23,25 +23,29 @@ public NeuropixelsV2eBetaDataFrame(ulong[] clock, ulong[] hubClock, Mat amplifie
2323
}
2424

2525
/// <summary>
26-
/// Gets the amplifier data array.
26+
/// Gets the buffered electrophysiology data array.
2727
/// </summary>
2828
/// <remarks>
29-
/// Wide band (0.5 Hz - 10 kHz) electrophysiology data array. Each element is an amplified sample from
30-
/// 384 electrodes (rows) acquired at 30 kHz (columns). Each sample is a 14-bit, offset binary value
31-
/// encoded as a <see cref="ushort"/>. To convert to microvolts, the following equation can be used:
29+
/// Electrophysiology samples are organized in 384xN matrix with rows representing electrophysiology
30+
/// channel number and N columns representing samples acquired at 30 kHz. Each column is a 384-channel
31+
/// vector of ADC 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 14-bit, offset
33+
/// binary value represented as a <see cref="ushort"/>. The following equation can be used to convert
34+
/// a sample to microvolts:
3235
/// <code>
33-
/// V_electrode (µV) = 0.76294 µV/bit × (ADC result – 8192) bits
36+
/// Electrode Voltage (µV) = 0.76294 × (ADC Sample – 8192)
3437
/// </code>
3538
/// </remarks>
3639
public Mat AmplifierData { get; }
3740

3841
/// <summary>
39-
/// Gets the frame count array.
42+
/// Gets the frame count value array.
4043
/// </summary>
4144
/// <remarks>
42-
/// Frame count is a 20-bit counter on the probe that increments its value for every frame produced.
43-
/// The value ranges from 0 to 1048575 (2^20-1), and should always increment by 1 until it wraps around back to 0.
44-
/// This can be used to detect dropped frames.
45+
/// A 20-bit counter on the probe that increments its value for every "frame" produced by the probe.
46+
/// Sixteen frames are produced for each 384-channel column of samples in <see cref="AmplifierData"/>.
47+
/// The value ranges from 0 to 1048575 (2^20-1), and should always increment by 1 until it wraps
48+
/// around back to 0. This can be used to detect dropped frames.
4549
/// </remarks>
4650
public int[] FrameCount { get; }
4751

OpenEphys.Onix1/NeuropixelsV2eDataFrame.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace OpenEphys.Onix1
55
{
66
/// <summary>
7-
/// Buffered data from a NeuropixelsV2e device.
7+
/// Buffered data from a NeuropixelsV2 probe.
88
/// </summary>
99
public class NeuropixelsV2eDataFrame : BufferedDataFrame
1010
{
@@ -21,14 +21,17 @@ public NeuropixelsV2eDataFrame(ulong[] clock, ulong[] hubClock, Mat amplifierDat
2121
}
2222

2323
/// <summary>
24-
/// Gets the amplifier data array.
24+
/// Gets the buffered electrophysiology data array.
2525
/// </summary>
2626
/// <remarks>
27-
/// Wide band (0.5 Hz - 10 kHz) electrophysiology data array. Each element is an amplified sample from
28-
/// 384 electrodes (rows) acquired at 30 kHz (columns). Each sample is a 12-bit, offset binary value
29-
/// encoded as a <see cref="ushort"/>. To convert to microvolts, the following equation can be used:
27+
/// Electrophysiology samples are organized in 384xN matrix with rows representing electrophysiology
28+
/// channel number and N columns representing samples acquired at 30 kHz. Each column is a 384-channel
29+
/// vector of ADC samples whose acquisition time is indicated by the corresponding elements in <see
30+
/// cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>. Each ADC sample is a 12-bit, offset
31+
/// binary value represented as a <see cref="ushort"/>. The following equation can be used to convert
32+
/// a sample to microvolts:
3033
/// <code>
31-
/// V_electrode (µV) = 3.05176 µV/bit × (ADC result – 2048) bits
34+
/// Electrode Voltage (µV) = 3.05176 × (ADC Sample – 2048)
3235
/// </code>
3336
/// </remarks>
3437
public Mat AmplifierData { get; }

OpenEphys.Onix1/Nric1384DataFrame.cs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace OpenEphys.Onix1
55
{
66
/// <summary>
7-
/// Buffered data from a Nric1384 bioacquisition device.
7+
/// Buffered data from a Nric1384 bioacquisition chip.
88
/// </summary>
99
public class Nric1384DataFrame : BufferedDataFrame
1010
{
@@ -28,29 +28,47 @@ public Nric1384DataFrame(ulong[] clock, ulong[] hubClock, int[] frameCount, Mat
2828
/// Gets the frame count value array.
2929
/// </summary>
3030
/// <remarks>
31-
/// A 20-bit counter on the chip that increments its value for every frame produced. The value ranges from 0 to
32-
/// 1048575 (2^20-1), and should always increment by 13 (one count is taken per super-frame and there are 13 frames
33-
/// in a super frame) until it wraps around back to 0. This can be used to detect dropped frames.
31+
/// A 20-bit counter on the probe that increments its value for every "frame" produced by the probe.
32+
/// Thirteen frames are produced for each 384-channel column of samples in <see cref="SpikeData"/>.
33+
/// The value ranges from 0 to 1048575 (2^20-1), and should always increment by 1 until it wraps
34+
/// around back to 0. This can be used to detect dropped frames.
3435
/// </remarks>
3536
public int[] FrameCount { get; }
3637

37-
3838
/// <summary>
39-
/// Gets the spike-band data as a <see cref="Mat"/> object.
39+
/// Gets spike-band electrophysiology data array.
4040
/// </summary>
4141
/// <remarks>
42-
/// Spike-band data has 384 rows (channels) with columns representing the samples acquired at 30 kHz. Each sample is a
43-
/// 10-bit, offset binary value encoded as a <see cref="ushort"/>.
42+
/// Spike-band (0.3-10 kHz) samples are organized in 384xN matrix with rows representing
43+
/// channel number and N columns representing samples acquired at 30 kHz. Each column is a 384-channel
44+
/// vector of ADC samples whose acquisition time is indicated by the corresponding elements in <see
45+
/// cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>. Each ADC sample is a 10-bit, offset
46+
/// binary value represented as a <see cref="ushort"/>. The following equation can be used to convert
47+
/// a sample to microvolts:
48+
/// <code>
49+
/// Electrode Voltage (µV) = (1,171.875 / AP Gain) × (ADC Sample – 512)
50+
/// </code>
51+
/// where <c>AP Gain</c> can be 50, 125, 250, 500, 1000, 1500, 2000, or 3000 depending on the value of <see
52+
/// cref="ConfigureNric1384.SpikeAmplifierGain"/>.
4453
/// </remarks>
4554
public Mat SpikeData { get; }
4655

4756

4857
/// <summary>
49-
/// Gets the LFP band data as a <see cref="Mat"/> object.
58+
/// Gets LFP-band electrophysiology data array.
5059
/// </summary>
5160
/// <remarks>
52-
/// LFP data has 32 rows (channels) with columns representing the samples acquired at 2.5 kHz. Each sample is a
53-
/// 10-bit, offset binary value encoded as a <see cref="ushort"/>.
61+
/// LFP-band (0.5-500 Hz) samples are organized in 384xN matrix with rows representing channel
62+
/// number and N columns representing samples acquired at 2.5 kHz. Each column is a 384-channel vector
63+
/// of ADC samples whose acquisition time is indicated by the corresponding elements in <see
64+
/// cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>. Each ADC sample is a 10-bit, offset
65+
/// binary value represented as a <see cref="ushort"/>. The following equation can be used to convert
66+
/// a sample to microvolts:
67+
/// <code>
68+
/// Electrode Voltage (µV) = (1,171.875 / LFP Gain) × (ADC Sample – 512)
69+
/// </code>
70+
/// where <c>LFP Gain</c> can be 50, 125, 250, 500, 1000, 1500, 2000, or 3000 depending on the value of <see
71+
/// cref="ConfigureNric1384.LfpAmplifierGain"/>.
5472
/// </remarks>
5573
public Mat LfpData { get; }
5674
}

OpenEphys.Onix1/Rhd2164DataFrame.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,32 @@ public Rhd2164DataFrame(ulong[] clock, ulong[] hubClock, Mat amplifierData, Mat
2626
/// Gets the buffered electrophysiology data array.
2727
/// </summary>
2828
/// <remarks>
29-
/// Each row corresponds to a channel. Each column corresponds to a sample whose time is indicated by
30-
/// the corresponding element <see cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>.
31-
/// Samples are 16-bits each and are represented using unsigned 16-bit integers. To convert to
32-
/// micro-volts, the following equation can be used:
29+
/// 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:
3335
/// <code>
34-
/// V_electrode (uV) = 0.195 µV × (ADC result – 32768)
36+
/// Electrode Voltage (µV) = 0.195 × (ADC Sample – 32768)
3537
/// </code>
3638
/// </remarks>
3739
public Mat AmplifierData { get; }
3840

3941
/// <summary>
40-
/// Gets the buffered auxiliary data array.
42+
/// Gets the buffered auxiliary data array.
4143
/// </summary>
4244
/// <remarks>
43-
/// Each row corresponds to a channel. Each column corresponds to a sample whose time is indicated by
44-
/// the corresponding element <see cref="DataFrame.Clock"/> and <see cref="DataFrame.HubClock"/>.
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:
50+
/// <code>
51+
/// Auxiliary Voltage (V) = 0.0000374 × ADC Sample
52+
/// </code>
53+
/// Note that auxiliary inputs have a 0.10-2.45V input range. Nonlinearities may occur if voltages
54+
/// outside of this range are applied to auxiliary inputs.
4555
/// </remarks>
4656
public Mat AuxData { get; }
4757
}

OpenEphys.Onix1/Rhs2116Data.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace OpenEphys.Onix1
1111
{
1212
/// <summary>
1313
/// Produces a sequence of <see cref="Rhs2116DataFrame"/> objects with data from an Intan
14-
/// Rhs2116 bioacquisition chip.
14+
/// Rhs2116 bidirectional bioacquisition chip.
1515
/// </summary>
1616
/// <remarks>
1717
/// This data IO operator must be linked to an appropriate configuration, such as a <see
@@ -28,11 +28,11 @@ public class Rhs2116Data : Source<Rhs2116DataFrame>
2828
/// Gets or sets the buffer size.
2929
/// </summary>
3030
/// <remarks>
31-
/// This property determines the number of samples that are collected from each of the 16 ephys
32-
/// channels before data is propagated. For instance, if this value is set to 30, then 16x30 samples,
33-
/// along with 30 corresponding clock values, will be collected and packed into each <see
34-
/// cref="Rhs2116DataFrame"/>. Because channels are sampled at 30 kHz, this is equivalent to 1
35-
/// millisecond of data from each channel.
31+
/// This property determines the number of samples that are collected from each of the 16
32+
/// electrophysiology channels before data is propagated. For instance, if this value is set to 30,
33+
/// then 16x30 samples, along with 30 corresponding clock values, will be collected and packed into
34+
/// each <see cref="Rhs2116DataFrame"/>. Because channels are sampled at 30 kHz, this is equivalent to
35+
/// 1 millisecond of data from each channel.
3636
/// </remarks>
3737
public int BufferSize { get; set; } = 30;
3838

0 commit comments

Comments
 (0)