示例#1
0
        /// <summary>
        /// Given three of the four current channels, calculates the
        /// missing channel based on the relationship IR = IA + IB + IC.
        /// </summary>
        /// <param name="meterInfo">Data context for accessing configuration tables in the database.</param>
        public DataSeries CalculateMissingCurrentChannel()
        {
            Meter      meter;
            DataSeries missingSeries;

            // If the data group does not have exactly 3 channels,
            // then there is no missing channel or there is not
            // enough data to calculate the missing channel
            if (DefinedCurrents != 3)
            {
                return(null);
            }

            // Get the meter associated with the channels in this data group
            meter = (I1 ?? I2).SeriesInfo.Channel.Meter;

            if (m_i1Index == -1)
            {
                // Calculate I1 = IR - I2 - I3
                missingSeries            = IR.Add(I2.Negate()).Add(I3.Negate());
                missingSeries.SeriesInfo = GetSeriesInfo(meter, m_dataGroup, "Current", "General1");
                m_i1Index = m_dataGroup.DataSeries.Count;
                m_dataGroup.Add(missingSeries);
            }
            else if (m_i2Index == -1)
            {
                // Calculate I2 = IR - I1 - I3
                missingSeries            = IR.Add(I1.Negate()).Add(I3.Negate());
                missingSeries.SeriesInfo = GetSeriesInfo(meter, m_dataGroup, "Current", "General2");
                m_i1Index = m_dataGroup.DataSeries.Count;
                m_dataGroup.Add(missingSeries);
            }
            else if (m_i3Index == -1)
            {
                // Calculate I3 = IR - I1 - I2
                missingSeries            = IR.Add(I1.Negate()).Add(I2.Negate());
                missingSeries.SeriesInfo = GetSeriesInfo(meter, m_dataGroup, "Current", "General3");
                m_i1Index = m_dataGroup.DataSeries.Count;
                m_dataGroup.Add(missingSeries);
            }
            else
            {
                // Calculate IR = I1 + I2 + I3
                missingSeries            = I1.Add(I2).Add(I3);
                missingSeries.SeriesInfo = GetSeriesInfo(meter, m_dataGroup, "Current", "RES");
                m_i1Index = m_dataGroup.DataSeries.Count;
                m_dataGroup.Add(missingSeries);
            }

            return(missingSeries);
        }
示例#2
0
        public DataGroup ToSubGroup(int startIndex, int endIndex)
        {
            DataGroup subGroup = new DataGroup();

            foreach (DataSeries dataSeries in m_dataSeries)
            {
                subGroup.Add(dataSeries.ToSubSeries(startIndex, endIndex));
            }

            return(subGroup);
        }
示例#3
0
        public static DataGroup Combine(params DataGroup[] dataGroups)
        {
            DataGroup combination = new DataGroup();

            foreach (DataGroup dataGroup in dataGroups)
            {
                foreach (DataSeries dataSeries in dataGroup.DataSeries)
                {
                    combination.Add(dataSeries);
                }
            }

            return(combination);
        }
示例#4
0
        public static DataGroup ToCycleDataGroup(DataSeries dataSeries, double frequency)
        {
            DataGroup dataGroup = new DataGroup();

            DataSeries rmsSeries   = new DataSeries();
            DataSeries phaseSeries = new DataSeries();
            DataSeries peakSeries  = new DataSeries();
            DataSeries errorSeries = new DataSeries();

            int samplesPerCycle;

            double[] yValues;
            double[] tValues;
            double   sum;

            DateTime cycleTime;
            SineWave sineFit;

            if ((object)dataSeries == null)
            {
                return(null);
            }

            // Set series info to the source series info
            rmsSeries.SeriesInfo   = dataSeries.SeriesInfo;
            phaseSeries.SeriesInfo = dataSeries.SeriesInfo;
            peakSeries.SeriesInfo  = dataSeries.SeriesInfo;
            errorSeries.SeriesInfo = dataSeries.SeriesInfo;

            // Get samples per cycle of the data series based on the given frequency
            samplesPerCycle = CalculateSamplesPerCycle(dataSeries, frequency);

            // Initialize arrays of y-values and t-values for calculating cycle data
            yValues = new double[samplesPerCycle];
            tValues = new double[samplesPerCycle];

            for (int i = 0; i <= dataSeries.DataPoints.Count - samplesPerCycle; i += samplesPerCycle)
            {
                // Use the time of the first data point in the cycle as the time of the cycle
                cycleTime = dataSeries.DataPoints[i].Time;
                sum       = 0.0D;

                // Copy values from the original data series into the y-value and t-value arrays
                for (int j = 0; j < samplesPerCycle; j++)
                {
                    yValues[j] = dataSeries.DataPoints[i + j].Value;
                    tValues[j] = (dataSeries.DataPoints[i + j].Time - cycleTime).TotalSeconds;
                    sum       += yValues[j] * yValues[j];
                }

                // Use a curve fitting algorithm to estimate the sine wave over this cycle
                sineFit = WaveFit.SineFit(yValues, tValues, frequency);

                // Add data points to each of the cycle data series
                rmsSeries.DataPoints.Add(new DataPoint()
                {
                    Time  = cycleTime,
                    Value = Math.Sqrt(sum / samplesPerCycle)
                });

                phaseSeries.DataPoints.Add(new DataPoint()
                {
                    Time  = cycleTime,
                    Value = sineFit.Phase
                });

                peakSeries.DataPoints.Add(new DataPoint()
                {
                    Time  = cycleTime,
                    Value = sineFit.Amplitude
                });

                errorSeries.DataPoints.Add(new DataPoint()
                {
                    Time = cycleTime,

                    Value = tValues
                            .Select(sineFit.CalculateY)
                            .Zip(yValues, (estimate, value) => Math.Abs(estimate - value))
                            .Sum()
                });
            }

            // Add a series to the data group for each series of cycle data
            dataGroup.Add(rmsSeries);
            dataGroup.Add(phaseSeries);
            dataGroup.Add(peakSeries);
            dataGroup.Add(errorSeries);

            return(dataGroup);
        }