/// <summary> /// Constructor used for Phase Termination Chart /// </summary> /// <param name="phase_number"></param> /// <param name="TerminationEventsTable"></param> /// <param name="consecutive_count"></param> public AnalysisPhaseUDOT(byte phase_number, List <PhaseTerminationEvents> TerminationEventsTable, int consecutive_count) { PhaseNumber = phase_number; IEnumerable <PhaseTerminationEvents> termRow; termRow = TerminationEventsTable.Where(d => (d.EventParam == phase_number & (d.EventCode == 4 | d.EventCode == 5 | d.EventCode == 6))).OrderBy(d => d.TimeStamp); IEnumerable <PhaseTerminationEvents> pedRow; pedRow = TerminationEventsTable.Where(d => d.EventParam == phase_number & (d.EventCode == 21 | d.EventCode == 23)).OrderBy(d => d.TimeStamp); foreach (PhaseTerminationEvents row in termRow) { ControllerEvent tEvent = new ControllerEvent(row.TimeStamp, row.EventCode); TerminationEvents.Add(tEvent); } foreach (PhaseTerminationEvents row in pedRow) { ControllerEvent tEvent = new ControllerEvent(Globals.UDOTSignalID, row.TimeStamp, row.EventCode, row.EventParam); PedestrianEvents.Add(tEvent); } ConsecutiveGapOuts = FindConsecutiveEvents(TerminationEvents, 4, consecutive_count); ConsecutiveMaxOut = FindConsecutiveEvents(TerminationEvents, 5, consecutive_count); ConsecutiveForceOff = FindConsecutiveEvents(TerminationEvents, 6, consecutive_count); UnknownTermination = FindUnknownTerminationEvents(TerminationEvents); // updated 10/2/18 // UnknownTermination = FindConsecutiveEvents(TerminationEvents, 7, consecutive_count) PercentMaxOuts = FindPercentageConsecutiveEvents(TerminationEvents, 5, consecutive_count); PercentForceOffs = FindPercentageConsecutiveEvents(TerminationEvents, 6, consecutive_count); TotalPhaseTerminations = TerminationEvents.Count; }
// added UDOT v4 - 10/2/18 private List <ControllerEvent> FindUnknownTerminationEvents(List <ControllerEvent> terminationEvents) { List <ControllerEvent> unknownTermEvents = new List <ControllerEvent>(); for (var x = 0; x <= terminationEvents.Count - 2; x++) { ControllerEvent currentEvent = terminationEvents[x]; ControllerEvent nextEvent = terminationEvents[x + 1]; if (currentEvent.EventCode == 7 & nextEvent.EventCode == 7) { unknownTermEvents.Add(currentEvent); } } return(unknownTermEvents); }
public void GetPlanCollection(DateTime start_date, DateTime end_date, int signal_id, List<SignalPhaseEventsUDOT> signal_table, List<DetectorEventsUDOT> detector_table, List<SignalPhaseEventsUDOT> preempt_table) { Globals.UDOTPatternChange.Clear(); // new v4 code - doesn't work well // Dim ds As New PlanBaseUDOT(signal_id, start_date, end_date) // For i = 0 To ds.Events.Count - 1 // 'if this is the last plan then we want the end of the plan // 'to coincide with the end of the graph // If ds.Events.Count - 1 = i Then // If ds.Events(i).TimeStamp <> end_date Then // Dim plan As New PlanUDOT(ds.Events(i).TimeStamp, end_date, ds.Events(i).EventParam, signal_table, detector_table, preempt_table, mSignalID, mPhase) // AddItem(plan) // Else // If ds.Events(i).TimeStamp <> ds.Events(i + 1).TimeStamp Then // 'else we add the plan with the next plan's timestamp as the end of the plan // Dim plan As New PlanUDOT(ds.Events(i).TimeStamp, ds.Events(i + 1).TimeStamp, ds.Events(i).EventParam, signal_table, detector_table, preempt_table, mSignalID, mPhase) // AddItem(plan) // End If // End If // End If // Next IEnumerable<ControllerEvent> tempPattern; tempPattern = Globals.UDOTEventLog.Where(a => a.TimeStamp >= start_date & a.TimeStamp <= end_date & a.SignalID == signal_id & a.EventCode == 131).OrderBy(a => a.TimeStamp); // 'assume free at midnight for now // Dim firstpattern As New PatternChangeUDOT // firstpattern.TimeStamp = start_date // firstpattern.EventParam = 254 // UDOTPatternChange.Add(firstpattern) foreach (ControllerEvent y in tempPattern) { PatternChange z = new PatternChange(); z.EventParam = y.EventParam; z.TimeStamp = y.TimeStamp; // ignore unknown plan starting at midnight - this will be assumed to be free if (!(y.EventParam == 0 & y.TimeStamp == start_date)) Globals.UDOTPatternChange.Add(z); // updated 3/24/19 to fix logic } // check for plan at start time int startPatterns = Globals.UDOTPatternChange.Where(a => Math.Abs((a.TimeStamp - start_date).TotalMinutes) <= 1).Count(); if (startPatterns == 0) // assume free to start if there are no other plans then Globals.UDOTPatternChange.Add(new PatternChange() { EventParam = 254, TimeStamp = start_date }); // Added 9/29/18 to override running plan with flash List<ControllerEvent> flashPatterns = Globals.UDOTEventLog.Where(a => a.TimeStamp >= start_date & a.TimeStamp <= end_date & a.SignalID == signal_id & a.EventCode == 173).OrderBy(a => a.TimeStamp).ToList(); foreach (var fp in flashPatterns) { if (fp.EventParam == 2) { if (fp.TimeStamp.Hour != 0 & fp.TimeStamp.Minute != 0) { // exit flash and return to normal operation // lookup previous plan (can't be flash plan, which can happen if it's alternating in and out of flash) byte previousPlan = Globals.UDOTPatternChange.Where(a => a.TimeStamp < fp.TimeStamp & a.EventParam != 255).OrderByDescending(a => a.TimeStamp).Select(a => a.EventParam).FirstOrDefault(); PatternChange z = new PatternChange(); z.EventParam = previousPlan; z.TimeStamp = fp.TimeStamp; Globals.UDOTPatternChange.Add(z); // remove plan entries while it's in flash ControllerEvent startFlash = flashPatterns.Where(a => a.TimeStamp < fp.TimeStamp & a.EventParam != 2).OrderByDescending(a => a.TimeStamp).FirstOrDefault(); if (startFlash == null) startFlash = new ControllerEvent(start_date, 1); else { } List<PatternChange> removeEvents = Globals.UDOTPatternChange.Where(a => a.TimeStamp >= startFlash.TimeStamp & a.TimeStamp < fp.TimeStamp & a.EventParam != 255).ToList(); foreach (var e in removeEvents) Globals.UDOTPatternChange.Remove(e); } } else { // controller started in flash PatternChange z = new PatternChange(); z.EventParam = 255; z.TimeStamp = fp.TimeStamp; Globals.UDOTPatternChange.Add(z); } } // Override manual control - added 9/30/18 List<ControllerEvent> manualControl = Globals.UDOTEventLog.Where(a => a.TimeStamp >= start_date & a.TimeStamp <= end_date & a.SignalID == signal_id & a.EventCode == 178).OrderBy(a => a.TimeStamp).ToList(); foreach (var mc in manualControl) { if (mc.EventParam == 0) { // end of manual control, find when it started // look up previous plan byte previousPlan = Globals.UDOTPatternChange.Where(a => a.TimeStamp < mc.TimeStamp & a.EventParam != 253).OrderByDescending(a => a.TimeStamp).Select(a => a.EventParam).FirstOrDefault(); PatternChange z = new PatternChange(); z.EventParam = previousPlan; z.TimeStamp = mc.TimeStamp; Globals.UDOTPatternChange.Add(z); // remove plan entries while it's in manual control ControllerEvent startManual = manualControl.Where(a => a.TimeStamp < mc.TimeStamp & a.EventParam == 0).OrderByDescending(a => a.TimeStamp).FirstOrDefault(); if (startManual == null) startManual = new ControllerEvent(start_date, 1); List<PatternChange> removeEvents = Globals.UDOTPatternChange.Where(a => a.TimeStamp >= mc.TimeStamp & a.TimeStamp < mc.TimeStamp & a.EventParam != 253).ToList(); foreach (var e in removeEvents) Globals.UDOTPatternChange.Remove(e); } else { // controller started in manual control PatternChange z = new PatternChange(); z.EventParam = 253; z.TimeStamp = mc.TimeStamp; Globals.UDOTPatternChange.Add(z); } } // sort the list Globals.UDOTPatternChange = Globals.UDOTPatternChange.OrderBy(a => a.TimeStamp).ToList(); // remove duplicate plan entries int x = -1; // Dim i As Integer = 0 'use to determine index // For Each PCrow As PatternChangeUDOT In UDOTPatternChange // If x = -1 Then // x = PCrow.EventParam // i += 1 // Continue For // ElseIf x <> PCrow.EventParam Then // x = PCrow.EventParam // i += 1 // Continue For // ElseIf x = PCrow.EventParam Then // x = PCrow.EventParam // 'UDOTPatternChange.RemoveAt(i) // i += 1 // Continue For // 'UDOTPatternChange.Remove(PCrow) // End If // i += 1 // Next for (int i = Globals.UDOTPatternChange.Count - 1; i >= 0; i += -1) { if (x == -1) { x = Globals.UDOTPatternChange[i].EventParam; continue; } else if (x != Globals.UDOTPatternChange[i].EventParam) { x = Globals.UDOTPatternChange[i].EventParam; continue; } else if (x == Globals.UDOTPatternChange[i].EventParam) { x = Globals.UDOTPatternChange[i].EventParam; Globals.UDOTPatternChange.RemoveAt(i + 1); continue; } } for (int i = 0; i <= Globals.UDOTPatternChange.Count - 1; i++) { // if this is the last plan then we want the end of the plan // to coincide with the end of the graph if (Globals.UDOTPatternChange.Count() - 1 == i) { if (Globals.UDOTPatternChange[i].TimeStamp != end_date) { PlanUDOT plan = new PlanUDOT(Globals.UDOTPatternChange[i].TimeStamp, end_date, Globals.UDOTPatternChange[i].EventParam, signal_table, detector_table, preempt_table, SignalID, Phase); AddItem(plan); } } else if (Globals.UDOTPatternChange[i].TimeStamp != Globals.UDOTPatternChange[i + 1].TimeStamp) { PlanUDOT plan = new PlanUDOT(Globals.UDOTPatternChange[i].TimeStamp, Globals.UDOTPatternChange[i + 1].TimeStamp, Globals.UDOTPatternChange[i].EventParam, signal_table, detector_table, preempt_table, SignalID, Phase); AddItem(plan); } } }