public CsvStats StripByEvents(string startString, string endString, bool invert, out int numFramesStripped) { CsvStats newCsvStats = new CsvStats(); List <int> startIndices = null; List <int> endIndices = null; GetEventFrameIndexDelimiters(startString, endString, out startIndices, out endIndices); numFramesStripped = 0; if (startIndices.Count == 0) { return(this); } numFramesStripped = -1; int frameCount = 0; // Strip out samples and recompute averages foreach (StatSamples stat in Stats.Values) { StatSamples newStat = new StatSamples(stat, false); newStat.samples = new List <float>(SampleCount); int stripEventIndex = 0; for (int i = 0; i < stat.samples.Count; i++) { int startIndex = (stripEventIndex < startIndices.Count) ? startIndices[stripEventIndex] : stat.samples.Count; int endIndex = (stripEventIndex < endIndices.Count) ? endIndices[stripEventIndex] : stat.samples.Count; if (i < startIndex) { newStat.samples.Add(stat.samples[i]); } else { if (i == endIndex) { stripEventIndex++; } } } if (numFramesStripped == -1) { numFramesStripped = stat.samples.Count - newStat.samples.Count; frameCount = stat.samples.Count; } newStat.ComputeAverageAndTotal(); newCsvStats.AddStat(newStat); } // Strip out the events int FrameOffset = 0; { int stripEventIndex = 0; for (int i = 0; i < Events.Count; i++) { CsvEvent csvEvent = Events[i]; int startIndex = (stripEventIndex < startIndices.Count) ? startIndices[stripEventIndex] : frameCount; int endIndex = (stripEventIndex < endIndices.Count) ? endIndices[stripEventIndex] : frameCount; CsvEvent newEvent = new CsvEvent(csvEvent.Name, csvEvent.Frame + FrameOffset); if (csvEvent.Frame < startIndex) { newCsvStats.Events.Add(newEvent); } else { if (csvEvent.Frame == startIndex) { // Check if this is the last event this frame if (i == Events.Count - 1 || Events[i + 1].Frame != csvEvent.Frame) { // Subsequent events will get offset by this amount FrameOffset -= endIndex - startIndex; } } if (csvEvent.Frame == endIndex + 1) { newCsvStats.Events.Add(newEvent); stripEventIndex++; } } } } newCsvStats.metaData = metaData; return(newCsvStats); }
// This will average only those stats that exist in all the stat sets // Stats are averaged per frame, and the the final length is be equal to the longest CSV // If CSVs are of varying length, this means later frames will be averaged over fewer samples than earlier frames public static CsvStats AverageByFrame(CsvStats[] statsToAvg, bool bStatsAvarage = false) { CsvStats avgStats = new CsvStats(); if (statsToAvg.Length > 0) { // We need to have all the frame per each stat in the file int maxFrames = 0; // Use the first as stat name basis string[] statKeys = statsToAvg[0].Stats.Keys.ToArray(); foreach (string statName in statKeys) { int maxSamples = 0; int statCount = 0; foreach (CsvStats stats in statsToAvg) { // Remove from the set of new stats if // it doesn't exist in one of the set. if (stats.Stats.ContainsKey(statName)) { maxSamples = Math.Max(stats.Stats[statName].samples.Count, maxSamples); statCount++; } } if (statCount == statsToAvg.Length && maxSamples > 0) { avgStats.AddStat(new StatSamples(statName)); maxFrames = Math.Max(maxFrames, maxSamples); } } // Copy meta data avgStats.metaData = statsToAvg[0].metaData; if (avgStats.metaData != null) { foreach (CsvStats stats in statsToAvg) { avgStats.metaData.CombineAndValidate(stats.metaData); } } foreach (string statName in avgStats.Stats.Keys) { // This should always exist StatSamples avgSamples = avgStats.GetStat(statName); if (avgSamples != null) { List <int> sampleCounts = new List <int>(); sampleCounts.AddRange(Enumerable.Repeat(0, maxFrames)); // Initialise sample to 0.0 avgSamples.samples.AddRange(Enumerable.Repeat(0.0f, maxFrames)); // Add samples from other stats foreach (CsvStats stats in statsToAvg) { StatSamples statSamples = stats.GetStat(statName); if ((statSamples != null) && (avgSamples.samples.Count >= statSamples.samples.Count)) { // This should always be true: avgSamples.samples.Count >= statSamples.samples.Count for (int i = 0; i < statSamples.samples.Count; i++) { avgSamples.samples[i] += statSamples.samples[i]; sampleCounts[i] += 1; } } } // Average the samples for (int i = 0; i < avgSamples.samples.Count; i++) { avgSamples.samples[i] /= (float)sampleCounts[i]; } } if (bStatsAvarage) { avgSamples.ComputeAverageAndTotal(); } } } return(avgStats); }