From 5bd48dabef8a9ebc5d27a71f8fe48fa5bd6fc747 Mon Sep 17 00:00:00 2001 From: bparks13 Date: Tue, 22 Oct 2024 12:11:54 -0400 Subject: [PATCH 1/2] Plot pulses in red to highlight them --- Directory.Build.props | 2 +- .../Rhs2116StimulusSequenceDialog.cs | 113 ++++++++++++++---- 2 files changed, 92 insertions(+), 23 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index d12448f..6266d68 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -13,7 +13,7 @@ LICENSE true icon.png - 0.4.0 + 0.4.1 10.0 strict diff --git a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs index 34de646..7704f82 100644 --- a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs +++ b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs @@ -4,6 +4,7 @@ using System.Windows.Forms; using ZedGraph; using System.IO; +using System.Collections.Generic; namespace OpenEphys.Onix1.Design { @@ -258,22 +259,24 @@ private void DrawStimulusWaveform() if (ChannelDialog.SelectedContacts[i] || plotAllContacts) { - PointPairList pointPairs = CreateStimulusWaveform(stimuli[i], channelOffset, peakToPeak); + List pulses = CreatePulses(stimuli[i], channelOffset, peakToPeak); - Color color; - if (stimuli[i].IsValid()) - { - color = Color.CornflowerBlue; - } - else + foreach (var pulse in pulses) { - color = Color.Red; + var pulseCurve = zedGraphWaveform.GraphPane.AddCurve("", pulse, Color.Red, SymbolType.None); + + pulseCurve.Label.IsVisible = false; + pulseCurve.Line.Width = 3; } - var curve = zedGraphWaveform.GraphPane.AddCurve("", pointPairs, color, SymbolType.None); + PointPairList pointPairs = CreateStimulusWaveform(stimuli[i], channelOffset, peakToPeak); + + Color color = stimuli[i].IsValid() ? Color.CornflowerBlue : Color.DarkRed; + + var waveformCurve = zedGraphWaveform.GraphPane.AddCurve("", pointPairs, color, SymbolType.None); - curve.Label.IsVisible = false; - curve.Line.Width = 3; + waveformCurve.Label.IsVisible = false; + waveformCurve.Line.Width = 3; maxLength = pointPairs.Last().X > maxLength ? pointPairs.Last().X : maxLength; } @@ -296,7 +299,7 @@ private void DrawStimulusWaveform() SetZoomOutBoundaries(zedGraphWaveform); - ZoomInBoundaryX = (ZoomOutBoundaryRight - ZoomOutBoundaryLeft) * 0.05; + ZoomInBoundaryX = (ZoomOutBoundaryRight - ZoomOutBoundaryLeft) * 0.01; dataGridViewStimulusTable.Refresh(); @@ -375,21 +378,17 @@ private PointPairList CreateStimulusWaveform(Rhs2116Stimulus stimulus, double yO for (int i = 0; i < stimulus.NumberOfStimuli; i++) { - double amplitude = (stimulus.AnodicFirst ? stimulus.AnodicAmplitudeSteps : -stimulus.CathodicAmplitudeSteps) * Sequence.CurrentStepSizeuA / peakToPeak + yOffset; - double width = (stimulus.AnodicFirst ? stimulus.AnodicWidthSamples : stimulus.CathodicWidthSamples) * SamplePeriodMilliSeconds; + double amplitude = CalculateFirstPulseAmplitude(stimulus.AnodicFirst, stimulus.AnodicAmplitudeSteps, stimulus.CathodicAmplitudeSteps, peakToPeak, yOffset); + double width = CalculateFirstPulseWidth(stimulus.AnodicFirst, stimulus.AnodicWidthSamples, stimulus.CathodicWidthSamples); - points.Add(points[points.Count - 1].X, amplitude); - points.Add(points[points.Count - 1].X + width, amplitude); - points.Add(points[points.Count - 1].X, yOffset); + points.AddRange(CreatePulse(points[points.Count - 1].X, amplitude, width, yOffset)); points.Add(points[points.Count - 1].X + stimulus.DwellSamples * SamplePeriodMilliSeconds, yOffset); - amplitude = (stimulus.AnodicFirst ? -stimulus.CathodicAmplitudeSteps : stimulus.AnodicAmplitudeSteps) * Sequence.CurrentStepSizeuA / peakToPeak + yOffset; - width = (stimulus.AnodicFirst ? stimulus.CathodicWidthSamples : stimulus.AnodicWidthSamples) * SamplePeriodMilliSeconds; + amplitude = CalculateSecondPulseAmplitude(stimulus.AnodicFirst, stimulus.AnodicAmplitudeSteps, stimulus.CathodicAmplitudeSteps, peakToPeak, yOffset); + width = CalculateSecondPulseWidth(stimulus.AnodicFirst, stimulus.AnodicWidthSamples, stimulus.CathodicWidthSamples); - points.Add(points[points.Count - 1].X, amplitude); - points.Add(points[points.Count - 1].X + width, amplitude); - points.Add(points[points.Count - 1].X, yOffset); + points.AddRange(CreatePulse(points[points.Count - 1].X, amplitude, width, yOffset)); points.Add(points[points.Count - 1].X + stimulus.InterStimulusIntervalSamples * SamplePeriodMilliSeconds, yOffset); } @@ -399,6 +398,76 @@ private PointPairList CreateStimulusWaveform(Rhs2116Stimulus stimulus, double yO return points; } + /// + /// Only create the pulses, so that they can be plotted as an overlay on top of the full waveform to highlight individual pulses + /// + /// + /// + /// + /// + private List CreatePulses(Rhs2116Stimulus stimulus, double yOffset, double peakToPeak) + { + yOffset /= peakToPeak; + + var pulses = new List(); + + for (int i = 0; i < stimulus.NumberOfStimuli; i++) + { + PointPairList pulse = new(); + + if (i == 0) + pulse.Add(stimulus.DelaySamples * SamplePeriodMilliSeconds, yOffset); + else + pulse.Add(pulses[pulses.Count - 1][0].X + stimulus.InterStimulusIntervalSamples * SamplePeriodMilliSeconds, yOffset); + + double amplitude = CalculateFirstPulseAmplitude(stimulus.AnodicFirst, stimulus.AnodicAmplitudeSteps, stimulus.CathodicAmplitudeSteps, peakToPeak, yOffset); + double width = CalculateFirstPulseWidth(stimulus.AnodicFirst, stimulus.AnodicWidthSamples, stimulus.CathodicWidthSamples); + + pulse.AddRange(CreatePulse(pulse[pulse.Count - 1].X, amplitude, width, yOffset)); + + pulse.Add(pulse[pulse.Count - 1].X + stimulus.DwellSamples * SamplePeriodMilliSeconds, yOffset); + + amplitude = CalculateSecondPulseAmplitude(stimulus.AnodicFirst, stimulus.AnodicAmplitudeSteps, stimulus.CathodicAmplitudeSteps, peakToPeak, yOffset); + width = CalculateSecondPulseWidth(stimulus.AnodicFirst, stimulus.AnodicWidthSamples, stimulus.CathodicWidthSamples); + + pulse.AddRange(CreatePulse(pulse[pulse.Count - 1].X, amplitude, width, yOffset)); + + pulses.Add(pulse); + } + + return pulses; + } + + private double CalculateSecondPulseWidth(bool anodicFirst, uint anodicWidthSamples, uint cathodicWidthSamples) + { + return (anodicFirst ? cathodicWidthSamples : anodicWidthSamples) * SamplePeriodMilliSeconds; + } + + private double CalculateSecondPulseAmplitude(bool anodicFirst, byte anodicAmplitudeSteps, byte cathodicAmplitudeSteps, double peakToPeak, double yOffset) + { + return (anodicFirst ? -cathodicAmplitudeSteps : anodicAmplitudeSteps) * Sequence.CurrentStepSizeuA / peakToPeak + yOffset; + } + + private List CreatePulse(double x, double amplitude, double width, double yOffset) + { + return new List() + { + { new PointPair(x, amplitude) }, + { new PointPair(x + width, amplitude) }, + { new PointPair(x + width, yOffset) }, + }; + } + + private double CalculateFirstPulseWidth(bool anodicFirst, uint anodicWidthSamples, uint cathodicWidthSamples) + { + return (anodicFirst ? anodicWidthSamples : cathodicWidthSamples) * SamplePeriodMilliSeconds; + } + + private double CalculateFirstPulseAmplitude(bool anodicFirst, byte anodicAmplitudeSteps, byte cathodicAmplitudeSteps, double peakToPeak, double yOffset) + { + return (anodicFirst ? anodicAmplitudeSteps : -cathodicAmplitudeSteps) * Sequence.CurrentStepSizeuA / peakToPeak + yOffset; + } + private void InitializeZedGraphWaveform() { zedGraphWaveform.IsZoomOnMouseCenter = true; From f11c18b78aafa3fa2a095726412515c8cf907e55 Mon Sep 17 00:00:00 2001 From: bparks13 Date: Tue, 22 Oct 2024 14:02:03 -0400 Subject: [PATCH 2/2] Corrected offsets for the pulse overlay - Modified the line widths so that the pulse overlay is more distinctive --- .../Rhs2116StimulusSequenceDialog.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs index 7704f82..b1fb528 100644 --- a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs +++ b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs @@ -266,7 +266,7 @@ private void DrawStimulusWaveform() var pulseCurve = zedGraphWaveform.GraphPane.AddCurve("", pulse, Color.Red, SymbolType.None); pulseCurve.Label.IsVisible = false; - pulseCurve.Line.Width = 3; + pulseCurve.Line.Width = 4; } PointPairList pointPairs = CreateStimulusWaveform(stimuli[i], channelOffset, peakToPeak); @@ -276,7 +276,7 @@ private void DrawStimulusWaveform() var waveformCurve = zedGraphWaveform.GraphPane.AddCurve("", pointPairs, color, SymbolType.None); waveformCurve.Label.IsVisible = false; - waveformCurve.Line.Width = 3; + waveformCurve.Line.Width = 2; maxLength = pointPairs.Last().X > maxLength ? pointPairs.Last().X : maxLength; } @@ -383,14 +383,14 @@ private PointPairList CreateStimulusWaveform(Rhs2116Stimulus stimulus, double yO points.AddRange(CreatePulse(points[points.Count - 1].X, amplitude, width, yOffset)); - points.Add(points[points.Count - 1].X + stimulus.DwellSamples * SamplePeriodMilliSeconds, yOffset); + points.Add(points.Last().X + stimulus.DwellSamples * SamplePeriodMilliSeconds, yOffset); amplitude = CalculateSecondPulseAmplitude(stimulus.AnodicFirst, stimulus.AnodicAmplitudeSteps, stimulus.CathodicAmplitudeSteps, peakToPeak, yOffset); width = CalculateSecondPulseWidth(stimulus.AnodicFirst, stimulus.AnodicWidthSamples, stimulus.CathodicWidthSamples); points.AddRange(CreatePulse(points[points.Count - 1].X, amplitude, width, yOffset)); - points.Add(points[points.Count - 1].X + stimulus.InterStimulusIntervalSamples * SamplePeriodMilliSeconds, yOffset); + points.Add(points.Last().X + stimulus.InterStimulusIntervalSamples * SamplePeriodMilliSeconds, yOffset); } points.Add(Sequence.SequenceLengthSamples * SamplePeriodMilliSeconds, yOffset); @@ -418,7 +418,7 @@ private List CreatePulses(Rhs2116Stimulus stimulus, double yOffse if (i == 0) pulse.Add(stimulus.DelaySamples * SamplePeriodMilliSeconds, yOffset); else - pulse.Add(pulses[pulses.Count - 1][0].X + stimulus.InterStimulusIntervalSamples * SamplePeriodMilliSeconds, yOffset); + pulse.Add(pulses.Last().Last().X + stimulus.InterStimulusIntervalSamples * SamplePeriodMilliSeconds, yOffset); double amplitude = CalculateFirstPulseAmplitude(stimulus.AnodicFirst, stimulus.AnodicAmplitudeSteps, stimulus.CathodicAmplitudeSteps, peakToPeak, yOffset); double width = CalculateFirstPulseWidth(stimulus.AnodicFirst, stimulus.AnodicWidthSamples, stimulus.CathodicWidthSamples);