diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
index b7b5b0b1..1a9f1e17 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorAbstract.cs
@@ -1,5 +1,6 @@
using AsbCloudDb.Model;
using System;
+using System.Collections.Generic;
using System.Linq;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
@@ -26,9 +27,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
positionEnd += stepLength;
if ((positionEnd > end))
- positionEnd = end;
+ break;
- if ((positionEnd == end) || DetectEnd(telemetry, positionEnd, previousOperation))
+ if (DetectEnd(telemetry, positionEnd, previousOperation))
{
result = MakeOperation(idTelemetry, telemetry, begin, positionEnd);
return true;
@@ -132,6 +133,131 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
var result = (double)(pEnd.WellDepth - pBegin.WellDepth) / (pEnd.DateTime - pBegin.DateTime).TotalHours;
return result;
}
+
+ ///
+ /// Расчет статистики по массиву данных за интервал
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected static (double min, double max, double sum, int count) CalcStat(
+ DetectableTelemetry[] telemetry,
+ Func getter,
+ int begin,
+ int count)
+ {
+ var sum = 0d;
+ var min = double.MaxValue;
+ var max = double.MinValue;
+ var end = begin + count;
+ end = end < telemetry.Length ? end : telemetry.Length;
+
+ for (var i = begin; i < end; i++)
+ {
+ var item = telemetry[i];
+ var itemValue = getter(item);
+ if (min > itemValue)
+ min = itemValue;
+ if (max < itemValue)
+ max = itemValue;
+ sum += itemValue;
+ }
+ return (min, max, sum, end - begin);
+ }
+
+ ///
+ /// Максимальное отклонение от среднего за интервал
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected static double CalcMaxDeviation(
+ DetectableTelemetry[] telemetry,
+ Func getter,
+ int begin,
+ int count)
+ {
+ var stat = CalcStat(telemetry, getter, begin, count);
+ var avg = stat.sum / stat.count;
+ var dev1 = avg - stat.min;
+ var dev2 = stat.max - avg;
+ var dev = dev1 > dev2 ? dev1 : dev2;
+ return dev;
+ }
+
+ ///
+ /// Определяет наличие разброса значений в интервале большего указанного значения.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected static bool ContainsDeviation(
+ DetectableTelemetry[] telemetry,
+ Func getter,
+ int begin,
+ int count,
+ double deviation)
+ {
+ var min = double.MaxValue;
+ var max = double.MinValue;
+ var end = begin + count;
+ end = end < telemetry.Length ? end : telemetry.Length;
+
+ for (var i = begin; i < end; i ++)
+ {
+ var item = telemetry[i];
+ var itemValue = getter(item);
+ if (min > itemValue)
+ min = itemValue;
+ if (max < itemValue)
+ max = itemValue;
+ if(max - min > deviation)
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Определяет наличие разброса значений в интервале большего указанного значения. По нескольким значениям из интервала.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected static bool ContainsDeviationApprox(
+ DetectableTelemetry[] telemetry,
+ Func getter,
+ int begin,
+ int count,
+ double deviation)
+ {
+ var min = double.MaxValue;
+ 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 item = telemetry[i];
+ var itemValue = getter(item);
+ if (min > itemValue)
+ min = itemValue;
+ if (max < itemValue)
+ max = itemValue;
+ if (max - min > deviation)
+ return true;
+ }
+ return false;
+ }
}
#nullable disable
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs
index 500b414b..a78075f1 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDevelopment.cs
@@ -30,9 +30,31 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
if (point0.RotorSpeed < 10)
return false;
+ if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03))
+ return false;
+
return true;
}
+ protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+ {
+ var point0 = telemetry[position];
+ var delta = point0.WellDepth - point0.BitDepth;
+ if (delta < 0.03d || delta > 30)
+ return true;
+
+ if (point0.Pressure < 15)
+ return true;
+
+ if (point0.BlockPosition > 31)
+ return true;
+
+ if (point0.RotorSpeed < 10)
+ return true;
+
+ return false;
+ }
+
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
=> IsValidByWellDepthDoesNotChange(telemetry, begin, end);
}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
index 8f0e2edc..90572270 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorSlipsTime.cs
@@ -18,6 +18,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
if (delta > 2.5d)
return false;
+ if (point0.Pressure > 15)
+ return false;
+
if (point0.BlockPosition > 8)
return false;
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs
index a623abab..f26e8a68 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorTemplating.cs
@@ -1,4 +1,5 @@
using AsbCloudDb.Model;
+using System.Collections.Generic;
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{
@@ -30,9 +31,31 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
if (point0.RotorSpeed > 10)
return false;
+ if (!ContainsDeviationApprox(telemetry, d => d.BlockPosition, position, 60, 0.03))
+ return false;
+
return true;
}
+ protected override bool DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
+ {
+ var point0 = telemetry[position];
+ var delta = point0.WellDepth - point0.BitDepth;
+ if (delta < 0.03d || delta > 30)
+ return true;
+
+ if (point0.Pressure < 15)
+ return true;
+
+ if (point0.BlockPosition > 31)
+ return true;
+
+ if (point0.RotorSpeed > 10)
+ return true;
+
+ return false;
+ }
+
protected override bool IsValid(DetectableTelemetry[] telemetry, int begin, int end)
=> IsValidByWellDepthDoesNotChange(telemetry, begin, end);
}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs b/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
index 67325c3d..2e44e1e8 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
@@ -95,7 +95,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
var affected = 0;
foreach (var item in JounedlastDetectedDates)
{
+ var stopwatch = Stopwatch.StartNew();
var newOperations = await DetectOperationsAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
+ stopwatch.Stop();
if (newOperations.Any())
{
db.DetectedOperations.AddRange(newOperations);
@@ -161,13 +163,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
}
if (isDetected)
- {
- startDate = detectedOperations.Last().DateEnd;
- }
+ startDate = lastDetectedOperation.DateEnd;
else
- {
startDate = data[positionEnd].DateTime;
- }
}
return detectedOperations;
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md
new file mode 100644
index 00000000..06cc4eea
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Бурение ротор и слайд.md
@@ -0,0 +1,22 @@
+# Алгоритм определения бурения в роторе
+## Описание
+
+## Метод определения бурения в роторе
+
+ Признак начала операции =
+ ( расстояние от долота до забоя < 0.03м ) И
+ ( давление > 25атм ) И
+ ( глубина забоя за следующую секунду больше текущей на 0.003м ) И
+ ( обороты ротора > 5 об/м );
+
+ Признак окончания операции =
+ ( расстояние от долота до забоя > 0.03м ) ИЛИ
+ ( давление < 25атм ) ИЛИ
+ ( среднее арифметическое оборотов ротора за 10 сек < 5 об/м )
+ ( глубина забоя в течении следующих 30 сек увеличивается медленнее 1 м/час );
+
+## Метод определения бурения в слайде
+Повторяет метод определения бурения в роторе, за исключением условия с оборотами ротора. Это уловие нужно инвертировать.
+
+## Ключевой параметр
+МСП = разность глубины забоя на конец и начало операции / продолжительность операции.
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Время в клиньях.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Время в клиньях.md
deleted file mode 100644
index fedc6b74..00000000
--- a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Время в клиньях.md
+++ /dev/null
@@ -1,44 +0,0 @@
-> Из писма Гранова А.П. от 19.04.2022 13:29 "Алгоритм определения наращивания БИ.docx"
-
-# Алгоритм определения времени в клиньях
-
-## Описание:
-Наращивание бурильного инструмента – операция, во время которой после добуривания очередной трубы/ свечи
-циркуляция выключается, инструмент разгружается в клиньях (остается только вес крюкоблока и ВСП),
-происходит развинчивание трубы от верхнего силового привода, берется очередная труба/ свеча,
-свинчивается с инструментом в клиньях, свинчивается с верхним силовым приводом, происходит подъем инструмента,
-вес на крюке увеличивается. Далее включается циркуляция и происходит механическое бурение.
-
-Наращиванию предшествует механическое бурение (наличие давления, увеличение глубины забоя) и
-после наращивания механическое бурение возобновляется (наличие давления, Увеличение глубины забоя).
-
-> Это не учитывать в методе, так как предыдущая и последующая операция могут быть определены не корректно.
-
- Наращивается определяется как время между:
-- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП).
- При этом давление менее 15 атм. В случае давления более 15 атм считать началом операции как
- снижение давления менее 15 атм и началом движения талевого блока вверх.
-- снятие инструмента с клиньев (вес увеличивается более, чем на 1т).
-- При этом движение талевого блока происходит вверх.
-
-## Метод определения:
-
-> Исправлено на совещании от 19.04.2022 16:50
-
-> Исправлено задачей в кайтен от 12.05.2022 16:49
-
-считать время в клиньях только при соотношении глубина забоя - глубина долота меньше 2,5 метра
-
-```
-Признак начала операции =
-(параметр «вес на крюке» < 22 тонн) И
-(давление < 15 атм) И
-(положение талевого блока < 8) И
-(глубина забоя - глубина долота < 2,5)
-
-
-Признак окончания операции =
-(вес на крюке > 22 ) И
-(давление > 15 атм)
-```
-
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Проработка перед наращиванием.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Проработка перед наращиванием.md
new file mode 100644
index 00000000..18421cc6
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Проработка перед наращиванием.md
@@ -0,0 +1,31 @@
+# Алгоритм определения шаблонировки перед наращиванием
+## Описание
+
+Проработка перед наращиванием бурильного инструмента – операция, во время которой после добуривания очередной трубы/ свечи начинается подъем и спуск бурильного инструмента с вращением. Следующей операцией после проработки будет либо шаблонировка (аналогично проработке, но без вращения), либо разгрузка инструмента в клинья (снижение веса на крюке) - наращивание
+
+Проработка перед наращиванием определяется как время между:
+- начало подъема/ спуска бурильного инструмента с вращением
+- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП). При этом давление менее 15 атм. ЛИБО
+- начало подъема/ спуска бурильного инструмента БЕЗ вращения
+- считать время на проработку только при соотношении глубина забоя - глубина долота не больше меньше 30 метров
+
+## Метод определения
+
+ Признак начала операции =
+ ( предыдущая операция НЕ удержание в клиньях) И
+ ( расстояние от долота до забоя > 0.03м ) И
+ ( расстояние от долота до забоя < 30м ) И
+ ( давление > 15 атм ) И
+ ( положение блока < 31м ) И
+ ( обороты ротора > 10 об/м ) И
+ ( высота блока изменяется больше чем на 0.03м в течении 60 сек с начала операции);
+
+ Признак окончания операции =
+ ( расстояние от долота до забоя < 0.03м ) ИЛИ
+ ( расстояние от долота до забоя < 30м ) ИЛИ
+ ( давление < 15 атм ) ИЛИ
+ ( положение блока > 31м ) ИЛИ
+ ( обороты ротора < 10 об/м );
+
+## Ключевой параметр
+Продолжительность операции.
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Удержание в клиньях.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Удержание в клиньях.md
new file mode 100644
index 00000000..fee75476
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Удержание в клиньях.md
@@ -0,0 +1,21 @@
+# Алгоритм определения времени в клиньях
+## Описание
+
+Наращивание бурильного инструмента – операция, во время которой после добуривания очередной трубы/ свечи циркуляция выключается, инструмент разгружается в клиньях (остается только вес крюкоблока и ВСП), происходит развинчивание трубы от верхнего силового привода, берется очередная труба/ свеча, свинчивается с инструментом в клиньях, свинчивается с верхним силовым приводом, происходит подъем инструмента, вес на крюке увеличивается. Далее включается циркуляция и происходит механическое бурение.
+
+ Наращивается определяется как время между:
+- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП). При этом давление менее 15 атм. В случае давления более 15 атм считать началом операции как снижение давления менее 15 атм и началом движения талевого блока вверх.
+- снятие инструмента с клиньев (вес увеличивается более, чем на 1т). При этом движение талевого блока происходит вверх.
+
+## Метод определения
+
+ Признак начала операции =
+ ( расстояние от долота до забоя < 2.5м ) И
+ ( положение талевого блока < 8 ) И
+ ( вес на крюке < 20 тонн ) И
+ ( давление < 15 атм );
+
+ Признак окончания операции = НЕ выполняется признак начала операции;
+
+## Ключевой параметр
+Продолжительность операции.
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Шаблонировки перед наращиванием.md b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Шаблонировки перед наращиванием.md
new file mode 100644
index 00000000..37cd488b
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Specifications/Шаблонировки перед наращиванием.md
@@ -0,0 +1,31 @@
+# Алгоритм определения шаблонировки перед наращиванием
+## Описание
+
+Шаблонировкаперед наращиванием бурильного инструмента – операция, во время которой после добуривания очередной трубы/ свечи начинается подъем и спуск бурильного инструмента БЕЗ вращения. Следующей операцией после шаблонировки будет либо проработка (аналогично шаблонировке, но С вращением), либо разгрузка инструмента в клинья (снижение веса на крюке) - наращивание
+
+Шаблонировка перед наращиванием определяется как время между:
+- начало подъема/ спуска бурильного инструмента БЕЗ вращения
+- разгрузкой инструмента на клинья (остается только вес крюкоблока и ВСП). При этом давление менее 15 атм. ЛИБО
+- начало подъема/ спуска бурильного инструмента БЕЗ вращения
+- считать время на шаблонировку только при соотношении глубина забоя - глубина долота не больше меньше 30 метров
+
+## Метод определения
+
+ Признак начала операции =
+ ( предыдущая операция НЕ удержание в клиньях) И
+ ( расстояние от долота до забоя > 0.03м ) И
+ ( расстояние от долота до забоя < 30м ) И
+ ( давление > 15 атм ) И
+ ( положение блока < 31м ) И
+ ( обороты ротора < 10 об/м ) И
+ ( высота блока изменяется больше чем на 0.03м в течении 60 сек с начала операции);
+
+ Признак окончания операции =
+ ( расстояние от долота до забоя < 0.03м ) ИЛИ
+ ( расстояние от долота до забоя < 30м ) ИЛИ
+ ( давление < 15 атм ) ИЛИ
+ ( положение блока > 31м ) ИЛИ
+ ( обороты ротора > 10 об/м );
+
+## Ключевой параметр
+Продолжительность операции.
\ No newline at end of file