예제 #1
0
        public void TestFixtureSetUp()
        {
            _values = new[] {
                new ReadingValues(1.0, 2.0, Double.NaN, 180, 4.0),
                new ReadingValues(2.0, Double.NaN, Double.NaN, 45, 6.0),
                new ReadingValues(3.0, 6.0, Double.NaN, 315, Double.NaN),
                new ReadingValues(Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN)
            };
            var minMaxCalc = new ReadingValueMinMaxCalculator <ReadingValues>();
            var meanCalc   = new ReadingValuesMeanCalculator <ReadingValues>();

            foreach (var readingValues in _values)
            {
                minMaxCalc.Proccess(readingValues);
                meanCalc.Proccess(readingValues);
            }
            _min    = minMaxCalc.Result.Min;
            _max    = minMaxCalc.Result.Max;
            _mean   = meanCalc.Result;
            _median = ReadingValues.CreateInvalid();
        }
예제 #2
0
        private static ReadingsSummary FormSummary <T>(DateTime dateRangeLow, DateTime dateRangeHigh, List <T> readings) where T : IReadingValues
        {
            int    tempCount  = 0;
            int    presCount  = 0;
            int    humCount   = 0;
            int    speedCount = 0;
            int    dirCount   = 0;
            double tempSum    = 0;
            double presSum    = 0;
            double humSum     = 0;
            double speedSum   = 0;
            double dirSinSum  = 0;
            double dirCosSum  = 0;

            var tempCounts  = new Dictionary <double, int>();
            var presCounts  = new Dictionary <double, int>();
            var humCounts   = new Dictionary <double, int>();
            var speedCounts = new Dictionary <double, int>();
            var dirCounts   = new Dictionary <double, int>();

            int count;

            ReadingValues minValues;
            ReadingValues maxValues;
            ReadingValues meanValues;
            ReadingValues sampleStandardDeviationValues;

            if (readings.Count > 0)
            {
                minValues = new ReadingValues(readings[0]);
                maxValues = new ReadingValues(readings[0]);

                double value;

                for (int i = 0; i < readings.Count; i++)
                {
                    T reading = readings[i];

                    if (reading.IsTemperatureValid)
                    {
                        tempCount++;
                        value    = reading.Temperature;
                        tempSum += value;

                        if (minValues.Temperature > value)
                        {
                            minValues.Temperature = value;
                        }
                        else if (maxValues.Temperature < value)
                        {
                            maxValues.Temperature = value;
                        }

                        value             = Math.Round(value);
                        tempCounts[value] = tempCounts.TryGetValue(value, out count) ? count + 1 : 1;
                    }
                    if (reading.IsPressureValid)
                    {
                        presCount++;
                        value    = reading.Pressure;
                        presSum += value;

                        if (minValues.Pressure > value)
                        {
                            minValues.Pressure = value;
                        }
                        else if (maxValues.Pressure < value)
                        {
                            maxValues.Pressure = value;
                        }

                        value             = Math.Round(value);
                        presCounts[value] = presCounts.TryGetValue(value, out count) ? count + 1 : 1;
                    }
                    if (reading.IsHumidityValid)
                    {
                        humCount++;
                        value   = reading.Humidity;
                        humSum += value;

                        if (minValues.Humidity > value)
                        {
                            minValues.Humidity = value;
                        }
                        else if (maxValues.Humidity < value)
                        {
                            maxValues.Humidity = value;
                        }

                        value            = Math.Round(value);
                        humCounts[value] = humCounts.TryGetValue(value, out count) ? count + 1 : 1;
                    }
                    if (reading.IsWindSpeedValid)
                    {
                        speedCount++;
                        value     = reading.WindSpeed;
                        speedSum += value;

                        if (minValues.WindSpeed > value)
                        {
                            minValues.WindSpeed = value;
                        }
                        else if (maxValues.WindSpeed < value)
                        {
                            maxValues.WindSpeed = value;
                        }

                        value = Math.Round(value * 2.0) / 2;                     // round to nearest .5
                        speedCounts[value] = speedCounts.TryGetValue(value, out count) ? count + 1 : 1;
                    }
                    if (reading.IsWindDirectionValid)
                    {
                        dirCount++;
                        value = reading.WindDirection;
                        //dirSum += value;

                        double dirRad = value * DegToRadFactor;
                        dirSinSum += Math.Sin(dirRad);
                        dirCosSum += Math.Cos(dirRad);

                        if (minValues.WindDirection > value)
                        {
                            minValues.WindDirection = value;
                        }
                        else if (maxValues.WindDirection < value)
                        {
                            maxValues.WindDirection = value;
                        }

                        value            = Math.Round(value);
                        dirCounts[value] = dirCounts.TryGetValue(value, out count) ? count + 1 : 1;
                    }
                }

                meanValues = new ReadingValues(
                    tempCount == 0 ? Double.NaN : (tempSum / tempCount),
                    presCount == 0 ? Double.NaN : (presSum / presCount),
                    humCount == 0 ? Double.NaN : (humSum / humCount),
                    (dirCount == 0 || Double.IsNaN(dirSinSum) || Double.IsNaN(dirCosSum))
                                                ? Double.NaN
                                                : UnitUtility.WrapDegree(Math.Atan2(dirSinSum / dirCount, dirCosSum / dirCount) * RadToDegFactor),
                    speedCount == 0 ? Double.NaN : (speedSum / speedCount)
                    );

                sampleStandardDeviationValues = new ReadingValues(0, 0, 0, 0, 0);

                for (int i = 0; i < readings.Count; i++)
                {
                    T reading = readings[i];

                    if (reading.IsTemperatureValid)
                    {
                        value = reading.Temperature - meanValues.Temperature;
                        sampleStandardDeviationValues.Temperature += value * value;
                    }
                    if (reading.IsPressureValid)
                    {
                        value = reading.Pressure - meanValues.Pressure;
                        sampleStandardDeviationValues.Pressure += value * value;
                    }
                    if (reading.IsHumidityValid)
                    {
                        value = reading.Humidity - meanValues.Humidity;
                        sampleStandardDeviationValues.Humidity += value * value;
                    }
                    if (reading.IsWindSpeedValid)
                    {
                        value = reading.WindSpeed - meanValues.WindSpeed;
                        sampleStandardDeviationValues.WindSpeed += value * value;
                    }
                    if (reading.IsWindDirectionValid)
                    {
                        value = reading.WindDirection - meanValues.WindDirection;
                        sampleStandardDeviationValues.WindDirection += value * value;
                    }
                }

                sampleStandardDeviationValues.Temperature   = Math.Sqrt(sampleStandardDeviationValues.Temperature / tempCount);
                sampleStandardDeviationValues.Pressure      = Math.Sqrt(sampleStandardDeviationValues.Pressure / presCount);
                sampleStandardDeviationValues.Humidity      = Math.Sqrt(sampleStandardDeviationValues.Humidity / humCount);
                sampleStandardDeviationValues.WindSpeed     = Math.Sqrt(sampleStandardDeviationValues.WindSpeed / speedCount);
                sampleStandardDeviationValues.WindDirection = Math.Sqrt(sampleStandardDeviationValues.WindDirection / dirCount);
            }
            else
            {
                minValues  = ReadingValues.CreateInvalid();
                maxValues  = ReadingValues.CreateInvalid();
                meanValues = ReadingValues.CreateInvalid();
                sampleStandardDeviationValues = ReadingValues.CreateInvalid();
            }

            return(new ReadingsSummary(
                       dateRangeLow,
                       dateRangeHigh.Subtract(new TimeSpan(1)),
                       minValues, maxValues,
                       meanValues, sampleStandardDeviationValues,
                       readings.Count,
                       tempCounts,
                       presCounts,
                       humCounts,
                       speedCounts,
                       dirCounts
                       ));
        }
예제 #3
0
 public new static ReadingAggregate CreateInvalid()
 {
     return(new ReadingAggregate(DateTime.MinValue, DateTime.MaxValue, ReadingValues.CreateInvalid(), 0));
 }
예제 #4
0
        public static ReadingsSummary Combine <TSummary>(List <TSummary> readings) where TSummary : IReadingsSummary
        {
            int      totalTempCount   = 0;
            int      totalPresCount   = 0;
            int      totalHumCount    = 0;
            int      totalSpeedCount  = 0;
            int      totalDirCount    = 0;
            int      totalRecordCount = 0;
            DateTime minStamp         = DateTime.MaxValue;
            DateTime maxStamp         = DateTime.MinValue;
            double   dirSinSum        = 0;
            double   dirCosSum        = 0;

            var summary = new ReadingsSummary(
                default(DateTime),
                default(DateTime),
                ReadingValues.CreateInvalid(),
                ReadingValues.CreateInvalid(),
                ReadingValues.CreateInvalid(),
                ReadingValues.CreateInvalid(),
                0,
                new Dictionary <double, int>(),
                new Dictionary <double, int>(),
                new Dictionary <double, int>(),
                new Dictionary <double, int>(),
                new Dictionary <double, int>()
                );

            if (0 == readings.Count)
            {
                return(summary);
            }

            summary.Min  = new ReadingValues(Double.MaxValue, Double.MaxValue, Double.MaxValue, Double.MaxValue, Double.MaxValue);
            summary.Max  = new ReadingValues(Double.MinValue, Double.MinValue, Double.MinValue, Double.MinValue, Double.MinValue);
            summary.Mean = new ReadingValues(0, 0, 0, 0, 0);
            summary.SampleStandardDeviation = new ReadingValues(0, 0, 0, 0, 0);

            foreach (var reading in readings)
            {
                if (reading.BeginStamp < minStamp)
                {
                    minStamp = reading.BeginStamp;
                }
                if (reading.EndStamp > maxStamp)
                {
                    maxStamp = reading.EndStamp;
                }

                if (summary.Min.Temperature > reading.Min.Temperature)
                {
                    summary.Min.Temperature = reading.Min.Temperature;
                }
                if (summary.Min.Pressure > reading.Min.Pressure)
                {
                    summary.Min.Pressure = reading.Min.Pressure;
                }
                if (summary.Min.Humidity > reading.Min.Humidity)
                {
                    summary.Min.Humidity = reading.Min.Humidity;
                }
                if (summary.Min.WindSpeed > reading.Min.WindSpeed)
                {
                    summary.Min.WindSpeed = reading.Min.WindSpeed;
                }
                if (summary.Min.WindDirection > reading.Min.WindDirection)
                {
                    summary.Min.WindDirection = reading.Min.WindDirection;
                }
                if (summary.Max.Temperature < reading.Max.Temperature)
                {
                    summary.Max.Temperature = reading.Max.Temperature;
                }
                if (summary.Max.Pressure < reading.Max.Pressure)
                {
                    summary.Max.Pressure = reading.Max.Pressure;
                }
                if (summary.Max.Humidity < reading.Max.Humidity)
                {
                    summary.Max.Humidity = reading.Max.Humidity;
                }
                if (summary.Max.WindSpeed < reading.Max.WindSpeed)
                {
                    summary.Max.WindSpeed = reading.Max.WindSpeed;
                }
                if (summary.Max.WindDirection < reading.Max.WindDirection)
                {
                    summary.Max.WindDirection = reading.Max.WindDirection;
                }

                int localTempCount  = AppendCounts(summary.TemperatureCounts, reading.GetTemperatureCounts());
                int localPresCount  = AppendCounts(summary.PressureCounts, reading.GetPressureCounts());
                int localHumCount   = AppendCounts(summary.HumidityCounts, reading.GetHumidityCounts());
                int localSpeedCount = AppendCounts(summary.WindSpeedCounts, reading.GetWindSpeedCounts());
                int localDirCount   = AppendCounts(summary.WindDirectionCounts, reading.GetWindDirectionCounts());

                totalTempCount   += localTempCount;
                totalPresCount   += localPresCount;
                totalHumCount    += localHumCount;
                totalSpeedCount  += localSpeedCount;
                totalDirCount    += localDirCount;
                totalRecordCount += reading.Count;

                summary.Mean.Temperature += reading.Mean.Temperature * localTempCount;
                summary.Mean.Pressure    += reading.Mean.Pressure * localPresCount;
                summary.Mean.Humidity    += reading.Mean.Humidity * localHumCount;
                summary.Mean.WindSpeed   += reading.Mean.WindSpeed * localSpeedCount;

                double dirRad = reading.Mean.WindDirection * DegToRadFactor;
                dirSinSum += Math.Sin(dirRad) * localDirCount;
                dirCosSum += Math.Cos(dirRad) * localDirCount;
            }

            if (0 != totalTempCount && 1 != totalTempCount)
            {
                summary.Mean.Temperature /= totalTempCount;
            }
            if (0 != totalPresCount && 1 != totalPresCount)
            {
                summary.Mean.Pressure /= totalPresCount;
            }
            if (0 != totalHumCount && 1 != totalHumCount)
            {
                summary.Mean.Humidity /= totalHumCount;
            }
            if (0 != totalSpeedCount && 1 != totalSpeedCount)
            {
                summary.Mean.WindSpeed /= totalSpeedCount;
            }
            summary.Mean.WindDirection = (totalDirCount == 0 || Double.IsNaN(dirSinSum) || Double.IsNaN(dirCosSum))
                            ? Double.NaN
                            : UnitUtility.WrapDegree(Math.Atan2(dirSinSum / totalDirCount, dirCosSum / totalDirCount) * RadToDegFactor);


            double dev;

            foreach (var reading in readings)
            {
                int localTempCount  = reading.GetTemperatureCounts().Sum(c => c.Value);
                int localPresCount  = reading.GetPressureCounts().Sum(c => c.Value);
                int localHumCount   = reading.GetHumidityCounts().Sum(c => c.Value);
                int localSpeedCount = reading.GetWindSpeedCounts().Sum(c => c.Value);
                int localDirCount   = reading.GetWindDirectionCounts().Sum(c => c.Value);

                dev = (reading.Mean.Temperature - summary.Mean.Temperature);
                summary.SampleStandardDeviation.Temperature += (dev * dev) * localTempCount;

                dev = (reading.Mean.Pressure - summary.Mean.Pressure);
                summary.SampleStandardDeviation.Pressure += (dev * dev) * localPresCount;

                dev = (reading.Mean.Humidity - summary.Mean.Humidity);
                summary.SampleStandardDeviation.Humidity += (dev * dev) * localHumCount;

                dev = (reading.Mean.WindSpeed - summary.Mean.WindSpeed);
                summary.SampleStandardDeviation.WindSpeed += (dev * dev) * localSpeedCount;

                dev = (reading.Mean.WindDirection - summary.Mean.WindDirection);
                summary.SampleStandardDeviation.WindDirection += (dev * dev) * localDirCount;
            }

            if (0 != totalTempCount && 1 != totalTempCount)
            {
                summary.SampleStandardDeviation.Temperature = Math.Sqrt(summary.SampleStandardDeviation.Temperature / totalTempCount);
            }
            if (0 != totalPresCount && 1 != totalPresCount)
            {
                summary.SampleStandardDeviation.Pressure = Math.Sqrt(summary.SampleStandardDeviation.Pressure / totalPresCount);
            }
            if (0 != totalHumCount && 1 != totalHumCount)
            {
                summary.SampleStandardDeviation.Humidity = Math.Sqrt(summary.SampleStandardDeviation.Humidity / totalHumCount);
            }
            if (0 != totalSpeedCount && 1 != totalSpeedCount)
            {
                summary.SampleStandardDeviation.WindSpeed = Math.Sqrt(summary.SampleStandardDeviation.WindSpeed / totalSpeedCount);
            }
            if (0 != totalDirCount && 1 != totalDirCount)
            {
                summary.SampleStandardDeviation.WindDirection = Math.Sqrt(summary.SampleStandardDeviation.WindDirection / totalDirCount);
            }

            summary.Count      = totalRecordCount;
            summary.BeginStamp = minStamp;
            summary.EndStamp   = maxStamp;
            return(summary);
        }