diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx b/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx index 9073c58d..1c366050 100644 Binary files a/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx and b/AsbCloudInfrastructure/Services/DetectOperations/DetectOperations.xlsx differ diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs index 3c1550c1..cfb115f0 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs @@ -14,7 +14,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations; public class DetectedOperationExportService { - private readonly DetectorAbstract[] detectors = { new DetectorDrilling(), new DetectorSlipsTime() }; + private readonly DetectorAbstract[] detectors = { new DetectorDrilling() }; private readonly IDictionary domains = new Dictionary { @@ -122,10 +122,17 @@ public class DetectedOperationExportService row.Cell(columnDepthStart).Value = detectedOperations[i].DepthStart; row.Cell(columnDepthEnd).Value = detectedOperations[i].DepthEnd; row.Cell(columnDepth).Value = detectedOperations[i].DepthEnd - detectedOperations[i].DepthStart; - row.Cell(columnIdReasonOfEnd).Value = detectedOperations[i].IdReasonOfEnd; + row.Cell(columnIdReasonOfEnd).Value = detectedOperations[i].IdReasonOfEnd switch + { + 0 => "Не определена", + 1 => "Не определено начало операции", + 101 => "Разница глубин забоя и положением долота", + 300 => "Низкое давление", + _ => detectedOperations[i].IdReasonOfEnd + }; var link = - $"{domains[idDomain]}/well/{well.Id}/telemetry/monitoring?end={Uri.EscapeDataString(dateStart.AddSeconds(3544).ToString("yyyy-MM-ddTHH:mm:ss.fff"))}&range=3600"; + $"{domains[idDomain]}/well/{well.Id}/telemetry/monitoring?end={Uri.EscapeDataString(dateStart.AddSeconds(1800 * 0.9).ToString("yyyy-MM-ddTHH:mm:ss.fff"))}&range=1800"; row.Cell(columnDateStart).Value = dateStart; row.Cell(columnDateStart).SetHyperlink(new XLHyperlink(link)); @@ -191,10 +198,8 @@ public class DetectedOperationExportService var isDetected = false; var positionBegin = 0; var positionEnd = data.Length - gap; - var step = 10; while (positionEnd > positionBegin) { - step++; foreach (var detector in detectors) { if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result)) @@ -203,14 +208,11 @@ public class DetectedOperationExportService detectedOperations.Add(result!.Operation); lastDetectedOperation = result.Operation; isDetected = true; - step = 1; positionBegin = result.TelemetryEnd; break; } - - if (step > 20) - step = 10; - positionBegin += step; + + positionBegin += 1; } if (isDetected) diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs index 38a3aeac..07d2b16e 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs @@ -4,8 +4,7 @@ using System.Linq; namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors { - - internal abstract class DetectorAbstract + public abstract class DetectorAbstract { private readonly int stepLength = 3; @@ -34,14 +33,15 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors protected const int IdReasonOfEnd_Drilling = 600; protected const int IdReasonOfEnd_Custom1 = 10_000; - - public abstract Func GetIdOperation { get; } - public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperation? previousOperation, out OperationDetectorResult? result) + protected abstract Func GetIdOperation { get; } + + public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperation? previousOperation, + out OperationDetectorResult? result) { // Проверка соответствия критерию начала операции if (DetectBegin(telemetry, begin, previousOperation)) - { + { // Поиск окончания соответствия критерию int idReasonOfEnd = 0; var positionEnd = begin; @@ -52,30 +52,31 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors break; idReasonOfEnd = DetectEnd(telemetry, positionEnd, previousOperation); - - if(idReasonOfEnd is IdReasonOfEnd_DeltaDepthIsHi or IdReasonOfEnd_PressureIsLo && - !IsValidByWellDepthDoesNotChange(telemetry, begin, positionEnd)) - break; - - if (idReasonOfEnd != IdReasonOfEnd_NotDetected) + + if (idReasonOfEnd != IdReasonOfEnd_NotDetected) break; } - result = null; result = MakeOperation(idTelemetry, telemetry, begin, positionEnd, idReasonOfEnd); - return true; + return result is not null; } + result = null; return false; } - protected abstract bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation); - protected virtual int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) - => DetectBegin(telemetry, position, previousOperation) - ? IdReasonOfEnd_NotDetected - : IdReasonOfEnd_NotDetectBegin; + protected virtual bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) => + operationDetectorResult.Operation.IdReasonOfEnd != IdReasonOfEnd_NotDetected; - private OperationDetectorResult MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, int idReasonOfEnd) + protected abstract bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation); + + protected virtual int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) + => DetectBegin(telemetry, position, previousOperation) + ? IdReasonOfEnd_NotDetected + : IdReasonOfEnd_NotDetectBegin; + + private OperationDetectorResult? MakeOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, + int idReasonOfEnd) { var pBegin = telemetry[begin]; var pEnd = telemetry[end]; @@ -96,10 +97,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors IdReasonOfEnd = idReasonOfEnd, }, }; - return result; - } - protected abstract bool IsValid(DetectableTelemetry[] telemetry, int begin, int end); + return !IsValidOperationDetectorResult(result) ? null : result; + } protected abstract double CalcValue(DetectableTelemetry[] telemetry, int begin, int end); @@ -118,16 +118,16 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors int fragmentLength) { var end = begin + fragmentLength; - end = end < telemetry.Length - ? end + end = end < telemetry.Length + ? end : telemetry.Length; var subData = telemetry[begin..end].Select(yGetter); if (end - begin > 10) { var ratio = (end - begin) / 5; - subData = subData.Where((_,i) => i % ratio > 0); - } - + subData = subData.Where((_, i) => i % ratio > 0); + } + var avg = subData.Average(); return avg; } @@ -189,9 +189,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors /// /// protected static (double min, double max, double sum, int count) CalcStat( - DetectableTelemetry[] telemetry, - Func getter, - int begin, + DetectableTelemetry[] telemetry, + Func getter, + int begin, int count) { var sum = 0d; @@ -210,6 +210,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors max = itemValue; sum += itemValue; } + return (min, max, sum, end - begin); } @@ -256,7 +257,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors var end = begin + count; end = end < telemetry.Length ? end : telemetry.Length; - for (var i = begin; i < end; i ++) + for (var i = begin; i < end; i++) { var item = telemetry[i]; var itemValue = getter(item); @@ -264,9 +265,10 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors min = itemValue; if (max < itemValue) max = itemValue; - if(max - min > deviation) + if (max - min > deviation) return true; } + return false; } @@ -290,8 +292,8 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors var max = double.MinValue; var end = begin + count; end = end < telemetry.Length ? end : telemetry.Length; - var step = count > 15 ? count / 5 : count > 3 ? 3: 1; - for (var i = begin; i < end; i+= step) + var step = count > 15 ? count / 5 : count > 3 ? 3 : 1; + for (var i = begin; i < end; i += step) { var item = telemetry[i]; var itemValue = getter(item); @@ -302,6 +304,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors if (max - min > deviation) return true; } + return false; } @@ -323,6 +326,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors if (Math.Abs(beginPointValue - itemValue) > deviation) return true; } + return false; } @@ -341,13 +345,12 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors { var item = telemetry[i]; var itemValue = getter(item); - if ( itemValue - beginPointValue > deviation) + if (itemValue - beginPointValue > deviation) return true; } + return false; } } - - } diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs index 64c01f6c..13f665e4 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs @@ -1,68 +1,66 @@ -using System; -using AsbCloudDb.Model; - -namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors -{ - - /// - /// Проработка перед наращиванием - /// - internal class DetectorDevelopment : DetectorAbstract - { - protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end) - => CalcDeltaMinutes(telemetry, begin, end); - - public override Func GetIdOperation => (_, _, _) - => WellOperationCategory.IdDevelopment; - - protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) - { - if (previousOperation?.IdCategory == WellOperationCategory.IdSlipsTime) - return false; - - var point0 = telemetry[position]; - var delta = point0.WellDepth - point0.BitDepth; - if (delta < 0.03d || delta > 30) - return false; - - if (point0.Pressure < 15) - return false; - - if (point0.BlockPosition > 2.5) - return false; - - if (point0.RotorSpeed < 10) - return false; - - if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03)) - 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 || delta > 30) - return IdReasonOfEnd_DeltaDepthOutOfRange; - - if (point0.Pressure < 15) - return IdReasonOfEnd_PressureIsLo; - - if (point0.BlockPosition > 31) - return IdReasonOfEnd_BlockPositionIsHi; - - if (point0.RotorSpeed < 10) - return IdReasonOfEnd_RotorSpeedIsLo; - - return IdReasonOfEnd_NotDetected; - } - - protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end) - => IsValidByWellDepthDoesNotChange(telemetry, begin, end); - } - - -} - +// using System; +// using AsbCloudDb.Model; +// +// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors +// { +// +// /// +// /// Проработка перед наращиванием +// /// +// internal class DetectorDevelopment : DetectorAbstract +// { +// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end) +// => CalcDeltaMinutes(telemetry, begin, end); +// +// public override Func GetIdOperation => (_, _, _) +// => WellOperationCategory.IdDevelopment; +// +// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) +// { +// if (previousOperation?.IdCategory == WellOperationCategory.IdSlipsTime) +// return false; +// +// var point0 = telemetry[position]; +// var delta = point0.WellDepth - point0.BitDepth; +// if (delta < 0.03d || delta > 30) +// return false; +// +// if (point0.Pressure < 15) +// return false; +// +// if (point0.BlockPosition > 2.5) +// return false; +// +// if (point0.RotorSpeed < 10) +// return false; +// +// if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03)) +// 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 || delta > 30) +// return IdReasonOfEnd_DeltaDepthOutOfRange; +// +// if (point0.Pressure < 15) +// return IdReasonOfEnd_PressureIsLo; +// +// if (point0.BlockPosition > 31) +// return IdReasonOfEnd_BlockPositionIsHi; +// +// if (point0.RotorSpeed < 10) +// return IdReasonOfEnd_RotorSpeedIsLo; +// +// return IdReasonOfEnd_NotDetected; +// } +// +// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end) +// => IsValidByWellDepthDoesNotChange(telemetry, begin, end); +// } +// } +// diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs index 3e7af4af..ef0484de 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs @@ -4,9 +4,9 @@ using AsbCloudDb.Model; namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors; -internal class DetectorDrilling : DetectorAbstract +public class DetectorDrilling : DetectorAbstract { - public override Func GetIdOperation => DefineDrillingOperation; + protected override Func GetIdOperation => DefineDrillingOperation; protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) { @@ -18,9 +18,6 @@ internal class DetectorDrilling : DetectorAbstract if (point0.Pressure < 25) return false; - if (point0.RotorSpeed < 5) - return false; - return true; } @@ -37,26 +34,38 @@ internal class DetectorDrilling : DetectorAbstract return IdReasonOfEnd_NotDetected; } - - protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end) - => IsValidByWellDepthIncreasing(telemetry, begin, end); - + 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]; - + 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 < 10) return WellOperationCategory.IdSlide; - - var despersion = telemetryRange - .Average(t => Math.Pow((t.RotorSpeed - avgRotorSpeed) / avgRotorSpeed, 2)); + + var despersion = telemetryRange.Average(t => Math.Pow(t.RotorSpeed/avgRotorSpeed - 1, 2)); return despersion < 0.2d ? WellOperationCategory.IdRotor : idSlideWithOscillation; } diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs index 8be8b197..187aee33 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs @@ -1,39 +1,39 @@ -using System; -using AsbCloudDb.Model; - -namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors -{ - - internal class DetectorSlipsTime : DetectorAbstract - { - protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end) - => CalcDeltaMinutes(telemetry, begin, end); - - public override Func GetIdOperation => (_, _, _) => WellOperationCategory.IdSlipsTime; - - protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) - { - var point0 = telemetry[position]; - var delta = point0.WellDepth - point0.BitDepth; - if (delta > 2.5d) - return false; - - if (point0.Pressure > 15) - return false; - - if (point0.BlockPosition > 8) - return false; - - if (point0.HookWeight > 20) - return false; - - return true; - } - - protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end) - => IsValidByWellDepthDoesNotChange(telemetry, begin, end); - } - - -} - +// using System; +// using AsbCloudDb.Model; +// +// namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors +// { +// +// internal class DetectorSlipsTime : DetectorAbstract +// { +// protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end) +// => CalcDeltaMinutes(telemetry, begin, end); +// +// public override Func GetIdOperation => (_, _, _) => WellOperationCategory.IdSlipsTime; +// +// protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation) +// { +// var point0 = telemetry[position]; +// var delta = point0.WellDepth - point0.BitDepth; +// if (delta > 2.5d) +// return false; +// +// if (point0.Pressure > 15) +// return false; +// +// if (point0.BlockPosition > 8) +// return false; +// +// if (point0.HookWeight > 20) +// return false; +// +// return true; +// } +// +// protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end) +// => IsValidByWellDepthDoesNotChange(telemetry, begin, end); +// } +// +// +// } +// diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/readme.md b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/readme.md deleted file mode 100644 index 5f282702..00000000 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/readme.md +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md index 965f271e..8d69d2b4 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md +++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md @@ -1,29 +1,27 @@ -Метод определения бурения +# Алгоритм определения бурения в роторе, слайде, слайде с осцилляцией -Признак начала операции = +## Метод определения операции бурения -расстояние от долота до забоя < 0.03м  И + Признак начала операции = + (расстояние от долота до забоя < 0.03м) И + (давление > 25атм) + + Признак окончания операции = + (расстояние от долота до забоя > 0.03м) ИЛИ + (давление < 25атм) -давление > 25атм +## Валидация + Для точного определения операции бурения, необходимо убрать диапазон в которых сработал признак окончания операции и не менялась глубина: + Определили точку окончания операции исходя из Признак окончания операции. + Определяем временной интервал, когда не менялась глубина (т.е. время шло, а глубина была неизменна) + Определив начальную точку и точку окончания операции + Исключаем этот интервал из операции. -Признак окончания операции = +## Метод определения бурения в слайде + Необходимо рассчитать средние обороты ротора за всю операцию бурения. + Если среднее арифметическое больше константы (10 об/мин), то это бурение в роторе, если меньше, то это бурение в слайде. -расстояние от долота до забоя > 0.03м  ИЛИ - -давление < 25атм - -Находим границы - -После того когда мы нашли границы, мы должны определить операцию, тогда мы смотрим на забой точки окончания операций сравниваем с забоем точками начала операций: - -Если они равны друг другу, то мы эту операцию дальше не обрабатываем, а выбрасываем. - -Если они не равны, то у нас произошло увеличение забоя, значит эта операция бурения. - -Дальше мы определяем как мы бурили в роторе или слайде, для этого нам необходимо рассчитать среднюю скорость(среднее арифметическое) за всю операцию бурения . Если среднее арифметическое больше константы (10 об/мин), то это бурение в роторе, если меньше, то это бурение в слайде. - -Если бурение в роторе, то мы считаем только дисперсию нормированных оборотов ротора(по среднему значению). (Так как это может быть бурение в слайде с осцилляцией и выглядеть как бурение в роторе): - -Если полученное значение меньше константы(0,2), то мы подтвердили что бурение в роторе. - -Если полученное значение больше константы, то это бурение в слайде с осцилляцией. \ No newline at end of file +## Метод определения бурения в роторе, слайде с осцилляцией + Необходимо рассчитать десперсию нормированных оборотов ротора по(по среднему значению) + 1. Если полученное значение больше константы(0,2), то мы подтвердили что бурение в роторе. + 2. Если полученное значение меньше константы, то это бурение в слайде с осцилляцией. \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs b/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs index 4673d032..fd762b09 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs @@ -16,11 +16,11 @@ public class WorkOperationDetection: Work { private static readonly DetectorAbstract[] detectors = new DetectorAbstract[] { + new DetectorDrilling() // new DetectorRotor(), // new DetectorSlide(), //new DetectorDevelopment(), //new DetectorTemplating(), - new DetectorSlipsTime(), //new DetectorStaticSurveying(), //new DetectorFlashingBeforeConnection(), //new DetectorFlashing(), @@ -116,7 +116,6 @@ public class WorkOperationDetection: Work { var data = await query .Where(d => d.DateTime > startDate) - .Take(take) .ToArrayAsync(token); if (data.Length < gap) @@ -125,25 +124,21 @@ public class WorkOperationDetection: Work var isDetected = false; var positionBegin = 0; var positionEnd = data.Length - gap; - var step = 10; while (positionEnd > positionBegin) { - step ++; - for (int i = 0; i < detectors.Length; i++) + foreach (var detector in detectors) { - if (detectors[i].TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out OperationDetectorResult? result)) - { - detectedOperations.Add(result!.Operation); - lastDetectedOperation = result.Operation; - isDetected = true; - step = 1; - positionBegin = result.TelemetryEnd; - break; - } + if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result)) + continue; + + detectedOperations.Add(result!.Operation); + lastDetectedOperation = result.Operation; + isDetected = true; + positionBegin = result.TelemetryEnd; + break; } - if (step > 20) - step = 10; - positionBegin += step; + + positionBegin += 1; } if (isDetected) diff --git a/AsbCloudWebApi.Tests/Services/DetectedOperations/Detectors/DetectorDrillingTests.cs b/AsbCloudWebApi.Tests/Services/DetectedOperations/Detectors/DetectorDrillingTests.cs new file mode 100644 index 00000000..4dc797fb --- /dev/null +++ b/AsbCloudWebApi.Tests/Services/DetectedOperations/Detectors/DetectorDrillingTests.cs @@ -0,0 +1,290 @@ +using System.Collections.Generic; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services.DetectOperations; +using AsbCloudInfrastructure.Services.DetectOperations.Detectors; +using Xunit; + +namespace AsbCloudWebApi.Tests.Services.DetectedOperations.Detectors; + +public class DetectorDrillingTests : DetectorDrilling +{ + private const int idSlide = 5002; + private const int idRotor = 5003; + private const int idSlideWithOscillation = 12000; + + [Theory] + [MemberData(nameof(TelemetryRangeDrillingRotor))] + public void DefineDrillingOperation_ShouldReturn_DrillingRotor(DetectableTelemetry[] telemetryRange) + { + //act + var result = GetIdOperation.Invoke(telemetryRange, 0, telemetryRange.Length); + + //assert + Assert.Equal(idRotor, result); + } + + [Theory] + [MemberData(nameof(TelemetryRangeDrillingSlide))] + public void DefineDrillingOperation_ShouldReturn_DrillingSlide(DetectableTelemetry[] telemetryRange) + { + //act + var result = GetIdOperation.Invoke(telemetryRange, 0, telemetryRange.Length); + + //assert + Assert.Equal(idSlide, result); + } + + [Theory] + [MemberData(nameof(TelemetryRangeDrillingSlideWithOscillation))] + public void DefineDrillingOperation_ShouldReturn_DrillingSlideWithOscillation(DetectableTelemetry[] telemetryRange) + { + //act + var result = GetIdOperation.Invoke(telemetryRange, 0, telemetryRange.Length); + + //assert + Assert.Equal(idSlideWithOscillation, result); + } + + [Fact] + public void IsValidOperationDetectorResult_ShouldReturn_True() + { + //arrange + var operationDetectorResult = new OperationDetectorResult + { + Operation = new DetectedOperation + { + IdReasonOfEnd = IdReasonOfEnd_PressureIsLo, + DepthStart = 5000, + DepthEnd = 6000 + } + }; + + //act + var result = IsValidOperationDetectorResult(operationDetectorResult); + + //assert + Assert.True(result); + } + + [Fact] + public void IsValidOperationDetectorResult_ShouldReturn_False() + { + //arrange + var operationDetectorResult = new OperationDetectorResult + { + Operation = new DetectedOperation + { + IdReasonOfEnd = IdReasonOfEnd_PressureIsLo, + DepthStart = 5000, + DepthEnd = 5000 + } + }; + + //act + var result = IsValidOperationDetectorResult(operationDetectorResult); + + //assert + Assert.False(result); + } + + public static IEnumerable TelemetryRangeDrillingRotor() + { + yield return new object[] + { + new[] + { + new DetectableTelemetry + { + WellDepth = 4.187f, + Pressure = 27.815952f, + HookWeight = 34.221367f, + BlockPosition = 24.388f, + BitDepth = 4.187f, + RotorSpeed = 40.3f + }, + new DetectableTelemetry + { + WellDepth = 4.232f, + Pressure = 28.080372f, + HookWeight = 34.162174f, + BlockPosition = 24.343f, + BitDepth = 4.232f, + RotorSpeed = 40.3f + }, + new DetectableTelemetry + { + WellDepth = 4.277f, + Pressure = 29.047901f, + HookWeight = 33.688717f, + BlockPosition = 24.298f, + BitDepth = 24.298f, + RotorSpeed = 40.3f + }, + new DetectableTelemetry + { + WellDepth = 4.309f, + Pressure = 29.574032f, + HookWeight = 33.692104f, + BlockPosition = 24.266f, + BitDepth = 4.309f, + RotorSpeed = 40.4f + }, + new DetectableTelemetry + { + WellDepth = 4.324f, + Pressure = 24.007977f, + HookWeight = 34.838448f, + BlockPosition = 24.251f, + BitDepth = 4.324f, + RotorSpeed = 40.5f + }, + new DetectableTelemetry + { + WellDepth = 4.324f, + Pressure = 24.04114f, + HookWeight = 34.423424f, + BlockPosition = 24.252f, + BitDepth = 4.323f, + RotorSpeed = 40.3f + } + } + }; + } + + public static IEnumerable TelemetryRangeDrillingSlide() + { + yield return new object[] + { + new[] + { + new DetectableTelemetry + { + WellDepth = 447.276001f, + Pressure = 26.619421f, + HookWeight = 40.9143829f, + BlockPosition = 4.559f, + BitDepth = 477.265991f, + RotorSpeed = 0 + }, + new DetectableTelemetry + { + WellDepth = 477.289f, + Pressure = 28.716f, + HookWeight = 38.27f, + BlockPosition = 4.5f, + BitDepth = 477.289f, + RotorSpeed = 0.1f + }, + new DetectableTelemetry + { + WellDepth = 477.30899f, + Pressure = 33.953495f, + HookWeight = 38.27f, + BlockPosition = 4.5359997f, + BitDepth = 477.289001f, + RotorSpeed = 0.1f + }, + } + }; + } + + public static IEnumerable TelemetryRangeDrillingSlideWithOscillation() + { + yield return new object[] + { + new[] + { + new DetectableTelemetry + { + IdUser = 1, + WellDepth = 415.306f, + Pressure = 53.731934f, + HookWeight = 41.049942f, + BlockPosition = 28.666f, + BitDepth = 415.293f, + RotorSpeed = 0.3f + }, + new DetectableTelemetry + { + IdUser = 1, + WellDepth = 415.311f, + Pressure = 57.660595f, + HookWeight = 40.898712f, + BlockPosition = 28.648f, + BitDepth = 415.311f, + RotorSpeed = 0.2f + }, + new DetectableTelemetry + { + IdUser = 1, + WellDepth = 415.326f, + Pressure = 59.211086f, + HookWeight = 40.882797f, + BlockPosition = 28.633f, + BitDepth = 415.326f, + RotorSpeed = 0.1f + }, + new DetectableTelemetry + { + IdUser = 1, + WellDepth = 415.344f, + Pressure = 59.484406f, + HookWeight = 40.91972f, + BlockPosition = 28.615f, + BitDepth = 415.344f, + RotorSpeed = 0.2f + }, + new DetectableTelemetry + { + IdUser = 1, + WellDepth = 415.364f, + Pressure = 60.739918f, + HookWeight = 40.795666f, + BlockPosition = 28.595f, + BitDepth = 415.364f, + RotorSpeed = 4.5f + }, + new DetectableTelemetry + { + IdUser = 1, + WellDepth = 415.378f, + Pressure = 62.528984f, + HookWeight = 40.52114f, + BlockPosition = 28.581f, + BitDepth = 415.378f, + RotorSpeed = 22.6f + }, + new DetectableTelemetry + { + IdUser = 1, + WellDepth = 415.392f, + Pressure = 67.0039f, + HookWeight = 38.878895f, + BlockPosition = 28.569f, + BitDepth = 415.39f, + RotorSpeed = 50f + }, + new DetectableTelemetry + { + IdUser = 1, + WellDepth = 415.392f, + Pressure = 65.72418f, + HookWeight = 42.53173f, + BlockPosition = 28.622f, + BitDepth = 415.337f, + RotorSpeed = 93f + }, + new DetectableTelemetry + { + IdUser = 1, + WellDepth = 415.392f, + Pressure = 56.82195f, + HookWeight = 43.15844f, + BlockPosition = 28.704f, + BitDepth = 415.255f, + RotorSpeed = 71.5f + } + } + }; + } +} \ No newline at end of file