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

91 lines
3.6 KiB
C#
Raw Normal View History

using System;
using System.Linq;
using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
public class DetectorDrilling : DetectorAbstract
{
private const double dispersionOfNormalizedRotorSpeedThreshold = 0.2d;
public const string ExtraDataKeyHasOscillation = "hasOscillation";
public const string ExtraDataKeyDispersionOfNormalizedRotorSpeed = "dispersionOfNormalizedRotorSpeed";
public const string ExtraDataKeyAvgRotorSpeed = "avgRotorSpeed";
public const string ExtraDataKeyIsAfbEnabled = "isAfbEnabled";
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) =>
Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
protected override (int Begin, int End) RefineEdges(DetectableTelemetry[] telemetry, int begin, int end)
{
var i = end;
for (; i > begin + 1; i--)
if (telemetry[i].WellDepth - telemetry[i - 1].WellDepth > 0.001d)
break;
return (begin, i);
}
protected override DetectedOperation MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end)
{
var (avgRotorSpeed, dispersionOfNormalizedRotorSpeed, isAfbEnabled) = CalcCriteries(telemetry, begin, end);
var operation = MakeDetectedOperationBlank(idTelemetry, telemetry, begin, end);
operation.IdCategory = GetIdOperation(avgRotorSpeed, dispersionOfNormalizedRotorSpeed);
operation.ExtraData[ExtraDataKeyAvgRotorSpeed] = avgRotorSpeed;
operation.ExtraData[ExtraDataKeyDispersionOfNormalizedRotorSpeed] = dispersionOfNormalizedRotorSpeed;
operation.ExtraData[ExtraDataKeyHasOscillation] = dispersionOfNormalizedRotorSpeed > dispersionOfNormalizedRotorSpeedThreshold;
operation.ExtraData[ExtraDataKeyIsAfbEnabled] = isAfbEnabled;
return operation;
}
private static (double avgRotorSpeed, double dispersionOfNormalizedRotorSpeed, bool isAfbEnabled) CalcCriteries(DetectableTelemetry[] telemetry, int begin, int end)
{
var telemetryRange = telemetry[begin..end];
var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed);
var dispersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed / avgRotorSpeed - 1, 2));
var isAfbEnabled = telemetryRange.Any(t => t.Mode > 0);
return (avgRotorSpeed, dispersion, isAfbEnabled);
}
private static int GetIdOperation(double avgRotorSpeed, double dispersionOfNormalizedRotorSpeed)
{
const int idSlideWithOscillation = WellOperationCategory.IdSlide;
if (avgRotorSpeed < 5)
return WellOperationCategory.IdSlide;
if (dispersionOfNormalizedRotorSpeed < dispersionOfNormalizedRotorSpeedThreshold)
return WellOperationCategory.IdRotor;
else
return idSlideWithOscillation;
}
}