/// <summary> /// Gets the Stim parameters for a Group /// </summary> /// <param name="theSummit">SummitSystem for making the api call to INS</param> /// <param name="group">Group number to get the data</param> /// <returns>StimParameterModel that contains stim amp, stim rate and pulse width</returns> public Tuple <bool, string, TherapyGroup> GetTherapyDataForGroup(SummitSystem theSummit, GroupNumber group) { TherapyGroup insStateGroup = null; if (theSummit == null || theSummit.IsDisposed) { return(Tuple.Create(false, "Summit Disposed", insStateGroup)); } try { //Get the data from the api bufferInfo = theSummit.ReadStimGroup(group, out insStateGroup); if (bufferInfo.RejectCode != 0 || insStateGroup == null) { _log.Warn("Could not read stim group from Medtronic api call"); return(Tuple.Create(false, "Could not read stim group from Medtronic api call", insStateGroup)); } } catch (Exception e) { _log.Error(e); return(Tuple.Create(false, "Error reading stim group.", insStateGroup)); } return(Tuple.Create(true, "Success", insStateGroup)); }
/// <summary> /// Constructor to set values for stimulation data for pulse width, stim rate and stim amp /// </summary> /// <param name="pulsewidth">Sets the pulseWidth value</param> /// <param name="stimrate">Sets the stimRate value</param> /// <param name="stimamp">Sets the stimAmp value</param> /// <param name="electrodesStim">Sets the electrode that is stimming</param> /// <param name="therapyElectrodes">Therapy electrodes</param> /// <param name="therapyGroup">Therapy group with all settings</param> public StimParameterModel(string pulsewidth, string stimrate, string stimamp, string electrodesStim, TherapyElectrodes therapyElectrodes, TherapyGroup therapyGroup) { PulseWidth = pulsewidth; StimRate = stimrate; StimAmp = stimamp; StimElectrodes = electrodesStim; TherapyElectrodes = therapyElectrodes; TherapyGroup = therapyGroup; }
/// <summary> /// Constructor to set values for stimulation data for pulse width, stim rate and stim amp /// </summary> /// <param name="pulsewidth">Sets the pulseWidth value</param> /// <param name="stimrate">Sets the stimRate value</param> /// <param name="stimamp">Sets the stimAmp value</param> /// <param name="electrodesStim">Sets the electrode that is stimming</param> /// <param name="therapyElectrodes">Therapy electrodes</param> /// <param name="therapyGroup">Therapy group with all settings</param> /// <param name="ampLimits">Amp Limits</param> /// <param name="rateValue">Rate value as double</param> /// <param name="ampValue">Amp value as double</param> /// <param name="pwValue">Pulse width value as double</param> public StimParameterModel(string pulsewidth, string stimrate, string stimamp, string electrodesStim, TherapyElectrodes therapyElectrodes, TherapyGroup therapyGroup, AmplitudeLimits ampLimits, double rateValue, double ampValue, int pwValue) { PulseWidth = pulsewidth; StimRate = stimrate; StimAmp = stimamp; StimElectrodes = electrodesStim; TherapyElectrodes = therapyElectrodes; TherapyGroup = therapyGroup; AmpLimits = ampLimits; StimAmpValue = ampValue; StimRateValue = rateValue; PulseWidthValue = pwValue; }
/// <summary> /// Finds the electrodes that are stimming /// </summary> /// <param name="therapyGroup">therapy group from the ins call</param> /// <param name="program">program number 0-3</param> /// <returns>Returns the contacts that are stimming along with anode or cathode</returns> public string FindStimElectrodes(TherapyGroup therapyGroup, int program) { string electrodesStimming = ""; if (therapyGroup.Valid) { if (therapyGroup.Programs[program].Valid) { for (int i = 0; i < 17; i++) { if (!therapyGroup.Programs[program].Electrodes[i].IsOff) { //Case is 16 so it gets a C. Otherwise give the number if (i == 16) { electrodesStimming += "C"; } else { electrodesStimming += i.ToString(); } // What type of electrode is it? switch (therapyGroup.Programs[program].Electrodes[i].ElectrodeType) { case ElectrodeTypes.Cathode: electrodesStimming += "-"; break; case ElectrodeTypes.Anode: electrodesStimming += "+"; break; default: break; } } } } } return(electrodesStimming); }
/// <summary> /// Sweep through all the indicated stimulation amplitudes, pulse widths, and frequencies. If stimulation engine failure flag is raised, or if user /// pushes quit button, the sweep is aborted. /// </summary> public bool Sweep() { bool sweepAborted = false; //go through each parameter, put thier number of values, stim stop, and pause durations in the right order List <int> numValues = new List <int>() { 0, 0, 0 }; List <int> pauseDurations = new List <int>() { 0, 0, 0 }; List <int> maxIters = new List <int>(2); for (int iLevel = 0; iLevel < m_sweepParameters.paramOrder.Count; iLevel++) { numValues[m_sweepParameters.paramOrder[iLevel]] = m_sweepParameters.paramNumValues[iLevel]; pauseDurations[m_sweepParameters.paramOrder[iLevel]] = m_sweepParameters.paramPauseDurationMilliSeconds[iLevel]; } //initialize current values if (!SummitUtils.CheckCurrentStimParameters(m_summit, m_groupNum, 0, out m_currentAmp, out m_currentPulseWidth, out m_currentFreq)) { sweepAborted = true; return(sweepAborted); } //bring pulse width and freq to starting values: if (m_currentAmp != 0) { //amp should be 0 so there will be no stimulation when setting pw and freq. Set to 0 if it's not. Console.WriteLine(String.Format("Sweep initialzation amplitude should be 0, but it's {0}! Cannot do stim sweep", m_currentAmp)); return(sweepAborted = true); } m_summitInfo = m_summit.StimChangeTherapyOn(); // Reset POR if set if (m_summitInfo.RejectCodeType == typeof(MasterRejectCode) && (MasterRejectCode)m_summitInfo.RejectCode == MasterRejectCode.ChangeTherapyPor) { // Inform user Console.WriteLine("POR set, resetting..."); // Reset POR m_summitInfo = SummitUtils.resetPOR(m_summit); } Thread.Sleep(1000); try { ResetSweep(); } catch { sweepAborted = true; return(sweepAborted); } //initialize a counter to 0's for the number of values we've already sweeped across for each parameter List <int> iterCounter = new List <int> { 0, 0, 0 }; int iParameter, iAmp = 0, iPW = 0, iFreq = 0; //make a listener thread to check for terminations Thread stopListenerThread = new Thread(StopSweepListener); //start stimulation by bringing amp to first value m_sweepFinished = false; m_summitInfo = m_summit.StimChangeStepAmp(0, m_sweepParameters.ampValues[0], out m_currentAmp); if (m_summitInfo.RejectCode != 0) { Console.WriteLine("Error when increasing stimulation amplitude to " + m_sweepParameters.ampValues[iAmp] + "mA. Error descriptor:" + m_summitInfo.Descriptor); if (!SummitUtils.CheckCurrentStimParameters(m_summit, m_groupNum, 0, out m_currentAmp, out m_currentPulseWidth, out m_currentFreq)) { sweepAborted = true; return(sweepAborted); } } Console.WriteLine("Sweep started at: " + m_currentAmp + "mA , " + m_currentPulseWidth + "us pulse width, and " + m_currentFreq + " Hz"); stopListenerThread.Start(); Thread.Sleep(m_sweepParameters.permutationDuration); //now do iteration by increasing the counter for each parameter (until all the parameter's value's have all been iterated across) while (iterCounter[0] < (numValues[0] - 1) || iterCounter[1] < (numValues[1] - 1) || iterCounter[2] < (numValues[2] - 1)) { //First do check here to see if the sweep has been stopped (either quit key has been pressed or stim engine out of range flag has been set) if (m_stopSweep) { Console.WriteLine("Stimulation Sweep Aborted"); sweepAborted = true; break; } if (iterCounter[0] < (numValues[0] - 1)) { try { //we're at innermost parameter IntraSweepPause(pauseDurations[0]); iterCounter[0]++; iParameter = 0; } catch { sweepAborted = true; return(sweepAborted); } } else if (iterCounter[1] < (numValues[1] - 1)) { //we're at the middle parameter try { IntraSweepPause(pauseDurations[1]); iterCounter[1]++; iParameter = 1; //reset innermost parameter ResetParameter(0, ref iAmp, ref iPW, ref iFreq); iterCounter[0] = 0; } catch { sweepAborted = true; return(sweepAborted); } Console.WriteLine(); } else { try { //we're at the outermost parameter IntraSweepPause(pauseDurations[2]); iterCounter[2]++; iParameter = 2; //reset innermost and middle parameter ResetParameter(0, ref iAmp, ref iPW, ref iFreq); ResetParameter(1, ref iAmp, ref iPW, ref iFreq); iterCounter[0] = 0; iterCounter[1] = 0; } catch { sweepAborted = true; return(sweepAborted); } Console.WriteLine(); } // increment the parameter we're at in the sweep if (iParameter == m_sweepParameters.ampOrder) { //increase stim amp iAmp++; m_summitInfo = m_summit.StimChangeStepAmp(0, Math.Round(m_sweepParameters.ampValues[iAmp] - m_currentAmp.Value, 1), out m_currentAmp); if (m_summitInfo.RejectCode != 0) { Console.WriteLine("Error when increasing stimulation amplitude to " + m_sweepParameters.ampValues[iAmp] + "mA. Error descriptor:" + m_summitInfo.Descriptor); if (!SummitUtils.CheckCurrentStimParameters(m_summit, m_groupNum, 0, out m_currentAmp, out m_currentPulseWidth, out m_currentFreq)) { sweepAborted = true; return(sweepAborted); } } Console.WriteLine("Increased amplitude to " + m_currentAmp + "mA"); m_stimPaused = false; Thread.Sleep(m_sweepParameters.permutationDuration); } else if (iParameter == m_sweepParameters.pulseWidthOrder) { //increase pulse duration iPW++; m_summitInfo = m_summit.StimChangeStepPW(0, m_sweepParameters.pulseWidthValues[iPW] - m_currentPulseWidth.Value, out m_currentPulseWidth); if (m_summitInfo.RejectCode != 0) { Console.WriteLine("Error when increasing stimulation pulse width to " + m_sweepParameters.pulseWidthValues[iPW] + "us. Error descriptor:" + m_summitInfo.Descriptor); if (!SummitUtils.CheckCurrentStimParameters(m_summit, m_groupNum, 0, out m_currentAmp, out m_currentPulseWidth, out m_currentFreq)) { sweepAborted = true; return(sweepAborted); } } Console.WriteLine("Increased pulse width to " + m_currentPulseWidth + "us"); //bring stimulation back, if it was turned off for pause if (m_stimPaused) { m_summitInfo = m_summit.StimChangeStepAmp(0, m_prePauseAmp, out m_currentAmp); if (m_summitInfo.RejectCode != 0) { Console.WriteLine("Error when increasing stimulation amplitude back after pulse width increase. Error descriptor:" + m_summitInfo.Descriptor); if (!SummitUtils.CheckCurrentStimParameters(m_summit, m_groupNum, 0, out m_currentAmp, out m_currentPulseWidth, out m_currentFreq)) { sweepAborted = true; return(sweepAborted); } } m_stimPaused = false; } Thread.Sleep(m_sweepParameters.permutationDuration); } else if (iParameter == m_sweepParameters.freqOrder) { //increase frequency iFreq++; m_summitInfo = m_summit.StimChangeStepFrequency(Math.Round(m_sweepParameters.freqValues[iFreq] - m_currentFreq.Value, 1), false, out m_currentFreq); if (m_summitInfo.RejectCode != 0) { Console.WriteLine("Error when increasing stimulation frequency to " + m_sweepParameters.freqValues[iFreq] + "Hz. Error descriptor:" + m_summitInfo.Descriptor); if (!SummitUtils.CheckCurrentStimParameters(m_summit, m_groupNum, 0, out m_currentAmp, out m_currentPulseWidth, out m_currentFreq)) { sweepAborted = true; return(sweepAborted); } } Console.WriteLine("Increased frequency to " + m_currentFreq + "Hz"); //bring stimulation back, if it was turned off for pause if (m_stimPaused) { m_summitInfo = m_summit.StimChangeStepAmp(0, m_prePauseAmp, out m_currentAmp); if (m_summitInfo.RejectCode != 0) { Console.WriteLine("Error when increasing stimulation amplitude back after frequency increase. Error descriptor:" + m_summitInfo.Descriptor); if (!SummitUtils.CheckCurrentStimParameters(m_summit, m_groupNum, 0, out m_currentAmp, out m_currentPulseWidth, out m_currentFreq)) { sweepAborted = true; return(sweepAborted); } } m_stimPaused = false; } Thread.Sleep(m_sweepParameters.permutationDuration); } //just call some function to interragate INS to allow any OOR info to arrive (add 100 ms sleep to all time for setting the abort flags) TherapyGroup groupInfo = new TherapyGroup(); m_summit.ReadStimGroup(m_groupNum, out groupInfo); Thread.Sleep(100); } //ok sweep finished, reset all parametrs and flags, and join listener thread m_stimOutOfRangeFlag = false; try { ResetSweep(); } catch { sweepAborted = true; return(sweepAborted); } //turn therapy off m_summit.StimChangeTherapyOff(false); m_sweepFinished = true; stopListenerThread.Join(); m_stopSweep = false; return(sweepAborted); }
/// <summary> /// Gets the stim parameters based on group from the actual API /// </summary> /// <param name="theSummit">SummitSystem for making the API call to INS</param> /// <param name="groupNumber">Group number corresponding to which group we want to get stim parameters from such as Group0, Group1, etc</param> /// <returns>StimParameterModel that contains stim amp, stim rate and pulse width</returns> private StimParameterModel GetStimParameterModel(SummitSystem theSummit, GroupNumber groupNumber, int program) { if (theSummit == null || theSummit.IsDisposed) { return(null); } TherapyGroup insStateGroup = null; AmplitudeLimits ampLimits = null; try { int counter = 5; do { bufferInfo = theSummit.ReadStimGroup(groupNumber, out insStateGroup); counter--; } while ((insStateGroup == null || bufferInfo.RejectCode != 0) && counter > 0); if (bufferInfo.RejectCode != 0 && counter == 0) { _log.Warn("Could not read stim group from Medtronic api call"); } } catch (Exception e) { _log.Error(e); } try { int counter = 5; do { bufferInfo = theSummit.ReadStimAmplitudeLimits(groupNumber, out ampLimits); counter--; } while ((insStateGroup == null || bufferInfo.RejectCode != 0) && counter > 0); if (bufferInfo.RejectCode != 0 && counter == 0) { _log.Warn("Could not read amp limits from Medtronic api call"); } } catch (Exception e) { _log.Error(e); } int pulseWidthValue = -1; double rateValue = -1; double ampValue = -1; try { //parse the data to get the pulsewidth if (insStateGroup != null) { pulseWidth = insStateGroup.Programs[program].PulseWidthInMicroseconds.ToString(); stimRate = insStateGroup.RateInHz.ToString(); stimAmp = insStateGroup.Programs[program].AmplitudeInMilliamps.ToString(); stimElectrode = FindStimElectrodes(insStateGroup, program); electrodes = insStateGroup?.Programs[program]?.Electrodes; pulseWidthValue = insStateGroup.Programs[program].PulseWidthInMicroseconds; rateValue = insStateGroup.RateInHz; ampValue = insStateGroup.Programs[program].AmplitudeInMilliamps; } } catch (Exception e) { _log.Error(e); } //Set the Model with these values and return model if (rateValue == -1 || ampValue == -1 || pulseWidthValue == -1) { StimParameterModel StimParameterModel = new StimParameterModel(pulseWidth, stimRate, stimAmp, stimElectrode, electrodes, insStateGroup, ampLimits); return(StimParameterModel); } else { StimParameterModel StimParameterModel = new StimParameterModel(pulseWidth, stimRate, stimAmp, stimElectrode, electrodes, insStateGroup, ampLimits, rateValue, ampValue, pulseWidthValue); return(StimParameterModel); } }