コード例 #1
0
ファイル: PQDIFReader.cs プロジェクト: daozh/openXDA
        /// <summary>
        /// Parses the file into a meter data set per meter contained in the file.
        /// </summary>
        /// <param name="filePath">The path to the file to be parsed.</param>
        /// <returns>List of meter data sets, one per meter.</returns>
        public void Parse(string filePath)
        {
            DataSourceRecord              dataSource = null;
            ObservationRecord             observation;
            IEnumerable <ChannelInstance> channelInstances;

            Meter      meter = null;
            Channel    channel;
            DataSeries dataSeries;

            DateTime[] timeData;

            while (m_parser.HasNextObservationRecord())
            {
                observation = m_parser.NextObservationRecord();

                if ((object)observation.DataSource == null)
                {
                    continue;
                }

                if ((object)dataSource == null)
                {
                    dataSource           = observation.DataSource;
                    meter                = ParseDataSource(dataSource);
                    m_meterDataSet.Meter = meter;
                }

                if (!AreEquivalent(dataSource, observation.DataSource))
                {
                    throw new InvalidDataException($"PQDIF file \"{filePath}\" defines too many data sources.");
                }

                channelInstances = observation.ChannelInstances
                                   .Where(channelInstance => QuantityType.IsQuantityTypeID(channelInstance.Definition.QuantityTypeID))
                                   .Where(channelInstance => channelInstance.SeriesInstances.Any())
                                   .Where(channelInstance => channelInstance.SeriesInstances[0].Definition.ValueTypeID == SeriesValueType.Time);

                foreach (ChannelInstance channelInstance in channelInstances)
                {
                    timeData = ParseTimeData(channelInstance);

                    foreach (SeriesInstance seriesInstance in channelInstance.SeriesInstances.Skip(1))
                    {
                        channel = ParseSeries(seriesInstance);

                        dataSeries            = new DataSeries();
                        dataSeries.DataPoints = timeData.Zip(ParseValueData(seriesInstance), (time, d) => new DataPoint()
                        {
                            Time = time, Value = d
                        }).ToList();
                        dataSeries.SeriesInfo = channel.Series[0];

                        meter.Channels.Add(channel);
                        m_meterDataSet.DataSeries.Add(dataSeries);
                    }
                }
            }
        }
コード例 #2
0
        public void Parse(string filePath)
        {
            List <DataSourceRecord>  dataSources;
            List <ObservationRecord> observationRecords;
            List <ChannelInstance>   channelInstances;
            List <SeriesInstance>    seriesInstances;
            List <SeriesDefinition>  seriesDefinitions;

            Meter      meter;
            Channel    channel;
            DataSeries dataSeries;

            DateTime[] timeData;

            // Build the list of observation records in the PQDIF file
            observationRecords = new List <ObservationRecord>();

            while (m_parser.HasNextObservationRecord())
            {
                observationRecords.Add(m_parser.NextObservationRecord());
            }

            // Build the list of all data source records in the PQDIF file
            dataSources = observationRecords
                          .Select(observation => observation.DataSource)
                          .Distinct()
                          .ToList();

            // If there are no data sources, there is no
            // need to go any further because we won't be
            // able to interpret any of the channel data
            if (!dataSources.Any())
            {
                return;
            }

            // Validate data sources to make sure there is only one data source defined in the file
            if (!dataSources.Zip(dataSources.Skip(1), (ds1, ds2) => AreEquivalent(ds1, ds2)).All(b => b))
            {
                throw new InvalidDataException($"PQDIF file \"{filePath}\" defines too many data sources.");
            }

            // Create a meter from the parsed data source
            meter = ParseDataSource(dataSources.First());

            // Build the list of all channel instances in the PQDIF file
            channelInstances = observationRecords
                               .SelectMany(observation => observation.ChannelInstances)
                               .Where(channelInstance => QuantityType.IsQuantityTypeID(channelInstance.Definition.QuantityTypeID))
                               .Where(channelInstance => channelInstance.SeriesInstances.Any())
                               .Where(channelInstance => channelInstance.SeriesInstances[0].Definition.ValueTypeID == SeriesValueType.Time)
                               .ToList();

            // Create the list of series instances so we can
            // build it as we process each channel instance
            seriesInstances = new List <SeriesInstance>();

            Dictionary <Channel, DataSeries> startChannelsAndDataSeries = new Dictionary <Channel, DataSeries>();
            Dictionary <Channel, DataSeries> endChannelsAndDataSeries   = new Dictionary <Channel, DataSeries>();

            foreach (ChannelInstance channelInstance in channelInstances)
            {
                bool timeValueChannel =
                    channelInstance.Definition.QuantityTypeID == QuantityType.WaveForm ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.ValueLog ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.Phasor ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.Flash ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.MagDurTime ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.MagDurCount;

                // TODO: Create representation for quantity types that do not define time/value data
                if (!timeValueChannel)
                {
                    continue;
                }

                // Parse time data from the channel instance
                timeData = ParseTimeData(channelInstance);

                foreach (SeriesInstance seriesInstance in channelInstance.SeriesInstances.Skip(1))
                {
                    // Create a channel from the parsed series instance
                    seriesInstances.Add(seriesInstance);
                    channel = ParseSeries(seriesInstance);

                    // Parse the values and zip them with time data to create data points
                    dataSeries            = new DataSeries();
                    dataSeries.DataPoints = timeData.Zip(ParseValueData(seriesInstance), (time, d) => new DataPoint()
                    {
                        Time = time, Value = d
                    }).ToList();
                    dataSeries.SeriesInfo = channel.Series[0];

                    // Add the new channel to the meter's channel list

                    if (channel.Name.ToLower().Contains("start"))
                    {
                        startChannelsAndDataSeries[channel] = dataSeries;
                    }
                    else if (channel.Name.ToLower().Contains("end"))
                    {
                        endChannelsAndDataSeries[channel] = dataSeries;
                    }
                    else
                    {
                        channel.Meter = meter;
                        meter.Channels.Add(channel);
                        m_meterDataSet.DataSeries.Add(dataSeries);
                    }
                }
            }

            foreach (Channel chan in startChannelsAndDataSeries.Keys)
            {
                string  baseChannelName = chan.Name.ToLower().Replace("start", "");
                Channel endChannel      = endChannelsAndDataSeries.Keys.Where(ch => ch.Name.ToLower().Replace("end", "") == baseChannelName).FirstOrDefault();

                if ((object)endChannel != null)
                {
                    Channel    combinedChannel    = chan;
                    DataSeries combinedDataSeries = startChannelsAndDataSeries[chan];

                    // Replace "Start" in combinedChannel.Name with "Start + End";
                    int index = combinedChannel.Name.IndexOf("start", StringComparison.OrdinalIgnoreCase);
                    combinedChannel.Name = combinedChannel.Name.Remove(index, 5).Insert(index, "Start + End");

                    combinedDataSeries.DataPoints.AddRange(endChannelsAndDataSeries[endChannel].DataPoints);

                    combinedChannel.Meter = meter;
                    meter.Channels.Add(combinedChannel);
                    m_meterDataSet.DataSeries.Add(combinedDataSeries);
                }
            }

            // Build a list of series definitions that were not instanced by this PQDIF file
            seriesDefinitions = dataSources
                                .SelectMany(dataSource => dataSource.ChannelDefinitions)
                                .SelectMany(channelDefinition => channelDefinition.SeriesDefinitions)
                                .Distinct()
                                .Except(seriesInstances.Select(seriesInstance => seriesInstance.Definition))
                                .ToList();

            // Add each of the series definitions which were not instanced to the meter's list of channels
            foreach (SeriesDefinition seriesDefinition in seriesDefinitions)
            {
                meter.Channels.Add(ParseSeries(seriesDefinition));
            }

            m_meterDataSet.Meter = meter;
        }
コード例 #3
0
ファイル: PQDIFReader.cs プロジェクト: alirex1/openXDA
        /// <summary>
        /// Parses the file into a meter data set per meter contained in the file.
        /// </summary>
        /// <param name="filePath">The path to the file to be parsed.</param>
        /// <returns>List of meter data sets, one per meter.</returns>
        public void Parse(string filePath)
        {
            List <DataSourceRecord>  dataSources;
            List <ObservationRecord> observationRecords;
            List <ChannelInstance>   channelInstances;
            List <SeriesInstance>    seriesInstances;
            List <SeriesDefinition>  seriesDefinitions;

            Meter      meter;
            Channel    channel;
            DataSeries dataSeries;

            DateTime[] timeData;

            // Build the list of observation records in the PQDIF file
            observationRecords = new List <ObservationRecord>();

            while (m_parser.HasNextObservationRecord())
            {
                observationRecords.Add(m_parser.NextObservationRecord());
            }

            // Build the list of all data source records in the PQDIF file
            dataSources = observationRecords
                          .Select(observation => observation.DataSource)
                          .Distinct()
                          .ToList();

            // If there are no data sources, there is no
            // need to go any further because we won't be
            // able to interpret any of the channel data
            if (!dataSources.Any())
            {
                return;
            }

            // Validate data sources to make sure there is only one data source defined in the file
            if (!dataSources.Zip(dataSources.Skip(1), (ds1, ds2) => AreEquivalent(ds1, ds2)).All(b => b))
            {
                throw new InvalidDataException($"PQDIF file \"{filePath}\" defines too many data sources.");
            }

            // Create a meter from the parsed data source
            meter = ParseDataSource(dataSources.First());
            m_meterDataSet.Meter = meter;

            // Build the list of all channel instances in the PQDIF file
            channelInstances = observationRecords
                               .SelectMany(observation => observation.ChannelInstances)
                               .Where(channelInstance => QuantityType.IsQuantityTypeID(channelInstance.Definition.QuantityTypeID))
                               .Where(channelInstance => channelInstance.SeriesInstances.Any())
                               .Where(channelInstance => channelInstance.SeriesInstances[0].Definition.ValueTypeID == SeriesValueType.Time)
                               .ToList();

            // Create the list of series instances so we can
            // build it as we process each channel instance
            seriesInstances = new List <SeriesInstance>();

            foreach (ChannelInstance channelInstance in channelInstances)
            {
                bool timeValueChannel =
                    channelInstance.Definition.QuantityTypeID == QuantityType.WaveForm ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.ValueLog ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.Phasor ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.Flash ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.MagDurTime ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.MagDurCount;

                // TODO: Create representation for quantity types that do not define time/value data
                if (!timeValueChannel)
                {
                    continue;
                }

                // Parse time data from the channel instance
                timeData = ParseTimeData(channelInstance);

                foreach (SeriesInstance seriesInstance in channelInstance.SeriesInstances.Skip(1))
                {
                    // Create a channel from the parsed series instance
                    seriesInstances.Add(seriesInstance);
                    channel = ParseSeries(seriesInstance);

                    // Parse the values and zip them with time data to create data points
                    dataSeries            = new DataSeries();
                    dataSeries.DataPoints = timeData.Zip(ParseValueData(seriesInstance), (time, d) => new DataPoint()
                    {
                        Time = time, Value = d
                    }).ToList();
                    dataSeries.SeriesInfo = channel.Series[0];

                    // Add the new channel to the meter's channel list
                    meter.Channels.Add(channel);
                    m_meterDataSet.DataSeries.Add(dataSeries);
                }
            }

            // Build a list of series definitions that were not instanced by this PQDIF file
            seriesDefinitions = dataSources
                                .SelectMany(dataSource => dataSource.ChannelDefinitions)
                                .SelectMany(channelDefinition => channelDefinition.SeriesDefinitions)
                                .Distinct()
                                .Except(seriesInstances.Select(seriesInstance => seriesInstance.Definition))
                                .ToList();

            // Add each of the series definitions which were not instanced to the meter's list of channels
            foreach (SeriesDefinition seriesDefinition in seriesDefinitions)
            {
                meter.Channels.Add(ParseSeries(seriesDefinition));
            }
        }
コード例 #4
0
        /// <summary>
        /// Parses the file into a meter data set per meter contained in the file.
        /// </summary>
        /// <param name="filePath">The path to the file to be parsed.</param>
        /// <returns>List of meter data sets, one per meter.</returns>
        public void Parse(string filePath)
        {
            List <DataSourceRecord>  dataSources;
            List <ObservationRecord> observationRecords;
            List <ChannelInstance>   channelInstances;
            List <SeriesInstance>    seriesInstances;
            List <SeriesDefinition>  seriesDefinitions;

            Meter      meter;
            Channel    channel;
            DataSeries dataSeries;

            DateTime[] timeData;

            // Build the list of observation records in the PQDIF file
            observationRecords = new List <ObservationRecord>();

            while (m_parser.HasNextObservationRecord())
            {
                observationRecords.Add(m_parser.NextObservationRecord());
            }

            // Build the list of all data source records in the PQDIF file
            dataSources = observationRecords
                          .Select(observation => observation.DataSource)
                          .Distinct()
                          .ToList();

            // If there are no data sources, there is no
            // need to go any further because we won't be
            // able to interpret any of the channel data
            if (!dataSources.Any())
            {
                return;
            }

            // Validate data sources to make sure there is only one data source defined in the file
            if (!dataSources.Zip(dataSources.Skip(1), (ds1, ds2) => AreEquivalent(ds1, ds2)).All(b => b))
            {
                throw new InvalidDataException($"PQDIF file \"{filePath}\" defines too many data sources.");
            }

            // Create a meter from the parsed data source
            meter = ParseDataSource(dataSources.First());

            // Build the list of all channel instances in the PQDIF file
            channelInstances = observationRecords
                               .SelectMany(observation => observation.ChannelInstances)
                               .Where(channelInstance => QuantityType.IsQuantityTypeID(channelInstance.Definition.QuantityTypeID))
                               .Where(channelInstance => channelInstance.SeriesInstances.Any())
                               .Where(channelInstance => channelInstance.SeriesInstances[0].Definition.ValueTypeID == SeriesValueType.Time)
                               .ToList();

            // Create the list of series instances so we can
            // build it as we process each channel instance
            seriesInstances = new List <SeriesInstance>();

            foreach (ChannelInstance channelInstance in channelInstances)
            {
                bool timeValueChannel =
                    channelInstance.Definition.QuantityTypeID == QuantityType.WaveForm ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.ValueLog ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.Phasor;

                if (!timeValueChannel)
                {
                    continue;
                }

                // Parse time data from the channel instance
                timeData = ParseTimeData(channelInstance, m_systemFrequency);

                foreach (SeriesInstance seriesInstance in channelInstance.SeriesInstances.Skip(1))
                {
                    // Create a channel from the parsed series instance
                    seriesInstances.Add(seriesInstance);
                    channel = ParseSeries(seriesInstance);

                    // Parse the values and zip them with time data to create data points
                    dataSeries            = new DataSeries();
                    dataSeries.DataPoints = timeData.Zip(ParseValueData(seriesInstance), (time, d) => new DataPoint()
                    {
                        Time = time, Value = d
                    }).ToList();
                    dataSeries.SeriesInfo = channel.Series[0];

                    // Add the new channel to the meter's channel list
                    channel.Meter = meter;
                    meter.Channels.Add(channel);
                    m_meterDataSet.DataSeries.Add(dataSeries);
                }
            }

            foreach (ChannelInstance channelInstance in channelInstances)
            {
                bool magDurChannel =
                    channelInstance.Definition.QuantityTypeID == QuantityType.MagDur ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.MagDurCount ||
                    channelInstance.Definition.QuantityTypeID == QuantityType.MagDurTime;

                if (!magDurChannel)
                {
                    continue;
                }

                timeData = channelInstance.SeriesInstances
                           .Where(seriesInstance => seriesInstance.Definition.ValueTypeID == SeriesValueType.Time)
                           .Select(seriesInstance => ParseTimeData(seriesInstance, m_systemFrequency))
                           .FirstOrDefault();

                Guid valType = SeriesValueType.Val;
                Guid maxType = SeriesValueType.Max;
                Guid minType = SeriesValueType.Min;
                Guid avgType = SeriesValueType.Avg;

                double[] valData = channelInstance.SeriesInstances
                                   .Where(seriesInstance => seriesInstance.Definition.ValueTypeID == valType)
                                   .Select(seriesInstance => ParseValueData(seriesInstance))
                                   .FirstOrDefault();

                double[] maxData = channelInstance.SeriesInstances
                                   .Where(seriesInstance => seriesInstance.Definition.ValueTypeID == maxType)
                                   .Select(seriesInstance => ParseValueData(seriesInstance))
                                   .FirstOrDefault() ?? valData;

                double[] minData = channelInstance.SeriesInstances
                                   .Where(seriesInstance => seriesInstance.Definition.ValueTypeID == minType)
                                   .Select(seriesInstance => ParseValueData(seriesInstance))
                                   .FirstOrDefault() ?? valData;

                double[] avgData = channelInstance.SeriesInstances
                                   .Where(seriesInstance => seriesInstance.Definition.ValueTypeID == avgType)
                                   .Select(seriesInstance => ParseValueData(seriesInstance))
                                   .FirstOrDefault() ?? valData;

                TimeSpan[] durData = channelInstance.SeriesInstances
                                     .Where(seriesInstance => seriesInstance.Definition.ValueTypeID == SeriesValueType.Duration)
                                     .Select(seriesInstance => ParseTimeSpanData(seriesInstance, m_systemFrequency))
                                     .FirstOrDefault();

                int minLength = Common.Min(timeData.Length, maxData.Length, minData.Length, avgData.Length, durData.Length);

                QuantityUnits units = channelInstance.SeriesInstances
                                      .Where(seriesInstance => new[] { valType, maxType, minType, avgType }.Contains(seriesInstance.Definition.ValueTypeID))
                                      .Select(seriesInstance => seriesInstance.Definition.QuantityUnits)
                                      .FirstOrDefault();

                for (int i = 0; i < minLength; i++)
                {
                    DateTime time = ((object)timeData != null)
                        ? timeData[i]
                        : channelInstance.ObservationRecord.StartTime;

                    double   max = maxData[i];
                    double   min = minData[i];
                    double   avg = avgData[i];
                    TimeSpan dur = durData[i];

                    m_meterDataSet.ReportedDisturbances.Add(new ReportedDisturbance(channelInstance.Definition.Phase, time, max, min, avg, dur, units));
                }
            }

            // Build a list of series definitions that were not instanced by this PQDIF file
            seriesDefinitions = dataSources
                                .SelectMany(dataSource => dataSource.ChannelDefinitions)
                                .SelectMany(channelDefinition => channelDefinition.SeriesDefinitions)
                                .Distinct()
                                .Except(seriesInstances.Select(seriesInstance => seriesInstance.Definition))
                                .ToList();

            // Add each of the series definitions which were not instanced to the meter's list of channels
            foreach (SeriesDefinition seriesDefinition in seriesDefinitions)
            {
                meter.Channels.Add(ParseSeries(seriesDefinition));
            }

            m_meterDataSet.Meter = meter;

            // Parse triggers from PQube data
            m_meterDataSet.Triggers = PQubeReader.GetTriggers(observationRecords);
        }