예제 #1
0
        /*
         * Scenario
         *  1. Called from UI-thread, on startup or change of timescale. invalidateData = true, isBackgrounThread = false
         *      -  calculate and store averaging factor
         *  2. Called from bakgroundthread when new data arrives. invalidateData = false, isBackgroundThread = false
         *      - recall averaging factor
         *  3. Called from backgroundthread to produce plots on disk. invalidateData = false, isBackgroundThread = true
         *      - calculate, do NOT store averaging factor
         */
        private List <EFOSDataPoint> GetData(DateTime from, DateTime to, bool invalidateData, bool isBackgroundThread = false)
        {
            List <EFOSDataPoint> data = d.LoadData(from, to);

            if (data.Count == 0)
            {
                return(data);
            }

            int avg = 0;

            // Average date to around 2000 points. Charts are slow with too many points.
            // Bug: If requesting more data than is available, averagingFactor will be incorrectly set.
            // Not expected to happen..
            string msg;

            if (invalidateData)
            {
                avg = (int)Math.Floor((double)data.Count / 2000);

                msg = String.Format("Averaging {0} pts", avg);

                if (!isBackgroundThread)
                {
                    if (InvokeRequired)
                    {
                        Invoke((MethodInvoker) delegate { averagingLabel.Text = msg; });
                    }
                    else
                    {
                        averagingLabel.Text = msg;
                    }

                    averagingFactor = avg;
                }
            }
            else
            {
                avg = averagingFactor;
            }

            //if (data.Count < averagingFactor)
            //    return;

            // averagingFactor is preserved from the first load, any updated data
            // will use the same factor.
            if (avg > 1)
            {
                List <EFOSDataPoint> averagedData = new List <EFOSDataPoint>();

                int i = 0;
                while (i < data.Count - 1)
                {
                    EFOSDataPoint avPt = new EFOSDataPoint();
                    int           cnt  = 0;

                    while (cnt < avg)
                    {
                        if (i + cnt > data.Count - 1)
                        {
                            goto Foo;   // Break out, ensuring that the last "incomplete" datapoint is not added to collection.
                        }
                        EFOSDataPoint dataPt = data[i + cnt];
                        avPt.timestamp = dataPt.timestamp;          // the timestamp of the last datapoint will be the
                                                                    // "from" to retrieve updated data
                        if (cnt == 0)
                        {
                            avPt.values = dataPt.values;
                        }
                        else
                        {
                            for (int idx = 0; idx < avPt.values.Length; idx++)
                            {
                                avPt.values[idx] += dataPt.values[idx];
                            }
                        }

                        cnt++;
                    }

                    // Average
                    for (int idx = 0; idx < avPt.values.Length; idx++)
                    {
                        avPt.values[idx] /= cnt;
                    }

                    i += cnt;

                    averagedData.Add(avPt);
                }
Foo:

                // Do not update from background thread.
                if (!isBackgroundThread)
                {
                    msg = string.Format("Received {0} pts, plotted {1} pts, left {2} pts", data.Count, averagedData.Count, data.Count - (averagedData.Count * averagingFactor));
                    if (InvokeRequired)
                    {
                        Invoke((MethodInvoker) delegate { debugLabel.Text = msg; });
                    }
                    else
                    {
                        debugLabel.Text = msg;
                    }
                }
                data = averagedData;
            }
            else
            {
                // Do not update from background thread.
                if (!isBackgroundThread)
                {
                    msg = string.Format("Received {0} pts", data.Count);
                    if (InvokeRequired)
                    {
                        Invoke((MethodInvoker) delegate { debugLabel.Text = msg; });
                    }
                    else
                    {
                        debugLabel.Text = msg;
                    }
                }
            }

            return(data);
        }
예제 #2
0
        public List <EFOSDataPoint> LoadData(DateTime from, DateTime to)
        {
            List <EFOSDataPoint> data = new List <EFOSDataPoint>();

            string[] files = Directory.EnumerateFiles(path, filenames).ToArray();
            Array.Sort(files);                                                              // Sort from oldest to newest

            // Need to strip off hour:in:sec from "from", in order to load the file containing that data.
            DateTime fromDate = DateTime.Parse(from.ToShortDateString());

            foreach (string file in files)
            {
                DateTime currentFile = DateTime.Parse(file.Substring(file.Length - 14, 10));

                // Filter out files older than "from"
                if (currentFile < fromDate)
                {
                    continue;
                }

                // Skip datafiles newer than "to".
                if (currentFile > to)
                {
                    continue;
                }

                var          fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader f  = new StreamReader(fs);

                // Read and discard first line, headers
                //f.ReadLine();

                while (!f.EndOfStream)
                {
                    try {
                        EFOSDataPoint d = new EFOSDataPoint();

                        string[] words = f.ReadLine().Split(';');

                        // First column is timestamp.
                        //d.timestamp = DateTime.Parse(words[0]).ToOADate();

                        //Skip lines where last field (parse error) is not 0
                        if (words[words.Length - 1] != "0")
                        {
                            continue;
                        }

                        // Skip lines not starting with a valid timestamp - headers
                        DateTime tmp;
                        if (!DateTime.TryParse(words[0], out tmp))
                        {
                            continue;
                        }

                        d.timestamp = tmp.ToOADate();

                        // Skip data older than from
                        if (d.timestamp <= from.ToOADate())
                        {
                            continue;
                        }

                        // Skip data newer than to
                        if (to != null && d.timestamp > to.ToOADate())
                        {
                            continue;
                        }

                        // The rest is doubles. Transform
                        transform t;
                        double[]  values = new double[words.Length - 2]; // Subract timestamp, and last field (error-flag)
                        for (int i = 0; i < values.Length; i++)
                        {
                            switch (i)
                            {
                            case (int)EFOScol.IntVacA:
                            case (int)EFOScol.IntVacV:
                            case (int)EFOScol.ExtVacA:
                            case (int)EFOScol.ExtVacV:
                                t = val => Math.Abs(val);
                                break;

                            case (int)EFOScol.p24V:
                                t = val => val - 24;
                                break;

                            case (int)EFOScol.p15V1:
                            case (int)EFOScol.p15V2:
                                t = val => val - 15;
                                break;

                            case (int)EFOScol.n15V1:
                            case (int)EFOScol.n15V2:
                                t = val => val + 15;
                                break;

                            case (int)EFOScol.p5V:
                                t = val => val - 5;
                                break;

                            default:
                                t = val => val;
                                break;
                            }
                            values[i] = t(double.Parse(words[i + 1], NumberStyles.Float | NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign));
                        }

                        d.values = values;

                        data.Add(d);
                    } catch (Exception) {
                        // TO do - log
                    }
                }

                f.Close();
            }

            // The last point read may be corrupted, as another process is writing to the file. Try to detect, and discard.
            if (data.Count > 0)
            {
                EFOSDataPoint last = data.Last();
                while (data.Count > 0 && last.values.Length != 35)
                {
                    data.Remove(last);
                    last = data.Last();
                }
            }

            return(data);
        }