diff --git a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs index 9872758..38ec350 100644 --- a/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs +++ b/OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs @@ -28,9 +28,6 @@ public partial class Rhs2116StimulusSequenceDialog : Form internal readonly Rhs2116ChannelConfigurationDialog ChannelDialog; - const double MinAmplitudeuA = 0.01; // NB: Minimum possible amplitude is 10 nA (0.01 µA) - const double MaxAmplitudeuA = 2550; // NB: Maximum possible amplitude is 2550000 nA (2550 µA) - /// /// Opens a dialog allowing for easy changing of stimulus sequence parameters, with visual feedback on what the resulting stimulus sequence looks like. /// @@ -1020,8 +1017,9 @@ private void Amplitude_TextChanged(object sender, EventArgs e) { if (!UpdateStepSizeFromAmplitude(result)) { - string text = result > MaxAmplitudeuA ? MaxAmplitudeuA.ToString() : "0"; - byte tag = result > MaxAmplitudeuA ? (byte)255 : (byte)0; + string text = "0"; + byte tag = 0; + textBox.Text = ""; UpdateAmplitudeTextBoxes(textBox, text, tag); @@ -1051,21 +1049,11 @@ private bool UpdateStepSizeFromAmplitude(double amplitude) { const string InvalidAmplitudeString = "Invalid Amplitude"; - if (amplitude > MaxAmplitudeuA) - { - MessageBox.Show($"Warning: Amplitude is too high. Amplitude must be less than or equal to {MaxAmplitudeuA} µA.", InvalidAmplitudeString); - return false; - } - else if (amplitude < 0) + if (amplitude < 0) { MessageBox.Show("Warning: Amplitude cannot be a negative value.", InvalidAmplitudeString); return false; } - else if (amplitude < MinAmplitudeuA && amplitude >= 0) - { - MessageBox.Show($"Amplitude is too small to be resolved. Amplitude must be greater than or equal to {MinAmplitudeuA} µA.", InvalidAmplitudeString); - return false; - } var stepSizes = Enum.GetValues(typeof(Rhs2116StepSize)).Cast(); var validStepSizes = stepSizes.Where(stepSize => IsValidNumberOfSteps(GetNumberOfSteps(amplitude, stepSize))); @@ -1078,7 +1066,7 @@ private bool UpdateStepSizeFromAmplitude(double amplitude) return true; } - StepSize = Rhs2116StimulusSequence.GetStepSizeWithMinError(validStepSizes, Sequence.Stimuli, Sequence.CurrentStepSize); + StepSize = Rhs2116StimulusSequence.GetStepSizeWithMinError(validStepSizes, Sequence.Stimuli, amplitude, Sequence.CurrentStepSize); textBoxStepSize.Text = GetStepSizeStringuA(StepSize); return true; diff --git a/OpenEphys.Onix1/Rhs2116StimulusSequence.cs b/OpenEphys.Onix1/Rhs2116StimulusSequence.cs index 1258dc0..998e2ac 100644 --- a/OpenEphys.Onix1/Rhs2116StimulusSequence.cs +++ b/OpenEphys.Onix1/Rhs2116StimulusSequence.cs @@ -230,7 +230,7 @@ private static void AddOrInsert(ref Dictionary table, int channe } } - internal static Rhs2116StepSize GetStepSizeWithMinError(IEnumerable stepSizes, Rhs2116Stimulus[] stimuli, Rhs2116StepSize currentStepSize) + internal static Rhs2116StepSize GetStepSizeWithMinError(IEnumerable stepSizes, Rhs2116Stimulus[] stimuli, double requestedAmplitude, Rhs2116StepSize currentStepSize) { var numberOfStepSizes = stepSizes.Count(); var maxError = new List(numberOfStepSizes); @@ -239,7 +239,9 @@ internal static Rhs2116StepSize GetStepSizeWithMinError(IEnumerable 0 && Math.Round(amplitude / stepSizeuA) <= 255 + ? Math.Abs((amplitude - (stepSizeuA * Math.Round(amplitude / stepSizeuA))) / amplitude) + : double.PositiveInfinity; } for (int s = 0; s < numberOfStepSizes; s++) @@ -253,16 +255,15 @@ static double CalculateError(double amplitude, double stepSizeuA) var anodicAmp = stimuli[c].AnodicAmplitudeSteps * currentStepSizeuA; var cathodicAmp = stimuli[c].CathodicAmplitudeSteps * currentStepSizeuA; - var anodicError = anodicAmp < stepSizesuA[s] || anodicAmp > stepSizesuA[s] * 255 ? - double.PositiveInfinity : - CalculateError(anodicAmp, stepSizesuA[s]); - - var cathodicError = cathodicAmp < stepSizesuA[s] || cathodicAmp > stepSizesuA[s] * 255 ? - double.PositiveInfinity : - CalculateError(cathodicAmp, stepSizesuA[s]); + var anodicError = CalculateError(anodicAmp, stepSizesuA[s]); + var cathodicError = CalculateError(cathodicAmp, stepSizesuA[s]); maxError[s] = Math.Max(maxError[s], Math.Max(anodicError, cathodicError)); } + + var requestedError = CalculateError(requestedAmplitude, stepSizesuA[s]); + + maxError[s] = Math.Max(maxError[s], requestedError); } if (maxError.Distinct().Count() == 1) @@ -271,7 +272,20 @@ static double CalculateError(double amplitude, double stepSizeuA) return stepSizes.OrderBy(s => Math.Abs(GetStepSizeuA(s) - currentStepSizeuA)).First(); } - var optimalStepIndex = maxError.IndexOf(maxError.Min()); + var minimumError = maxError.Min(); + var optimalStepIndex = maxError + .Select((e, ind) => + { + if (e == minimumError) + { + return (Min: true, Ind: ind); + } + return (Min: false, Ind: -1); + }) + .Where(e => e.Min) + .OrderBy(e => Math.Abs(GetStepSizeuA(stepSizes.ElementAt(e.Ind)) - currentStepSizeuA)) + .Select(e => e.Ind) + .First(); return stepSizes.ElementAt(optimalStepIndex); }