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.Designer.cs b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.Designer.cs
index e98c78b..a73db59 100644
--- a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.Designer.cs
+++ b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.Designer.cs
@@ -192,9 +192,9 @@ private void InitializeComponent()
this.groupBoxCathode.Controls.Add(this.textboxPulseWidthCathodic);
this.groupBoxCathode.Controls.Add(this.textboxAmplitudeCathodic);
this.groupBoxCathode.Location = new System.Drawing.Point(231, 94);
- this.groupBoxCathode.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
+ this.groupBoxCathode.Margin = new System.Windows.Forms.Padding(4);
this.groupBoxCathode.Name = "groupBoxCathode";
- this.groupBoxCathode.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4);
+ this.groupBoxCathode.Padding = new System.Windows.Forms.Padding(4);
this.groupBoxCathode.Size = new System.Drawing.Size(195, 69);
this.groupBoxCathode.TabIndex = 3;
this.groupBoxCathode.TabStop = false;
@@ -236,7 +236,6 @@ private void InitializeComponent()
this.textboxAmplitudeCathodic.Name = "textboxAmplitudeCathodic";
this.textboxAmplitudeCathodic.Size = new System.Drawing.Size(55, 22);
this.textboxAmplitudeCathodic.TabIndex = 5;
- this.textboxAmplitudeCathodic.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.ParameterKeyPress_Amplitude);
this.textboxAmplitudeCathodic.Leave += new System.EventHandler(this.Amplitude_TextChanged);
//
// groupBoxAnode
@@ -246,9 +245,9 @@ private void InitializeComponent()
this.groupBoxAnode.Controls.Add(this.textboxPulseWidthAnodic);
this.groupBoxAnode.Controls.Add(this.textboxAmplitudeAnodic);
this.groupBoxAnode.Location = new System.Drawing.Point(13, 94);
- this.groupBoxAnode.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
+ this.groupBoxAnode.Margin = new System.Windows.Forms.Padding(4);
this.groupBoxAnode.Name = "groupBoxAnode";
- this.groupBoxAnode.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4);
+ this.groupBoxAnode.Padding = new System.Windows.Forms.Padding(4);
this.groupBoxAnode.Size = new System.Drawing.Size(195, 69);
this.groupBoxAnode.TabIndex = 2;
this.groupBoxAnode.TabStop = false;
@@ -289,7 +288,6 @@ private void InitializeComponent()
this.textboxAmplitudeAnodic.Name = "textboxAmplitudeAnodic";
this.textboxAmplitudeAnodic.Size = new System.Drawing.Size(55, 22);
this.textboxAmplitudeAnodic.TabIndex = 3;
- this.textboxAmplitudeAnodic.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.ParameterKeyPress_Amplitude);
this.textboxAmplitudeAnodic.Leave += new System.EventHandler(this.Amplitude_TextChanged);
//
// buttonClearPulses
@@ -501,7 +499,7 @@ private void InitializeComponent()
this.tabPageTable.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
this.tabPageTable.Name = "tabPageTable";
this.tabPageTable.Padding = new System.Windows.Forms.Padding(3, 2, 3, 2);
- this.tabPageTable.Size = new System.Drawing.Size(1083, 644);
+ this.tabPageTable.Size = new System.Drawing.Size(1082, 646);
this.tabPageTable.TabIndex = 1;
this.tabPageTable.Text = "Table";
this.tabPageTable.UseVisualStyleBackColor = true;
@@ -519,7 +517,7 @@ private void InitializeComponent()
this.dataGridViewStimulusTable.Name = "dataGridViewStimulusTable";
this.dataGridViewStimulusTable.RowHeadersWidth = 62;
this.dataGridViewStimulusTable.RowTemplate.Height = 28;
- this.dataGridViewStimulusTable.Size = new System.Drawing.Size(1077, 640);
+ this.dataGridViewStimulusTable.Size = new System.Drawing.Size(1076, 642);
this.dataGridViewStimulusTable.TabIndex = 0;
this.dataGridViewStimulusTable.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.DataGridViewStimulusTable_CellEndEdit);
this.dataGridViewStimulusTable.DataBindingComplete += new System.Windows.Forms.DataGridViewBindingCompleteEventHandler(this.DataGridViewStimulusTable_DataBindingComplete);
diff --git a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs
index 34de646..5ea07c4 100644
--- a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs
+++ b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs
@@ -652,11 +652,12 @@ private void ButtonAddPulses_Click(object sender, EventArgs e)
return (ValidAmplitudes: validAnodicAmplitude && newAnodicSteps != 0 && validCathodicAmplitude && newCathodicSteps != 0,
s.Index,
+ s.Stimulus,
NewAnodicSteps: newAnodicSteps,
NewCathodicSteps: newCathodicSteps);
});
- foreach (var (ValidAmplitudes, Index, NewAnodicSteps, NewCathodicSteps) in stimuli)
+ foreach (var (ValidAmplitudes, Index, Stimulus, NewAnodicSteps, NewCathodicSteps) in stimuli)
{
if (ValidAmplitudes)
{
@@ -665,9 +666,9 @@ private void ButtonAddPulses_Click(object sender, EventArgs e)
}
else
{
- var result = MessageBox.Show($"To produce this new sequence, the step size needs to be {GetStepSizeStringuA(StepSize)}," +
- $" but the stimulus on channel {Index} cannot be defined with this step size. " +
- $"Press Ok to clear the stimulus from channel {Index}, or Cancel to stop adding this sequence.",
+ var result = MessageBox.Show($"The new amplitude ({GetAmplitudeString((byte)textboxAmplitudeAnodic.Tag) + " µA"}) is using a step size of {GetStepSizeStringuA(StepSize)}," +
+ $" but channel {Index} ({GetAmplitudeString(Stimulus.AnodicAmplitudeSteps, Sequence.CurrentStepSize) + " µA"}) cannot be defined with this step size. " +
+ $"Press Ok to clear channel {Index}, or Cancel to stop adding this sequence.",
"Amplitude Out of Range", MessageBoxButtons.OKCancel);
if (result == DialogResult.Cancel)
@@ -764,14 +765,6 @@ private void ParameterKeyPress_Time(object sender, KeyPressEventArgs e)
}
}
- private void ParameterKeyPress_Amplitude(object sender, KeyPressEventArgs e)
- {
- if (e.KeyChar == '\r')
- {
- Amplitude_TextChanged(sender, e);
- }
- }
-
private void DataGridViewStimulusTable_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
dataGridViewStimulusTable.BindingContext[dataGridViewStimulusTable.DataSource].EndCurrentEdit();
@@ -808,34 +801,21 @@ private string GetStepSizeStringuA(Rhs2116StepSize stepSize)
return Rhs2116StimulusSequence.GetStepSizeuA(stepSize).ToString() + " µA";
}
- private double GetStepSizeuA(Rhs2116StepSize stepSize)
+ private string GetAmplitudeString(byte amplitude)
{
- return stepSize switch
- {
- Rhs2116StepSize.Step10nA => 0.01,
- Rhs2116StepSize.Step20nA => 0.02,
- Rhs2116StepSize.Step50nA => 0.05,
- Rhs2116StepSize.Step100nA => 0.1,
- Rhs2116StepSize.Step200nA => 0.2,
- Rhs2116StepSize.Step500nA => 0.5,
- Rhs2116StepSize.Step1000nA => 1.0,
- Rhs2116StepSize.Step2000nA => 2.0,
- Rhs2116StepSize.Step5000nA => 5.0,
- Rhs2116StepSize.Step10000nA => 10.0,
- _ => throw new ArgumentException("Invalid stimulus step size selection."),
- };
+ return GetAmplitudeString(amplitude, StepSize);
}
- private string GetAmplitudeString(byte amplitude)
+ private string GetAmplitudeString(byte amplitude, Rhs2116StepSize stepSize)
{
- string format = StepSize switch
+ string format = stepSize switch
{
Rhs2116StepSize.Step10nA or Rhs2116StepSize.Step20nA or Rhs2116StepSize.Step50nA => "{0:F2}",
Rhs2116StepSize.Step100nA or Rhs2116StepSize.Step200nA or Rhs2116StepSize.Step500nA => "{0:F1}",
Rhs2116StepSize.Step1000nA or Rhs2116StepSize.Step2000nA or Rhs2116StepSize.Step5000nA or Rhs2116StepSize.Step10000nA => "{0:F0}",
_ => "{0:F3}",
};
- return string.Format(format, GetAmplitudeFromSample(amplitude));
+ return string.Format(format, GetAmplitudeFromSample(amplitude, stepSize));
}
private string GetTimeString(uint time)
@@ -927,11 +907,6 @@ private double GetTimeFromSample(uint value)
return value * SamplePeriodMilliSeconds;
}
- private double GetAmplitudeFromSample(byte value)
- {
- return GetAmplitudeFromSample(value, StepSize);
- }
-
private double GetAmplitudeFromSample(byte value, Rhs2116StepSize stepSize)
{
return value * Rhs2116StimulusSequence.GetStepSizeuA(stepSize);
@@ -1054,8 +1029,7 @@ private bool UpdateStepSizeFromAmplitude(double amplitude)
.Cast()
.Where(s =>
{
- var numSteps = (int)(amplitude / GetStepSizeuA(s));
- return numSteps > 0 && numSteps <= 255;
+ return IsValidNumberOfSteps(GetNumberOfSteps(amplitude, s));
});
if (possibleStepSizes.Count() == 1)
@@ -1070,7 +1044,33 @@ private bool UpdateStepSizeFromAmplitude(double amplitude)
}
else
{
- StepSize = possibleStepSizes.First();
+ // NB: Search through the possible step sizes and try to find one that matches all current amplitudes
+ var validStepSizes = possibleStepSizes.Where(s =>
+ {
+ var numberOfStimuli = Sequence.Stimuli.Length;
+
+ bool[] isValid = new bool[numberOfStimuli];
+
+ for (int i = 0; i < numberOfStimuli; i++)
+ {
+ isValid[i] = IsValidNumberOfSteps(GetNumberOfSteps(GetAmplitudeFromSample(Sequence.Stimuli[i].AnodicAmplitudeSteps, Sequence.CurrentStepSize), s));
+ }
+
+ return isValid.All(i => i);
+ });
+
+ if (!validStepSizes.Any())
+ {
+ MessageBox.Show("No step size found that fits all existing and new amplitudes. " +
+ "Either clear existing stimuli that fall outside the range of the new step size, or modify " +
+ "the new amplitude.", "Invalid Amplitude");
+
+ StepSize = possibleStepSizes.First();
+ }
+ else
+ {
+ StepSize = validStepSizes.First();
+ }
}
}
@@ -1079,6 +1079,16 @@ private bool UpdateStepSizeFromAmplitude(double amplitude)
return true;
}
+ private bool IsValidNumberOfSteps(int numberOfSteps)
+ {
+ return numberOfSteps > 0 && numberOfSteps <= 255;
+ }
+
+ private int GetNumberOfSteps(double amplitude, Rhs2116StepSize stepSize)
+ {
+ return (int)(amplitude / Rhs2116StimulusSequence.GetStepSizeuA(stepSize));
+ }
+
private void Checkbox_CheckedChanged(object sender, EventArgs e)
{
if (checkboxBiphasicSymmetrical.Checked)
@@ -1144,9 +1154,6 @@ private void ButtonReadPulses_Click(object sender, EventArgs e)
.Select(c => c.Ind)
.First();
- if (Sequence.Stimuli[index].NumberOfStimuli == 0 || !Sequence.Stimuli[index].IsValid())
- return;
-
if (Sequence.Stimuli[index].AnodicAmplitudeSteps == Sequence.Stimuli[index].CathodicAmplitudeSteps &&
Sequence.Stimuli[index].AnodicWidthSamples == Sequence.Stimuli[index].CathodicWidthSamples)
{
@@ -1190,6 +1197,14 @@ private void ButtonReadPulses_Click(object sender, EventArgs e)
private void MenuItemSaveFile_Click(object sender, EventArgs e)
{
+ if (!Sequence.Valid)
+ {
+ var result = MessageBox.Show("Warning: Not all stimuli are valid; are you sure you want to save this file?",
+ "Invalid Stimuli", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
+
+ if (result == DialogResult.No) return;
+ }
+
using SaveFileDialog sfd = new();
sfd.Filter = "Stimulus Sequence Files (*.json)|*.json";
sfd.FilterIndex = 1;
@@ -1226,10 +1241,16 @@ private void MenuItemLoadFile_Click(object sender, EventArgs e)
{
Sequence = sequence;
dataGridViewStimulusTable.DataSource = Sequence.Stimuli;
+
+ if (!Sequence.Valid)
+ {
+ MessageBox.Show("Warning: Invalid stimuli found in the recently opened file. Check all values to ensure they are what is expected.",
+ "Invalid Stimuli", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
}
else
{
- MessageBox.Show("Incoming sequence is not valid. Check file for validity.");
+ MessageBox.Show("Incoming file is not valid. Check file for validity.");
}
DrawStimulusWaveform();