Skip to content

Commit 067989b

Browse files
authored
Merge pull request #393 from open-ephys/issue-392
Rhs2116 step size algorithm now accounts for requested amplitude
2 parents 8d8ba02 + acb084b commit 067989b

File tree

2 files changed

+29
-27
lines changed

2 files changed

+29
-27
lines changed

OpenEphys.Onix1.Design/Rhs2116StimulusSequenceDialog.cs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ public partial class Rhs2116StimulusSequenceDialog : Form
2828

2929
internal readonly Rhs2116ChannelConfigurationDialog ChannelDialog;
3030

31-
const double MinAmplitudeuA = 0.01; // NB: Minimum possible amplitude is 10 nA (0.01 µA)
32-
const double MaxAmplitudeuA = 2550; // NB: Maximum possible amplitude is 2550000 nA (2550 µA)
33-
3431
/// <summary>
3532
/// Opens a dialog allowing for easy changing of stimulus sequence parameters, with visual feedback on what the resulting stimulus sequence looks like.
3633
/// </summary>
@@ -1020,8 +1017,9 @@ private void Amplitude_TextChanged(object sender, EventArgs e)
10201017
{
10211018
if (!UpdateStepSizeFromAmplitude(result))
10221019
{
1023-
string text = result > MaxAmplitudeuA ? MaxAmplitudeuA.ToString() : "0";
1024-
byte tag = result > MaxAmplitudeuA ? (byte)255 : (byte)0;
1020+
string text = "0";
1021+
byte tag = 0;
1022+
textBox.Text = "";
10251023

10261024
UpdateAmplitudeTextBoxes(textBox, text, tag);
10271025

@@ -1051,21 +1049,11 @@ private bool UpdateStepSizeFromAmplitude(double amplitude)
10511049
{
10521050
const string InvalidAmplitudeString = "Invalid Amplitude";
10531051

1054-
if (amplitude > MaxAmplitudeuA)
1055-
{
1056-
MessageBox.Show($"Warning: Amplitude is too high. Amplitude must be less than or equal to {MaxAmplitudeuA} µA.", InvalidAmplitudeString);
1057-
return false;
1058-
}
1059-
else if (amplitude < 0)
1052+
if (amplitude < 0)
10601053
{
10611054
MessageBox.Show("Warning: Amplitude cannot be a negative value.", InvalidAmplitudeString);
10621055
return false;
10631056
}
1064-
else if (amplitude < MinAmplitudeuA && amplitude >= 0)
1065-
{
1066-
MessageBox.Show($"Amplitude is too small to be resolved. Amplitude must be greater than or equal to {MinAmplitudeuA} µA.", InvalidAmplitudeString);
1067-
return false;
1068-
}
10691057

10701058
var stepSizes = Enum.GetValues(typeof(Rhs2116StepSize)).Cast<Rhs2116StepSize>();
10711059
var validStepSizes = stepSizes.Where(stepSize => IsValidNumberOfSteps(GetNumberOfSteps(amplitude, stepSize)));
@@ -1078,7 +1066,7 @@ private bool UpdateStepSizeFromAmplitude(double amplitude)
10781066
return true;
10791067
}
10801068

1081-
StepSize = Rhs2116StimulusSequence.GetStepSizeWithMinError(validStepSizes, Sequence.Stimuli, Sequence.CurrentStepSize);
1069+
StepSize = Rhs2116StimulusSequence.GetStepSizeWithMinError(validStepSizes, Sequence.Stimuli, amplitude, Sequence.CurrentStepSize);
10821070
textBoxStepSize.Text = GetStepSizeStringuA(StepSize);
10831071

10841072
return true;

OpenEphys.Onix1/Rhs2116StimulusSequence.cs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ private static void AddOrInsert(ref Dictionary<uint, BitArray> table, int channe
230230
}
231231
}
232232

233-
internal static Rhs2116StepSize GetStepSizeWithMinError(IEnumerable<Rhs2116StepSize> stepSizes, Rhs2116Stimulus[] stimuli, Rhs2116StepSize currentStepSize)
233+
internal static Rhs2116StepSize GetStepSizeWithMinError(IEnumerable<Rhs2116StepSize> stepSizes, Rhs2116Stimulus[] stimuli, double requestedAmplitude, Rhs2116StepSize currentStepSize)
234234
{
235235
var numberOfStepSizes = stepSizes.Count();
236236
var maxError = new List<double>(numberOfStepSizes);
@@ -239,7 +239,9 @@ internal static Rhs2116StepSize GetStepSizeWithMinError(IEnumerable<Rhs2116StepS
239239

240240
static double CalculateError(double amplitude, double stepSizeuA)
241241
{
242-
return Math.Abs((amplitude - (stepSizeuA * Math.Round(amplitude / stepSizeuA))) / amplitude);
242+
return Math.Round(amplitude / stepSizeuA) > 0 && Math.Round(amplitude / stepSizeuA) <= 255
243+
? Math.Abs((amplitude - (stepSizeuA * Math.Round(amplitude / stepSizeuA))) / amplitude)
244+
: double.PositiveInfinity;
243245
}
244246

245247
for (int s = 0; s < numberOfStepSizes; s++)
@@ -253,16 +255,15 @@ static double CalculateError(double amplitude, double stepSizeuA)
253255
var anodicAmp = stimuli[c].AnodicAmplitudeSteps * currentStepSizeuA;
254256
var cathodicAmp = stimuli[c].CathodicAmplitudeSteps * currentStepSizeuA;
255257

256-
var anodicError = anodicAmp < stepSizesuA[s] || anodicAmp > stepSizesuA[s] * 255 ?
257-
double.PositiveInfinity :
258-
CalculateError(anodicAmp, stepSizesuA[s]);
259-
260-
var cathodicError = cathodicAmp < stepSizesuA[s] || cathodicAmp > stepSizesuA[s] * 255 ?
261-
double.PositiveInfinity :
262-
CalculateError(cathodicAmp, stepSizesuA[s]);
258+
var anodicError = CalculateError(anodicAmp, stepSizesuA[s]);
259+
var cathodicError = CalculateError(cathodicAmp, stepSizesuA[s]);
263260

264261
maxError[s] = Math.Max(maxError[s], Math.Max(anodicError, cathodicError));
265262
}
263+
264+
var requestedError = CalculateError(requestedAmplitude, stepSizesuA[s]);
265+
266+
maxError[s] = Math.Max(maxError[s], requestedError);
266267
}
267268

268269
if (maxError.Distinct().Count() == 1)
@@ -271,7 +272,20 @@ static double CalculateError(double amplitude, double stepSizeuA)
271272
return stepSizes.OrderBy(s => Math.Abs(GetStepSizeuA(s) - currentStepSizeuA)).First();
272273
}
273274

274-
var optimalStepIndex = maxError.IndexOf(maxError.Min());
275+
var minimumError = maxError.Min();
276+
var optimalStepIndex = maxError
277+
.Select((e, ind) =>
278+
{
279+
if (e == minimumError)
280+
{
281+
return (Min: true, Ind: ind);
282+
}
283+
return (Min: false, Ind: -1);
284+
})
285+
.Where(e => e.Min)
286+
.OrderBy(e => Math.Abs(GetStepSizeuA(stepSizes.ElementAt(e.Ind)) - currentStepSizeuA))
287+
.Select(e => e.Ind)
288+
.First();
275289

276290
return stepSizes.ElementAt(optimalStepIndex);
277291
}

0 commit comments

Comments
 (0)