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..b1fb528 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 = 4;
}
- 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 = 2;
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,23 +378,19 @@ 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);
+ points.Add(points.Last().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);
+ points.Add(points.Last().X + stimulus.InterStimulusIntervalSamples * SamplePeriodMilliSeconds, yOffset);
}
points.Add(Sequence.SequenceLengthSamples * 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.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);
+
+ 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;