public void Process(LightningContext context) { var closePackets = context.Datapackets.Where(x => x.Received > this.packet.Received - TOACorrelator.MAXDELAY); var fullInfo = (from data in closePackets join status in context.Statuspackets on data.Batchid equals status.Batchid select new { DetectionInstance = DetectionInstance.FromPacket(data), Status = status }).ToList(); foreach (var x in fullInfo) { x.DetectionInstance.DetectorLat = x.Status.Gpslat.Value; x.DetectionInstance.DetectorLon = x.Status.Gpslon.Value; } Strike strike = TOACorrelator.Correlate(fullInfo.Select(x => x.DetectionInstance).ToList()); if (strike != null) { context.Add(strike); } }
public static Strike Correlate(List <DetectionInstance> instances) { if (instances.Any()) { // select the first (not in any order) var rootDetector = instances.OrderBy(x => x.DetectionTime).First(); List <DetectorDelta> detectorDeltas = new List <DetectorDelta>(); // create the intersections foreach (var secondaryDetector in instances.Where(x => x != rootDetector)) { var firstToHear = rootDetector.DetectionTime > secondaryDetector.DetectionTime ? rootDetector : secondaryDetector; var secondToHear = rootDetector.DetectionTime > secondaryDetector.DetectionTime ? secondaryDetector : rootDetector; detectorDeltas.Add(new DetectorDelta { deltaLat = rootDetector.DetectorLat - secondaryDetector.DetectorLat, deltaLon = rootDetector.DetectorLon - secondaryDetector.DetectorLon, deltaTime = rootDetector.DetectionTime - secondaryDetector.DetectionTime, Primary = firstToHear, Secondary = secondToHear, Angle = Math.Atan2(secondToHear.DetectorLat - firstToHear.DetectorLat, secondToHear.DetectorLon - firstToHear.DetectorLon) }); } var strike = new Strike(); detectorDeltas = detectorDeltas.OrderBy(x => x.deltaTime).ToList(); foreach (var delta in detectorDeltas) { var distance = delta.GetKilometers(); var timeDiff = delta.deltaTime; // time diff is the radius of the 'circle of difference' and 'opposite of the RHTriangle' var adjacent = timeDiff * SIGNALSPEED; var hypotenuse = distance; var opposite = Math.Sqrt((hypotenuse * hypotenuse) - (adjacent * adjacent)); // sin theta = O / H var angleFromDetector = Math.Asin(opposite / hypotenuse); // this angle represents the angle from normal between the two points, relative, get absolute. var finalAngle = angleFromDetector + delta.Angle; // as we are treating as a front, no curve, take detector 1 as point for now ( could work out midpoint of line between detectors) strike.Vectors.Add(new Vector() { Angle = finalAngle, Lat = delta.Primary.DetectorLat, Lon = delta.Primary.DetectorLon }); } if (strike.Vectors.Any()) { return(strike); } } return(null); }