Skip to content

Commit

Permalink
Merge pull request #272 from open-ephys/issue-252
Browse files Browse the repository at this point in the history
Fix loading channel configuration files
  • Loading branch information
bparks13 authored Sep 6, 2024
2 parents 1c74d68 + 60a3bfa commit d439fe8
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 83 deletions.
141 changes: 118 additions & 23 deletions OpenEphys.Onix1.Design/ChannelConfigurationDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,10 @@ private struct ProbeEdge

public ProbeEdge(ZedGraphControl zedGraphControl)
{
Left = GetProbeContourMinX(zedGraphControl.GraphPane.GraphObjList);
Right = GetProbeContourMaxX(zedGraphControl.GraphPane.GraphObjList);
Bottom = GetProbeContourMinY(zedGraphControl.GraphPane.GraphObjList);
Top = GetProbeContourMaxY(zedGraphControl.GraphPane.GraphObjList);
Left = GetProbeMinX(zedGraphControl.GraphPane.GraphObjList);
Right = GetProbeMaxX(zedGraphControl.GraphPane.GraphObjList);
Bottom = GetProbeMinY(zedGraphControl.GraphPane.GraphObjList);
Top = GetProbeMaxY(zedGraphControl.GraphPane.GraphObjList);
}
}

Expand Down Expand Up @@ -423,13 +423,13 @@ private void FormShown(object sender, EventArgs e)
}
}

internal virtual void OpenFile<T>() where T : ProbeGroup
internal virtual bool OpenFile<T>() where T : ProbeGroup
{
var newConfiguration = OpenAndParseConfigurationFile<T>();

if (newConfiguration == null)
{
return;
return false;
}

if (ChannelConfiguration.NumberOfContacts == newConfiguration.NumberOfContacts)
Expand All @@ -439,11 +439,15 @@ internal virtual void OpenFile<T>() where T : ProbeGroup
ChannelConfiguration = newConfiguration;
DrawProbeGroup();
RefreshZedGraph();

return true;
}
else
{
throw new InvalidOperationException($"Number of contacts does not match; expected {ChannelConfiguration.NumberOfContacts} contacts" +
$", but found {newConfiguration.NumberOfContacts} contacts");
MessageBox.Show($"Error: Number of contacts does not match; expected {ChannelConfiguration.NumberOfContacts} contacts" +
$", but found {newConfiguration.NumberOfContacts} contacts", "Contact Number Mismatch");

return false;
}
}

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

return newConfiguration ?? throw new InvalidOperationException($"Unable to open {ofd.FileName}");
return newConfiguration;
}

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

DrawProbeContour();
DrawContacts();
SetEqualAspectRatio();
SetZoomOutBoundaries();
DrawContacts();
HighlightEnabledContacts();
HighlightSelectedContacts();
DrawContactLabels();
Expand All @@ -492,6 +496,8 @@ internal void DrawProbeContour()

foreach (var probe in ChannelConfiguration.Probes)
{
if (probe == null || probe.ProbePlanarContour == null) continue;

PointD[] planarContours = ConvertFloatArrayToPointD(probe.ProbePlanarContour);
PolyObj contour = new(planarContours, Color.LightGray, Color.White)
{
Expand Down Expand Up @@ -521,10 +527,10 @@ internal void SetEqualAspectRatio()
if (zedGraphChannels.GraphPane.GraphObjList.Count == 0)
return;

var minX = GetProbeContourMinX(zedGraphChannels.GraphPane.GraphObjList);
var minY = GetProbeContourMinY(zedGraphChannels.GraphPane.GraphObjList);
var maxX = GetProbeContourMaxX(zedGraphChannels.GraphPane.GraphObjList);
var maxY = GetProbeContourMaxY(zedGraphChannels.GraphPane.GraphObjList);
var minX = GetProbeMinX(zedGraphChannels.GraphPane.GraphObjList);
var minY = GetProbeMinY(zedGraphChannels.GraphPane.GraphObjList);
var maxX = GetProbeMaxX(zedGraphChannels.GraphPane.GraphObjList);
var maxY = GetProbeMaxY(zedGraphChannels.GraphPane.GraphObjList);

var rangeX = maxX - minX;
var rangeY = maxY - minY;
Expand Down Expand Up @@ -578,6 +584,8 @@ internal void DrawContacts()

contactObj.Border.Width = borderWidth;
contactObj.Border.IsVisible = false;
contactObj.Location.AlignV = AlignV.Center;
contactObj.Location.AlignH = AlignH.Center;

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

contactObj.Border.Width = borderWidth;
contactObj.Border.IsVisible = false;
contactObj.Location.AlignV = AlignV.Bottom;
contactObj.Location.AlignH = AlignH.Left;

zedGraphChannels.GraphPane.GraphObjList.Add(contactObj);
}
Expand Down Expand Up @@ -802,25 +812,105 @@ internal float ContactSize()

return 1f;
}
// TODO: Convert from MinX/MaxX/... to Left / Right / etc.
internal static double GetProbeMinX(GraphObjList graphObjs)
{
if (graphObjs == null || graphObjs.Count == 0) return 0f;

if (graphObjs.OfType<PolyObj>().Count() == 0)
{
return GetContactMinX(graphObjs);
}
else
{
return GetProbeContourMinX(graphObjs);
}
}

internal static double GetContactMinX(GraphObjList graphObjs)
{
return graphObjs.OfType<BoxObj>()
.Min(obj => { return obj.Location.Rect.Left; });
}

internal static double GetProbeContourMinX(GraphObjList graphObjs)
{
return graphObjs.OfType<PolyObj>()
.Min(obj => { return obj.Points.Min(p => p.X); });
}

internal static double GetProbeMinY(GraphObjList graphObjs)
{
if (graphObjs == null || graphObjs.Count == 0) return 0f;

if (graphObjs.OfType<PolyObj>().Count() == 0)
{
return GetContactMinY(graphObjs);
}
else
{
return GetProbeContourMinY(graphObjs);
}
}

internal static double GetContactMinY(GraphObjList graphObjs)
{
return graphObjs.OfType<BoxObj>()
.Min(obj => { return obj.Location.Rect.Top - obj.Location.Height; });
}

internal static double GetProbeContourMinY(GraphObjList graphObjs)
{
return graphObjs.OfType<PolyObj>()
.Min(obj => { return obj.Points.Min(p => p.Y); });
}

internal static double GetProbeMaxX(GraphObjList graphObjs)
{
if (graphObjs == null || graphObjs.Count == 0) return 0f;

if (graphObjs.OfType<PolyObj>().Count() == 0)
{
return GetContactMaxX(graphObjs);
}
else
{
return GetProbeContourMaxX(graphObjs);
}
}

internal static double GetContactMaxX(GraphObjList graphObjs)
{
return graphObjs.OfType<BoxObj>()
.Max(obj => { return obj.Location.Rect.Right; });
}

internal static double GetProbeContourMaxX(GraphObjList graphObjs)
{
return graphObjs.OfType<PolyObj>()
.Max(obj => { return obj.Points.Max(p => p.X); });
}

internal static double GetProbeMaxY(GraphObjList graphObjs)
{
if (graphObjs == null || graphObjs.Count == 0) return 0f;

if (graphObjs.OfType<PolyObj>().Count() == 0)
{
return GetContactMaxY(graphObjs);
}
else
{
return GetProbeContourMaxY(graphObjs);
}
}

internal static double GetContactMaxY(GraphObjList graphObjs)
{
return graphObjs.OfType<BoxObj>()
.Max(obj => { return obj.Location.Rect.Bottom - obj.Location.Height; });
}

internal static double GetProbeContourMaxY(GraphObjList graphObjs)
{
return graphObjs.OfType<PolyObj>()
Expand Down Expand Up @@ -969,9 +1059,11 @@ private void UpdateControlSizeBasedOnAxisSize()

private void MenuItemOpenFile(object sender, EventArgs e)
{
OpenFile<ProbeGroup>();
DrawProbeGroup();
RefreshZedGraph();
if (OpenFile<ProbeGroup>())
{
DrawProbeGroup();
RefreshZedGraph();
}
}

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

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

var minY = GetProbeContourMinY(zedGraphChannels.GraphPane.GraphObjList);
var maxY = GetProbeContourMaxY(zedGraphChannels.GraphPane.GraphObjList);
var minY = GetProbeMinY(zedGraphChannels.GraphPane.GraphObjList);
var maxY = GetProbeMaxY(zedGraphChannels.GraphPane.GraphObjList);

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

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

internal float GetRelativeVerticalPosition()
{
var minY = GetProbeContourMinY(zedGraphChannels.GraphPane.GraphObjList);
var maxY = GetProbeContourMaxY(zedGraphChannels.GraphPane.GraphObjList);
var minY = GetProbeMinY(zedGraphChannels.GraphPane.GraphObjList);
var maxY = GetProbeMaxY(zedGraphChannels.GraphPane.GraphObjList);

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

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

return SelectedContacts[tag.ContactIndex];
}
Expand Down
40 changes: 37 additions & 3 deletions OpenEphys.Onix1.Design/DesignHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand All @@ -9,10 +9,44 @@ namespace OpenEphys.Onix1.Design
{
static class DesignHelper
{
public static T DeserializeString<T>(string channelLayout)
/// <summary>
/// Given a string with a valid JSON structure, deserialize the string to the given type.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="channelLayout"></param>
/// <returns></returns>
#nullable enable
public static T? DeserializeString<T>(string channelLayout)
{
return JsonConvert.DeserializeObject<T>(channelLayout);
var errors = new List<string>();

var serializerSettings = new JsonSerializerSettings()
{
Error = delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
errors.Add(args.ErrorContext.Error.Message);
args.ErrorContext.Handled = true;
}
};

var obj = JsonConvert.DeserializeObject<T>(channelLayout, serializerSettings);

if (errors.Count > 0)
{
MessageBox.Show($"There were errors encountered while parsing a JSON string. Check the console " +
$"for an error log.", "JSON Parse Error");

foreach (var e in errors)
{
Console.Error.WriteLine(e);
}

return default;
}

return obj;
}
#nullable disable

public static void SerializeObject(object _object, string filepath)
{
Expand Down
29 changes: 19 additions & 10 deletions OpenEphys.Onix1.Design/NeuropixelsV1eChannelConfigurationDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,19 @@ internal override void LoadDefaultChannelLayout()
OnFileOpenHandler();
}

internal override void OpenFile<T>()
internal override bool OpenFile<T>()
{
base.OpenFile<NeuropixelsV1eProbeGroup>();
if (base.OpenFile<NeuropixelsV1eProbeGroup>())
{
ProbeConfiguration = new((NeuropixelsV1eProbeGroup)ChannelConfiguration, ProbeConfiguration.SpikeAmplifierGain, ProbeConfiguration.LfpAmplifierGain, ProbeConfiguration.Reference, ProbeConfiguration.SpikeFilter);
ChannelConfiguration = ProbeConfiguration.ChannelConfiguration;

ProbeConfiguration = new((NeuropixelsV1eProbeGroup)ChannelConfiguration, ProbeConfiguration.SpikeAmplifierGain, ProbeConfiguration.LfpAmplifierGain, ProbeConfiguration.Reference, ProbeConfiguration.SpikeFilter);
ChannelConfiguration = ProbeConfiguration.ChannelConfiguration;
OnFileOpenHandler();

OnFileOpenHandler();
return true;
}

return false;
}

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

var x = GetProbeContourMaxX(zedGraphChannels.GraphPane.GraphObjList) + 40;
var minY = GetProbeContourMinY(zedGraphChannels.GraphPane.GraphObjList);
var maxY = GetProbeContourMaxY(zedGraphChannels.GraphPane.GraphObjList);
var x = GetProbeMaxX(zedGraphChannels.GraphPane.GraphObjList) + 40;
var minY = GetProbeMinY(zedGraphChannels.GraphPane.GraphObjList);
var maxY = GetProbeMaxY(zedGraphChannels.GraphPane.GraphObjList);

int textPosition = 0;

PointPairList pointList = new();

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

if (!zoomedOut || i % (5 * MajorTickIncrement) == 0)
if (!zoomedOut || countMajorTicks % 5 == 0)
{
TextObj textObj = new($"{i} µm", majorTickLocation.X + 10, majorTickLocation.Y, CoordType.AxisXYScale, AlignH.Left, AlignV.Center)
TextObj textObj = new($"{textPosition} µm", majorTickLocation.X + 10, majorTickLocation.Y, CoordType.AxisXYScale, AlignH.Left, AlignV.Center)
{
Tag = ScaleTextTag
};
textObj.FontSpec.Border.IsVisible = false;
textObj.FontSpec.Size = fontSize;
zedGraphChannels.GraphPane.GraphObjList.Add(textObj);

textPosition += zoomedOut ? 5 * MajorTickIncrement : MajorTickIncrement;
}

if (!zoomedOut)
Expand Down
Loading

0 comments on commit d439fe8

Please sign in to comment.