public void AddActivation(SplitFailDetectorActivation Activation) { if (Activations.ContainsKey(Activation.DetectorOn)) { do { Activation.DetectorOn = Activation.DetectorOn.AddSeconds(.01); Activation.DetectorOff = Activation.DetectorOff.AddSeconds(.01); } while (Activations.ContainsKey(Activation.DetectorOn)); Activations.Add(Activation.DetectorOn, Activation); } else { Activations.Add(Activation.DetectorOn, Activation); } }
public double FindModifiedActivationDuration(DateTime startTime, DateTime endTime, SplitFailDetectorActivation a) { double d = 0; //After start, before end if ((a.DetectorOn >= startTime && a.DetectorOn <= endTime) && (a.DetectorOff >= startTime && a.DetectorOff <= endTime)) { d = a.Duration; } //Before start, before end else if ((a.DetectorOn <= startTime && a.DetectorOn <= endTime) && (a.DetectorOff <= endTime && a.DetectorOff >= startTime)) { d = (a.DetectorOff - startTime).TotalMilliseconds; } //After start, After end else if ((a.DetectorOn >= startTime && a.DetectorOn <= endTime) && (a.DetectorOff >= endTime && a.DetectorOff >= startTime)) { d = (endTime - a.DetectorOn).TotalMilliseconds; } //Before Start, After end else if ((a.DetectorOn <= startTime && a.DetectorOn <= endTime) && (a.DetectorOff >= endTime && a.DetectorOff >= startTime)) { d = (endTime - startTime).TotalMilliseconds; } // else { d = 0; } return(d); }
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); } }
private void CombineDetectorActivations() { var tempDetectorActivations = new List <SplitFailDetectorActivation>(); //look at every item in the original list foreach (var current in _detectorActivations) { if (!current.ReviewedForOverlap) { var overlapingActivations = _detectorActivations.Where(d => d.ReviewedForOverlap == false && ( // if it starts after current starts and starts before current ends and end after current ends d.DetectorOn >= current.DetectorOn && d.DetectorOn <= current.DetectorOff && d.DetectorOff >= current.DetectorOff //OR if it starts BEFORE curent starts and ends AFTER current starts and ends BEFORE current ends || d.DetectorOn <= current.DetectorOn && d.DetectorOff >= current.DetectorOn && d.DetectorOff <= current.DetectorOff //OR if it starts AFTER current starts and it ends BEFORE current ends || d.DetectorOn >= current.DetectorOn && d.DetectorOff <= current.DetectorOff //OR if it starts BEFORE current starts and it ens AFTER current ends || d.DetectorOn <= current.DetectorOn && d.DetectorOff >= current.DetectorOff ) //then add it to the overlap list ).ToList(); //if there are any in the list (and here should be at least one that matches current) if (overlapingActivations.Any()) { //Then make a new activation that starts witht eh earliest start and ends with the latest end var tempDetectorActivation = new SplitFailDetectorActivation { DetectorOn = overlapingActivations.Min(o => o.DetectorOn), DetectorOff = overlapingActivations.Max(o => o.DetectorOff) }; //and add the new one to a temp list tempDetectorActivations.Add(tempDetectorActivation); //mark everything in the overlap list as Reviewed foreach (var splitFailDetectorActivation in overlapingActivations) { splitFailDetectorActivation.ReviewedForOverlap = true; } } } } //since we went through every item in the original list, if there were no overlaps, it shoudl equal the temp list if (_detectorActivations.Count != tempDetectorActivations.Count) { //if the counts do not match, we have to set the original list to the temp list and try the combinaitons again _detectorActivations = tempDetectorActivations; CombineDetectorActivations(); } }