Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix loading channel configuration files #272

Merged
merged 4 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
34 changes: 31 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,38 @@ 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($"Warning: There were {errors.Count} errors found while deserializing the JSON string.\n" +
$"The first error was '{errors.First()}'.", "Deserializer Error");
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