forked from ddrilling/AsbCloudServer
DetectorDrilling. Extract RefineEdges method from GetIdOperation.
Move detectedOperation helper data to ExtraData property
This commit is contained in:
parent
fd8b0de5a0
commit
948002955d
@ -1,5 +1,6 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
@ -40,8 +41,8 @@ namespace AsbCloudDb.Model
|
|||||||
[Column("value"), Comment("Ключевой показатель операции")]
|
[Column("value"), Comment("Ключевой показатель операции")]
|
||||||
public double Value { get; set; }
|
public double Value { get; set; }
|
||||||
|
|
||||||
[Column("id_reason_of_end"), Comment("Код признака окончания операции")]
|
[Column("extra_data", TypeName = "jsonb"), Comment("доп. инфо по операции")]
|
||||||
public int IdReasonOfEnd { get; set; }
|
public IDictionary<string, object> ExtraData { get; set; } = null!;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
[ForeignKey(nameof(IdTelemetry))]
|
[ForeignKey(nameof(IdTelemetry))]
|
||||||
|
@ -10,6 +10,8 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudInfrastructure.Repository;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations;
|
namespace AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
|
|
||||||
@ -46,11 +48,13 @@ public class DetectedOperationExportService
|
|||||||
private const int columnComment = 10;
|
private const int columnComment = 10;
|
||||||
|
|
||||||
private readonly IAsbCloudDbContext dbContext;
|
private readonly IAsbCloudDbContext dbContext;
|
||||||
|
private readonly IWellOperationRepository wellOperationRepository;
|
||||||
|
|
||||||
public DetectedOperationExportService(IAsbCloudDbContext dbContext)
|
public DetectedOperationExportService(IAsbCloudDbContext dbContext, IWellOperationRepository wellOperationRepository)
|
||||||
{
|
{
|
||||||
this.dbContext = dbContext;
|
this.dbContext = dbContext;
|
||||||
}
|
this.wellOperationRepository = wellOperationRepository;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Stream> ExportAsync(int idWell, int idDomain, CancellationToken cancellationToken)
|
public async Task<Stream> ExportAsync(int idWell, int idDomain, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
@ -112,31 +116,26 @@ public class DetectedOperationExportService
|
|||||||
sheet.Cell(cellWellName).Value = well.Caption;
|
sheet.Cell(cellWellName).Value = well.Caption;
|
||||||
sheet.Cell(cellDeltaDate).Value = operationDetectorResults.Max(o => o.Operation.DateEnd) - operationDetectorResults.Min(o => o.Operation.DateStart);
|
sheet.Cell(cellDeltaDate).Value = operationDetectorResults.Max(o => o.Operation.DateEnd) - operationDetectorResults.Min(o => o.Operation.DateStart);
|
||||||
|
|
||||||
|
var detectedOperations = operationDetectorResults.Select(o => o.Operation).ToArray();
|
||||||
|
|
||||||
for (int i = 0; i < operationDetectorResults.Count; i++)
|
for (int i = 0; i < operationDetectorResults.Count; i++)
|
||||||
{
|
{
|
||||||
var detectedOperations = operationDetectorResults.Select(o => o.Operation).ToArray();
|
var current = detectedOperations[i];
|
||||||
|
var dateStart = current.DateStart.ToRemoteDateTime(well.Timezone.Hours);
|
||||||
var dateStart = detectedOperations[i].DateStart.ToRemoteDateTime(well.Timezone.Hours);
|
var dateEnd = current.DateEnd.ToRemoteDateTime(well.Timezone.Hours);
|
||||||
var dateEnd = detectedOperations[i].DateEnd.ToRemoteDateTime(well.Timezone.Hours);
|
|
||||||
|
|
||||||
var row = sheet.Row(5 + i + headerRowsCount);
|
var row = sheet.Row(5 + i + headerRowsCount);
|
||||||
|
|
||||||
row.Cell(columnOperationName).Value = detectedOperations[i].IdCategory == 12000
|
row.Cell(columnOperationName).Value = GetCategoryName(wellOperationCategories, current);
|
||||||
? "Бурение в слайде с осцилляцией"
|
|
||||||
: wellOperationCategories.Single(o => o.Id == detectedOperations[i].IdCategory).Name;
|
|
||||||
row.Cell(columnDateEnd).Value = dateEnd;
|
row.Cell(columnDateEnd).Value = dateEnd;
|
||||||
row.Cell(columnDuration).Value = (dateEnd - dateStart).TotalMinutes;
|
row.Cell(columnDuration).Value = (dateEnd - dateStart).TotalMinutes;
|
||||||
row.Cell(columnDepthStart).Value = detectedOperations[i].DepthStart;
|
row.Cell(columnDepthStart).Value = current.DepthStart;
|
||||||
row.Cell(columnDepthEnd).Value = detectedOperations[i].DepthEnd;
|
row.Cell(columnDepthEnd).Value = current.DepthEnd;
|
||||||
row.Cell(columnDepth).Value = detectedOperations[i].DepthEnd - detectedOperations[i].DepthStart;
|
row.Cell(columnDepth).Value = current.DepthEnd - current.DepthStart;
|
||||||
row.Cell(columnIdReasonOfEnd).Value = detectedOperations[i].IdReasonOfEnd switch
|
|
||||||
{
|
if (current.ExtraData.TryGetValue("IdReasonOfEnd", out object? idReasonOfEndObject)
|
||||||
0 => "Не определена",
|
&& idReasonOfEndObject is int idReasonOfEnd)
|
||||||
1 => "Не определено начало операции",
|
row.Cell(columnIdReasonOfEnd).Value = GetIdReasonOfEnd(idReasonOfEnd);
|
||||||
101 => "Разница глубин забоя и положением долота",
|
|
||||||
300 => "Низкое давление",
|
|
||||||
_ => detectedOperations[i].IdReasonOfEnd
|
|
||||||
};
|
|
||||||
|
|
||||||
var link =
|
var link =
|
||||||
$"{domains[idDomain]}/well/{well.Id}/telemetry/monitoring?end={Uri.EscapeDataString(dateStart.AddSeconds(1800 * 0.9).ToString("yyyy-MM-ddTHH:mm:ss.fff"))}&range=1800";
|
$"{domains[idDomain]}/well/{well.Id}/telemetry/monitoring?end={Uri.EscapeDataString(dateStart.AddSeconds(1800 * 0.9).ToString("yyyy-MM-ddTHH:mm:ss.fff"))}&range=1800";
|
||||||
@ -145,14 +144,40 @@ public class DetectedOperationExportService
|
|||||||
row.Cell(columnDateStart).SetHyperlink(new XLHyperlink(link));
|
row.Cell(columnDateStart).SetHyperlink(new XLHyperlink(link));
|
||||||
|
|
||||||
row.Cell(columnDeltaDepth).Value = i > 0 && i + 1 < detectedOperations.Length
|
row.Cell(columnDeltaDepth).Value = i > 0 && i + 1 < detectedOperations.Length
|
||||||
? detectedOperations[i].DepthStart - detectedOperations[i - 1].DepthEnd
|
? current.DepthStart - detectedOperations[i - 1].DepthEnd
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
row.Cell(columnComment).Value = CreateComment(operationDetectorResults[i]);
|
row.Cell(columnComment).Value = CreateComment(operationDetectorResults[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Stream> GetExcelTemplateStreamAsync(CancellationToken cancellationToken)
|
private static string GetCategoryName(IEnumerable<WellOperationCategory> wellOperationCategories, DetectedOperation current)
|
||||||
|
{
|
||||||
|
var idCategory = current.IdCategory;
|
||||||
|
if (idCategory == WellOperationCategory.IdSlide
|
||||||
|
&& current.ExtraData[DetectorDrilling.ExtraDataKeyHasOscillation] is bool hasOscillation
|
||||||
|
&& hasOscillation)
|
||||||
|
return "Бурение в слайде с осцилляцией";
|
||||||
|
|
||||||
|
var category = wellOperationCategories.FirstOrDefault(o => o.Id == current.IdCategory);
|
||||||
|
|
||||||
|
if(category is not null)
|
||||||
|
return category.Name;
|
||||||
|
|
||||||
|
return $"Операция №{idCategory}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetIdReasonOfEnd(int idReasonOfEnd)
|
||||||
|
=> idReasonOfEnd switch {
|
||||||
|
0 => "Не определена",
|
||||||
|
1 => "Не определено начало операции",
|
||||||
|
101 => "Разница глубин забоя и положением долота",
|
||||||
|
300 => "Низкое давление",
|
||||||
|
_ => idReasonOfEnd.ToString($"Причина № {idReasonOfEnd}"),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
private async Task<Stream> GetExcelTemplateStreamAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
string resourceName = Assembly.GetExecutingAssembly()
|
string resourceName = Assembly.GetExecutingAssembly()
|
||||||
.GetManifestResourceNames()
|
.GetManifestResourceNames()
|
||||||
@ -170,22 +195,23 @@ public class DetectedOperationExportService
|
|||||||
|
|
||||||
private string? CreateComment(OperationDetectorResult operationDetectorResult)
|
private string? CreateComment(OperationDetectorResult operationDetectorResult)
|
||||||
{
|
{
|
||||||
switch (operationDetectorResult.Operation.IdCategory)
|
var operation = operationDetectorResult.Operation;
|
||||||
|
switch (operation.IdCategory)
|
||||||
{
|
{
|
||||||
case 12000:
|
case WellOperationCategory.IdRotor:
|
||||||
case 5002:
|
case WellOperationCategory.IdSlide:
|
||||||
case 5003:
|
|
||||||
{
|
{
|
||||||
var detectorDrilling = detectors.FirstOrDefault(d => d is DetectorDrilling) as DetectorDrilling;
|
var avgRotorSpeed = operation.ExtraData[DetectorDrilling.ExtraDataKeyAvgRotorSpeed];
|
||||||
var avgRotorSpeed = Math.Round(detectorDrilling.AvgRotorSpeedDict[(operationDetectorResult.TelemetryBegin, operationDetectorResult.TelemetryEnd)], 2);
|
var dispersionOfNormalizedRotorSpeed = operation.ExtraData[DetectorDrilling.ExtraDataKeyDispersionOfNormalizedRotorSpeed];
|
||||||
var despersion = Math.Round(detectorDrilling.DespersionDict[(operationDetectorResult.TelemetryBegin, operationDetectorResult.TelemetryEnd)], 2);
|
var isAfbEnabledObject = operation.ExtraData[DetectorDrilling.ExtraDataKeyIsAfbEnabled];
|
||||||
|
var AfbState = "";
|
||||||
|
if (isAfbEnabledObject is bool isAfbEnabled && isAfbEnabled)
|
||||||
|
AfbState = "АКБ - вкл";
|
||||||
|
|
||||||
var stringBuilder = new StringBuilder();
|
var comment = $"Средняя скорость оборотов ротора: {avgRotorSpeed}\r\n" +
|
||||||
|
$"Дисперсия нормированных оборотов ротора: {dispersionOfNormalizedRotorSpeed} \r\n" +
|
||||||
stringBuilder.AppendLine($"Средняя скорость оборотов ротора: {avgRotorSpeed}");
|
$"{AfbState}";
|
||||||
stringBuilder.AppendLine($"Нормированные обороты ротора: {despersion}");
|
return comment;
|
||||||
|
|
||||||
return stringBuilder.ToString();
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
@ -55,16 +56,31 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = MakeOperation(idTelemetry, telemetry, begin, positionEnd, idReasonOfEnd);
|
var (Begin, End) = RefineEdges(telemetry, begin, positionEnd);
|
||||||
return result is not null;
|
|
||||||
|
if (!IsValidTelemetryRange(telemetry, Begin, End))
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = MakeOperationDetectorResult(idTelemetry, telemetry, Begin, End, idReasonOfEnd);
|
||||||
|
|
||||||
|
return IsValidOperationDetectorResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = null;
|
result = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
|
protected virtual bool IsValidTelemetryRange(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
operationDetectorResult.Operation.IdReasonOfEnd != IdReasonOfEnd_NotDetected;
|
=> end - begin > 1;
|
||||||
|
|
||||||
|
protected virtual (int Begin, int End) RefineEdges(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
|
=> (begin, end);
|
||||||
|
|
||||||
|
protected virtual bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult)
|
||||||
|
=> operationDetectorResult.Operation.DateEnd - operationDetectorResult.Operation.DateStart > TimeSpan.FromSeconds(3);
|
||||||
|
|
||||||
protected abstract bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation);
|
protected abstract bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation);
|
||||||
|
|
||||||
@ -73,36 +89,51 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
? IdReasonOfEnd_NotDetected
|
? IdReasonOfEnd_NotDetected
|
||||||
: IdReasonOfEnd_NotDetectBegin;
|
: IdReasonOfEnd_NotDetectBegin;
|
||||||
|
|
||||||
private OperationDetectorResult? MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end,
|
private OperationDetectorResult MakeOperationDetectorResult(
|
||||||
|
int idTelemetry,
|
||||||
|
DetectableTelemetry[] telemetry,
|
||||||
|
int begin,
|
||||||
|
int end,
|
||||||
int idReasonOfEnd)
|
int idReasonOfEnd)
|
||||||
{
|
{
|
||||||
var pBegin = telemetry[begin];
|
var operation = MakeOperation(idTelemetry, telemetry, begin, end);
|
||||||
var pEnd = telemetry[end];
|
|
||||||
|
operation.ExtraData["IdReasonOfEnd"] = idReasonOfEnd;
|
||||||
|
|
||||||
var result = new OperationDetectorResult
|
var result = new OperationDetectorResult
|
||||||
{
|
{
|
||||||
TelemetryBegin = begin,
|
TelemetryBegin = begin,
|
||||||
TelemetryEnd = end,
|
TelemetryEnd = end,
|
||||||
Operation = new DetectedOperation
|
Operation = operation,
|
||||||
{
|
|
||||||
IdTelemetry = idTelemetry,
|
|
||||||
IdCategory = GetIdOperation(telemetry, begin, end),
|
|
||||||
IdUsersAtStart = pBegin.IdUser ?? -1,
|
|
||||||
DateStart = pBegin.DateTime,
|
|
||||||
DateEnd = pEnd.DateTime,
|
|
||||||
DepthStart = (double)pBegin.WellDepth,
|
|
||||||
DepthEnd = (double)pEnd.WellDepth,
|
|
||||||
Value = CalcValue(telemetry, begin, end),
|
|
||||||
IdReasonOfEnd = idReasonOfEnd,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return !IsValidOperationDetectorResult(result) ? null : result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract int GetIdOperation(DetectableTelemetry[] telemetry, int begin, int end);
|
protected abstract DetectedOperation MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end);
|
||||||
|
|
||||||
protected abstract double CalcValue(DetectableTelemetry[] telemetry, int begin, int end);
|
protected abstract double CalcValue(DetectableTelemetry[] telemetry, int begin, int end);
|
||||||
|
|
||||||
|
protected DetectedOperation MakeDetectedOperationBlank(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
|
{
|
||||||
|
var pBegin = telemetry[begin];
|
||||||
|
var pEnd = telemetry[end];
|
||||||
|
|
||||||
|
var operation = new DetectedOperation
|
||||||
|
{
|
||||||
|
IdTelemetry = idTelemetry,
|
||||||
|
IdUsersAtStart = pBegin.IdUser ?? -1,
|
||||||
|
DateStart = pBegin.DateTime,
|
||||||
|
DateEnd = pEnd.DateTime,
|
||||||
|
DepthStart = (double)pBegin.WellDepth,
|
||||||
|
DepthEnd = (double)pEnd.WellDepth,
|
||||||
|
ExtraData = new Dictionary<string, object>(),
|
||||||
|
Value = CalcValue(telemetry, begin, end),
|
||||||
|
};
|
||||||
|
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Среднее арифметическое
|
/// Среднее арифметическое
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -111,7 +142,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
/// <param name="begin"></param>
|
/// <param name="begin"></param>
|
||||||
/// <param name="fragmentLength"></param>
|
/// <param name="fragmentLength"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static double CalcAvgAppr(
|
protected static double CalcAvgAppr(
|
||||||
Func<DetectableTelemetry, double> yGetter,
|
Func<DetectableTelemetry, double> yGetter,
|
||||||
DetectableTelemetry[] telemetry,
|
DetectableTelemetry[] telemetry,
|
||||||
int begin,
|
int begin,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
|
|
||||||
@ -7,10 +6,13 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
|||||||
|
|
||||||
public class DetectorDrilling : DetectorAbstract
|
public class DetectorDrilling : DetectorAbstract
|
||||||
{
|
{
|
||||||
public IDictionary<(int, int), float> AvgRotorSpeedDict { get; } = new Dictionary<(int, int), float>();
|
private const double dispersionOfNormalizedRotorSpeedThreshold = 0.2d;
|
||||||
public IDictionary<(int, int), double> DespersionDict { get; } = new Dictionary<(int, int), double>();
|
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)
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
||||||
{
|
{
|
||||||
var point0 = telemetry[position];
|
var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
var delta = point0.WellDepth - point0.BitDepth;
|
||||||
@ -41,36 +43,49 @@ public class DetectorDrilling : DetectorAbstract
|
|||||||
=> CalcRop(telemetry, begin, end);
|
=> CalcRop(telemetry, begin, end);
|
||||||
|
|
||||||
protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
|
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;
|
Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
|
||||||
|
|
||||||
protected override int GetIdOperation(DetectableTelemetry[] telemetry, int begin, int end)
|
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 = 12000;
|
const int idSlideWithOscillation = WellOperationCategory.IdSlide;
|
||||||
|
|
||||||
var telemetryRange = telemetry[begin.. end]
|
if (avgRotorSpeed < 5)
|
||||||
.OrderBy(x => x.DateTime).ToList();
|
return WellOperationCategory.IdSlide;
|
||||||
|
|
||||||
for (var i = telemetryRange.Count - 1; i >= 0 && telemetryRange.Count > 1; i--)
|
if (dispersionOfNormalizedRotorSpeed < dispersionOfNormalizedRotorSpeedThreshold)
|
||||||
{
|
return WellOperationCategory.IdRotor;
|
||||||
if (Math.Abs(telemetryRange[i].WellDepth - telemetryRange[i - 1].WellDepth) < 0.001d)
|
else
|
||||||
{
|
return idSlideWithOscillation;
|
||||||
telemetryRange.RemoveAt(i);
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var avgRotorSpeed = telemetryRange.Average(t => t.RotorSpeed);
|
|
||||||
var despersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed/avgRotorSpeed - 1, 2));
|
|
||||||
|
|
||||||
AvgRotorSpeedDict.Add((begin, end), avgRotorSpeed);
|
|
||||||
DespersionDict.Add((begin, end), despersion);
|
|
||||||
|
|
||||||
if (avgRotorSpeed < 5)
|
|
||||||
return WellOperationCategory.IdSlide;
|
|
||||||
|
|
||||||
return despersion < 0.2d ? WellOperationCategory.IdRotor : idSlideWithOscillation;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -27,10 +27,14 @@ public class DetectorSlipsTime : DetectorAbstract
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override int GetIdOperation(DetectableTelemetry[] telemetry, int begin, int end)
|
|
||||||
=> WellOperationCategory.IdSlipsTime;
|
|
||||||
|
|
||||||
protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
|
protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
|
||||||
Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
|
Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
|
||||||
|
|
||||||
|
protected override DetectedOperation MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
|
{
|
||||||
|
var operation = MakeDetectedOperationBlank(idTelemetry, telemetry, begin, end);
|
||||||
|
operation.IdCategory = WellOperationCategory.IdSlipsTime;
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user