DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
2022-06-30 17:37:57 +05:00

140 lines
5.4 KiB
C#

using AsbCloudDb.Model;
using System;
using System.Linq;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
#nullable enable
internal abstract class DetectorAbstract
{
private readonly int idOperation;
private readonly int stepLength = 3;
protected DetectorAbstract(int idOperation)
{
this.idOperation = idOperation;
}
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperation? previousOperation, out OperationDetectorResult? result)
{
// Проверка соответствия критерию начала операции
if (DetectBegin(telemetry, begin, previousOperation))
{
// Поиск окончания соответствия критерию
var positionEnd = begin;
while (positionEnd < end)
{
positionEnd += stepLength;
if ((positionEnd > end))
positionEnd = end;
if ((positionEnd == end) || DetectEnd(telemetry, positionEnd, previousOperation))
{
result = MakeOperation(idTelemetry, telemetry, begin, positionEnd);
return true;
}
}
}
result = null;
return false;
}
protected abstract bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation);
protected virtual bool DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
=> !DetectBegin(telemetry, position, previousOperation);
private OperationDetectorResult MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end)
{
var pBegin = telemetry[begin];
var pEnd = telemetry[end];
var result = new OperationDetectorResult
{
TelemetryBegin = begin,
TelemetryEnd = end,
Operation = new DetectedOperation
{
IdTelemetry = idTelemetry,
IdCategory = idOperation,
IdUsersAtStart = pBegin.IdUser ?? -1,
DateStart = pBegin.DateTime,
DateEnd = pEnd.DateTime,
DepthStart = (double)pBegin.WellDepth,
DepthEnd = (double)pEnd.WellDepth,
Value = CalcValue(telemetry, begin, end),
},
};
return result;
}
protected abstract bool IsValid(DetectableTelemetry[] telemetry, int begin, int end);
protected abstract double CalcValue(DetectableTelemetry[] telemetry, int begin, int end);
public static InterpolationLine MakeInterpolationLine(
Func<DetectableTelemetry, double> yGetter,
DetectableTelemetry[] telemetry,
int begin,
int fragmentLength)
{
DetectableTelemetry[] data;
if (fragmentLength > 0 && (begin + fragmentLength) < telemetry.Length)
data = telemetry[begin..(begin + fragmentLength)];
else
data = telemetry[begin..];
var line = new InterpolationLine(data.Select(d => (yGetter(d), (d.DateTime - telemetry[0].DateTime).TotalHours)));
return line;
}
/// <summary>
/// расчет продолжительности операции
/// </summary>
/// <param name="telemetry"></param>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <returns></returns>
protected static double CalcDeltaTime(DetectableTelemetry[] telemetry, int begin, int end)
{
var pBegin = telemetry[begin];
var pEnd = telemetry[end];
var result = (pEnd.DateTime - pBegin.DateTime).TotalHours;
return result;
}
/// <summary>
/// часто используемый предикат для определения отсутствия изменения глубины ствола скважины
/// </summary>
/// <param name="telemetry"></param>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <returns></returns>
protected static bool IsValidByWellDepthDoesNotChange(DetectableTelemetry[] telemetry, int begin, int end)
{
var pBegin = telemetry[begin];
var pEnd = telemetry[end];
if (Math.Abs((double)(pBegin.WellDepth - pEnd.WellDepth)) > 0.01)
return false;
return true;
}
protected static bool IsValidByWellDepthIncreasing(DetectableTelemetry[] telemetry, int begin, int end)
{
var pBegin = telemetry[begin];
var pEnd = telemetry[end];
if (pBegin.WellDepth >= pEnd.WellDepth)
return false;
return true;
}
protected static double CalcRop(DetectableTelemetry[] telemetry, int begin, int end)
{
var pBegin = telemetry[begin];
var pEnd = telemetry[end];
var result = (double)(pEnd.WellDepth - pBegin.WellDepth) / (pEnd.DateTime - pBegin.DateTime).TotalHours;
return result;
}
}
#nullable disable
}