Skip to content

Commit d439fe8

Browse files
authored
Merge pull request #272 from open-ephys/issue-252
Fix loading channel configuration files
2 parents 1c74d68 + 60a3bfa commit d439fe8

11 files changed

+230
-83
lines changed

OpenEphys.Onix1.Design/ChannelConfigurationDialog.cs

Lines changed: 118 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,10 @@ private struct ProbeEdge
169169

170170
public ProbeEdge(ZedGraphControl zedGraphControl)
171171
{
172-
Left = GetProbeContourMinX(zedGraphControl.GraphPane.GraphObjList);
173-
Right = GetProbeContourMaxX(zedGraphControl.GraphPane.GraphObjList);
174-
Bottom = GetProbeContourMinY(zedGraphControl.GraphPane.GraphObjList);
175-
Top = GetProbeContourMaxY(zedGraphControl.GraphPane.GraphObjList);
172+
Left = GetProbeMinX(zedGraphControl.GraphPane.GraphObjList);
173+
Right = GetProbeMaxX(zedGraphControl.GraphPane.GraphObjList);
174+
Bottom = GetProbeMinY(zedGraphControl.GraphPane.GraphObjList);
175+
Top = GetProbeMaxY(zedGraphControl.GraphPane.GraphObjList);
176176
}
177177
}
178178

@@ -423,13 +423,13 @@ private void FormShown(object sender, EventArgs e)
423423
}
424424
}
425425

426-
internal virtual void OpenFile<T>() where T : ProbeGroup
426+
internal virtual bool OpenFile<T>() where T : ProbeGroup
427427
{
428428
var newConfiguration = OpenAndParseConfigurationFile<T>();
429429

430430
if (newConfiguration == null)
431431
{
432-
return;
432+
return false;
433433
}
434434

435435
if (ChannelConfiguration.NumberOfContacts == newConfiguration.NumberOfContacts)
@@ -439,11 +439,15 @@ internal virtual void OpenFile<T>() where T : ProbeGroup
439439
ChannelConfiguration = newConfiguration;
440440
DrawProbeGroup();
441441
RefreshZedGraph();
442+
443+
return true;
442444
}
443445
else
444446
{
445-
throw new InvalidOperationException($"Number of contacts does not match; expected {ChannelConfiguration.NumberOfContacts} contacts" +
446-
$", but found {newConfiguration.NumberOfContacts} contacts");
447+
MessageBox.Show($"Error: Number of contacts does not match; expected {ChannelConfiguration.NumberOfContacts} contacts" +
448+
$", but found {newConfiguration.NumberOfContacts} contacts", "Contact Number Mismatch");
449+
450+
return false;
447451
}
448452
}
449453

@@ -460,7 +464,7 @@ internal T OpenAndParseConfigurationFile<T>() where T : ProbeGroup
460464
{
461465
var newConfiguration = DesignHelper.DeserializeString<T>(File.ReadAllText(ofd.FileName));
462466

463-
return newConfiguration ?? throw new InvalidOperationException($"Unable to open {ofd.FileName}");
467+
return newConfiguration;
464468
}
465469

466470
return null;
@@ -471,9 +475,9 @@ internal void DrawProbeGroup()
471475
zedGraphChannels.GraphPane.GraphObjList.Clear();
472476

473477
DrawProbeContour();
478+
DrawContacts();
474479
SetEqualAspectRatio();
475480
SetZoomOutBoundaries();
476-
DrawContacts();
477481
HighlightEnabledContacts();
478482
HighlightSelectedContacts();
479483
DrawContactLabels();
@@ -492,6 +496,8 @@ internal void DrawProbeContour()
492496

493497
foreach (var probe in ChannelConfiguration.Probes)
494498
{
499+
if (probe == null || probe.ProbePlanarContour == null) continue;
500+
495501
PointD[] planarContours = ConvertFloatArrayToPointD(probe.ProbePlanarContour);
496502
PolyObj contour = new(planarContours, Color.LightGray, Color.White)
497503
{
@@ -521,10 +527,10 @@ internal void SetEqualAspectRatio()
521527
if (zedGraphChannels.GraphPane.GraphObjList.Count == 0)
522528
return;
523529

524-
var minX = GetProbeContourMinX(zedGraphChannels.GraphPane.GraphObjList);
525-
var minY = GetProbeContourMinY(zedGraphChannels.GraphPane.GraphObjList);
526-
var maxX = GetProbeContourMaxX(zedGraphChannels.GraphPane.GraphObjList);
527-
var maxY = GetProbeContourMaxY(zedGraphChannels.GraphPane.GraphObjList);
530+
var minX = GetProbeMinX(zedGraphChannels.GraphPane.GraphObjList);
531+
var minY = GetProbeMinY(zedGraphChannels.GraphPane.GraphObjList);
532+
var maxX = GetProbeMaxX(zedGraphChannels.GraphPane.GraphObjList);
533+
var maxY = GetProbeMaxY(zedGraphChannels.GraphPane.GraphObjList);
528534

529535
var rangeX = maxX - minX;
530536
var rangeY = maxY - minY;
@@ -578,6 +584,8 @@ internal void DrawContacts()
578584

579585
contactObj.Border.Width = borderWidth;
580586
contactObj.Border.IsVisible = false;
587+
contactObj.Location.AlignV = AlignV.Center;
588+
contactObj.Location.AlignH = AlignH.Center;
581589

582590
zedGraphChannels.GraphPane.GraphObjList.Add(contactObj);
583591
}
@@ -593,6 +601,8 @@ internal void DrawContacts()
593601

594602
contactObj.Border.Width = borderWidth;
595603
contactObj.Border.IsVisible = false;
604+
contactObj.Location.AlignV = AlignV.Bottom;
605+
contactObj.Location.AlignH = AlignH.Left;
596606

597607
zedGraphChannels.GraphPane.GraphObjList.Add(contactObj);
598608
}
@@ -802,25 +812,105 @@ internal float ContactSize()
802812

803813
return 1f;
804814
}
815+
// TODO: Convert from MinX/MaxX/... to Left / Right / etc.
816+
internal static double GetProbeMinX(GraphObjList graphObjs)
817+
{
818+
if (graphObjs == null || graphObjs.Count == 0) return 0f;
819+
820+
if (graphObjs.OfType<PolyObj>().Count() == 0)
821+
{
822+
return GetContactMinX(graphObjs);
823+
}
824+
else
825+
{
826+
return GetProbeContourMinX(graphObjs);
827+
}
828+
}
829+
830+
internal static double GetContactMinX(GraphObjList graphObjs)
831+
{
832+
return graphObjs.OfType<BoxObj>()
833+
.Min(obj => { return obj.Location.Rect.Left; });
834+
}
805835

806836
internal static double GetProbeContourMinX(GraphObjList graphObjs)
807837
{
808838
return graphObjs.OfType<PolyObj>()
809839
.Min(obj => { return obj.Points.Min(p => p.X); });
810840
}
811841

842+
internal static double GetProbeMinY(GraphObjList graphObjs)
843+
{
844+
if (graphObjs == null || graphObjs.Count == 0) return 0f;
845+
846+
if (graphObjs.OfType<PolyObj>().Count() == 0)
847+
{
848+
return GetContactMinY(graphObjs);
849+
}
850+
else
851+
{
852+
return GetProbeContourMinY(graphObjs);
853+
}
854+
}
855+
856+
internal static double GetContactMinY(GraphObjList graphObjs)
857+
{
858+
return graphObjs.OfType<BoxObj>()
859+
.Min(obj => { return obj.Location.Rect.Top - obj.Location.Height; });
860+
}
861+
812862
internal static double GetProbeContourMinY(GraphObjList graphObjs)
813863
{
814864
return graphObjs.OfType<PolyObj>()
815865
.Min(obj => { return obj.Points.Min(p => p.Y); });
816866
}
817867

868+
internal static double GetProbeMaxX(GraphObjList graphObjs)
869+
{
870+
if (graphObjs == null || graphObjs.Count == 0) return 0f;
871+
872+
if (graphObjs.OfType<PolyObj>().Count() == 0)
873+
{
874+
return GetContactMaxX(graphObjs);
875+
}
876+
else
877+
{
878+
return GetProbeContourMaxX(graphObjs);
879+
}
880+
}
881+
882+
internal static double GetContactMaxX(GraphObjList graphObjs)
883+
{
884+
return graphObjs.OfType<BoxObj>()
885+
.Max(obj => { return obj.Location.Rect.Right; });
886+
}
887+
818888
internal static double GetProbeContourMaxX(GraphObjList graphObjs)
819889
{
820890
return graphObjs.OfType<PolyObj>()
821891
.Max(obj => { return obj.Points.Max(p => p.X); });
822892
}
823893

894+
internal static double GetProbeMaxY(GraphObjList graphObjs)
895+
{
896+
if (graphObjs == null || graphObjs.Count == 0) return 0f;
897+
898+
if (graphObjs.OfType<PolyObj>().Count() == 0)
899+
{
900+
return GetContactMaxY(graphObjs);
901+
}
902+
else
903+
{
904+
return GetProbeContourMaxY(graphObjs);
905+
}
906+
}
907+
908+
internal static double GetContactMaxY(GraphObjList graphObjs)
909+
{
910+
return graphObjs.OfType<BoxObj>()
911+
.Max(obj => { return obj.Location.Rect.Bottom - obj.Location.Height; });
912+
}
913+
824914
internal static double GetProbeContourMaxY(GraphObjList graphObjs)
825915
{
826916
return graphObjs.OfType<PolyObj>()
@@ -969,9 +1059,11 @@ private void UpdateControlSizeBasedOnAxisSize()
9691059

9701060
private void MenuItemOpenFile(object sender, EventArgs e)
9711061
{
972-
OpenFile<ProbeGroup>();
973-
DrawProbeGroup();
974-
RefreshZedGraph();
1062+
if (OpenFile<ProbeGroup>())
1063+
{
1064+
DrawProbeGroup();
1065+
RefreshZedGraph();
1066+
}
9751067
}
9761068

9771069
private void MenuItemLoadDefaultConfig(object sender, EventArgs e)
@@ -1009,13 +1101,14 @@ public void MoveToVerticalPosition(float relativePosition)
10091101
{
10101102
if (relativePosition < 0.0 || relativePosition > 1.0)
10111103
{
1012-
throw new ArgumentOutOfRangeException(nameof(relativePosition));
1104+
MessageBox.Show($"Warning: Invalid relative position given while moving. Expected values between 0.0 and 1.0, but received {relativePosition}.", "Invalid Relative Position");
1105+
return;
10131106
}
10141107

10151108
var currentRange = zedGraphChannels.GraphPane.YAxis.Scale.Max - zedGraphChannels.GraphPane.YAxis.Scale.Min;
10161109

1017-
var minY = GetProbeContourMinY(zedGraphChannels.GraphPane.GraphObjList);
1018-
var maxY = GetProbeContourMaxY(zedGraphChannels.GraphPane.GraphObjList);
1110+
var minY = GetProbeMinY(zedGraphChannels.GraphPane.GraphObjList);
1111+
var maxY = GetProbeMaxY(zedGraphChannels.GraphPane.GraphObjList);
10191112

10201113
var newMinY = (maxY - minY - currentRange) * relativePosition;
10211114

@@ -1025,8 +1118,8 @@ public void MoveToVerticalPosition(float relativePosition)
10251118

10261119
internal float GetRelativeVerticalPosition()
10271120
{
1028-
var minY = GetProbeContourMinY(zedGraphChannels.GraphPane.GraphObjList);
1029-
var maxY = GetProbeContourMaxY(zedGraphChannels.GraphPane.GraphObjList);
1121+
var minY = GetProbeMinY(zedGraphChannels.GraphPane.GraphObjList);
1122+
var maxY = GetProbeMaxY(zedGraphChannels.GraphPane.GraphObjList);
10301123

10311124
var currentRange = zedGraphChannels.GraphPane.YAxis.Scale.Max - zedGraphChannels.GraphPane.YAxis.Scale.Min;
10321125

@@ -1200,7 +1293,9 @@ internal void SetAllSelections(bool newStatus)
12001293
private bool GetContactStatus(ContactTag tag)
12011294
{
12021295
if (tag == null)
1203-
throw new ArgumentNullException("Attempted to check contact status of an object that is not a contact.");
1296+
{
1297+
MessageBox.Show($"Error: Attempted to check status of an object that is not a contact.", "Invalid Object Selected");
1298+
}
12041299

12051300
return SelectedContacts[tag.ContactIndex];
12061301
}

OpenEphys.Onix1.Design/DesignHelper.cs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
@@ -9,10 +9,44 @@ namespace OpenEphys.Onix1.Design
99
{
1010
static class DesignHelper
1111
{
12-
public static T DeserializeString<T>(string channelLayout)
12+
/// <summary>
13+
/// Given a string with a valid JSON structure, deserialize the string to the given type.
14+
/// </summary>
15+
/// <typeparam name="T"></typeparam>
16+
/// <param name="channelLayout"></param>
17+
/// <returns></returns>
18+
#nullable enable
19+
public static T? DeserializeString<T>(string channelLayout)
1320
{
14-
return JsonConvert.DeserializeObject<T>(channelLayout);
21+
var errors = new List<string>();
22+
23+
var serializerSettings = new JsonSerializerSettings()
24+
{
25+
Error = delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
26+
{
27+
errors.Add(args.ErrorContext.Error.Message);
28+
args.ErrorContext.Handled = true;
29+
}
30+
};
31+
32+
var obj = JsonConvert.DeserializeObject<T>(channelLayout, serializerSettings);
33+
34+
if (errors.Count > 0)
35+
{
36+
MessageBox.Show($"There were errors encountered while parsing a JSON string. Check the console " +
37+
$"for an error log.", "JSON Parse Error");
38+
39+
foreach (var e in errors)
40+
{
41+
Console.Error.WriteLine(e);
42+
}
43+
44+
return default;
45+
}
46+
47+
return obj;
1548
}
49+
#nullable disable
1650

1751
public static void SerializeObject(object _object, string filepath)
1852
{

OpenEphys.Onix1.Design/NeuropixelsV1eChannelConfigurationDialog.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,19 @@ internal override void LoadDefaultChannelLayout()
6262
OnFileOpenHandler();
6363
}
6464

65-
internal override void OpenFile<T>()
65+
internal override bool OpenFile<T>()
6666
{
67-
base.OpenFile<NeuropixelsV1eProbeGroup>();
67+
if (base.OpenFile<NeuropixelsV1eProbeGroup>())
68+
{
69+
ProbeConfiguration = new((NeuropixelsV1eProbeGroup)ChannelConfiguration, ProbeConfiguration.SpikeAmplifierGain, ProbeConfiguration.LfpAmplifierGain, ProbeConfiguration.Reference, ProbeConfiguration.SpikeFilter);
70+
ChannelConfiguration = ProbeConfiguration.ChannelConfiguration;
6871

69-
ProbeConfiguration = new((NeuropixelsV1eProbeGroup)ChannelConfiguration, ProbeConfiguration.SpikeAmplifierGain, ProbeConfiguration.LfpAmplifierGain, ProbeConfiguration.Reference, ProbeConfiguration.SpikeFilter);
70-
ChannelConfiguration = ProbeConfiguration.ChannelConfiguration;
72+
OnFileOpenHandler();
7173

72-
OnFileOpenHandler();
74+
return true;
75+
}
76+
77+
return false;
7378
}
7479

7580
private void OnFileOpenHandler()
@@ -122,9 +127,11 @@ internal override void DrawScale()
122127
var majorTickOffset = MajorTickLength + CalculateScaleRange(zedGraphChannels.GraphPane.XAxis.Scale) * 0.015;
123128
majorTickOffset = majorTickOffset > 50 ? 50 : majorTickOffset;
124129

125-
var x = GetProbeContourMaxX(zedGraphChannels.GraphPane.GraphObjList) + 40;
126-
var minY = GetProbeContourMinY(zedGraphChannels.GraphPane.GraphObjList);
127-
var maxY = GetProbeContourMaxY(zedGraphChannels.GraphPane.GraphObjList);
130+
var x = GetProbeMaxX(zedGraphChannels.GraphPane.GraphObjList) + 40;
131+
var minY = GetProbeMinY(zedGraphChannels.GraphPane.GraphObjList);
132+
var maxY = GetProbeMaxY(zedGraphChannels.GraphPane.GraphObjList);
133+
134+
int textPosition = 0;
128135

129136
PointPairList pointList = new();
130137

@@ -138,15 +145,17 @@ internal override void DrawScale()
138145
pointList.Add(majorTickLocation);
139146
pointList.Add(new PointPair(x, minY + MajorTickIncrement * countMajorTicks));
140147

141-
if (!zoomedOut || i % (5 * MajorTickIncrement) == 0)
148+
if (!zoomedOut || countMajorTicks % 5 == 0)
142149
{
143-
TextObj textObj = new($"{i} µm", majorTickLocation.X + 10, majorTickLocation.Y, CoordType.AxisXYScale, AlignH.Left, AlignV.Center)
150+
TextObj textObj = new($"{textPosition} µm", majorTickLocation.X + 10, majorTickLocation.Y, CoordType.AxisXYScale, AlignH.Left, AlignV.Center)
144151
{
145152
Tag = ScaleTextTag
146153
};
147154
textObj.FontSpec.Border.IsVisible = false;
148155
textObj.FontSpec.Size = fontSize;
149156
zedGraphChannels.GraphPane.GraphObjList.Add(textObj);
157+
158+
textPosition += zoomedOut ? 5 * MajorTickIncrement : MajorTickIncrement;
150159
}
151160

152161
if (!zoomedOut)

0 commit comments

Comments
 (0)