/// <summary> /// Gets the power band bins and actual hz values. Program shuts down if can't compute /// </summary> /// <param name="localModel">SenseModel</param> /// <returns>List of PowerBandModel class</returns> public List <PowerBandModel> GetPowerBands(SenseModel localModel) { List <PowerBandModel> powerBandsList = new List <PowerBandModel>(); try { CalculateFFTBins(ConfigConversions.FftSizesConvert(localModel.Sense.FFT.FftSize), ConfigConversions.TDSampleRateConvert(localModel.Sense.TDSampleRate)); binWidth = bins[1] - bins[0]; CalculateUpperBins(); CalculateLowerBins(); } catch (Exception e) { HandleException(e); } for (int i = 0; i < 8;) { try { PowerBandModel powerBandModel = new PowerBandModel(); //Gets the lower index value and upper index value based from the config file value. powerBandModel.lowerIndexBand0 = GetLowerIndex(localModel.Sense.PowerBands[i].ChannelPowerBand[0]); powerBandModel.upperIndexBand0 = GetUpperIndex(localModel.Sense.PowerBands[i].ChannelPowerBand[1]); //This checks to make sure that the upper power bin index is bigger than the lower; cannot have upper index that is less than lower index //if the upper index value is not bigger than the lower, then the upper index is set to lower index for error handling powerBandModel.upperIndexBand0 = CheckThatUpperPowerBandGreaterThanLowerPowerBand(powerBandModel.lowerIndexBand0, powerBandModel.upperIndexBand0); //Actual lower and upper power values are calculated from the users estimated power values from the config file //This is done in the CalculatePowerBins class. Below saves the actual lower and upper power values in each array to 2 decimal places. //These arrays are instantiated in MainViewModel.cs powerBandModel.lowerActualValueHzBand0 = Math.Round(ActualLowerPowerValue, 2); powerBandModel.UpperActualValueHzBand0 = Math.Round(ActualUpperPowerValue, 2); //increment i so that the next power band can be set. There are 8 (0-7). There are 4 power channels (0-3); i++; //Repeat this step for next power band powerBandModel.lowerIndexBand1 = GetLowerIndex(localModel.Sense.PowerBands[i].ChannelPowerBand[0]); powerBandModel.upperIndexBand1 = GetUpperIndex(localModel.Sense.PowerBands[i].ChannelPowerBand[1]); powerBandModel.upperIndexBand1 = CheckThatUpperPowerBandGreaterThanLowerPowerBand(powerBandModel.lowerIndexBand1, powerBandModel.upperIndexBand1); powerBandModel.lowerActualValueHzBand1 = Math.Round(ActualLowerPowerValue, 2); powerBandModel.upperActualValueHzBand1 = Math.Round(ActualUpperPowerValue, 2); i++; powerBandsList.Add(powerBandModel); } catch (Exception e) { HandleException(e); } } return(powerBandsList); }
/// <summary> /// Write Sense Configuration Settings /// </summary> /// <param name="localModel">The config file to use for sensing parameters</param> /// <param name="theSummit">Summit system</param> /// <param name="showErrorMessage">True if you want a popup message on errors or false if show no error popup</param> /// <returns>true if successfully configuring sensing or false if unsuccessful</returns> public bool SummitConfigureSensing(SummitSystem theSummit, SenseModel localModel, bool showErrorMessage) { APIReturnInfo bufferReturnInfo; //This checks to see if sensing is already enabled. This can happen if adaptive is already running and we don't need to configure it. //If it is, then skip setting up sensing if (CheckIsAdaptiveRunning(theSummit)) { return(true); } int counter = 5; while (counter > 0) { if (StopSensing(theSummit, showErrorMessage)) { break; } else { _log.Warn("Could not stop sensing before configure sensing. Trying again..."); counter--; Thread.Sleep(500); } } if (counter == 0) { _log.Warn("Could not stop sensing before configure sensing. Returning false"); return(false); } // Create a sensing configuration List <TimeDomainChannel> TimeDomainChannels = new List <TimeDomainChannel>(4); // Channel Specific configuration - 0 TimeDomainChannels.Add(new TimeDomainChannel( GetTDSampleRate(localModel.Sense.TimeDomains[0].IsEnabled, localModel), ConfigConversions.TdMuxInputsConvert(localModel.Sense.TimeDomains[0].Inputs[0]), ConfigConversions.TdMuxInputsConvert(localModel.Sense.TimeDomains[0].Inputs[1]), ConfigConversions.TdEvokedResponseEnableConvert(localModel.Sense.TimeDomains[0].TdEvokedResponseEnable), ConfigConversions.TdLpfStage1Convert(localModel.Sense.TimeDomains[0].Lpf1), ConfigConversions.TdLpfStage2Convert(localModel.Sense.TimeDomains[0].Lpf2), ConfigConversions.TdHpfsConvert(localModel.Sense.TimeDomains[0].Hpf))); // Channel Specific configuration - 1 TimeDomainChannels.Add(new TimeDomainChannel( GetTDSampleRate(localModel.Sense.TimeDomains[1].IsEnabled, localModel), ConfigConversions.TdMuxInputsConvert(localModel.Sense.TimeDomains[1].Inputs[0]), ConfigConversions.TdMuxInputsConvert(localModel.Sense.TimeDomains[1].Inputs[1]), ConfigConversions.TdEvokedResponseEnableConvert(localModel.Sense.TimeDomains[1].TdEvokedResponseEnable), ConfigConversions.TdLpfStage1Convert(localModel.Sense.TimeDomains[1].Lpf1), ConfigConversions.TdLpfStage2Convert(localModel.Sense.TimeDomains[1].Lpf2), ConfigConversions.TdHpfsConvert(localModel.Sense.TimeDomains[1].Hpf))); // Channel Specific configuration - 2 TimeDomainChannels.Add(new TimeDomainChannel( GetTDSampleRate(localModel.Sense.TimeDomains[2].IsEnabled, localModel), ConfigConversions.TdMuxInputsConvert(localModel.Sense.TimeDomains[2].Inputs[0]), ConfigConversions.TdMuxInputsConvert(localModel.Sense.TimeDomains[2].Inputs[1]), ConfigConversions.TdEvokedResponseEnableConvert(localModel.Sense.TimeDomains[2].TdEvokedResponseEnable), ConfigConversions.TdLpfStage1Convert(localModel.Sense.TimeDomains[2].Lpf1), ConfigConversions.TdLpfStage2Convert(localModel.Sense.TimeDomains[2].Lpf2), ConfigConversions.TdHpfsConvert(localModel.Sense.TimeDomains[2].Hpf))); // Channel Specific configuration - 3 TimeDomainChannels.Add(new TimeDomainChannel( GetTDSampleRate(localModel.Sense.TimeDomains[3].IsEnabled, localModel), ConfigConversions.TdMuxInputsConvert(localModel.Sense.TimeDomains[3].Inputs[0]), ConfigConversions.TdMuxInputsConvert(localModel.Sense.TimeDomains[3].Inputs[1]), ConfigConversions.TdEvokedResponseEnableConvert(localModel.Sense.TimeDomains[3].TdEvokedResponseEnable), ConfigConversions.TdLpfStage1Convert(localModel.Sense.TimeDomains[3].Lpf1), ConfigConversions.TdLpfStage2Convert(localModel.Sense.TimeDomains[3].Lpf2), ConfigConversions.TdHpfsConvert(localModel.Sense.TimeDomains[3].Hpf))); // Set up the FFT FftConfiguration fftChannel = new FftConfiguration( ConfigConversions.FftSizesConvert(localModel.Sense.FFT.FftSize), localModel.Sense.FFT.FftInterval, ConfigConversions.FftWindowAutoLoadsConvert(localModel.Sense.FFT.WindowLoad), localModel.Sense.FFT.WindowEnabled, ConfigConversions.FftWeightMultipliesConvert(localModel.Sense.FFT.WeightMultiplies), localModel.Sense.FFT.StreamSizeBins, localModel.Sense.FFT.StreamOffsetBins); // Set up the Power channels List <PowerChannel> powerChannels = new List <PowerChannel>(); //This goes through each power channel and gets the lower power band and upper power band. //Medtronic api uses bin index values for setting power channels instead of actual values in Hz //This calls the CalculatePowerBins class to convert to proper medtronic api values from the user config file //User config file has estimated values in Hz for each channel. //CalculatePowerBins converts them to actual power values and we are able to get the bin index value from that. CalculatePowerBins calculatePowerBins = new CalculatePowerBins(_log); List <PowerBandModel> powerBandsList = calculatePowerBins.GetPowerBands(localModel); if (powerBandsList == null || powerBandsList.Count < 3) { MessageBox.Show("Error calculating power bins. Please check that power bins are correct in the config file and try again.", "Error", MessageBoxButton.OK, MessageBoxImage.Hand); return(false); } for (int i = 0; i < 4; i++) { //Add the lower and upper power bands to the power channel powerChannels.Add(new PowerChannel(powerBandsList[i].lowerIndexBand0, powerBandsList[i].upperIndexBand0, powerBandsList[i].lowerIndexBand1, powerBandsList[i].upperIndexBand1)); } //Gets the enabled power bands from the sense config file and returns the correct api call for all enabled BandEnables theBandEnables = ConfigConversions.PowerBandEnablesConvert(localModel); // Set up the miscellaneous settings MiscellaneousSensing miscsettings = new MiscellaneousSensing(); miscsettings.StreamingRate = ConfigConversions.MiscStreamRateConvert(localModel.Sense.Misc.StreamingRate); miscsettings.LrTriggers = ConfigConversions.MiscloopRecordingTriggersConvert(localModel.Sense.Misc.LoopRecordingTriggersState, localModel.Sense.Misc.LoopRecordingTriggersIsEnabled); miscsettings.LrPostBufferTime = localModel.Sense.Misc.LoopRecordingPostBufferTime; miscsettings.Bridging = ConfigConversions.MiscBridgingConfigConvert(localModel.Sense.Misc.Bridging); //Writes all sensing information here try { bufferReturnInfo = theSummit.WriteSensingTimeDomainChannels(TimeDomainChannels); if (!CheckForReturnError(bufferReturnInfo, "Writing Sensing Time Domain", showErrorMessage)) { return(false); } bufferReturnInfo = theSummit.WriteSensingFftSettings(fftChannel); if (!CheckForReturnError(bufferReturnInfo, "Writing Sensing FFT", showErrorMessage)) { return(false); } bufferReturnInfo = theSummit.WriteSensingPowerChannels(theBandEnables, powerChannels); if (!CheckForReturnError(bufferReturnInfo, "Writing Sensing Power", showErrorMessage)) { return(false); } bufferReturnInfo = theSummit.WriteSensingMiscSettings(miscsettings); if (!CheckForReturnError(bufferReturnInfo, "Writing Sensing Misc", showErrorMessage)) { return(false); } bufferReturnInfo = theSummit.WriteSensingAccelSettings(ConfigConversions.AccelSampleRateConvert(localModel.Sense.Accelerometer.SampleRate, localModel.Sense.Accelerometer.SampleRateDisabled)); if (!CheckForReturnError(bufferReturnInfo, "Writing Sensing Accel", showErrorMessage)) { return(false); } } catch (Exception error) { _log.Error(error); return(false); } return(true); }