From efb08521dc32b96bab878eee2d6405e15cf4ab39 Mon Sep 17 00:00:00 2001 From: Elias Bruvik Date: Thu, 30 Nov 2023 11:19:01 +0000 Subject: [PATCH] FIX-2160 allow different index curves when splicing logs --- .../Workers/SpliceLogsWorker.cs | 23 ++++++--- .../Workers/SpliceLogsWorkerTests.cs | 47 ++++++++++++++----- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Workers/SpliceLogsWorker.cs b/Src/WitsmlExplorer.Api/Workers/SpliceLogsWorker.cs index 6aaa47189..a5e3c408b 100644 --- a/Src/WitsmlExplorer.Api/Workers/SpliceLogsWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/SpliceLogsWorker.cs @@ -82,8 +82,6 @@ private async Task GetLogHeaders(string wellUid, string wellboreUid, private static void VerifyLogHeaders(WitsmlLogs logHeaders) { if (logHeaders.Logs.IsNullOrEmpty()) throw new ArgumentException("Log headers could not be fetched"); - var indexCurve = logHeaders.Logs.FirstOrDefault().IndexCurve; - if (logHeaders.Logs.Any(log => log.IndexCurve.Value != indexCurve.Value)) throw new ArgumentException("IndexCurve must match for all logs"); var direction = logHeaders.Logs.FirstOrDefault().Direction; if (logHeaders.Logs.Any(log => log.Direction != direction)) throw new ArgumentException("Direction must match for all logs"); var indexType = logHeaders.Logs.FirstOrDefault().IndexType; @@ -144,6 +142,7 @@ private async Task CreateNewLog(WitsmlLog newLogHeader) private static WitsmlLog CreateNewLogQuery(WitsmlLogs logHeaders, string newLogUid, string newLogName) { + // The main data should be taken from the first log, but LogCurveInfo and IndexCurve should be taken from the last log. WitsmlLog baseLog = logHeaders.Logs.FirstOrDefault(); return new() { @@ -154,14 +153,24 @@ private static WitsmlLog CreateNewLogQuery(WitsmlLogs logHeaders, string newLogU UidWell = baseLog.UidWell, UidWellbore = baseLog.UidWellbore, IndexType = baseLog.IndexType, - IndexCurve = baseLog.IndexCurve, + IndexCurve = logHeaders.Logs.LastOrDefault().IndexCurve, Direction = baseLog.Direction, - LogCurveInfo = logHeaders.Logs - .SelectMany(log => log.LogCurveInfo) + LogCurveInfo = GetNewLogCurveInfo(logHeaders) + }; + } + + private static List GetNewLogCurveInfo(WitsmlLogs logHeaders) + { + // Returns the LogCurveInfo where curves from the last logs are prioritized. + // The index curve from the last log is also placed first in the new LogCurveInfo. + var indexLogCurveInfo = logHeaders.Logs.LastOrDefault().LogCurveInfo.FirstOrDefault(); + List otherLogCurveInfos = logHeaders.Logs.SelectMany(log => log.LogCurveInfo.Skip(1)).ToList(); // Skip index curve of each log. + var newLogCurveInfo = otherLogCurveInfos .GroupBy(x => x.Mnemonic) .Select(g => g.Last()) - .ToList() - }; + .Prepend(indexLogCurveInfo) + .ToList(); + return newLogCurveInfo; } private async Task AddDataToLog(string wellUid, string wellboreUid, string logUid, WitsmlLogData data) diff --git a/Tests/WitsmlExplorer.Api.Tests/Workers/SpliceLogsWorkerTests.cs b/Tests/WitsmlExplorer.Api.Tests/Workers/SpliceLogsWorkerTests.cs index 556243e2f..e128e7b9e 100644 --- a/Tests/WitsmlExplorer.Api.Tests/Workers/SpliceLogsWorkerTests.cs +++ b/Tests/WitsmlExplorer.Api.Tests/Workers/SpliceLogsWorkerTests.cs @@ -359,11 +359,36 @@ public async Task Execute_IndexCurveNotFirstInLCI_HasCorrectHeader(string indexT Assert.Equal("IndexCurve", newLogHeader.LogCurveInfo.First().Mnemonic); } - private (SpliceLogsJob, WitsmlLogs, WitsmlLogs) SetupTest(string[] logUids, string indexType, int[] startIndexNum, int[] endIndexNum, Action logHeaderCallback, Action logDataCallback) + [Theory] + [InlineData(WitsmlLog.WITSML_INDEX_TYPE_MD)] + [InlineData(WitsmlLog.WITSML_INDEX_TYPE_DATE_TIME)] + public async Task Execute_DifferentIndexCurveNames_HasCorrectHeader(string indexType) + { + string[] logUids = { "log1Uid", "log2Uid" }; + int[] startIndexNum = { 0, 0 }; // start indexes for each log + int[] endIndexNum = { 10, 10 }; // end indexes for each log + string[] indexCurves = { "IndexCurve1", "IndexCurve2" }; + WitsmlLogs capturedLogHeader = null; + WitsmlLogs capturedLogData = null; + + var (job, logHeaders, logData) = SetupTest(logUids, indexType, startIndexNum, endIndexNum, (log) => capturedLogHeader = log, (log) => capturedLogData = log, indexCurves); + + var (workerResult, refreshAction) = await _worker.Execute(job); + + WitsmlLog newLogHeader = capturedLogHeader.Logs.First(); + WitsmlLog newLogDataHeader = capturedLogData.Logs.First(); + + // When Log Curve Info varies between logs, the Log Curve Info of the last log is prioritized. + Assert.Equal("IndexCurve2", newLogHeader.IndexCurve.Value); + Assert.Equal("IndexCurve2", newLogHeader.LogCurveInfo.First().Mnemonic); + Assert.Equal("IndexCurve2", newLogDataHeader.LogData.MnemonicList.Split(',')[0]); + } + + private (SpliceLogsJob, WitsmlLogs, WitsmlLogs) SetupTest(string[] logUids, string indexType, int[] startIndexNum, int[] endIndexNum, Action logHeaderCallback, Action logDataCallback, string[] indexCurves = null) { SpliceLogsJob job = CreateSpliceLogsJob(logUids); - WitsmlLogs logHeaders = CreateSampleLogHeaders(logUids, indexType, startIndexNum, endIndexNum); - WitsmlLogs logData = CreateSampleLogData(logUids, indexType, startIndexNum, endIndexNum); + WitsmlLogs logHeaders = CreateSampleLogHeaders(logUids, indexType, startIndexNum, endIndexNum, indexCurves); + WitsmlLogs logData = CreateSampleLogData(logUids, indexType, startIndexNum, endIndexNum, indexCurves); SetupClient(_witsmlClient, logHeaders, logData, logHeaderCallback, logDataCallback); return (job, logHeaders, logData); } @@ -387,7 +412,7 @@ private SpliceLogsJob CreateSpliceLogsJob(string[] logUids) }; } - private WitsmlLogs CreateSampleLogHeaders(string[] logUids, string indexType, int[] startIndexNum, int[] endIndexNum) + private WitsmlLogs CreateSampleLogHeaders(string[] logUids, string indexType, int[] startIndexNum, int[] endIndexNum, string[] indexCurves = null) { var isDepthLog = indexType == WitsmlLog.WITSML_INDEX_TYPE_MD; return new WitsmlLogs @@ -403,24 +428,24 @@ private WitsmlLogs CreateSampleLogHeaders(string[] logUids, string indexType, in StartDateTimeIndex = isDepthLog ? null : _baseDateTime.AddMinutes(startIndexNum[i]).ToISODateTimeString(), EndIndex = isDepthLog ? new WitsmlIndex() { Value = (endIndexNum[i]).ToString(), Uom = "m" } : null, EndDateTimeIndex = isDepthLog ? null : _baseDateTime.AddMinutes(endIndexNum[i]).ToISODateTimeString(), - IndexCurve = new WitsmlIndexCurve() { Value = "IndexCurve" }, - LogCurveInfo = GetLogCurveInfo(logUids, uid, indexType, startIndexNum, endIndexNum) + IndexCurve = new WitsmlIndexCurve() { Value = indexCurves != null ? indexCurves[i] : "IndexCurve" }, + LogCurveInfo = GetLogCurveInfo(logUids, uid, indexType, startIndexNum, endIndexNum, indexCurves) }).ToList() }; } - private WitsmlLogs CreateSampleLogData(string[] logUids, string indexType, int[] startIndexNum, int[] endIndexNum) + private WitsmlLogs CreateSampleLogData(string[] logUids, string indexType, int[] startIndexNum, int[] endIndexNum, string[] indexCurves = null) { return new WitsmlLogs { - Logs = logUids.Select(uid => new WitsmlLog + Logs = logUids.Select((uid, i) => new WitsmlLog { Uid = uid, UidWell = _wellUid, UidWellbore = _wellboreUid, LogData = new() { - MnemonicList = "IndexCurve,Curve1,Curve2", + MnemonicList = indexCurves != null ? $"{indexCurves[i]},Curve1,Curve2" : "IndexCurve,Curve1,Curve2", UnitList = indexType == WitsmlLog.WITSML_INDEX_TYPE_MD ? "m,Unit1,Unit2" : "DateTime,Unit1,Unit2", Data = GetLogData(logUids, uid, indexType, startIndexNum, endIndexNum) } @@ -438,7 +463,7 @@ private List GetLogData(string[] logUids, string uid, string indexTy return indexes.Select((curveIndex, index) => new WitsmlData() { Data = $"{curveIndex},{uidNum},{index}" }).ToList(); } - private List GetLogCurveInfo(string[] logUids, string uid, string indexType, int[] startIndexNum, int[] endIndexNum) + private List GetLogCurveInfo(string[] logUids, string uid, string indexType, int[] startIndexNum, int[] endIndexNum, string[] indexCurves = null) { var uidNum = logUids.ToList().FindIndex(i => i == uid); var isDepthLog = indexType == WitsmlLog.WITSML_INDEX_TYPE_MD; @@ -450,7 +475,7 @@ private List GetLogCurveInfo(string[] logUids, string uid, s { new WitsmlLogCurveInfo { - Mnemonic = "IndexCurve", + Mnemonic = indexCurves != null ? indexCurves[uidNum] : "IndexCurve", Unit = isDepthLog ? "m" : "DateTime", MinIndex = minIndex, MinDateTimeIndex = minDateTimeIndex,