Example #1
0
        private void FixCOMTRADEData(COMTRADEData comtradeData, Parser parser, TimeSpan timeZoneOffset)
        {
            // Function to convert a digital channel from the COMTRADE files to COMTRADEChannelData
            Func <DigitalChannel, int, COMTRADEChannelData> toChannelData = (digitalChannel, index) =>
                                                                            new COMTRADEChannelData()
            {
                GroupOrder           = 1,
                LoadOrder            = index,
                OriginalChannelIndex = index,
                Name = digitalChannel.Name,
                Data = new DataSeries(),
                OriginalDigitalChannel = digitalChannel
            };

            // List of COMTRADEChannelData containing data about the digital channels in the COMTRADE file
            List <COMTRADEChannelData> originalDigitalChannelData = parser.Schema.DigitalChannels
                                                                    .Select(toChannelData)
                                                                    .ToList();

            // The number of analog channels in the COMTRADE file
            int analogChannels = parser.Schema.AnalogChannels.Length;

            // Set COMTRADE schema information to match that of the original file
            comtradeData.StationName = parser.Schema.StationName;
            comtradeData.DeviceID    = parser.Schema.DeviceID;

            // First map the analog channel data to the analog channels in the file, then update the analog channel data to match the information in the file
            foreach (var mapping in comtradeData.AnalogChannelData.Join(parser.Schema.AnalogChannels, channelData => channelData.OriginalChannelIndex, channel => channel.Index, (channelData, channel) => new { ChannelData = channelData, Channel = channel }))
            {
                mapping.ChannelData.Name = mapping.Channel.Name;
                mapping.ChannelData.OriginalAnalogChannel = mapping.Channel;
            }

            // Populate the new digital channels with data from the COMTRADE file
            while (parser.ReadNext())
            {
                foreach (COMTRADEChannelData channelData in originalDigitalChannelData)
                {
                    channelData.Data.DataPoints.Add(new DataPoint()
                    {
                        Time  = parser.Timestamp + timeZoneOffset,
                        Value = parser.Values[analogChannels + channelData.OriginalChannelIndex]
                    });
                }
            }

            // Add the new digital channels to the digitalChannelData collection
            comtradeData.DigitalChannelData.AddRange(originalDigitalChannelData);
        }
Example #2
0
        private void WriteResults(EventDataSet eventDataSet, Parser originalFileParser)
        {
            // Assume the data file path is the same as the results file path
            // and determine the path to the header and schema files
            string directory      = FilePath.GetDirectoryName(eventDataSet.ResultsPath);
            string rootFileName   = FilePath.GetFileNameWithoutExtension(eventDataSet.ResultsPath);
            string headerFilePath = Path.Combine(directory, rootFileName + ".hdr");
            string schemaFilePath = Path.Combine(directory, rootFileName + ".cfg");
            string dataFilePath   = eventDataSet.ResultsPath;
            Schema schema;

            // Get structures containing the data to be written to the results files
            COMTRADEData comtradeData = new COMTRADEData();

            // If there are no waveforms to be written to the file, give up
            if (!eventDataSet.OutputChannels.Any())
            {
                return;
            }

            comtradeData.StationName   = eventDataSet.MeterDataSet.Meter.Name;
            comtradeData.DeviceID      = eventDataSet.MeterDataSet.Meter.AssetKey;
            comtradeData.DataStartTime = eventDataSet.DataGroup.StartTime;
            comtradeData.SampleCount   = eventDataSet.DataGroup.Samples;
            comtradeData.SamplingRate  = eventDataSet.DataGroup.Samples / (eventDataSet.DataGroup.EndTime - eventDataSet.DataGroup.StartTime).TotalSeconds;

            comtradeData.AnalogChannelData  = GetAnalogChannelData(eventDataSet);
            comtradeData.DigitalChannelData = GetDigitalChannelData(eventDataSet);

            // If the original file is available, use data from the original file
            // in order to update the data to be written to the results files
            if ((object)originalFileParser != null)
            {
                FixCOMTRADEData(comtradeData, originalFileParser, eventDataSet.TimeZoneOffset);
            }

            // Write data to the header file
            WriteHeaderFile(eventDataSet, headerFilePath);

            // Write data to the schema file
            schema = WriteSchemaFile(comtradeData, schemaFilePath);

            // Write data to the data file
            WriteDataFile(comtradeData, schema, dataFilePath);
        }
Example #3
0
        private void WriteDataFile(COMTRADEData comtradeData, Schema schema, string dataFilePath)
        {
            // Function to get the value at a given index from a data series
            Func <DataSeries, int, double> valueAt = (series, i) =>
                                                     (i < series.DataPoints.Count)
                ? series.DataPoints[i].Value
                : series.DataPoints.Last().Value;

            // Get the list of data series for every channel in the COMTRADE file
            IEnumerable <DataSeries> digitalSeriesList = comtradeData.DigitalChannelData
                                                         .Select(channelData => channelData.Data)
                                                         .Select((series, index) => series.Multiply(Math.Pow(2.0D, index % 16)))
                                                         .Select((series, index) => Tuple.Create(index / 16, series))
                                                         .GroupBy(tuple => tuple.Item1)
                                                         .Select(group => group.Select(tuple => tuple.Item2))
                                                         .Select(group => group.Aggregate((sum, series) => sum.Add(series)));

            List <DataSeries> allChannels = comtradeData.AnalogChannelData
                                            .Select(channelData => channelData.Data)
                                            .Concat(digitalSeriesList)
                                            .ToList();

            // Use the longest data series as the series
            // from which time values will be used
            DataSeries timeSeries = allChannels
                                    .OrderByDescending(series => series.DataPoints.Count)
                                    .First();

            // Open the data file for writing
            using (FileStream fileStream = File.Create(FilePath.GetAbsolutePath(dataFilePath)))
            {
                // Write the timestamp and values to each line of the data file
                for (int i = 0; i < comtradeData.SampleCount; i++)
                {
                    Ticks timestamp = timeSeries.DataPoints[i].Time;

                    double[] values = allChannels
                                      .Select(series => valueAt(series, i))
                                      .ToArray();

                    Writer.WriteNextRecordBinary(fileStream, schema, timestamp, values, (uint)i, false);
                }
            }
        }
        private Schema WriteSchemaFile(COMTRADEData comtradeData, string schemaFilePath)
        {
            Schema schema = Writer.CreateSchema(new List<ChannelMetadata>(), comtradeData.StationName, comtradeData.DeviceID, comtradeData.DataStartTime, comtradeData.SampleCount, samplingRate: comtradeData.SamplingRate, includeFracSecDefinition: false, nominalFrequency: m_systemFrequency);
            List<AnalogChannel> analogChannels = new List<AnalogChannel>();
            List<DigitalChannel> digitalChannels = new List<DigitalChannel>();
            int i = 1;

            // Populate the analog channel list with analog channel metadata
            foreach (COMTRADEChannelData channelData in comtradeData.AnalogChannelData)
            {
                AnalogChannel analogChannel = new AnalogChannel();

                analogChannel.Index = i;
                analogChannel.Name = channelData.Name;
                analogChannel.MinValue = -short.MaxValue;
                analogChannel.MaxValue = short.MaxValue;
                analogChannel.Units = channelData.Units;

                if ((object)channelData.OriginalAnalogChannel != null)
                {
                    analogChannel.PhaseID = channelData.OriginalAnalogChannel.PhaseID;
                    analogChannel.CircuitComponent = channelData.OriginalAnalogChannel.CircuitComponent;
                    analogChannel.Units = channelData.OriginalAnalogChannel.Units;
                    analogChannel.Skew = channelData.OriginalAnalogChannel.Skew;
                    analogChannel.PrimaryRatio = channelData.OriginalAnalogChannel.PrimaryRatio;
                    analogChannel.SecondaryRatio = channelData.OriginalAnalogChannel.SecondaryRatio;
                    analogChannel.ScalingIdentifier = channelData.OriginalAnalogChannel.ScalingIdentifier;

                    if (analogChannel.Units.ToUpper().Contains("KA") || analogChannel.Units.ToUpper().Contains("KV"))
                        channelData.Data = channelData.Data.Multiply(0.001);
                }

                analogChannel.Multiplier = (channelData.Data.Maximum - channelData.Data.Minimum) / (2 * short.MaxValue);
                analogChannel.Adder = (channelData.Data.Maximum + channelData.Data.Minimum) / 2.0D;

                analogChannels.Add(analogChannel);

                i++;
            }

            i = 1;

            // Populate the digital channel list with digital channel metadata
            foreach (COMTRADEChannelData channelData in comtradeData.DigitalChannelData)
            {
                DigitalChannel digitalChannel = new DigitalChannel();

                digitalChannel.Index = i;
                digitalChannel.Name = channelData.Name;

                if ((object)channelData.OriginalDigitalChannel != null)
                {
                    digitalChannel.PhaseID = channelData.OriginalDigitalChannel.PhaseID;
                    digitalChannel.CircuitComponent = channelData.OriginalDigitalChannel.CircuitComponent;
                    digitalChannel.NormalState = channelData.OriginalDigitalChannel.NormalState;
                }

                digitalChannels.Add(digitalChannel);

                i++;
            }

            schema.AnalogChannels = analogChannels.ToArray();
            schema.DigitalChannels = digitalChannels.ToArray();

            // Dump the generated schema to the schema file
            File.WriteAllText(FilePath.GetAbsolutePath(schemaFilePath), schema.FileImage, Encoding.ASCII);

            // Return the schema
            return schema;
        }
        private void WriteResults(EventDataSet eventDataSet, Parser originalFileParser)
        {
            // Assume the data file path is the same as the results file path
            // and determine the path to the header and schema files
            string directory = FilePath.GetDirectoryName(eventDataSet.ResultsPath);
            string rootFileName = FilePath.GetFileNameWithoutExtension(eventDataSet.ResultsPath);
            string headerFilePath = Path.Combine(directory, rootFileName + ".hdr");
            string schemaFilePath = Path.Combine(directory, rootFileName + ".cfg");
            string dataFilePath = eventDataSet.ResultsPath;
            Schema schema;

            // Get structures containing the data to be written to the results files
            COMTRADEData comtradeData = new COMTRADEData();

            // If there are no waveforms to be written to the file, give up
            if (!eventDataSet.OutputChannels.Any())
                return;

            comtradeData.StationName = eventDataSet.MeterDataSet.Meter.Name;
            comtradeData.DeviceID = eventDataSet.MeterDataSet.Meter.AssetKey;
            comtradeData.DataStartTime = eventDataSet.DataGroup.StartTime;
            comtradeData.SampleCount = eventDataSet.DataGroup.Samples;
            comtradeData.SamplingRate = eventDataSet.DataGroup.Samples / (eventDataSet.DataGroup.EndTime - eventDataSet.DataGroup.StartTime).TotalSeconds;

            comtradeData.AnalogChannelData = GetAnalogChannelData(eventDataSet);
            comtradeData.DigitalChannelData = GetDigitalChannelData(eventDataSet);

            // If the original file is available, use data from the original file
            // in order to update the data to be written to the results files
            if ((object)originalFileParser != null)
                FixCOMTRADEData(comtradeData, originalFileParser, eventDataSet.TimeZoneOffset);

            // Write data to the header file
            WriteHeaderFile(eventDataSet, headerFilePath);

            // Write data to the schema file
            schema = WriteSchemaFile(comtradeData, schemaFilePath);

            // Write data to the data file
            WriteDataFile(comtradeData, schema, dataFilePath);
        }
        private void WriteDataFile(COMTRADEData comtradeData, Schema schema, string dataFilePath)
        {
            // Function to get the value at a given index from a data series
            Func<DataSeries, int, double> valueAt = (series, i) =>
                (i < series.DataPoints.Count)
                ? series.DataPoints[i].Value
                : series.DataPoints.Last().Value;

            // Get the list of data series for every channel in the COMTRADE file
            IEnumerable<DataSeries> digitalSeriesList = comtradeData.DigitalChannelData
                .Select(channelData => channelData.Data)
                .Select((series, index) => series.Multiply(Math.Pow(2.0D, index % 16)))
                .Select((series, index) => Tuple.Create(index / 16, series))
                .GroupBy(tuple => tuple.Item1)
                .Select(group => group.Select(tuple => tuple.Item2))
                .Select(group => group.Aggregate((sum, series) => sum.Add(series)));

            List<DataSeries> allChannels = comtradeData.AnalogChannelData
                .Select(channelData => channelData.Data)
                .Concat(digitalSeriesList)
                .ToList();

            // Use the longest data series as the series
            // from which time values will be used
            DataSeries timeSeries = allChannels
                .OrderByDescending(series => series.DataPoints.Count)
                .First();

            // Open the data file for writing
            using (FileStream fileStream = File.Create(FilePath.GetAbsolutePath(dataFilePath)))
            {
                // Write the timestamp and values to each line of the data file
                for (int i = 0; i < comtradeData.SampleCount; i++)
                {
                    Ticks timestamp = timeSeries.DataPoints[i].Time;

                    double[] values = allChannels
                        .Select(series => valueAt(series, i))
                        .ToArray();

                    Writer.WriteNextRecordBinary(fileStream, schema, timestamp, values, (uint)i, false);
                }
            }
        }
        private void FixCOMTRADEData(COMTRADEData comtradeData, Parser parser, TimeSpan timeZoneOffset)
        {
            // Function to convert a digital channel from the COMTRADE files to COMTRADEChannelData
            Func<DigitalChannel, int, COMTRADEChannelData> toChannelData = (digitalChannel, index) =>
                new COMTRADEChannelData()
                {
                    GroupOrder = 1,
                    LoadOrder = index,
                    OriginalChannelIndex = index,
                    Name = digitalChannel.Name,
                    Data = new DataSeries(),
                    OriginalDigitalChannel = digitalChannel
                };

            // List of COMTRADEChannelData containing data about the digital channels in the COMTRADE file
            List<COMTRADEChannelData> originalDigitalChannelData = parser.Schema.DigitalChannels
                .Select(toChannelData)
                .ToList();

            // The number of analog channels in the COMTRADE file
            int analogChannels = parser.Schema.AnalogChannels.Length;

            // Set COMTRADE schema information to match that of the original file
            comtradeData.StationName = parser.Schema.StationName;
            comtradeData.DeviceID = parser.Schema.DeviceID;

            // First map the analog channel data to the analog channels in the file, then update the analog channel data to match the information in the file
            foreach (var mapping in comtradeData.AnalogChannelData.Join(parser.Schema.AnalogChannels, channelData => channelData.OriginalChannelIndex, channel => channel.Index, (channelData, channel) => new { ChannelData = channelData, Channel = channel }))
            {
                mapping.ChannelData.Name = mapping.Channel.Name;
                mapping.ChannelData.OriginalAnalogChannel = mapping.Channel;
            }

            // Populate the new digital channels with data from the COMTRADE file
            while (parser.ReadNext())
            {
                foreach (COMTRADEChannelData channelData in originalDigitalChannelData)
                {
                    channelData.Data.DataPoints.Add(new DataPoint()
                    {
                        Time = parser.Timestamp + timeZoneOffset,
                        Value = parser.Values[analogChannels + channelData.OriginalChannelIndex]
                    });
                }
            }

            // Add the new digital channels to the digitalChannelData collection
            comtradeData.DigitalChannelData.AddRange(originalDigitalChannelData);
        }
Example #8
0
        private Schema WriteSchemaFile(COMTRADEData comtradeData, string schemaFilePath)
        {
            Schema schema = Writer.CreateSchema(new List <ChannelMetadata>(), comtradeData.StationName, comtradeData.DeviceID, comtradeData.DataStartTime, comtradeData.SampleCount, samplingRate: comtradeData.SamplingRate, includeFracSecDefinition: false, nominalFrequency: m_systemFrequency);
            List <AnalogChannel>  analogChannels  = new List <AnalogChannel>();
            List <DigitalChannel> digitalChannels = new List <DigitalChannel>();
            int i = 1;

            // Populate the analog channel list with analog channel metadata
            foreach (COMTRADEChannelData channelData in comtradeData.AnalogChannelData)
            {
                AnalogChannel analogChannel = new AnalogChannel();

                analogChannel.Index    = i;
                analogChannel.Name     = channelData.Name;
                analogChannel.MinValue = -short.MaxValue;
                analogChannel.MaxValue = short.MaxValue;
                analogChannel.Units    = channelData.Units;

                if ((object)channelData.OriginalAnalogChannel != null)
                {
                    analogChannel.PhaseID           = channelData.OriginalAnalogChannel.PhaseID;
                    analogChannel.CircuitComponent  = channelData.OriginalAnalogChannel.CircuitComponent;
                    analogChannel.Units             = channelData.OriginalAnalogChannel.Units;
                    analogChannel.Skew              = channelData.OriginalAnalogChannel.Skew;
                    analogChannel.PrimaryRatio      = channelData.OriginalAnalogChannel.PrimaryRatio;
                    analogChannel.SecondaryRatio    = channelData.OriginalAnalogChannel.SecondaryRatio;
                    analogChannel.ScalingIdentifier = channelData.OriginalAnalogChannel.ScalingIdentifier;

                    if (analogChannel.Units.ToUpper().Contains("KA") || analogChannel.Units.ToUpper().Contains("KV"))
                    {
                        channelData.Data = channelData.Data.Multiply(0.001);
                    }
                }

                analogChannel.Multiplier = (channelData.Data.Maximum - channelData.Data.Minimum) / (2 * short.MaxValue);
                analogChannel.Adder      = (channelData.Data.Maximum + channelData.Data.Minimum) / 2.0D;

                analogChannels.Add(analogChannel);

                i++;
            }

            i = 1;

            // Populate the digital channel list with digital channel metadata
            foreach (COMTRADEChannelData channelData in comtradeData.DigitalChannelData)
            {
                DigitalChannel digitalChannel = new DigitalChannel();

                digitalChannel.Index = i;
                digitalChannel.Name  = channelData.Name;

                if ((object)channelData.OriginalDigitalChannel != null)
                {
                    digitalChannel.PhaseID          = channelData.OriginalDigitalChannel.PhaseID;
                    digitalChannel.CircuitComponent = channelData.OriginalDigitalChannel.CircuitComponent;
                    digitalChannel.NormalState      = channelData.OriginalDigitalChannel.NormalState;
                }

                digitalChannels.Add(digitalChannel);

                i++;
            }

            schema.AnalogChannels  = analogChannels.ToArray();
            schema.DigitalChannels = digitalChannels.ToArray();

            // Dump the generated schema to the schema file
            File.WriteAllText(FilePath.GetAbsolutePath(schemaFilePath), schema.FileImage, Encoding.ASCII);

            // Return the schema
            return(schema);
        }