public SpeedExportApproachDirectionCollection(DateTime startDate, DateTime endDate, string signalID, int binSize) { Models.Repositories.ISignalsRepository signalRepository = Models.Repositories.SignalsRepositoryFactory.Create(); var signal = signalRepository.GetSignalBySignalID(signalID); List <Models.Detector> distinctPhases = signal.GetDetectorsForSignalThatSupportAMetric(10); //If there are phases in the database add the charts if (distinctPhases.Count > 0) { foreach (Models.Detector detector in distinctPhases) { //Get the phase int phase = detector.Approach.ProtectedPhaseNumber; string direction = detector.Approach.DirectionType.Description; int movementDelay = detector.MovementDelay.Value; int Decision_Point = detector.DecisionPoint.Value; int MPH = detector.Approach.MPH.Value; Business.SpeedExportApproachDirection approachDirection = new MOE.Common.Business.SpeedExportApproachDirection( startDate, endDate, signalID, phase, detector.DetectorID , direction, MPH, movementDelay, Decision_Point, binSize, detector.MinSpeedFilter.Value, detector.DistanceFromStopBar.Value); this.List.Add(approachDirection); } } }
protected void AddDataToChart(Chart chart) { List <ControllerEventLogs> Tables = new List <ControllerEventLogs>(); List <DateTime> SplitFails = new List <DateTime>(); int totalFails = 0; Models.Repositories.ISignalsRepository signalRepository = Models.Repositories.SignalsRepositoryFactory.Create(); //var signal = signalRepository.GetSignalBySignalID(phase.SignalID); var ApproachDetectors = Phase.Approach.GetDetectorsForMetricType(12); //get occupancy events for each lane for the approach. if (ApproachDetectors.Count() > 0) { foreach (Models.Detector row in ApproachDetectors) { MOE.Common.Business.ControllerEventLogs TEMPdetectortable = new ControllerEventLogs(Phase.SignalID, Options.StartDate, Options.EndDate, row.DetChannel, new List <int>() { 81, 82 }); if (TEMPdetectortable.Events.Count > 0) { Tables.Add(TEMPdetectortable); } } Dictionary <string, string> statistics = new Dictionary <string, string>(); if (Tables.Count > 0) { //for (int CurCycleIndex = 0; CurCycleIndex < phase.Cycles.Count -1 ; CurCycleIndex++) //int tempCycleCounter = 0; //Parallel.ForEach(phase.Cycles, c => foreach (MOE.Common.Business.CustomReport.Cycle c in Phase.Cycles) { //tempCycleCounter++; //SplitFailDetectorActivationCollection activations = new SplitFailDetectorActivationCollection(); //for each lane //Parallel.ForEach(Tables, table => foreach (ControllerEventLogs table in Tables) { int channel = table.Events[0].EventParam; List <MOE.Common.Models.Controller_Event_Log> DetectorHitsForCycle = new List <MOE.Common.Models.Controller_Event_Log>(); //Parallel.ForEach(table.Events, e => foreach (MOE.Common.Models.Controller_Event_Log e in table.Events) { if (e.Timestamp >= c.CycleStart && e.Timestamp <= c.CycleEnd) { DetectorHitsForCycle.Add(e); } } //); if (DetectorHitsForCycle.Count > 0) { var eventsInOrder = DetectorHitsForCycle.OrderBy(r => r.Timestamp); if (eventsInOrder.Count() > 1) { for (int i = 0; i < eventsInOrder.Count() - 1; i++) { MOE.Common.Models.Controller_Event_Log current = eventsInOrder.ElementAt(i); MOE.Common.Models.Controller_Event_Log next = eventsInOrder.ElementAt(i + 1); if (current.Timestamp.Ticks == next.Timestamp.Ticks) { continue; } //If the first event is 'Off', then set 'On' to cyclestart if (i == 0 && current.EventCode == 81) { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); da.DetectorOn = c.CycleStart; da.DetectorOff = current.Timestamp; c.Activations.AddActivation(da); } //This is the prefered sequence; an 'On' followed by an 'off' if (current.EventCode == 82 && next.EventCode == 81) { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); da.DetectorOn = current.Timestamp; da.DetectorOff = next.Timestamp; c.Activations.AddActivation(da); continue; } //if we are at the penultimate event, and the last event is 'on', set 'off' as CycleEnd. if (i + 2 == eventsInOrder.Count() && next.EventCode == 82) { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); da.DetectorOn = next.Timestamp; da.DetectorOff = c.CycleEnd; c.Activations.AddActivation(da); continue; } } } else { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); MOE.Common.Models.Controller_Event_Log current = eventsInOrder.First(); switch (current.EventCode) { //if the only event is off case 81: da.DetectorOn = c.CycleStart; da.DetectorOff = current.Timestamp; c.Activations.AddActivation(da); break; //if the only event is on case 82: da.DetectorOn = current.Timestamp; da.DetectorOff = c.CycleEnd; c.Activations.AddActivation(da); break; } } } //if there are no hits in the cycle, we need to determine if the a previous detector activaition lasts the entire cycle else if (DetectorHitsForCycle.Count <= 0) { SplitFailDetectorActivation da = new SplitFailDetectorActivation(); DateTime earlierTime = c.CycleStart.AddMinutes(-30); List <int> li = new List <int> { 81, 82 }; ControllerEventLogs cs = new ControllerEventLogs(Phase.SignalID, earlierTime, c.CycleStart, channel, li); //if the last detecotr eventCodes was ON, and there is no matching off event, assume the detector was on for the whole cycle if (cs.Events.Count > 0 && cs.Events.LastOrDefault().EventCode == 82) { da.DetectorOn = c.CycleStart; da.DetectorOff = c.CycleEnd; c.Activations.AddActivation(da); } //} } } //); //end of Lane loop //merge the detectors for the different lanes for (int i = 0; i < c.Activations.Activations.Count - 1;) { SplitFailDetectorActivation current = c.Activations.Activations.ElementAt(i).Value; SplitFailDetectorActivation next = c.Activations.Activations.ElementAt(i + 1).Value; //if the next activaiton is between the previos one, remove the nextone and start again. if (next.DetectorOn >= current.DetectorOn && next.DetectorOff <= current.DetectorOff) { c.Activations.Activations.RemoveAt(i + 1); continue; } //if the next activaiton starts during the current, but ends later, atler current end time, and remove next, and start over. else if (next.DetectorOn >= current.DetectorOn && next.DetectorOn < current.DetectorOff && next.DetectorOff > current.DetectorOff) { current.DetectorOff = next.DetectorOff; c.Activations.Activations.RemoveAt(i + 1); continue; } else { i++; } } //if (c.Activations.Activations.Count > 0 && c.CycleStart > startDate && c.CycleStart < endDate) if (c.CycleStart > Options.StartDate && c.CycleStart < Options.EndDate) { double gor = c.Activations.GreenOccupancy(c) * 100; double ror = c.Activations.StartOfRedOccupancy(c, Options.FirstSecondsOfRed) * 100; if (c.TerminationEvent == MOE.Common.Business.CustomReport.Cycle.TerminationCause.GapOut) { chart.Series["GOR - GapOut"].Points.AddXY(c.CycleStart, gor); chart.Series["ROR - GapOut"].Points.AddXY(c.CycleStart, ror); } else { chart.Series["GOR - ForceOff"].Points.AddXY(c.CycleStart, gor); chart.Series["ROR - ForceOff"].Points.AddXY(c.CycleStart, ror); } if ((gor > 79 && ror > 79)) { if (Options.ShowFailLines) { chart.Series["SplitFail"].Points.AddXY(c.CycleStart, 100); } SplitFails.Add(c.CycleStart); totalFails++; } } } //); statistics.Add("Total Split Failures ", totalFails.ToString()); //end of Cycle loop //Average Loop DateTime counterTime = Options.StartDate; do { double binTotalGOR = 0; double binTotalROR = 0; var CycleBin = from cur in Phase.Cycles where cur.CycleStart >= counterTime && cur.CycleStart <= counterTime.AddMinutes(15) orderby cur.CycleStart select cur; var failsInBin = from s in SplitFails where s >= counterTime && s <= counterTime.AddMinutes(15) select s; double binFails = failsInBin.Count(); //Parallel.ForEach(CycleBin, c => foreach (MOE.Common.Business.CustomReport.Cycle c in CycleBin) { binTotalGOR += c.Activations.GreenOccupancy(c) * 100; binTotalROR += c.Activations.StartOfRedOccupancy(c, Options.FirstSecondsOfRed) * 100; } //); if (Options.ShowPercentFailLines) { if (binFails > 0 && CycleBin.Count() > 0) { double binFailPercent = (binFails / Convert.ToDouble(CycleBin.Count())); chart.Series["Percent Fails"].Points.AddXY(counterTime, Convert.ToInt32(binFailPercent * 100)); } else { chart.Series["Percent Fails"].Points.AddXY(counterTime, 0); } } if (Options.ShowAvgLines) { if (CycleBin.Count() > 0) { double avggor = binTotalGOR / CycleBin.Count(); double avgror = binTotalROR / CycleBin.Count(); chart.Series["Avg. GOR"].Points.AddXY(counterTime, avggor); chart.Series["Avg. ROR"].Points.AddXY(counterTime, avgror); } if (CycleBin.Count() == 0) { chart.Series["Avg. GOR"].Points.AddXY(counterTime, 0); chart.Series["Avg. ROR"].Points.AddXY(counterTime, 0); } } counterTime = counterTime.AddMinutes(15); } while (counterTime < Options.EndDate.AddMinutes(15)); //End Average Loop } SetChartTitle(statistics); AddPlanStrips(chart, Phase, Options.StartDate, Options.EndDate, SplitFails); } }