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

92 lines
3.5 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Drawing;
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 (int IdCategory, IDictionary<string, object> ExtraData) GetSpecificInformation(DetectableTelemetry[] telemetry, int begin, int end)
{
var (avgRotorSpeed, dispersionOfNormalizedRotorSpeed) = CalcCriteries(telemetry, begin, end);
var idCategory = GetIdOperation(avgRotorSpeed, dispersionOfNormalizedRotorSpeed);
var extraData = new Dictionary<string, object>();
extraData[ExtraDataKeyAvgRotorSpeed] = avgRotorSpeed;
extraData[ExtraDataKeyDispersionOfNormalizedRotorSpeed] = dispersionOfNormalizedRotorSpeed;
extraData[ExtraDataKeyHasOscillation] = dispersionOfNormalizedRotorSpeed > dispersionOfNormalizedRotorSpeedThreshold;
return (idCategory, extraData);
}
private static (double avgRotorSpeed, double dispersionOfNormalizedRotorSpeed) 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));
return (avgRotorSpeed, dispersion);
}
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;
}
}