/// <summary> /// Creates a new instance of the <see cref="CorrectiveParser"/> class. /// </summary> public CorrectiveParser() { m_parser = new Parser(); }
/// <summary> /// Opens all EMAX data file streams. /// </summary> public void OpenFiles() { long previousMilliseconds; long milliseconds; int count; int sampleRate; int distributionIndex; m_parser.OpenFiles(); sampleRate = m_parser.ControlFile.SystemParameters.samples_per_second; m_subsecondDistribution = Ticks.SubsecondDistribution(sampleRate); using (Parser parser = new Parser()) { parser.ControlFile = m_parser.ControlFile; parser.FileName = m_parser.FileName; // Open EMAX data file parser.OpenFiles(); m_currentSecond = DateTime.MinValue; previousMilliseconds = -1; milliseconds = 0; count = 0; while (parser.ReadNext()) { // Set currentSecond to this frame's timestamp m_currentSecond = parser.Timestamp; // Get total milliseconds since epoch milliseconds = m_currentSecond.Ticks / Ticks.PerMillisecond; // If the milliseconds are exactly one millisecond greater than the previous // timestamp's milliseconds, we can accurately find the timestamp of this frame if (previousMilliseconds > 0 && milliseconds - previousMilliseconds == 1) break; // Update previousMilliseconds and count previousMilliseconds = milliseconds; count++; } // Remove subseconds from currentSecond m_currentSecond = m_currentSecond.AddTicks(-(m_currentSecond.Ticks % Ticks.PerSecond)); // Get the milliseconds since the top of the second milliseconds %= 1000; // This should get very near to the index of the // desired value in the subsecond distribution distributionIndex = ((int)milliseconds * sampleRate) / 1000; // Scan forward in the subsecond distribution until we are sure we've found the correct index while ((long)m_subsecondDistribution[distributionIndex].ToMilliseconds() != milliseconds) distributionIndex++; // Set currentIndex to the index in the distribution of the first timestamp in this file m_currentIndex = distributionIndex - count; // Subtract seconds from currentSecond and add the equivalent number of indexes // to currentIndex until currentIndex is greater than or equal to zero while (m_currentIndex < 0) { m_currentSecond = m_currentSecond.AddSeconds(-1.0D); m_currentIndex += sampleRate; } } }
/// <summary> /// Closes all EMAX data file streams. /// </summary> public void CloseFiles() { if ((object)m_parser != null) { m_parser.Dispose(); m_parser = null; } }
/// <summary> /// Opens all EMAX data file streams. /// </summary> public void OpenFiles() { long previousMilliseconds; long milliseconds; int count; int sampleRate; int distributionIndex; m_parser.OpenFiles(); sampleRate = m_parser.ControlFile.SystemParameters.samples_per_second; m_subsecondDistribution = Ticks.SubsecondDistribution(sampleRate); using (Parser parser = new Parser()) { parser.ControlFile = m_parser.ControlFile; parser.FileName = m_parser.FileName; // Open EMAX data file parser.OpenFiles(); m_currentSecond = DateTime.MinValue; previousMilliseconds = -1; milliseconds = 0; count = 0; while (parser.ReadNext()) { if (parser.TimeError) continue; // Set currentSecond to this frame's timestamp m_currentSecond = parser.Timestamp; // Get total milliseconds since epoch milliseconds = m_currentSecond.Ticks / Ticks.PerMillisecond; // If the milliseconds are exactly one millisecond greater than the previous // timestamp's milliseconds, we can accurately find the timestamp of this frame if (previousMilliseconds > 0 && milliseconds - previousMilliseconds == 1) break; // Update previousMilliseconds and count previousMilliseconds = milliseconds; count++; } if (m_currentSecond == DateTime.MinValue) { // If there was an error reading the timestamps in the parser, // calculate the timestamp from the data in the control file TimeZoneInfo tzInfo = parser.ControlFile.SystemParameters.GetTimeZoneInfo(); DateTime faultTime = parser.ControlFile.SystemParameters.FaultTime; string daylightName = parser.ControlFile.SystemParameters.time_zone_information.DaylightName; short faultMilliseconds = parser.ControlFile.SystemParameters.mS_time; short prefaultSamples = parser.ControlFile.SystemParameters.prefault_samples; short startOffsetSamples = parser.ControlFile.SystemParameters.start_offset_samples; // Set currentSecond to the timestamp of the first frame m_currentSecond = faultTime.AddMilliseconds(faultMilliseconds).AddSeconds(-(prefaultSamples + startOffsetSamples) / (double)sampleRate); // Get total milliseconds since epoch milliseconds = m_currentSecond.Ticks / Ticks.PerMillisecond; // Timestamps in the control file are stored in UTC (or close to it), // but it seems that sometimes EMAX adjusts timestamps without applying DST // rules so we use the DaylightName of the time zone info as a sanity check // and fall back on the BaseUtcOffset property in these weird cases if (daylightName == tzInfo.DaylightName || daylightName != tzInfo.Id) m_currentSecond = TimeZoneInfo.ConvertTimeFromUtc(m_currentSecond, tzInfo); else m_currentSecond += tzInfo.BaseUtcOffset; m_currentSecond = DateTime.SpecifyKind(m_currentSecond, DateTimeKind.Unspecified); } // Remove subseconds from currentSecond m_currentSecond = m_currentSecond.AddTicks(-(m_currentSecond.Ticks % Ticks.PerSecond)); // Get the milliseconds since the top of the second milliseconds %= 1000; // This should get very near to the index of the // desired value in the subsecond distribution distributionIndex = ((int)milliseconds * sampleRate) / 1000; // Scan forward in the subsecond distribution until we are sure we've found the correct index while ((long)m_subsecondDistribution[distributionIndex].ToMilliseconds() != milliseconds) distributionIndex++; // Set currentIndex to the index in the distribution of the first timestamp in this file m_currentIndex = distributionIndex - count; // Subtract seconds from currentSecond and add the equivalent number of indexes // to currentIndex until currentIndex is greater than or equal to zero while (m_currentIndex < 0) { m_currentSecond = m_currentSecond.AddSeconds(-1.0D); m_currentIndex += sampleRate; } } }