/// <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();
}