Esempio n. 1
0
        /// <summary>
        /// After the channel models (gmm's) have been created and trained, this function
        /// is used to classifty newly detected spikes for which a valide channel model exisits.
        /// </summary>
        /// <param name="newSpikes"> An EventBuffer conataining spikes to be classified</param>
        public void Classify(ref EventBuffer <SpikeEvent> newSpikes)
        {
            // Make sure the channel models are trained.
            if (!trained)
            {
                throw new InvalidOperationException("The channel models were not yet trained so classification is not possible.");
            }

            // Sort the channels that need sorting
            for (int i = 0; i < channelsToSort.Count; ++i)
            {
                // Current channel
                int currentChannel = channelsToSort[i];

                // Get the spikes that belong to this channel
                List <SpikeEvent> spikesOnChan = newSpikes.Buffer.Where(x => x.Channel == currentChannel).ToList();

                // If there are no spikes on this channel
                if (spikesOnChan.Count == 0)
                {
                    continue;
                }

                // Get the channel model for this channel
                ChannelModel thisChannelModel = channelModels[channelsToSort.IndexOf(currentChannel)];

                // Project the spikes
                if (this.projectionType == "Maximum Voltage Inflection")
                {
                    thisChannelModel.MaxInflectProject(spikesOnChan.ToList(), inflectionSample);
                }
                else if (this.projectionType == "Double Voltage Inflection")
                {
                    thisChannelModel.DoubleInflectProject(spikesOnChan.ToList(), inflectionSample, secondInflectionIndex);
                }
                else if (this.projectionType == "PCA")
                {
                    thisChannelModel.PCProject(spikesOnChan.ToList());
                }
                else if (this.projectionType == "Haar Wavelet")
                {
                    thisChannelModel.HaarProject(spikesOnChan.ToList());
                }

                // Sort the spikes
                thisChannelModel.ClassifyThresh();

                // Update the newSpikes buffer
                for (int j = 0; j < spikesOnChan.Count; ++j)
                {
                    if (thisChannelModel.classes[j] < 0)
                    {
                        spikesOnChan[j].SetUnit((Int16)0);
                    }
                    else
                    {
                        spikesOnChan[j].SetUnit((Int16)(thisChannelModel.classes[j] + thisChannelModel.unitStartIndex + 1));
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Trains a classifier for each channel so long as (int)minSpikes worth of spikes have been collected
        /// for that channel in the training buffer
        /// </summary>
        private void Train()
        {
            // Clear old channel models
            channelsToSort = new List <int>();
            channelModels.Clear();
            trained            = false;
            totalNumberOfUnits = 0;

            // Clear old unit dictionary
            unitDictionary = new Hashtable();

            // Add the zero unit to the dictionary
            unitDictionary.Add(0, 0);

            // Clear the old unit2channel map
            unit2Channel = new Dictionary <int, int>();

            // Make sure we have something in the training matrix
            if (trainingSpikes.Buffer.Count == 0)
            {
                throw new InvalidOperationException("The training data set was empty");
            }

            for (int i = 0; i < numberChannels; ++i)
            {
                // Current channel
                int currentChannel = i;

                // Get the spikes that belong to this channel
                List <SpikeEvent> spikesOnChan = trainingSpikes.Buffer.Where(x => x.Channel == currentChannel).ToList();

                // Project channel data
                if (spikesOnChan.Count >= minSpikes)
                {
                    // Train a channel model for this channel
                    ChannelModel thisChannelModel = new ChannelModel(currentChannel, maxK, totalNumberOfUnits, pValue, projectionDimension);

                    // Project Data
                    if (projectionType == "PCA")
                    {
                        thisChannelModel.PCCompute(spikesOnChan.ToList());
                    }
                    else
                    {
                        thisChannelModel.HaarCompute(spikesOnChan.ToList());
                    }

                    // Train Classifier
                    thisChannelModel.Train();

                    // If there was a training failure (e.g. convergence)
                    if (!thisChannelModel.trained)
                    {
                        continue;
                    }

                    // Note that we have to sort spikes on this channel
                    channelsToSort.Add(currentChannel);

                    // Update the unit dicationary and increment the total number of units
                    for (int k = 1; k <= thisChannelModel.K; ++k)
                    {
                        unitDictionary.Add(totalNumberOfUnits + k, k);
                        unit2Channel.Add(totalNumberOfUnits + k, i);
                    }

                    totalNumberOfUnits += thisChannelModel.K;

                    // Add the channel model to the list
                    channelModels.Add(thisChannelModel);
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Trains a classifier for each channel so long as (int)minSpikes worth of spikes have been collected
        /// for that channel in the training buffer
        /// </summary>
        private void Train()
        {
            // Clear old channel models
            channelsToSort = new List<int>();
            channelModels.Clear();
            trained = false;
            totalNumberOfUnits = 0;

            // Clear old unit dictionary
            unitDictionary = new Hashtable();

            // Add the zero unit to the dictionary
            unitDictionary.Add(0, 0);

            // Clear the old unit2channel map
            unit2Channel = new Dictionary<int, int>();

            // Make sure we have something in the training matrix
            if (trainingSpikes.Buffer.Count == 0)
            {
                throw new InvalidOperationException("The training data set was empty");
            }

            for (int i = 0; i < numberChannels; ++i)
            {
                // Current channel
                int currentChannel = i;

                // Get the spikes that belong to this channel
                List<SpikeEvent> spikesOnChan = trainingSpikes.Buffer.Where(x => x.Channel == currentChannel).ToList();

                // Project channel data
                if (spikesOnChan.Count >= minSpikes)
                {
                    // Train a channel model for this channel
                    ChannelModel thisChannelModel = new ChannelModel(currentChannel, maxK, totalNumberOfUnits, pValue, projectionDimension);

                    // Project Data
                    if (projectionType == "PCA")
                        thisChannelModel.PCCompute(spikesOnChan.ToList());
                    else
                        thisChannelModel.HaarCompute(spikesOnChan.ToList());

                    // Train Classifier
                    thisChannelModel.Train();

                    // If there was a training failure (e.g. convergence)
                    if (!thisChannelModel.trained)
                        continue;

                    // Note that we have to sort spikes on this channel
                    channelsToSort.Add(currentChannel);

                    // Update the unit dicationary and increment the total number of units
                    for (int k = 1; k <= thisChannelModel.K; ++k)
                    {
                        unitDictionary.Add(totalNumberOfUnits + k, k);
                        unit2Channel.Add(totalNumberOfUnits + k, i);
                    }

                    totalNumberOfUnits += thisChannelModel.K;

                    // Add the channel model to the list
                    channelModels.Add(thisChannelModel);
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Trains a classifier for each channel so long as (int)minSpikes worth of spikes have been collected
        /// for that channel in the training buffer. This uses to time points as the projection: The peak sample
        /// of the waveform and sample at some fixed  (mSecToSecondSample) delay from the peak sample. Preferably,
        /// this should be in the middle of the AHP.
        /// </summary>
        /// <param name="peakSample"> Sample that the peak of the waveform occured at </param>
        /// <param name="mSecToSecondSample">Delay, in msec, to get the second data point</param>
        private void Train(int peakSample, double mSecToSecondSample, int sampleFreqHz)
        {
            // Clear old channel models
            channelsToSort = new List <int>();
            channelModels.Clear();
            trained            = false;
            totalNumberOfUnits = 0;

            // Clear old unit dictionary
            unitDictionary = new Hashtable();

            // Add the zero unit to the dictionary
            unitDictionary.Add(0, 0);

            // Clear the old unit2channel map
            unit2Channel = new Dictionary <int, int>();

            // Set the inflection sample
            inflectionSample      = peakSample;
            secondInflectionIndex = peakSample + (int)(sampleFreqHz * (mSecToSecondSample / 1000));

            // Make sure we have something in the training matrix
            if (trainingSpikes.Buffer.Count == 0)
            {
                throw new InvalidOperationException("The training data set was empty");
            }

            for (int i = 0; i < numberChannels; ++i)
            {
                // Current channel
                int currentChannel = i;

                // Get the spikes that belong to this channel
                List <SpikeEvent> spikesOnChan = trainingSpikes.Buffer.Where(x => x.Channel == currentChannel).ToList();

                // Project channel data
                if (spikesOnChan.Count >= minSpikes)
                {
                    // Train a channel model for this channel
                    ChannelModel thisChannelModel = new ChannelModel(currentChannel, maxK, totalNumberOfUnits, pValue);

                    // Project Data
                    thisChannelModel.DoubleInflectProject(spikesOnChan.ToList(), inflectionSample, secondInflectionIndex);

                    // Train Classifier
                    thisChannelModel.Train();

                    // If there was a training failure (e.g. convergence)
                    if (!thisChannelModel.trained)
                    {
                        continue;
                    }

                    // Note that we have to sort spikes on this channel
                    channelsToSort.Add(currentChannel);

                    // Update the unit dicationary and increment the total number of units
                    for (int k = 1; k <= thisChannelModel.K; ++k)
                    {
                        unitDictionary.Add(totalNumberOfUnits + k, k);
                        unit2Channel.Add(totalNumberOfUnits + k, i);
                    }

                    totalNumberOfUnits += thisChannelModel.K;

                    // Add the channel model to the list
                    channelModels.Add(thisChannelModel);
                }
            }

            // All finished
            trained = true;
        }
Esempio n. 5
0
        /// <summary>
        /// Trains a classifier for each channel so long as (int)minSpikes worth of spikes have been collected
        /// for that channel in the training buffer. This uses to time points as the projection: The peak sample
        /// of the waveform and sample at some fixed  (mSecToSecondSample) delay from the peak sample. Preferably,
        /// this should be in the middle of the AHP.
        /// </summary>
        /// <param name="peakSample"> Sample that the peak of the waveform occured at </param>
        /// <param name="mSecToSecondSample">Delay, in msec, to get the second data point</param>
        private void Train(int peakSample, double mSecToSecondSample, int sampleFreqHz)
        {
            // Clear old channel models
            channelsToSort = new List<int>();
            channelModels.Clear();
            trained = false;
            totalNumberOfUnits = 0;

            // Clear old unit dictionary
            unitDictionary = new Hashtable();

            // Add the zero unit to the dictionary
            unitDictionary.Add(0, 0);

            // Clear the old unit2channel map
            unit2Channel = new Dictionary<int, int>();

            // Set the inflection sample
            inflectionSample = peakSample;
            secondInflectionIndex = peakSample + (int)(sampleFreqHz * (mSecToSecondSample / 1000));

            // Make sure we have something in the training matrix
            if (trainingSpikes.Buffer.Count == 0)
            {
                throw new InvalidOperationException("The training data set was empty");
            }

            for (int i = 0; i < numberChannels; ++i)
            {
                // Current channel
                int currentChannel = i;

                // Get the spikes that belong to this channel
                List<SpikeEvent> spikesOnChan = trainingSpikes.Buffer.Where(x => x.Channel == currentChannel).ToList();

                // Project channel data
                if (spikesOnChan.Count >= minSpikes)
                {

                    // Train a channel model for this channel
                    ChannelModel thisChannelModel = new ChannelModel(currentChannel, maxK, totalNumberOfUnits, pValue);

                    // Project Data
                    thisChannelModel.DoubleInflectProject(spikesOnChan.ToList(), inflectionSample, secondInflectionIndex);

                    // Train Classifier
                    thisChannelModel.Train();

                    // If there was a training failure (e.g. convergence)
                    if (!thisChannelModel.trained)
                        continue;

                    // Note that we have to sort spikes on this channel
                    channelsToSort.Add(currentChannel);

                    // Update the unit dicationary and increment the total number of units
                    for (int k = 1; k <= thisChannelModel.K; ++k)
                    {
                        unitDictionary.Add(totalNumberOfUnits + k, k);
                        unit2Channel.Add(totalNumberOfUnits + k, i);
                    }

                    totalNumberOfUnits += thisChannelModel.K;

                    // Add the channel model to the list
                    channelModels.Add(thisChannelModel);
                }
            }

            // All finished
            trained = true;
        }