diff --git a/AsbCloudInfrastructure/Services/AnalyticsService.cs b/AsbCloudInfrastructure/Services/AnalyticsService.cs index ed8e4233..8f4899f3 100644 --- a/AsbCloudInfrastructure/Services/AnalyticsService.cs +++ b/AsbCloudInfrastructure/Services/AnalyticsService.cs @@ -222,51 +222,57 @@ namespace AsbCloudInfrastructure.Services public DrillingAnalysis GetDrillingAnalysis(IEnumerable dataSaubBases) { - var saubWellDepths = dataSaubBases.Select(s => (s.WellDepth, - TotalSeconds: (s.Date - - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds - 1530000000)); - var saubBitDepths = dataSaubBases.Select(s => (s.BitDepth, - TotalSeconds: (s.Date - - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds - 1530000000)); - var saubBlockPositions = dataSaubBases.Select(s => (s.BlockPosition, - TotalSeconds: (s.Date - - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds - 1530000000)); - var saubRotorSpeeds = dataSaubBases.Select(s => (s.RotorSpeed, - TotalSeconds: (s.Date - - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds - 1530000000)); - var saubPressures = dataSaubBases.Select(s => (s.Pressure, - TotalSeconds: (s.Date - - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds - 1530000000)); - var saubHookWeights = dataSaubBases.Select(s => (s.HookWeight, - TotalSeconds: (s.Date - - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds - 1530000000)); + var lastSaubDate = dataSaubBases.Last().Date; - var wellDepthChangingIndex = GetAForLinearFormula(saubWellDepths); - var bitPositionChangingIndex = GetAForLinearFormula(saubBitDepths); - var blockPositionChangingIndex = GetAForLinearFormula(saubBlockPositions); - var rotorSpeedChangingIndex = GetAForLinearFormula(saubRotorSpeeds); - var pressureChangingIndex = GetAForLinearFormula(saubPressures); - var hookWeightChangingIndex = GetAForLinearFormula(saubHookWeights); + var saubWellDepths = dataSaubBases.Where(sw => sw.WellDepth is not null) + .Select(s => (Value: (double)s.WellDepth, + (s.Date - dataSaubBases.First().Date).TotalSeconds)); + var saubBitDepths = dataSaubBases.Where(sw => sw.BitDepth is not null) + .Select(s => (Value: (double)s.BitDepth, + (s.Date - dataSaubBases.First().Date).TotalSeconds)); + var saubBlockPositions = dataSaubBases.Where(sw => sw.BlockPosition is not null) + .Select(s => (Value: (double)s.BlockPosition, + (s.Date - dataSaubBases.First().Date).TotalSeconds)); + var saubRotorSpeeds = dataSaubBases.Where(sw => sw.RotorSpeed is not null) + .Select(s => (Value: (double)s.RotorSpeed, + (s.Date - dataSaubBases.First().Date).TotalSeconds)); + var saubPressures = dataSaubBases.Where(sw => sw.Pressure is not null) + .Select(s => (Value: (double)s.Pressure, + (s.Date - dataSaubBases.First().Date).TotalSeconds)); + var saubHookWeights = dataSaubBases.Where(sw => sw.HookWeight is not null) + .Select(s => (Value: (double)s.HookWeight, + (s.Date - dataSaubBases.First().Date).TotalSeconds)); + + var wellDepthChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubWellDepths); + var bitPositionChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubBitDepths); + var blockPositionChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubBlockPositions); + var rotorSpeedChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubRotorSpeeds); + var pressureChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubPressures); + var hookWeightChangingIndex = LinearFunctionCalculator.GetAForLinearFormula(saubHookWeights); + + var IsBlockRising = LinearFunctionCalculator.IsValueGoesDown(blockPositionChangingIndex, -0.0001); + var IsBlockGoesDown = LinearFunctionCalculator.IsValueGoesUp(blockPositionChangingIndex, 0.0001); + var IsBlockStandsStill = LinearFunctionCalculator.IsValueNotChanges(blockPositionChangingIndex, (0.0001, -0.0001)); var drillingAnalysis = new DrillingAnalysis { IdTelemetry = dataSaubBases.First().IdTelemetry, - Date = dataSaubBases.Last().Date, - IsDepthChanges = wellDepthChangingIndex >= 0.0001 || wellDepthChangingIndex <= -0.0001, - IsDepthNotChanges = wellDepthChangingIndex < 0.0001 && wellDepthChangingIndex > -0.0001, - IsBitRising = bitPositionChangingIndex >= 0.0001, - IsBitGoesDown = bitPositionChangingIndex <= -0.0001, - IsBitStandsStill = bitPositionChangingIndex < 0.0001 && bitPositionChangingIndex > -0.0001, - IsBitDepthLess20 = (saubBitDepths.Sum(s => s.BitDepth) / saubBitDepths.Count()) < 20.0, - IsBlockRising = blockPositionChangingIndex >= 0.0001, - IsBlockGoesDown = blockPositionChangingIndex <= -0.0001, - IsBlockStandsStill = blockPositionChangingIndex < 0.001 && blockPositionChangingIndex > -0.0001, - IsRotorSpeedLess3 = (saubRotorSpeeds.Sum(s => s.RotorSpeed) / saubRotorSpeeds.Count()) < 3, - IsRotorSpeedMore3 = (saubRotorSpeeds.Sum(s => s.RotorSpeed) / saubRotorSpeeds.Count()) >= 3, - IsPressureLess20 = (saubPressures.Sum(s => s.Pressure) / saubPressures.Count()) < 20.0, - IsPressureMore20 = (saubPressures.Sum(s => s.Pressure) / saubPressures.Count()) >= 20.0, - IsHookWeightNotChanges = hookWeightChangingIndex < 0.0001 && hookWeightChangingIndex > 0.0001, - IsHookWeightLess3 = (saubHookWeights.Sum(s => s.HookWeight) / saubHookWeights.Count()) < 3.0, + Date = lastSaubDate, + IsDepthChanges = LinearFunctionCalculator.IsValueChanges(wellDepthChangingIndex, (0.0001, -0.0001)), + IsDepthNotChanges = LinearFunctionCalculator.IsValueNotChanges(wellDepthChangingIndex, (0.0001, -0.0001)), + IsBitRising = LinearFunctionCalculator.IsValueGoesDown(bitPositionChangingIndex, -0.0001), + IsBitGoesDown = LinearFunctionCalculator.IsValueGoesUp(bitPositionChangingIndex, 0.0001), + IsBitStandsStill = LinearFunctionCalculator.IsValueNotChanges(bitPositionChangingIndex, (0.0001, -0.0001)), + IsBitDepthLess20 = LinearFunctionCalculator.IsAverageLessThanBound(saubBitDepths, 20), + IsBlockRising = LinearFunctionCalculator.IsValueGoesDown(blockPositionChangingIndex, -0.0001), + IsBlockGoesDown = LinearFunctionCalculator.IsValueGoesUp(blockPositionChangingIndex, 0.0001), + IsBlockStandsStill = LinearFunctionCalculator.IsValueNotChanges(blockPositionChangingIndex, (0.0001, -0.0001)), + IsRotorSpeedLess3 = LinearFunctionCalculator.IsAverageLessThanBound(saubRotorSpeeds, 3), + IsRotorSpeedMore3 = LinearFunctionCalculator.IsAverageMoreThanBound(saubRotorSpeeds, 3), + IsPressureLess20 = LinearFunctionCalculator.IsAverageLessThanBound(saubPressures, 20), + IsPressureMore20 = LinearFunctionCalculator.IsAverageMoreThanBound(saubPressures, 20), + IsHookWeightNotChanges = LinearFunctionCalculator.IsValueNotChanges(hookWeightChangingIndex, (0.0001, -0.0001)), + IsHookWeightLess3 = LinearFunctionCalculator.IsAverageLessThanBound(saubHookWeights, 3), IdOperation = 1 }; @@ -274,37 +280,5 @@ namespace AsbCloudInfrastructure.Services return drillingAnalysis; } - - private static double GetAForLinearFormula(IEnumerable<(double?, double)> rawData) - { - var (xSum, ySum, xySum, x2Sum) = GetFormulaVariables(rawData); - - return (xSum * ySum - rawData.Count() * xySum) / - (xSum * xSum - rawData.Count() * x2Sum); - } - - private static double GetBForLinearFormula(IEnumerable<(double?, double)> rawData) - { - var (xSum, ySum, xySum, x2Sum) = GetFormulaVariables(rawData); - - return (xSum * xySum - x2Sum * ySum) / - (xSum * xSum - rawData.Count() * x2Sum); - } - - private static (double xSum, double ySum, double xySum, double x2Sum) GetFormulaVariables( - IEnumerable<(double? value, double timestamp)> rawData) - { - var data = rawData.Select((d) => new - { - X = d.timestamp, - Y = d.value ?? 0.0 - }); - var xSum = data.Sum(d => d.X); - var ySum = data.Sum(d => d.Y); - var xySum = data.Sum(d => d.X * d.Y); - var x2Sum = data.Sum(d => d.X * d.X); - - return (xSum, ySum, xySum, x2Sum); - } } } diff --git a/AsbCloudInfrastructure/Services/LinearFunctionCalculator.cs b/AsbCloudInfrastructure/Services/LinearFunctionCalculator.cs new file mode 100644 index 00000000..5f905b67 --- /dev/null +++ b/AsbCloudInfrastructure/Services/LinearFunctionCalculator.cs @@ -0,0 +1,66 @@ +using System.Collections.Generic; +using System.Linq; + +namespace AsbCloudInfrastructure.Services +{ + public static class LinearFunctionCalculator + { + public static double GetAForLinearFormula(IEnumerable<(double value, double timestamp)> rawData) + { + var (xSum, ySum, xySum, x2Sum) = GetFormulaVariables(rawData); + + var result = (xSum * ySum - rawData.Count() * xySum) / + (xSum * xSum - rawData.Count() * x2Sum); + + return (double)result; + } + + public static double GetBForLinearFormula(IEnumerable<(double value, double timestamp)> rawData) + { + var (xSum, ySum, xySum, x2Sum) = GetFormulaVariables(rawData); + + var result = (xSum * xySum - x2Sum * ySum) / + (xSum * xSum - rawData.Count() * x2Sum); + + return (double)result; + } + + public static bool IsValueChanges(double value, + (double upperBound, double lowerBound) bounds) => + value >= bounds.upperBound || value <= bounds.lowerBound; + + public static bool IsValueNotChanges(double value, + (double upperBound, double lowerBound) bounds) => + value < bounds.upperBound && value > bounds.lowerBound; + + public static bool IsValueGoesUp(double value, double bound) => + value >= bound; + + public static bool IsValueGoesDown(double value, double bound) => + value <= bound; + + public static bool IsAverageLessThanBound(IEnumerable<(double Value, double TotalSeconds)> values, + double bound) => + (values.Sum(s => s.Value) / values.Count()) < bound; + + public static bool IsAverageMoreThanBound(IEnumerable<(double Value, double TotalSeconds)> values, + double bound) => + (values.Sum(s => s.Value) / values.Count()) >= bound; + + private static (decimal xSum, decimal ySum, decimal xySum, decimal x2Sum) GetFormulaVariables( + IEnumerable<(double value, double timestamp)> rawData) + { + var data = rawData.Select((d) => new + { + X = d.timestamp, + Y = d.value + }); + var xSum = (decimal)data.Sum(d => d.X); + var ySum = (decimal)data.Sum(d => d.Y); + var xySum = (decimal)data.Sum(d => d.X * d.Y); + var x2Sum = (decimal)data.Sum(d => d.X * d.X); + + return (xSum, ySum, xySum, x2Sum); + } + } +}