예제 #1
0
        protected IArtifactDetector NewCompetitor()
        {
            if (latestSamples.Count < learningSetSize)
            {
                throw new InvalidOperationException();
            }

            double[] x    = latestSamples.ToArray();
            var      p    = StatsUtils.EstimateAROrder(x, 50);
            double   mean = StatsUtils.SampleMean(x);

            double[] arParams = StatsUtils.FitAR(p, x);
            Logger.Log("Created new competitor: p={0}, c={1}, phi={2}", p, mean, string.Join(", ", arParams));
            return(new ARArtifactDetector(new ARModel(mean, arParams)));
        }
예제 #2
0
        protected override bool Process(object item)
        {
            EEGEvent evt = (EEGEvent)item;

            var n = evt.data.Length;

            double[] buffer = new double[evt.data.Length];
            for (int i = 0; i < n; i++)
            {
                buffer[i] = signalFilters[i].Filter(evt.data[i]);
            }

            // TODO test artifact detection
            if (isLearning)
            {
                // add samples to window and test if window is sufficiently large
                bool stillLearning = false;
                for (int i = 0; i < n; i++)
                {
                    artifactLearningSamples[i].Enqueue(evt.data[i]);
                    stillLearning = artifactLearningSamples[i].Count < artifactLearningSize;
                }
                // sufficient samples to fit AR model
                if (!stillLearning)
                {
                    for (int i = 0; i < n; i++)
                    {
                        double[] x        = artifactLearningSamples[i].ToArray();
                        var      p        = StatsUtils.EstimateAROrder(x, 50);
                        double   mean     = StatsUtils.SampleMean(x);
                        double[] arParams = StatsUtils.FitAR(p, x);
                        Logger.Log("Estimated AR params: p={0}, c={1}, phi={2}", p, mean, string.Join(", ", arParams));
                        arPredictors[i]    = new ARModel(mean, arParams);
                        lastPredictions[i] = arPredictors[i].Predict(evt.data[i]);
                    }
                }
                isLearning = stillLearning;
            }
            else
            {
                bool isArtifact = false;
                for (int i = 0; i < n; i++)
                {
                    var x         = evt.data[i];
                    var error     = x - lastPredictions[i];
                    var errorDist = arError[i];
                    errorDist.Update(error);
                    lastPredictions[i] = arPredictors[i].Predict(x);

                    if (errorDist.isValid)
                    {
                        var errorS       = Math.Sqrt(errorDist.var);
                        var errorMaxCI95 = errorDist.mean + 2 * errorS;
                        var errorMinCI95 = errorDist.mean - 2 * errorS;
                        //Logger.Log("Error={0}, 95% CI = [{1}, {2}]", error, errorMinCI95, errorMaxCI95);
                        isArtifact = error > errorMaxCI95 || error < errorMinCI95;
                    }
                }

                if (isArtifact)
                {
                    Logger.Log("Detected large amplitude artifact via AR model");
                    return(true);
                }
            }

            Add(new EEGEvent(evt.timestamp, evt.type, buffer, evt.extra));

            return(true);
        }
예제 #3
0
 protected override double Compute(double[] x, double[] y)
 {
     return(StatsUtils.WeightedCorrelation(x, y, bandWeights));
 }