/// <summary> /// This maybe should go into a different class like Stimulation.cs, but it's here for now. ///It gets the group stim params based on the group that was read from the device. ///if Group b was read from the device, then it gets the params for that specific group. /// </summary> /// <param name="theSummit">Summit System</param> /// <param name="group">Active Group after being converted: Group A, Group B, Group C, Group D</param> /// <param name="program">program 0-3</param> /// <returns>StimParameterModel filled with data</returns> public StimParameterModel GetStimParamsBasedOnGroup(SummitSystem theSummit, string group, int program) { StimParameterModel stimParam = new StimParameterModel("Error", "Error", "Error", "Error", null); if (string.IsNullOrEmpty(group)) { return(stimParam); } switch (group) { case "Group A": stimParam = GetStimParameterModel(theSummit, GroupNumber.Group0, program); break; case "Group B": stimParam = GetStimParameterModel(theSummit, GroupNumber.Group1, program); break; case "Group C": stimParam = GetStimParameterModel(theSummit, GroupNumber.Group2, program); break; case "Group D": stimParam = GetStimParameterModel(theSummit, GroupNumber.Group3, program); break; default: break; } return(stimParam); }
public MontageViewModel(ref SummitSystem theSummitLeft, ref SummitSystem theSummitRight, ILog _log, AppModel appModel) { this.theSummitLeft = theSummitLeft; this.theSummitRight = theSummitRight; this.isBilateral = appModel.Bilateral; this._log = _log; this.appModel = appModel; IsMontageEnabled = true; summitSensing = new SummitSensing(_log); jSONService = new JSONService(_log); stimParameterLeft = new StimParameterModel("", "", "", "", null); stimParameterRight = new StimParameterModel("", "", "", "", null); montageModel = jSONService.GetMontageModelFromFile(MONTAGE_FILEPATH); if (montageModel == null) { MessageBox.Show("The montage config file could not be read from the file. Please check that it exists.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return; } montageSweepConfigListLeft = montageSweepConfigListRight = LoadSenseJSONFilesForMontage(MONTAGE_BASEFILEPATH, MONTAGE_FILETYPE, montageModel); if (montageSweepConfigListLeft == null || montageSweepConfigListRight == null) { IsMontageEnabled = false; return; } //Get total time left and total time for montage. Display on progress bar timeLeftForMontage = totalTimeForMontage = GetTotalTimeForMontage(montageModel); TimeSpan time = TimeSpan.FromSeconds(timeLeftForMontage); //here backslash is must to tell that colon is //not the part of format, it just a character that we want in output string str = time.ToString(@"hh\:mm\:ss"); MontageTimeTextBox = "Total Montage Time: " + str; InstructionsTextBox = montageModel?.Instructions; }
private void MontageRightThreadCode() { APIReturnInfo rightBufferReturnInfo; int counter; if (theSummitRight == null) { MessageBox.Show("The summit system is null. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } if (_stopBothThreads) { return; } if (theSummitRight.IsDisposed) { MessageBox.Show("The summit system is disposed. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } if (_stopBothThreads) { return; } try { //Make sure embedded therapy is turned off while setting up parameters //try it 5 times before error out counter = 5; while (counter > 0) { //Make sure embedded therapy is turned off while setting up parameters rightBufferReturnInfo = theSummitRight.WriteAdaptiveMode(AdaptiveTherapyModes.Disabled); if (rightBufferReturnInfo.RejectCode != 0) { counter--; Thread.Sleep(300); } else { break; } if (_stopBothThreads) { return; } } if (counter == 0) { MessageBox.Show("Could not turn off adaptive therapy. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } } catch (Exception e) { MessageBox.Show("Could not turn off adaptive therapy. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _log.Error(e); _stopBothThreads = true; } if (_stopBothThreads) { return; } //Check if therapy active. If so, then check if 0-3 contacts stimming //if so, then change lfp1 and lfp2 to 100 for each time domain 0 and 1 bool shouldChangeLfp1andLfp2to100 = false; bool shouldChangeLfp1andLfp2to100ForUpper = false; SummitStimulationInfo stimInfoRight = new SummitStimulationInfo(_log); if (stimInfoRight.GetTherapyStatus(ref theSummitRight).Equals("TherapyActive")) { StimParameterModel localStimModel = new StimParameterModel("", "", "", "", null); localStimModel = stimInfoRight.GetStimParamsBasedOnGroup(theSummitRight, stimInfoRight.GetActiveGroup(ref theSummitRight), 0); for (int i = 0; i < 4; i++) { if (!localStimModel.TherapyElectrodes[i].IsOff) { shouldChangeLfp1andLfp2to100 = true; } } for (int i = 8; i < 12; i++) { if (!localStimModel.TherapyElectrodes[i].IsOff) { shouldChangeLfp1andLfp2to100ForUpper = true; } } } int montageIndex = 0; foreach (SenseModel localSenseModel in montageSweepConfigListRight) { if (shouldChangeLfp1andLfp2to100) { localSenseModel.Sense.TimeDomains[0].Lpf1 = 100; localSenseModel.Sense.TimeDomains[0].Lpf2 = 100; localSenseModel.Sense.TimeDomains[1].Lpf1 = 100; localSenseModel.Sense.TimeDomains[1].Lpf2 = 100; } if (shouldChangeLfp1andLfp2to100ForUpper) { localSenseModel.Sense.TimeDomains[2].Lpf1 = 100; localSenseModel.Sense.TimeDomains[2].Lpf2 = 100; localSenseModel.Sense.TimeDomains[3].Lpf1 = 100; localSenseModel.Sense.TimeDomains[3].Lpf2 = 100; } if (_stopBothThreads) { return; } //stop/configure sensing. Try for 5 times before error out counter = 5; while (counter > 0) { if (summitSensing.SummitConfigureSensing(theSummitRight, localSenseModel, false)) { break; } else { counter--; Thread.Sleep(300); } if (_stopBothThreads) { return; } } if (counter == 0) { MessageBox.Show("Could not configure sensing. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } if (_stopBothThreads) { return; } //start sensing. Try for 5 times before error out counter = 5; while (counter > 0) { if (summitSensing.StartSensingAndStreaming(theSummitRight, localSenseModel, false)) { break; } else { counter--; Thread.Sleep(300); } if (_stopBothThreads) { return; } } if (counter == 0) { MessageBox.Show("Could not start sensing. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } if (_stopBothThreads) { return; } //Set timer to run for timeToRun amount int timeToRunForCurrentMontage = montageModel.MontageFiles[montageIndex].TimeToRunInSeconds; int timeMarkerToAddEvent = timeToRunForCurrentMontage - TIME_BEFORE_BEGIN_END_MONTAGE; bool startTimeHasRun = false; bool stopTimeHasRun = false; while (timeToRunForCurrentMontage > 0) { if (timeMarkerToAddEvent == timeToRunForCurrentMontage && !startTimeHasRun) { try { //try once and if fails then try one more time rightBufferReturnInfo = theSummitRight.LogCustomEvent(DateTime.Now, DateTime.Now, "Start : " + montageModel.MontageFiles[montageIndex].Filename, DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); if (rightBufferReturnInfo.RejectCode == 0) { startTimeHasRun = true; } else { rightBufferReturnInfo = theSummitRight.LogCustomEvent(DateTime.Now, DateTime.Now, "Start : " + montageModel.MontageFiles[montageIndex].Filename, DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); startTimeHasRun = true; } } catch (Exception e) { _log.Error(e); } } if (timeToRunForCurrentMontage == TIME_BEFORE_BEGIN_END_MONTAGE && !stopTimeHasRun) { try { //try once and if fails then try one more time rightBufferReturnInfo = theSummitRight.LogCustomEvent(DateTime.Now, DateTime.Now, "Stop : " + montageModel.MontageFiles[montageIndex].Filename, DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); if (rightBufferReturnInfo.RejectCode == 0) { stopTimeHasRun = true; } else { rightBufferReturnInfo = theSummitRight.LogCustomEvent(DateTime.Now, DateTime.Now, "Stop : " + montageModel.MontageFiles[montageIndex].Filename, DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); stopTimeHasRun = true; } } catch (Exception e) { _log.Error(e); } } if (_stopBothThreads) { return; } timeToRunForCurrentMontage--; Thread.Sleep(1000); } montageIndex++; } rightFinished = true; while (true) { if (leftFinished) { break; } } }
private void MontageLeftThreadCode() { APIReturnInfo leftBufferReturnInfo; int counter; if (theSummitLeft == null) { MessageBox.Show("The summit system is null. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } if (_stopBothThreads) { return; } try { if (theSummitLeft.IsDisposed) { MessageBox.Show("The summit system is disposed. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } } catch (Exception e) { _log.Error(e); _stopBothThreads = true; } if (_stopBothThreads) { return; } try { //Make sure embedded therapy is turned off while setting up parameters //try it 5 times before error out counter = 5; while (counter > 0) { leftBufferReturnInfo = theSummitLeft.WriteAdaptiveMode(AdaptiveTherapyModes.Disabled); if (leftBufferReturnInfo.RejectCode != 0) { counter--; Thread.Sleep(300); } else { break; } } if (counter == 0) { MessageBox.Show("Could not turn off adaptive therapy. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } } catch (Exception e) { MessageBox.Show("Could not turn off adaptive therapy. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _log.Error(e); _stopBothThreads = true; } if (_stopBothThreads) { return; } //Check if therapy active. If so, then check if 0-3 contacts stimming //if so, then change lfp1 and lfp2 to 100 for each time domain 0 and 1 bool shouldChangeLfp1andLfp2to100ForLower = false; bool shouldChangeLfp1andLfp2to100ForUpper = false; SummitStimulationInfo stimInfoLeft = new SummitStimulationInfo(_log); if (stimInfoLeft.GetTherapyStatus(ref theSummitLeft).Equals("TherapyActive")) { StimParameterModel localStimModel = new StimParameterModel("", "", "", "", null); localStimModel = stimInfoLeft.GetStimParamsBasedOnGroup(theSummitLeft, stimInfoLeft.GetActiveGroup(ref theSummitLeft), 0); for (int i = 0; i < 4; i++) { if (!localStimModel.TherapyElectrodes[i].IsOff) { shouldChangeLfp1andLfp2to100ForLower = true; } } for (int i = 8; i < 12; i++) { if (!localStimModel.TherapyElectrodes[i].IsOff) { shouldChangeLfp1andLfp2to100ForUpper = true; } } } int montageIndex = 0; foreach (SenseModel localSenseModel in montageSweepConfigListLeft) { if (shouldChangeLfp1andLfp2to100ForLower) { localSenseModel.Sense.TimeDomains[0].Lpf1 = 100; localSenseModel.Sense.TimeDomains[0].Lpf2 = 100; localSenseModel.Sense.TimeDomains[1].Lpf1 = 100; localSenseModel.Sense.TimeDomains[1].Lpf2 = 100; } if (shouldChangeLfp1andLfp2to100ForUpper) { localSenseModel.Sense.TimeDomains[2].Lpf1 = 100; localSenseModel.Sense.TimeDomains[2].Lpf2 = 100; localSenseModel.Sense.TimeDomains[3].Lpf1 = 100; localSenseModel.Sense.TimeDomains[3].Lpf2 = 100; } if (_stopBothThreads) { return; } //stop/configure sensing. Try for 5 times before error out counter = 5; while (counter > 0) { if (summitSensing.SummitConfigureSensing(theSummitLeft, localSenseModel, false)) { break; } else { counter--; Thread.Sleep(300); } if (_stopBothThreads) { return; } } if (counter == 0) { MessageBox.Show("Could not configure sensing. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } if (_stopBothThreads) { return; } //start sensing. Try for 5 times before error out counter = 5; while (counter > 0) { if (summitSensing.StartSensingAndStreaming(theSummitLeft, localSenseModel, false)) { break; } else { counter--; Thread.Sleep(300); } if (_stopBothThreads) { return; } } if (counter == 0) { MessageBox.Show("Could not start sensing. Please try montage again", "Error", MessageBoxButton.OK, MessageBoxImage.Error); _stopBothThreads = true; } if (_stopBothThreads) { return; } //Set timer to run for timeToRun amount int timeToRunForCurrentMontage = montageModel.MontageFiles[montageIndex].TimeToRunInSeconds; int timeMarkerToAddEvent = timeToRunForCurrentMontage - TIME_BEFORE_BEGIN_END_MONTAGE; bool startTimeHasRun = false; bool stopTimeHasRun = false; while (timeToRunForCurrentMontage > 0) { if (timeToRunForCurrentMontage == timeMarkerToAddEvent && !startTimeHasRun) { try { //try once and if fails then try one more time leftBufferReturnInfo = theSummitLeft.LogCustomEvent(DateTime.Now, DateTime.Now, "Start : " + montageModel.MontageFiles[montageIndex].Filename, DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); if (leftBufferReturnInfo.RejectCode == 0) { startTimeHasRun = true; } else { leftBufferReturnInfo = theSummitLeft.LogCustomEvent(DateTime.Now, DateTime.Now, "Start : " + montageModel.MontageFiles[montageIndex].Filename, DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); startTimeHasRun = true; } } catch (Exception e) { _log.Error(e); } } if (timeToRunForCurrentMontage == TIME_BEFORE_BEGIN_END_MONTAGE && !stopTimeHasRun) { try { //try once and if fails then try one more time leftBufferReturnInfo = theSummitLeft.LogCustomEvent(DateTime.Now, DateTime.Now, "Stop : " + montageModel.MontageFiles[montageIndex].Filename, DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); if (leftBufferReturnInfo.RejectCode == 0) { stopTimeHasRun = true; } else { leftBufferReturnInfo = theSummitLeft.LogCustomEvent(DateTime.Now, DateTime.Now, "Stop : " + montageModel.MontageFiles[montageIndex].Filename, DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); stopTimeHasRun = true; } } catch (Exception e) { _log.Error(e); } } if (_stopBothThreads) { return; } timeToRunForCurrentMontage--; int precentageDoneForTotalMontage = 100 - (int)Math.Round((double)(100 * timeLeftForMontage) / totalTimeForMontage); timeLeftForMontage--; CurrentProgress = precentageDoneForTotalMontage; TimeSpan time = TimeSpan.FromSeconds(timeLeftForMontage); //here backslash is must to tell that colon is //not the part of format, it just a character that we want in output string str = time.ToString(@"hh\:mm\:ss"); ProgressText = str + " time left"; Thread.Sleep(1000); } ProgressText = "Loading next montage file..."; montageIndex++; } ProgressText = "Finishing up..."; leftFinished = true; while (true) { if (rightFinished) { try { theSummitLeft.LogCustomEvent(DateTime.Now, DateTime.Now, "Montage Stop", DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); if (isBilateral) { theSummitRight.LogCustomEvent(DateTime.Now, DateTime.Now, "Montage Stop", DateTime.Now.ToString("MM_dd_yyyy hh:mm:ss tt")); } } catch (Exception e) { _log.Error(e); MessageBox.Show("Could not log stop event.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } ProgressText = "Success"; MessageBox.Show("Montage Successful. Report Screen will open after clicking OK.", "Success", MessageBoxButton.OK, MessageBoxImage.Information); CancelMontageButtonClick(); break; } } }
/// <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); } }