forked from ddrilling/AsbCloudServer
140 lines
5.4 KiB
C#
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
|
|
}
|
|
|