CS2-24: Логика расчета линейной функции вынесена в отдельный класс

This commit is contained in:
KharchenkoVV 2021-06-28 11:35:52 +05:00
parent 86f38dfbad
commit 3e6a55b547
2 changed files with 112 additions and 72 deletions

View File

@ -222,51 +222,57 @@ namespace AsbCloudInfrastructure.Services
public DrillingAnalysis GetDrillingAnalysis(IEnumerable<DataSaubBase> 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);
}
}
}

View File

@ -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);
}
}
}