COMTRADE data file(s) parser.
Inheritance: IDisposable
        public bool CanParse(string filePath, DateTime fileCreationTime)
        {
            string schemaFileName = Path.ChangeExtension(filePath, "cfg");
            string extension = FilePath.GetExtension(filePath);
            string[] fileList = FilePath.GetFileList(Path.ChangeExtension(filePath, "*"));
            bool multipleDataFiles = !extension.Equals(".dat", StringComparison.OrdinalIgnoreCase);

            if (!File.Exists(schemaFileName))
                return false;

            if (fileList.Any(file => !FilePath.TryGetReadLockExclusive(file)))
                return false;

            if (multipleDataFiles && DateTime.UtcNow - fileCreationTime < m_minWaitTime)
                return false;

            try
            {
                m_parser = new Parser();
                m_parser.Schema = new Schema(schemaFileName);
                m_parser.FileName = filePath;
                m_parser.InferTimeFromSampleRates = true;
                m_parser.OpenFiles();
            }
            catch (IOException)
            {
                return false;
            }

            return true;
        }
 public void Dispose()
 {
     if (!m_disposed)
     {
         try
         {
             if ((object)m_parser != null)
             {
                 m_parser.Dispose();
                 m_parser = null;
             }
         }
         finally
         {
             m_disposed = true;
         }
     }
 }
        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);
        }
示例#4
0
        private void COMTRADEButton_Click(object sender, EventArgs e)
        {
            string directory;
            string rootFileName;
            string configurationFileName;

            DateTime?startTime = null;

            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.Filter = "COMTRADE Files|*.dat;*.d00|All Files|*.*";
                dialog.Title  = "Browse COMTRADE Files";

                if (dialog.ShowDialog() == DialogResult.Cancel)
                {
                    return;
                }

                if (!File.Exists(dialog.FileName))
                {
                    return;
                }

                // Comtrade parsing will require a CFG file, make sure this exists...
                directory             = Path.GetDirectoryName(dialog.FileName) ?? string.Empty;
                rootFileName          = FilePath.GetFileNameWithoutExtension(dialog.FileName);
                configurationFileName = Path.Combine(directory, rootFileName + ".cfg");

                if (!File.Exists(configurationFileName))
                {
                    return;
                }

                using (Parser parser = new Parser())
                {
                    parser.Schema   = new Schema(configurationFileName);
                    parser.FileName = dialog.FileName;
                    parser.InferTimeFromSampleRates = true;

                    // Open COMTRADE data files
                    parser.OpenFiles();

                    // Parse COMTRADE schema into channels
                    m_channels = parser.Schema.AnalogChannels
                                 .Select(channel => new ParsedChannel()
                    {
                        Index      = channel.Index,
                        Name       = ((object)channel.ChannelName != null) ? string.Format("{0} ({1})", channel.StationName, channel.ChannelName) : channel.StationName,
                        TimeValues = new List <DateTime>(),
                        XValues    = new List <object>(),
                        YValues    = new List <object>()
                    }).ToList();

                    // Read values from COMTRADE data file
                    while (parser.ReadNext())
                    {
                        if ((object)startTime == null)
                        {
                            startTime = parser.Timestamp;
                        }

                        for (int i = 0; i < m_channels.Count; i++)
                        {
                            m_channels[i].TimeValues.Add(parser.Timestamp);
                            m_channels[i].XValues.Add(parser.Timestamp.Subtract(startTime.Value).TotalSeconds);
                            m_channels[i].YValues.Add(parser.Values[i]);
                        }
                    }
                }

                // Clear the list box and data chart
                ChannelListBox.Items.Clear();
                DataChart.Series.Clear();

                // Populate the list box with channel names
                ChannelListBox.Items.AddRange(m_channels
                                              .Select(channel => string.Format("[{0}] {1}", channel.Index, channel.Name))
                                              .Cast <object>()
                                              .ToArray());

                // Select the first channel in the list
                ChannelListBox.SelectedIndex = 0;

                // Change the title text of the window to show what file the user has open
                m_fileName = dialog.SafeFileName;
                Text       = string.Format("COMTRADE - [{0}]", dialog.SafeFileName);
            }
        }
        private void WriteResults(EventDataSet eventDataSet)
        {
            const StringComparison IgnoreCase = StringComparison.OrdinalIgnoreCase;

            // Get the path to the original data file
            string dataFilePath;
            string directory;
            string rootFileName;
            string schemaFilePath;

            Parser originalFileParser = null;

            dataFilePath = eventDataSet.MeterDataSet.FileGroup.DataFiles
                .Select(dataFile => dataFile.FilePath)
                .FirstOrDefault(path => path.EndsWith(".dat", IgnoreCase) || path.EndsWith(".d00", IgnoreCase));

            if (File.Exists(dataFilePath))
            {
                // Get the path to the original schema file
                directory = FilePath.GetDirectoryName(dataFilePath);
                rootFileName = FilePath.GetFileNameWithoutExtension(dataFilePath);
                schemaFilePath = Path.Combine(directory, rootFileName + ".cfg");

                if (File.Exists(schemaFilePath))
                {
                    // Create a parser to parse the original COMTRADE files
                    originalFileParser = new Parser()
                    {
                        FileName = dataFilePath,
                        InferTimeFromSampleRates = true,
                        Schema = new Schema(schemaFilePath)
                    };
                }
            }

            using (originalFileParser)
            {
                if ((object)originalFileParser != null)
                    originalFileParser.OpenFiles();

                // Write results to the COMTRADE fault record using the parser
                WriteResults(eventDataSet, originalFileParser);
            }
        }
        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);
        }
        /// <summary>
        /// Populate known voltage and current data from PQDIF file.
        /// </summary>
        /// <param name="faultDataSet">Fault data set to be populated.</param>
        /// <param name="settings">Source parameters.</param>
        /// <param name="line">Associated XML event file definition.</param>
        public static void PopulateDataSet(FaultLocationDataSet faultDataSet, Dictionary<string, string> settings, Line line)
        {
            string fileName;

            if ((object)line == null)
                throw new ArgumentNullException("line");

            if (!settings.TryGetValue("fileName", out fileName) || !File.Exists(fileName))
                throw new ArgumentException("Parameters must define a valid \"fileName\" setting.");

            // Comtrade parsing will require a CFG file, make sure this exists...
            string directory = Path.GetDirectoryName(fileName) ?? string.Empty;
            string rootFileName = FilePath.GetFileNameWithoutExtension(fileName);
            string configurationFileName = Path.Combine(directory, rootFileName + ".cfg");

            if (!File.Exists(configurationFileName))
                throw new FileNotFoundException(string.Format("Associated CFG file \"{0}\" for COMTRADE data file does not exist - cannot parse COMTRADE file.", configurationFileName));

            // Parse configuration file
            Schema schema = new Schema(configurationFileName);

            // Find <Channels> element in XML line definition
            XElement channels = line.ChannelsElement;

            if ((object)channels == null)
                throw new NullReferenceException("No \"<channels>\" element was found in event file definition - cannot load COMTRADE data file.");

            // Extract COMTRADE channel ID's for desired voltage and current elements
            IEnumerable<Tuple<int, int>> vaIndexes = GetValueIndex(schema, channels, "VA").ToList();
            IEnumerable<Tuple<int, int>> vbIndexes = GetValueIndex(schema, channels, "VB").ToList();
            IEnumerable<Tuple<int, int>> vcIndexes = GetValueIndex(schema, channels, "VC").ToList();
            IEnumerable<Tuple<int, int>> iaIndexes = GetValueIndex(schema, channels, "IA").ToList();
            IEnumerable<Tuple<int, int>> ibIndexes = GetValueIndex(schema, channels, "IB").ToList();
            IEnumerable<Tuple<int, int>> icIndexes = GetValueIndex(schema, channels, "IC").ToList();

            List<long> times = new List<long>();
            List<double> vaValues = new List<double>();
            List<double> vbValues = new List<double>();
            List<double> vcValues = new List<double>();
            List<double> iaValues = new List<double>();
            List<double> ibValues = new List<double>();
            List<double> icValues = new List<double>();

            SampleRate sampleRate;

            ValidateIndexes("VA", vaIndexes);
            ValidateIndexes("VB", vbIndexes);
            ValidateIndexes("VC", vcIndexes);
            ValidateIndexes("IA", iaIndexes);
            ValidateIndexes("IB", ibIndexes);
            ValidateIndexes("IC", icIndexes);

            // Create a new COMTRADE file parser
            using (Parser parser = new Parser()
            {
                Schema = schema,
                FileName = fileName,
                InferTimeFromSampleRates = true
            })
            {
                // Open COMTRADE data files
                parser.OpenFiles();

                faultDataSet.Frequency = schema.NominalFrequency;
                sampleRate = schema.SampleRates.First();

                if (sampleRate.Rate != 0)
                    faultDataSet.SetSampleRates((int)(sampleRate.Rate / faultDataSet.Frequency));

                // Read all COMTRADE records
                while (parser.ReadNext())
                {
                    times.Add(parser.Timestamp.Ticks);
                    vaValues.Add(GetValue(parser, vaIndexes));
                    vbValues.Add(GetValue(parser, vbIndexes));
                    vcValues.Add(GetValue(parser, vcIndexes));
                    iaValues.Add(GetValue(parser, iaIndexes));
                    ibValues.Add(GetValue(parser, ibIndexes));
                    icValues.Add(GetValue(parser, icIndexes));
                }
            }

            // Populate voltage data set
            faultDataSet.Voltages.AN.Times = times.ToArray();
            faultDataSet.Voltages.AN.Measurements = vaValues.ToArray();
            faultDataSet.Voltages.BN.Times = times.ToArray();
            faultDataSet.Voltages.BN.Measurements = vbValues.ToArray();
            faultDataSet.Voltages.CN.Times = times.ToArray();
            faultDataSet.Voltages.CN.Measurements = vcValues.ToArray();

            // Populate current data set
            faultDataSet.Currents.AN.Times = times.ToArray();
            faultDataSet.Currents.AN.Measurements = iaValues.ToArray();
            faultDataSet.Currents.BN.Times = times.ToArray();
            faultDataSet.Currents.BN.Measurements = ibValues.ToArray();
            faultDataSet.Currents.CN.Times = times.ToArray();
            faultDataSet.Currents.CN.Measurements = icValues.ToArray();
        }
 // Gets the actual value as the combination of the given indexes.
 private static double GetValue(Parser parser, IEnumerable<Tuple<int, int>> indexes)
 {
     return indexes.Sum(index => index.Item1 * parser.Values[index.Item2]);
 }
        private void COMTRADEButton_Click(object sender, EventArgs e)
        {
            string directory;
            string rootFileName;
            string configurationFileName;

            DateTime? startTime = null;

            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.Filter = "COMTRADE Files|*.dat;*.d00|All Files|*.*";
                dialog.Title = "Browse COMTRADE Files";

                if (dialog.ShowDialog() == DialogResult.Cancel)
                    return;

                if (!File.Exists(dialog.FileName))
                    return;

                // Comtrade parsing will require a CFG file, make sure this exists...
                directory = Path.GetDirectoryName(dialog.FileName) ?? string.Empty;
                rootFileName = FilePath.GetFileNameWithoutExtension(dialog.FileName);
                configurationFileName = Path.Combine(directory, rootFileName + ".cfg");

                if (!File.Exists(configurationFileName))
                    return;

                using (Parser parser = new Parser())
                {
                    parser.Schema = new Schema(configurationFileName);
                    parser.FileName = dialog.FileName;
                    parser.InferTimeFromSampleRates = true;

                    // Open COMTRADE data files
                    parser.OpenFiles();

                    // Parse COMTRADE schema into channels
                    m_channels = parser.Schema.AnalogChannels
                        .Select(channel => new ParsedChannel()
                        {
                            Index = channel.Index,
                            Name = ((object)channel.ChannelName != null) ? string.Format("{0} ({1})", channel.StationName, channel.ChannelName) : channel.StationName,
                            TimeValues = new List<DateTime>(),
                            XValues = new List<object>(),
                            YValues = new List<object>()
                        }).ToList();

                    // Read values from COMTRADE data file
                    while (parser.ReadNext())
                    {
                        if ((object)startTime == null)
                            startTime = parser.Timestamp;

                        for (int i = 0; i < m_channels.Count; i++)
                        {
                            m_channels[i].TimeValues.Add(parser.Timestamp);
                            m_channels[i].XValues.Add(parser.Timestamp.Subtract(startTime.Value).TotalSeconds);
                            m_channels[i].YValues.Add(parser.Values[i]);
                        }
                    }
                }

                // Clear the list box and data chart
                ChannelListBox.Items.Clear();
                DataChart.Series.Clear();

                // Populate the list box with channel names
                ChannelListBox.Items.AddRange(m_channels
                    .Select(channel => string.Format("[{0}] {1}", channel.Index, channel.Name))
                    .Cast<object>()
                    .ToArray());

                // Select the first channel in the list
                ChannelListBox.SelectedIndex = 0;

                // Change the title text of the window to show what file the user has open
                m_fileName = dialog.SafeFileName;
                Text = string.Format("COMTRADE - [{0}]", dialog.SafeFileName);
            }
        }