DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs

72 lines
2.2 KiB
C#
Raw Normal View History

using System;
using System.Linq;
using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
public class DetectorDrilling : DetectorAbstract
{
protected override Func<DetectableTelemetry[], int, int, int> GetIdOperation => DefineDrillingOperation;
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
{
var point0 = telemetry[position];
var delta = point0.WellDepth - point0.BitDepth;
if (delta > 0.03d)
return false;
if (point0.Pressure < 18)
return false;
return true;
}
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
{
var point0 = telemetry[position];
var delta = point0.WellDepth - point0.BitDepth;
if (delta > 0.03d)
return IdReasonOfEnd_DeltaDepthIsHi;
if (point0.Pressure < 18)
return IdReasonOfEnd_PressureIsLo;
return IdReasonOfEnd_NotDetected;
}
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
=> CalcRop(telemetry, begin, end);
protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
operationDetectorResult.Operation.IdReasonOfEnd is IdReasonOfEnd_DeltaDepthIsHi or IdReasonOfEnd_PressureIsLo &&
Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
private static int DefineDrillingOperation(DetectableTelemetry[] telemetry, int begin, int end)
{
const int idSlideWithOscillation = 12000;
var telemetryRange = telemetry[begin.. end]
.OrderBy(x => x.DateTime).ToList();
for (var i = telemetryRange.Count - 1; i >= 0 && telemetryRange.Count > 1; i--)
{
if (Math.Abs(telemetryRange[i].WellDepth - telemetryRange[i - 1].WellDepth) < 0.001d)
{
telemetryRange.RemoveAt(i);
continue;
}
break;
}
var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed);
if (avgRotorSpeed < 5)
return WellOperationCategory.IdSlide;
var despersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed/avgRotorSpeed - 1, 2));
return despersion < 0.2d ? WellOperationCategory.IdRotor : idSlideWithOscillation;
}
}