Skip to content

Commit 51bf2cc

Browse files
committed
Add support for single-shank Neuropixels 2.0 probes
- Deprecate the QuadShank classes in favor of the more generic configuration classes that can be either quad- or single-shank - Update shift register bit setting for single-shank probes - Add combo box to the 2.0 GUIs allowing the user to change the probe type
1 parent 4fd9cb5 commit 51bf2cc

17 files changed

+1095
-583
lines changed

OpenEphys.Onix1.Design/ChannelConfigurationDialog.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public abstract partial class ChannelConfigurationDialog : Form
2222

2323
internal readonly List<int> ReferenceContacts = new();
2424

25-
internal readonly bool[] SelectedContacts = null;
25+
internal bool[] SelectedContacts { get; private set; } = null;
2626

2727
/// <summary>
2828
/// Constructs the dialog window using the given probe group, and plots all contacts after loading.
@@ -73,6 +73,7 @@ public ChannelConfigurationDialog(ProbeGroup probeGroup)
7373
internal virtual void LoadDefaultChannelLayout()
7474
{
7575
ProbeGroup = DefaultChannelLayout();
76+
SelectedContacts = new bool[ProbeGroup.NumberOfContacts];
7677
}
7778

7879
/// <summary>
@@ -432,13 +433,26 @@ internal virtual bool OpenFile<T>() where T : ProbeGroup
432433
return false;
433434
}
434435

435-
if (ProbeGroup.NumberOfContacts == newConfiguration.NumberOfContacts)
436+
bool skipContactNumberMismatchCheck = false;
437+
438+
if (ProbeGroup.Probes.First().Annotations.Name != newConfiguration.Probes.First().Annotations.Name)
439+
{
440+
var result = MessageBox.Show($"There is a mismatch between the current probe name ({ProbeGroup.Probes.First().Annotations.Name})" +
441+
$" and the new probe name ({newConfiguration.Probes.First().Annotations.Name}). Continue loading?", "Probe Name Mismatch", MessageBoxButtons.YesNo);
442+
443+
if (result == DialogResult.No)
444+
return false;
445+
446+
skipContactNumberMismatchCheck = true; // NB: If the probe names do not match, skip the check to see if the number of contacts match.
447+
// Example: loading a Neuropixels single-shank 2.0 probe, but the current probe is a quad-shank 2.0 probe.
448+
}
449+
450+
if (skipContactNumberMismatchCheck || ProbeGroup.NumberOfContacts == newConfiguration.NumberOfContacts)
436451
{
437452
newConfiguration.Validate();
438453

439454
ProbeGroup = newConfiguration;
440-
DrawProbeGroup();
441-
RefreshZedGraph();
455+
SelectedContacts = new bool[ProbeGroup.NumberOfContacts];
442456

443457
return true;
444458
}
@@ -1075,6 +1089,8 @@ private void MenuItemOpenFile(object sender, EventArgs e)
10751089
if (OpenFile<ProbeGroup>())
10761090
{
10771091
DrawProbeGroup();
1092+
ResetZoom();
1093+
UpdateFontSize();
10781094
RefreshZedGraph();
10791095
}
10801096
}
@@ -1083,6 +1099,7 @@ private void MenuItemLoadDefaultConfig(object sender, EventArgs e)
10831099
{
10841100
LoadDefaultChannelLayout();
10851101
DrawProbeGroup();
1102+
ResetZoom();
10861103
UpdateFontSize();
10871104
RefreshZedGraph();
10881105
}
@@ -1342,8 +1359,8 @@ internal static bool HasContactAnnotations(ProbeGroup probeGroup)
13421359
{
13431360
foreach (var probe in probeGroup.Probes)
13441361
{
1345-
if (probe.ContactAnnotations != null
1346-
&& probe.ContactAnnotations.Annotations != null
1362+
if (probe.ContactAnnotations != null
1363+
&& probe.ContactAnnotations.Annotations != null
13471364
&& probe.ContactAnnotations.Annotations.Length > 0)
13481365
{
13491366
return true;

OpenEphys.Onix1.Design/NeuropixelsV2eChannelConfigurationDialog.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Drawing;
43
using System.Linq;
54
using System.Windows.Forms;
@@ -17,24 +16,24 @@ public partial class NeuropixelsV2eChannelConfigurationDialog : ChannelConfigura
1716
internal event EventHandler OnFileLoad;
1817

1918
/// <summary>
20-
/// Public <see cref="NeuropixelsV2QuadShankProbeConfiguration"/> object that is manipulated by
19+
/// Public <see cref="NeuropixelsV2ProbeConfiguration"/> object that is manipulated by
2120
/// <see cref="NeuropixelsV2eChannelConfigurationDialog"/>.
2221
/// </summary>
23-
public NeuropixelsV2QuadShankProbeConfiguration ProbeConfiguration;
22+
public NeuropixelsV2ProbeConfiguration ProbeConfiguration;
2423

2524
/// <summary>
2625
/// Initializes a new instance of <see cref="NeuropixelsV2eChannelConfigurationDialog"/>.
2726
/// </summary>
28-
/// <param name="probeConfiguration">A <see cref="NeuropixelsV2QuadShankProbeConfiguration"/> object holding the current configuration settings.</param>
29-
public NeuropixelsV2eChannelConfigurationDialog(NeuropixelsV2QuadShankProbeConfiguration probeConfiguration)
27+
/// <param name="probeConfiguration">A <see cref="NeuropixelsV2ProbeConfiguration"/> object holding the current configuration settings.</param>
28+
public NeuropixelsV2eChannelConfigurationDialog(NeuropixelsV2ProbeConfiguration probeConfiguration)
3029
: base(probeConfiguration.ProbeGroup)
3130
{
3231
zedGraphChannels.ZoomButtons = MouseButtons.None;
3332
zedGraphChannels.ZoomButtons2 = MouseButtons.None;
3433

3534
zedGraphChannels.ZoomStepFraction = 0.5;
3635

37-
ProbeConfiguration = probeConfiguration;
36+
ProbeConfiguration = new(probeConfiguration);
3837

3938
ZoomInBoundaryX = 600;
4039
ZoomInBoundaryY = 600;
@@ -46,13 +45,16 @@ public NeuropixelsV2eChannelConfigurationDialog(NeuropixelsV2QuadShankProbeConfi
4645

4746
internal override ProbeGroup DefaultChannelLayout()
4847
{
49-
return new NeuropixelsV2eProbeGroup();
48+
return new NeuropixelsV2eProbeGroup(ProbeConfiguration.ProbeType);
5049
}
5150

5251
internal override void LoadDefaultChannelLayout()
5352
{
54-
ProbeConfiguration = new(ProbeConfiguration.Probe, ProbeConfiguration.Reference);
55-
ProbeGroup = ProbeConfiguration.ProbeGroup;
53+
base.LoadDefaultChannelLayout();
54+
ProbeConfiguration = new((NeuropixelsV2eProbeGroup)ProbeGroup,
55+
ProbeConfiguration.Probe,
56+
ProbeConfiguration.ProbeType,
57+
ProbeConfiguration.Reference);
5658

5759
OnFileOpenHandler();
5860
}
@@ -61,8 +63,6 @@ internal override bool OpenFile<T>()
6163
{
6264
if (base.OpenFile<NeuropixelsV2eProbeGroup>())
6365
{
64-
ProbeConfiguration = new((NeuropixelsV2eProbeGroup)ProbeGroup, ProbeConfiguration.Reference, ProbeConfiguration.Probe);
65-
6666
OnFileOpenHandler();
6767

6868
return true;
@@ -173,7 +173,7 @@ internal override void DrawScale()
173173

174174
const float scaleBarWidth = 1;
175175

176-
curve.Line.Width = scaleBarWidth;
176+
curve.Line.Width = scaleBarWidth;
177177
curve.Label.IsVisible = false;
178178
curve.Symbol.IsVisible = false;
179179
curve.Tag = ScalePointsTag;
@@ -197,7 +197,7 @@ internal override void HighlightEnabledContacts()
197197
var contactsToEnable = contactObjects.Where(c =>
198198
{
199199
var tag = c.Tag as ContactTag;
200-
var channel = NeuropixelsV2QuadShankElectrode.GetChannelNumber(tag.ContactIndex);
200+
var channel = NeuropixelsV2Electrode.GetChannelNumber(tag.ContactIndex, ProbeConfiguration.ProbeType);
201201
return ProbeConfiguration.ChannelMap[channel].Index == tag.ContactIndex;
202202
});
203203

@@ -227,7 +227,7 @@ internal override void UpdateContactLabels()
227227
textObjsToUpdate = textObjs.Where(c =>
228228
{
229229
var tag = c.Tag as ContactTag;
230-
var channel = NeuropixelsV2QuadShankElectrode.GetChannelNumber(tag.ContactIndex);
230+
var channel = NeuropixelsV2Electrode.GetChannelNumber(tag.ContactIndex, ProbeConfiguration.ProbeType);
231231
return ProbeConfiguration.ChannelMap[channel].Index == tag.ContactIndex;
232232
});
233233

@@ -242,7 +242,7 @@ internal override string ContactString(int deviceChannelIndex, int index)
242242
return index.ToString();
243243
}
244244

245-
internal void EnableElectrodes(NeuropixelsV2QuadShankElectrode[] electrodes)
245+
internal void EnableElectrodes(NeuropixelsV2Electrode[] electrodes)
246246
{
247247
ProbeConfiguration.SelectElectrodes(electrodes);
248248
}

0 commit comments

Comments
 (0)