C# General Software Down-sampling Code

Post your .Net discussions here
Post Reply
Sanjay
User
User
Posts: 3
Joined: Mon Jun 20, 2016 1:08 pm

C# General Software Down-sampling Code

Post by Sanjay »

The Picoscope already has hardware down-sampling, this is the code I have used in my spare time for Software down-sampling whilst using the SDK.
Tested on the PS5000A, should work for any version.

Method used: Largest Triangle Three Buckets
Information: 4.2 Page 21 http://skemman.is/stream/get/1946/15343 ... thesis.pdf

Method (Where threshold is the amount of samples that will be left after the downsample):

Code: Select all

public static IEnumerable> downsample(List> data, int threshold)
        {
            int dataLength = data.Count;
            if (threshold >= dataLength || threshold == 0)
                return data; // Nothing to do

            List> sampled = new List>(threshold);

            // Bucket size. Leave room for start and end data points
            double every = (double)(dataLength - 2) / (threshold - 2);

            int a = 0;
            Tuple maxAreaPoint = new Tuple(0, 0);
            int nextA = 0;

            sampled.Add(data[a]); // Always add the first point

            for (int i = 0; i < threshold - 2; i++)
            {
                // Calculate point average for next bucket (containing c)
                double avgX = 0;
                double avgY = 0;
                int avgRangeStart = (int)(Math.Floor((i + 1) * every) + 1);
                int avgRangeEnd = (int)(Math.Floor((i + 2) * every) + 1);
                avgRangeEnd = avgRangeEnd < dataLength ? avgRangeEnd : dataLength;

                int avgRangeLength = avgRangeEnd - avgRangeStart;

                for (; avgRangeStart < avgRangeEnd; avgRangeStart++)
                {
                    avgX += data[avgRangeStart].Item1; // * 1 enforces Number (value may be Date)
                    avgY += data[avgRangeStart].Item2;
                }
                avgX /= avgRangeLength;

                avgY /= avgRangeLength;

                // Get the range for this bucket
                int rangeOffs = (int)(Math.Floor((i + 0) * every) + 1);
                int rangeTo = (int)(Math.Floor((i + 1) * every) + 1);

                // Point a
                double pointAx = data[a].Item1; // enforce Number (value may be Date)
                double pointAy = data[a].Item2;

                double maxArea = -1;

                for (; rangeOffs < rangeTo; rangeOffs++)
                {
                    // Calculate triangle area over three buckets
                    double area = Math.Abs((pointAx - avgX) * (data[rangeOffs].Item2 - pointAy) -
                                           (pointAx - data[rangeOffs].Item1) * (avgY - pointAy)
                                      ) * 0.5;
                    if (area > maxArea)
                    {
                        maxArea = area;
                        maxAreaPoint = data[rangeOffs];
                        nextA = rangeOffs; // Next a is this b
                    }
                }

                sampled.Add(maxAreaPoint); // Pick this point from the bucket
                a = nextA; // This a is the next a (chosen b)
            }

            sampled.Add(data[dataLength - 1]); // Always add last

            return sampled;
        }
Usage (Only after results have been collected):

Code: Select all

                        //Create new list with tuples
                                 List> list = new List>();
                                 //Iterate through results after runblock
                                 for (int i = 0; i < maxBuffers[channel].Length; i++)
                                 {
                                    //Populate tuple list
                                    list.Add(new Tuple(i * timeInterval, maxBuffers[channel][i]));
                                 }

                                IEnumerable> downsampledData = GraphModel.downsample(list, App.downsampleSize); //Sampled down data to process
Example:
Signal Generated:
Image

All 100K Samples:
http://i.imgur.com/CLYGazk.png

100K Samples down-sampled to 5K samples:
http://i.imgur.com/96q91p3.png

100K Samples down-sampled to 1K samples:
http://i.imgur.com/aYC61j4.png

Post Reply