From 23f53f3ed9332295766e84df4a24a092d4a13fea Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Fri, 15 Nov 2024 09:25:44 +0100 Subject: [PATCH 01/10] =?UTF-8?q?Download=20log=20data=20as=20a=20LAS=20fi?= =?UTF-8?q?le=F0=9F=92=A1=20#2588?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Jobs/DownloadLogDataJob.cs | 5 + .../Workers/DownloadLogDataWorker.cs | 387 +++++++++++++++++- .../ContentViews/CurveValuesView.tsx | 46 ++- .../models/jobs/downloadLogDataJob.tsx | 1 + 4 files changed, 434 insertions(+), 5 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Jobs/DownloadLogDataJob.cs b/Src/WitsmlExplorer.Api/Jobs/DownloadLogDataJob.cs index 8bbca2110..08575bd24 100644 --- a/Src/WitsmlExplorer.Api/Jobs/DownloadLogDataJob.cs +++ b/Src/WitsmlExplorer.Api/Jobs/DownloadLogDataJob.cs @@ -25,6 +25,11 @@ public record DownloadLogDataJob : Job /// public bool StartIndexIsInclusive { get; init; } + /// + /// If to export to LAS format (default is CVS) + /// + public bool ExportToLas { get; init; } + /// /// Start index for range selection /// diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index 9d1701874..dad01bd03 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; +using System.Globalization; +using System.IO; using System.Linq; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -20,16 +23,19 @@ public class DownloadLogDataWorker : BaseWorker, IWorker { public JobType JobType => JobType.DownloadLogData; private readonly ILogObjectService _logObjectService; + private readonly IWellService _wellService; private readonly char _newLineCharacter = '\n'; private readonly char _separator = ','; public DownloadLogDataWorker( ILogger logger, IWitsmlClientProvider witsmlClientProvider, - ILogObjectService logObjectService) + ILogObjectService logObjectService, + IWellService wellService) : base(witsmlClientProvider, logger) { _logObjectService = logObjectService; + _wellService = wellService; } /// /// Downaloads all log data and generates a report. @@ -56,11 +62,15 @@ public DownloadLogDataWorker( } var logData = await _logObjectService.ReadLogData(job.LogReference.WellUid, job.LogReference.WellboreUid, job.LogReference.Uid, job.Mnemonics.ToList(), job.StartIndexIsInclusive, job.LogReference.StartIndex, job.LogReference.EndIndex, true, cancellationToken, progressReporter); - - return DownloadLogDataResult(job, logData.Data, logData.CurveSpecifications); + var well = await _wellService.GetWell(job.LogReference.WellUid); + return (job.ExportToLas) + ? DownloadLogDataResultLasFile(job, logData.Data, + logData.CurveSpecifications, well) + : DownloadLogDataResultCvsFile(job, logData.Data, + logData.CurveSpecifications); } - private (WorkerResult, RefreshAction) DownloadLogDataResult(DownloadLogDataJob job, ICollection> reportItems, ICollection curveSpecifications) + private (WorkerResult, RefreshAction) DownloadLogDataResultCvsFile(DownloadLogDataJob job, ICollection> reportItems, ICollection curveSpecifications) { Logger.LogInformation("Download of all data is done. {jobDescription}", job.Description()); string content = GetCsvFileContent(reportItems, curveSpecifications); @@ -69,6 +79,26 @@ public DownloadLogDataWorker( return (workerResult, null); } + private (WorkerResult, RefreshAction) DownloadLogDataResultLasFile(DownloadLogDataJob job, ICollection> reportItems, ICollection curveSpecifications, Well well) + { + Logger.LogInformation("Download of all data is done. {jobDescription}", job.Description()); + var columnLengths = CalculateColumnLength(reportItems, + curveSpecifications); + var maxHeaderLength = + CalculateMaxHeaderLength(curveSpecifications); + using var writer = new StringWriter(); + WriteLogCommonInformation(writer, maxHeaderLength); + var limitValues = GetLimitValues(curveSpecifications, reportItems); + WriteWellInformationSection(writer, well, maxHeaderLength, limitValues); + WriteLogDefinitionSection(writer, curveSpecifications, maxHeaderLength); + WriteColumnHeaderSection(writer, curveSpecifications, columnLengths); + WriteDataSection(writer, reportItems, curveSpecifications, columnLengths); + string content = writer.ToString(); + job.JobInfo.Report = DownloadLogDataReport(job.LogReference, content, "las"); + WorkerResult workerResult = new(GetTargetWitsmlClientOrThrow().GetServerHostname(), true, $"Download of all data is ready, jobId: ", jobId: job.JobInfo.Id); + return (workerResult, null); + } + private DownloadLogDataReport DownloadLogDataReport(LogObject logReference, string fileContent, string fileExtension) { return new DownloadLogDataReport @@ -114,4 +144,353 @@ private string GetReportBody(ICollection> repor ); return body; } + + private Dictionary CalculateColumnLength( + ICollection> data, ICollection curveSpecifications) + { + var result = new Dictionary(); + foreach (var curveSpecification in curveSpecifications) + { + var oneColumn = data.Select(row => + + row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) + ? value.Value.ToString()!.Length + : 0 + ).Max(); + result[curveSpecification.Mnemonic] = (curveSpecification.Mnemonic.Length + curveSpecification.Unit.Length + 3) > oneColumn ? curveSpecification.Mnemonic.Length + curveSpecification.Unit.Length + 3: oneColumn ; + } + return result; + } + + private int CalculateMaxHeaderLength( + ICollection curveSpecifications) + { + var result = 0; + foreach (var curveSpecification in curveSpecifications) + { + if ((curveSpecification.Mnemonic.Length + + curveSpecification.Unit.Length) > result) + result = curveSpecification.Mnemonic.Length + + curveSpecification.Unit.Length; + } + return result; + } + + private LimitValues GetLimitValues(ICollection curveSpecifications, + ICollection> data) + { + var curveSpecificationDepth = + curveSpecifications.FirstOrDefault(x => x.Mnemonic.ToLower() == "depth"); + var curveSpecificationTime = curveSpecifications.FirstOrDefault(x => x.Mnemonic.ToLower() == "time"); + var isDepthBasedSeries = curveSpecificationDepth != null; + var result = new LimitValues() ; + if (curveSpecificationDepth == null && curveSpecificationTime == null) + return result; + var oneColumn = isDepthBasedSeries + ? data.Select(row => + + row.TryGetValue(curveSpecificationDepth.Mnemonic, out LogDataValue value) + ? value.Value.ToString() + : "0" + ).ToList() + : data.Select(row => + row.TryGetValue(curveSpecificationTime.Mnemonic, out LogDataValue value) + ? value.Value.ToString() + : DateTime.Now.ToString(CultureInfo.InvariantCulture) + ).ToList(); + var firstValue = oneColumn.First(); + var lastValue = oneColumn.Last(); + result.Start = firstValue; + result.Stop = lastValue; + + result.Step = CalculateStep(oneColumn, firstValue, isDepthBasedSeries); + + result.Unit = isDepthBasedSeries + ? curveSpecificationDepth.Unit + : curveSpecificationTime.Unit; + result.LogType = isDepthBasedSeries + ? "DEPTH" + : "TIME"; + return result; + } + + private static string CalculateStep(List oneColumn, string firstValue, bool isDepthBasedSeries) + { + var result = string.Empty; + foreach (var row in oneColumn) + { + if (firstValue == row) + { + continue; + } + + result = isDepthBasedSeries ? CalculateStepDepth(row, firstValue) : CalculateStepTime(row, firstValue); + if (result == string.Empty) + return result; + firstValue = row; + } + return result; + } + + private static string CalculateStepTime(string row, string firstValue) + { + var secondValue = StringHelpers.ToDateTime(row); + var difference = secondValue - + StringHelpers.ToDateTime(firstValue); + var newDifference = StringHelpers.ToDateTime(row) - StringHelpers.ToDateTime(firstValue); + if (difference != newDifference) + { + return string.Empty; + } + + return difference.ToString(); + } + + private static string CalculateStepDepth(string row, string firstValue) + { + var secondValue = StringHelpers.ToDecimal(row); + var difference = secondValue - + StringHelpers.ToDecimal(firstValue); + var newDifference = StringHelpers.ToDecimal(row) - StringHelpers.ToDecimal(firstValue); + if (difference != newDifference) + { + return string.Empty; + } + return difference.ToString(CultureInfo.InvariantCulture); + } + + private void WriteLogCommonInformation(StringWriter writer, int maxColumnLenght) + { + writer.WriteLine("~VERSION INFORMATION"); + WriteCommonParameter(writer, "VERS.", "2.0", "CWLS LOG ASCII STANDARD - VERSION 2.0", maxColumnLenght); + WriteCommonParameter(writer, "WRAP.", "NO", "ONE LINE PER STEP", maxColumnLenght); + WriteCommonParameter(writer, "PROD.", "Equinor", "LAS Producer", maxColumnLenght); + WriteCommonParameter(writer, "PROG.", "WITSML Explorer", "LAS Program name", maxColumnLenght); + WriteCommonParameter(writer, "CREA.", DateTime.Now.ToShortDateString(), "LAS Creation date", maxColumnLenght); + } + private void WriteLogDefinitionSection(StringWriter writer, ICollection curveSpecifications, int maxColumnLenght) + { + writer.WriteLine("~PARAMETER INFORMATION"); + writer.WriteLine("~CURVE INFORMATION"); + CreateHeader(writer, maxColumnLenght, "API CODE", "CURVE DESCRIPTION"); + int i = 1; + foreach (var curveSpecification in curveSpecifications) + { + var line = new StringBuilder(); + line.Append(curveSpecification.Mnemonic); + line.Append(new string(' ', maxColumnLenght - curveSpecification.Mnemonic.Length)); + line.Append('.'); + line.Append(curveSpecification.Unit); + line.Append(new string(' ', maxColumnLenght - curveSpecification.Unit.Length)); + line.Append(new string(' ', maxColumnLenght -1)); + line.Append(": "); + line.Append(i++); + line.Append(' '); + line.Append(curveSpecification.Mnemonic.Replace("_", " ")); + line.Append(" ("); + line.Append(curveSpecification.Unit); + line.Append(')'); + writer.WriteLine(line.ToString()); + } + } + + private static void CreateHeader(StringWriter writer, int maxColumnLenght, string thirdColumn, string fourthColumn) + { + var header = new StringBuilder(); + var secondHeader = new StringBuilder(); + header.Append("#MNEM"); + secondHeader.Append("#----"); + if (maxColumnLenght > 5) + { + header.Append(new string(' ', maxColumnLenght - 5)); + secondHeader.Append(new string(' ', maxColumnLenght - 5)); + } + header.Append(".UNIT"); + secondHeader.Append(new string('-', 5)); + if (maxColumnLenght > 5) + { + header.Append(new string(' ', maxColumnLenght - 5)); + secondHeader.Append(new string(' ', maxColumnLenght - 5)); + } + header.Append(thirdColumn); + secondHeader.Append(new string('-', thirdColumn.Length)); + if (maxColumnLenght > thirdColumn.Length) + { + header.Append(new string(' ', maxColumnLenght - thirdColumn.Length)); + secondHeader.Append(new string(' ', maxColumnLenght - thirdColumn.Length)); + } + header.Append(fourthColumn); + secondHeader.Append(new string('-', fourthColumn.Length)); + writer.WriteLine(header.ToString()); + writer.WriteLine(secondHeader.ToString()); + } + + private void WriteColumnHeaderSection(StringWriter writer, ICollection curveSpecifications, Dictionary maxColumnLenghts) + { + writer.WriteLine("#"); + writer.WriteLine( + "#-----------------------------------------------------------"); + int i = 0; + var line = new StringBuilder(); + foreach (var curveSpecification in curveSpecifications) + { + int emptySpaces = maxColumnLenghts[curveSpecification.Mnemonic] - + curveSpecification.Mnemonic.Length - + curveSpecification.Unit.Length - 3; + if (i == 0) + { + line.Append("# "); + if (emptySpaces > 2) + line.Append(new string(' ', emptySpaces -2)); + } + else + { + if (emptySpaces > 0) + line.Append(new string(' ', emptySpaces)); + } + + line.Append(curveSpecification.Mnemonic); + line.Append(" ("); + line.Append(curveSpecification.Unit); + if (i < curveSpecifications.Count) + line.Append(") "); + else + { + line.Append(')'); + } + i++; + } + writer.WriteLine(line.ToString()); + writer.WriteLine( + "#-----------------------------------------------------------"); + writer.WriteLine("~A"); + } + + private void WriteWellInformationSection(StringWriter writer, Well well, int maxColumnLength, LimitValues limitValues) + { + writer.WriteLine("~WELL INFORMATION BLOCK"); + CreateHeader(writer, maxColumnLength, "DATA", "DESCRIPTION OF MNEMONIC"); + WriteWellParameter(writer, "STRT", limitValues.Unit, limitValues.Start,$"START {limitValues.LogType}", maxColumnLength); + WriteWellParameter(writer, "STOP", limitValues.Unit, limitValues.Stop, $"STOP {limitValues.LogType}", maxColumnLength); + WriteWellParameter(writer, "STEP", limitValues.Unit, limitValues.Step, "STEP VALUE", maxColumnLength); + WriteWellParameter(writer, "SNULL", "", "", "NULL VALUE", maxColumnLength); + WriteWellParameter(writer, "SCOMP", "", well.Operator, "COMPANY NAME", maxColumnLength); + WriteWellParameter(writer, "SWELL", "", well.Name, "WELL NAME", maxColumnLength); + WriteWellParameter(writer, "SFLD", "", "", "FIELD NAME", maxColumnLength); + WriteWellParameter(writer, "SRIGN", "", "", "RIG NAME", maxColumnLength); + WriteWellParameter(writer, "SRIGTYP", "", "", "RIG TYPE", maxColumnLength); + WriteWellParameter(writer, "SSON", "", "", "Service Order Number", maxColumnLength); + WriteWellParameter(writer, "SSRVC", "", "", "SERVICE COMPANY NAME", maxColumnLength); + WriteWellParameter(writer, "SSRVL", "", "", "SERVICE LINE NAME", maxColumnLength); + WriteWellParameter(writer, "SLOGC", "", "", "LOGGING COMPANY NAME", maxColumnLength); + WriteWellParameter(writer, "SDEGT", "", "", "DEGASSER TYPE NAME", maxColumnLength); + WriteWellParameter(writer, "SDETT", "", "", "DEECTOR TYPE NAME", maxColumnLength); + WriteWellParameter(writer, "SAPPC", "", "", "APPLIED CORRECTIONS", maxColumnLength); + WriteWellParameter(writer, "SDATE", "", $"{DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}", "DATE", maxColumnLength); + WriteWellParameter(writer, "SCLAB", "", "", "County label", maxColumnLength); + WriteWellParameter(writer, "SSLAB", "", "", "State/Province label", maxColumnLength); + WriteWellParameter(writer, "SPROV", "", "", "State or Province", maxColumnLength); + WriteWellParameter(writer, "SCTRY", "", well.Country, "COUNTRY", maxColumnLength); + WriteWellParameter(writer, "SCONT_REGION", "", "", "Continent Region", maxColumnLength); + WriteWellParameter(writer, "SSECT", "", "", "Section", maxColumnLength); + WriteWellParameter(writer, "STOWN", "", "", "Township", maxColumnLength); + WriteWellParameter(writer, "SRANGE", "", "", "Range", maxColumnLength); + WriteWellParameter(writer, "SAPI", "", "", "API Number", maxColumnLength); + WriteWellParameter(writer, "SUWI", "", "", "UNIQUE WELL IDENTIFIER", maxColumnLength); + WriteWellParameter(writer, "SLUL", "", "", "Logging Unit Location", maxColumnLength); + WriteWellParameter(writer, "SLUN", "", "", "Logging Unit Number", maxColumnLength); + WriteWellParameter(writer, "SLOC", "", "", "Field Location", maxColumnLength); + WriteWellParameter(writer, "SFL1", "", "", "Field Location line 1", maxColumnLength); + WriteWellParameter(writer, "SFL2", "", "", "Field Location line 2", maxColumnLength); + WriteWellParameter(writer, "SLATI", "deg", "", "Latitude", maxColumnLength); + WriteWellParameter(writer, "SLONG", "deg", "", "Local Permanent Datum", maxColumnLength); + WriteWellParameter(writer, "SPDAT", "", "", "Geodetic Datum", maxColumnLength); + WriteWellParameter(writer, "SGDAT", "", "", "Geodetic Datum", maxColumnLength); + WriteWellParameter(writer, "SLMF", "", "", "Logging Measured From", maxColumnLength); + WriteWellParameter(writer, "SAPD", limitValues.Unit, "", "Elevation of Depth Reference (LMF) above Permanent Datum", maxColumnLength); + WriteWellParameter(writer, "SEPD", limitValues.Unit, "", "Elevation of Permanent Datum (PDAT) above Mean Sea Level", maxColumnLength); + WriteWellParameter(writer, "SEKD", limitValues.Unit, "", "Elevation of Kelly Bushing above Permanent Datum", maxColumnLength); + WriteWellParameter(writer, "SEDF", limitValues.Unit, "", "Elevation of Drill Floor above Permanent Datum", maxColumnLength); + } + + private void WriteCommonParameter(StringWriter writer, string nameOfParemeter, string data, string description, int maxColumnLength) + { + var line = new StringBuilder(); + line.Append(nameOfParemeter); + if (maxColumnLength - nameOfParemeter.Length > 0) + { + line.Append(new string(' ', maxColumnLength - nameOfParemeter.Length)); + } + line.Append(" "); + line.Append(data); + if ((maxColumnLength * 2) - data.Length - 1 > 0) + { + line.Append(new string(' ', (maxColumnLength * 2) - data.Length - 1)); + } + line.Append(':'); + line.Append(description); + writer.WriteLine(line.ToString()); + } + private void WriteWellParameter(StringWriter writer, string nameOfParemeter, string unit, + string data, string description, int maxColumnLength) + { + var line = new StringBuilder(); + line.Append(nameOfParemeter); + if (maxColumnLength - nameOfParemeter.Length > 0) + { + line.Append(new string(' ', maxColumnLength - nameOfParemeter.Length)); + } + line.Append('.'); + line.Append(unit); + if (maxColumnLength - unit.Length - 1 > 0) + { + line.Append(new string(' ', maxColumnLength - unit.Length - 1)); + } + line.Append(data); + if (maxColumnLength - data.Length > 0) + { + line.Append(new string(' ', maxColumnLength - data.Length)); + } + line.Append(':'); + line.Append(description); + writer.WriteLine(line.ToString()); + } + + + private void WriteDataSection(StringWriter writer, + ICollection> data, ICollection curveSpecifications, Dictionary columnsLength) + { + foreach (var row in data) + { + var line = new StringBuilder(); + int i = 0; + foreach (var curveSpecification in curveSpecifications) + { + var cell = row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) + ? value.Value.ToString() + : string.Empty; + + int length = columnsLength[curveSpecification.Mnemonic] - cell!.Length; + if (i == 0 && length != 0) + { + length += 2; + } + if (length > 0) line.Append(new string(' ', length )); + line.Append(cell); + if (i < curveSpecifications.Count -1) line.Append(' '); + i++; + } + writer.WriteLine(line.ToString()); + } + } + + private class LimitValues + { + public string Start { get; set; } + public string Stop { get; set; } + public string Step { get; set; } + public string Unit { get; set; } + public string LogType { get; set; } + } + } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx index b2e754135..e59cd2a75 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx @@ -86,6 +86,11 @@ enum DownloadOptions { SelectedIndexValues = "SelectedIndexValues" } +enum DownloadFormat { + Csv = "Csv", + Las = "Las" +} + export const CurveValuesView = (): React.ReactElement => { const { operationState: { timeZone, dateTimeFormat, colors, theme }, @@ -127,6 +132,7 @@ export const CurveValuesView = (): React.ReactElement => { const { exportData, exportOptions } = useExport(); const justFinishedStreaming = useRef(false); let downloadOptions: DownloadOptions = DownloadOptions.SelectedRange; + let downloadFormat: DownloadFormat = DownloadFormat.Csv; const { components: logCurveInfoList, isFetching: isFetchingLogCurveInfo } = useGetComponents( connectedServer, @@ -152,6 +158,14 @@ export const CurveValuesView = (): React.ReactElement => { downloadOptions = enumToString; }; + const onChangeDownloadFormat = ( + event: React.ChangeEvent + ) => { + const selectedValue = event.target.value; + const enumToString = selectedValue as DownloadFormat; + downloadFormat = enumToString; + }; + const onRowSelectionChange = useCallback( (rows: CurveValueRow[]) => setSelectedRows(rows), [] @@ -409,10 +423,13 @@ export const CurveValuesView = (): React.ReactElement => { const exportSelectedRange = async () => { const logReference: LogObject = log; const startIndexIsInclusive = !autoRefresh; + const exportToLas = downloadFormat === DownloadFormat.Las; + console.log(exportToLas); const downloadLogDataJob: DownloadLogDataJob = { logReference, mnemonics, startIndexIsInclusive, + exportToLas, startIndex, endIndex }; @@ -422,10 +439,13 @@ export const CurveValuesView = (): React.ReactElement => { const exportAll = async () => { const logReference: LogObject = log; const startIndexIsInclusive = !autoRefresh; + const exportToLas = downloadFormat === DownloadFormat.Las; + console.log(exportToLas); const downloadLogDataJob: DownloadLogDataJob = { logReference, mnemonics, - startIndexIsInclusive + startIndexIsInclusive, + exportToLas }; callExportJob(downloadLogDataJob); }; @@ -484,6 +504,30 @@ export const CurveValuesView = (): React.ReactElement => { /> Download all data + +
+ + Choose file type + + + } onConfirm={() => { diff --git a/Src/WitsmlExplorer.Frontend/models/jobs/downloadLogDataJob.tsx b/Src/WitsmlExplorer.Frontend/models/jobs/downloadLogDataJob.tsx index 8bf59db81..8e2f15afb 100644 --- a/Src/WitsmlExplorer.Frontend/models/jobs/downloadLogDataJob.tsx +++ b/Src/WitsmlExplorer.Frontend/models/jobs/downloadLogDataJob.tsx @@ -4,6 +4,7 @@ export default interface DownloadLogDataJob { logReference: LogObject; mnemonics: string[]; startIndexIsInclusive: boolean; + exportToLas: boolean; startIndex?: string; endIndex?: string; } From 60f30ad9317e0dfd110da54bcde667be6467401e Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Fri, 15 Nov 2024 09:34:45 +0100 Subject: [PATCH 02/10] test --- Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs | 3 +-- .../components/ContentViews/CurveValuesView.tsx | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index dad01bd03..318452eab 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -145,8 +145,7 @@ private string GetReportBody(ICollection> repor return body; } - private Dictionary CalculateColumnLength( - ICollection> data, ICollection curveSpecifications) + private Dictionary CalculateColumnLength(ICollection> data, ICollection curveSpecifications) { var result = new Dictionary(); foreach (var curveSpecification in curveSpecifications) diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx index e59cd2a75..e4631b858 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx @@ -424,7 +424,6 @@ export const CurveValuesView = (): React.ReactElement => { const logReference: LogObject = log; const startIndexIsInclusive = !autoRefresh; const exportToLas = downloadFormat === DownloadFormat.Las; - console.log(exportToLas); const downloadLogDataJob: DownloadLogDataJob = { logReference, mnemonics, @@ -440,7 +439,6 @@ export const CurveValuesView = (): React.ReactElement => { const logReference: LogObject = log; const startIndexIsInclusive = !autoRefresh; const exportToLas = downloadFormat === DownloadFormat.Las; - console.log(exportToLas); const downloadLogDataJob: DownloadLogDataJob = { logReference, mnemonics, From 381455c89335ba0a136271f6bf7386e2ee33c6d3 Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Fri, 15 Nov 2024 09:44:05 +0100 Subject: [PATCH 03/10] test --- .../Workers/DownloadLogDataWorker.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index 318452eab..ea9bff1b1 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -156,7 +156,7 @@ private Dictionary CalculateColumnLength(ICollection oneColumn ? curveSpecification.Mnemonic.Length + curveSpecification.Unit.Length + 3: oneColumn ; + result[curveSpecification.Mnemonic] = (curveSpecification.Mnemonic.Length + curveSpecification.Unit.Length + 3) > oneColumn ? curveSpecification.Mnemonic.Length + curveSpecification.Unit.Length + 3 : oneColumn; } return result; } @@ -182,7 +182,7 @@ private LimitValues GetLimitValues(ICollection curveSpecific curveSpecifications.FirstOrDefault(x => x.Mnemonic.ToLower() == "depth"); var curveSpecificationTime = curveSpecifications.FirstOrDefault(x => x.Mnemonic.ToLower() == "time"); var isDepthBasedSeries = curveSpecificationDepth != null; - var result = new LimitValues() ; + var result = new LimitValues(); if (curveSpecificationDepth == null && curveSpecificationTime == null) return result; var oneColumn = isDepthBasedSeries @@ -236,7 +236,7 @@ private static string CalculateStepTime(string row, string firstValue) var secondValue = StringHelpers.ToDateTime(row); var difference = secondValue - StringHelpers.ToDateTime(firstValue); - var newDifference = StringHelpers.ToDateTime(row) - StringHelpers.ToDateTime(firstValue); + var newDifference = StringHelpers.ToDateTime(row) - StringHelpers.ToDateTime(firstValue); if (difference != newDifference) { return string.Empty; @@ -250,7 +250,7 @@ private static string CalculateStepDepth(string row, string firstValue) var secondValue = StringHelpers.ToDecimal(row); var difference = secondValue - StringHelpers.ToDecimal(firstValue); - var newDifference = StringHelpers.ToDecimal(row) - StringHelpers.ToDecimal(firstValue); + var newDifference = StringHelpers.ToDecimal(row) - StringHelpers.ToDecimal(firstValue); if (difference != newDifference) { return string.Empty; @@ -281,7 +281,7 @@ private void WriteLogDefinitionSection(StringWriter writer, ICollection 2) - line.Append(new string(' ', emptySpaces -2)); + line.Append(new string(' ', emptySpaces - 2)); } else { @@ -369,7 +369,7 @@ private void WriteWellInformationSection(StringWriter writer, Well well, int max { writer.WriteLine("~WELL INFORMATION BLOCK"); CreateHeader(writer, maxColumnLength, "DATA", "DESCRIPTION OF MNEMONIC"); - WriteWellParameter(writer, "STRT", limitValues.Unit, limitValues.Start,$"START {limitValues.LogType}", maxColumnLength); + WriteWellParameter(writer, "STRT", limitValues.Unit, limitValues.Start, $"START {limitValues.LogType}", maxColumnLength); WriteWellParameter(writer, "STOP", limitValues.Unit, limitValues.Stop, $"STOP {limitValues.LogType}", maxColumnLength); WriteWellParameter(writer, "STEP", limitValues.Unit, limitValues.Step, "STEP VALUE", maxColumnLength); WriteWellParameter(writer, "SNULL", "", "", "NULL VALUE", maxColumnLength); @@ -422,7 +422,7 @@ private void WriteCommonParameter(StringWriter writer, string nameOfParemeter, s } line.Append(" "); line.Append(data); - if ((maxColumnLength * 2) - data.Length - 1 > 0) + if ((maxColumnLength * 2) - data.Length - 1 > 0) { line.Append(new string(' ', (maxColumnLength * 2) - data.Length - 1)); } @@ -465,7 +465,7 @@ private void WriteDataSection(StringWriter writer, int i = 0; foreach (var curveSpecification in curveSpecifications) { - var cell = row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) + var cell = row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) ? value.Value.ToString() : string.Empty; @@ -474,9 +474,9 @@ private void WriteDataSection(StringWriter writer, { length += 2; } - if (length > 0) line.Append(new string(' ', length )); + if (length > 0) line.Append(new string(' ', length)); line.Append(cell); - if (i < curveSpecifications.Count -1) line.Append(' '); + if (i < curveSpecifications.Count - 1) line.Append(' '); i++; } writer.WriteLine(line.ToString()); From 836d0ea56cc60d87aa62942ba4330079e0c738f5 Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Fri, 15 Nov 2024 12:28:27 +0100 Subject: [PATCH 04/10] test --- .../Workers/DownloadLogDataWorker.cs | 213 +++++++++--------- 1 file changed, 112 insertions(+), 101 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index ea9bff1b1..5d3edab90 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -84,13 +85,14 @@ public DownloadLogDataWorker( Logger.LogInformation("Download of all data is done. {jobDescription}", job.Description()); var columnLengths = CalculateColumnLength(reportItems, curveSpecifications); + var maxDataLenght = CalculateMaxDataLenght(well); var maxHeaderLength = CalculateMaxHeaderLength(curveSpecifications); using var writer = new StringWriter(); - WriteLogCommonInformation(writer, maxHeaderLength); + WriteLogCommonInformation(writer, maxHeaderLength, maxDataLenght); var limitValues = GetLimitValues(curveSpecifications, reportItems); - WriteWellInformationSection(writer, well, maxHeaderLength, limitValues); - WriteLogDefinitionSection(writer, curveSpecifications, maxHeaderLength); + WriteWellInformationSection(writer, well, maxHeaderLength, maxDataLenght, limitValues); + WriteLogDefinitionSection(writer, curveSpecifications, maxHeaderLength, maxDataLenght); WriteColumnHeaderSection(writer, curveSpecifications, columnLengths); WriteDataSection(writer, reportItems, curveSpecifications, columnLengths); string content = writer.ToString(); @@ -161,6 +163,26 @@ private Dictionary CalculateColumnLength(ICollection result) + { + result = value.ToString().Length; + } + } + } + return result; + } + private int CalculateMaxHeaderLength( ICollection curveSpecifications) { @@ -201,9 +223,7 @@ private LimitValues GetLimitValues(ICollection curveSpecific var lastValue = oneColumn.Last(); result.Start = firstValue; result.Stop = lastValue; - result.Step = CalculateStep(oneColumn, firstValue, isDepthBasedSeries); - result.Unit = isDepthBasedSeries ? curveSpecificationDepth.Unit : curveSpecificationTime.Unit; @@ -213,7 +233,7 @@ private LimitValues GetLimitValues(ICollection curveSpecific return result; } - private static string CalculateStep(List oneColumn, string firstValue, bool isDepthBasedSeries) + private string CalculateStep(List oneColumn, string firstValue, bool isDepthBasedSeries) { var result = string.Empty; foreach (var row in oneColumn) @@ -231,7 +251,7 @@ private static string CalculateStep(List oneColumn, string firstValue, b return result; } - private static string CalculateStepTime(string row, string firstValue) + private string CalculateStepTime(string row, string firstValue) { var secondValue = StringHelpers.ToDateTime(row); var difference = secondValue - @@ -241,11 +261,10 @@ private static string CalculateStepTime(string row, string firstValue) { return string.Empty; } - return difference.ToString(); } - private static string CalculateStepDepth(string row, string firstValue) + private string CalculateStepDepth(string row, string firstValue) { var secondValue = StringHelpers.ToDecimal(row); var difference = secondValue - @@ -258,65 +277,61 @@ private static string CalculateStepDepth(string row, string firstValue) return difference.ToString(CultureInfo.InvariantCulture); } - private void WriteLogCommonInformation(StringWriter writer, int maxColumnLenght) + private void WriteLogCommonInformation(StringWriter writer, int maxColumnLenght, int maxDataLength) { writer.WriteLine("~VERSION INFORMATION"); - WriteCommonParameter(writer, "VERS.", "2.0", "CWLS LOG ASCII STANDARD - VERSION 2.0", maxColumnLenght); - WriteCommonParameter(writer, "WRAP.", "NO", "ONE LINE PER STEP", maxColumnLenght); - WriteCommonParameter(writer, "PROD.", "Equinor", "LAS Producer", maxColumnLenght); - WriteCommonParameter(writer, "PROG.", "WITSML Explorer", "LAS Program name", maxColumnLenght); - WriteCommonParameter(writer, "CREA.", DateTime.Now.ToShortDateString(), "LAS Creation date", maxColumnLenght); + WriteCommonParameter(writer, "VERS.", "2.0", "CWLS LOG ASCII STANDARD - VERSION 2.0", maxColumnLenght ,maxDataLength); + WriteCommonParameter(writer, "WRAP.", "NO", "ONE LINE PER STEP", maxColumnLenght ,maxDataLength); + WriteCommonParameter(writer, "PROD.", "Equinor", "LAS Producer", maxColumnLenght ,maxDataLength); + WriteCommonParameter(writer, "PROG.", "WITSML Explorer", "LAS Program name", maxColumnLenght ,maxDataLength); + WriteCommonParameter(writer, "CREA.", DateTime.Now.ToShortDateString(), "LAS Creation date", maxColumnLenght ,maxDataLength); } - private void WriteLogDefinitionSection(StringWriter writer, ICollection curveSpecifications, int maxColumnLenght) + private void WriteLogDefinitionSection(StringWriter writer, ICollection curveSpecifications, int maxColumnLenght, int maxDataLenght) { writer.WriteLine("~PARAMETER INFORMATION"); writer.WriteLine("~CURVE INFORMATION"); - CreateHeader(writer, maxColumnLenght, "API CODE", "CURVE DESCRIPTION"); + CreateHeader(writer, maxColumnLenght, maxDataLenght, "#MNEM", ".UNIT", "API CODE", "CURVE DESCRIPTION"); int i = 1; foreach (var curveSpecification in curveSpecifications) { var line = new StringBuilder(); line.Append(curveSpecification.Mnemonic); line.Append(new string(' ', maxColumnLenght - curveSpecification.Mnemonic.Length)); - line.Append('.'); - line.Append(curveSpecification.Unit); + line.Append($".{curveSpecification.Unit}"); line.Append(new string(' ', maxColumnLenght - curveSpecification.Unit.Length)); - line.Append(new string(' ', maxColumnLenght - 1)); - line.Append(": "); - line.Append(i++); - line.Append(' '); + line.Append(new string(' ', maxDataLenght)); + line.Append($": {i++} "); line.Append(curveSpecification.Mnemonic.Replace("_", " ")); - line.Append(" ("); - line.Append(curveSpecification.Unit); - line.Append(')'); + line.Append($" ({curveSpecification.Unit})"); writer.WriteLine(line.ToString()); } } - private static void CreateHeader(StringWriter writer, int maxColumnLenght, string thirdColumn, string fourthColumn) + private void CreateHeader(StringWriter writer, int maxColumnLenght, int maxDataLenght, string firstColumn, string secondColumn, string thirdColumn, string fourthColumn) { var header = new StringBuilder(); var secondHeader = new StringBuilder(); - header.Append("#MNEM"); - secondHeader.Append("#----"); - if (maxColumnLenght > 5) + header.Append(firstColumn); + secondHeader.Append('#'); + secondHeader.Append(new string('-', firstColumn.Length -1)); + if (maxColumnLenght > firstColumn.Length) { - header.Append(new string(' ', maxColumnLenght - 5)); - secondHeader.Append(new string(' ', maxColumnLenght - 5)); + header.Append(new string(' ', maxColumnLenght - firstColumn.Length)); + secondHeader.Append(new string(' ', maxColumnLenght - firstColumn.Length)); } - header.Append(".UNIT"); - secondHeader.Append(new string('-', 5)); - if (maxColumnLenght > 5) + header.Append(secondColumn); + secondHeader.Append(new string('-', secondColumn.Length)); + if (maxColumnLenght > secondColumn.Length) { - header.Append(new string(' ', maxColumnLenght - 5)); - secondHeader.Append(new string(' ', maxColumnLenght - 5)); + header.Append(new string(' ', maxColumnLenght - secondColumn.Length)); + secondHeader.Append(new string(' ', maxColumnLenght - secondColumn.Length)); } header.Append(thirdColumn); secondHeader.Append(new string('-', thirdColumn.Length)); - if (maxColumnLenght > thirdColumn.Length) + if (maxDataLenght > thirdColumn.Length) { - header.Append(new string(' ', maxColumnLenght - thirdColumn.Length)); - secondHeader.Append(new string(' ', maxColumnLenght - thirdColumn.Length)); + header.Append(new string(' ', maxDataLenght - thirdColumn.Length + 1)); + secondHeader.Append(new string(' ', maxDataLenght - thirdColumn.Length + 1)); } header.Append(fourthColumn); secondHeader.Append(new string('-', fourthColumn.Length)); @@ -365,73 +380,72 @@ private void WriteColumnHeaderSection(StringWriter writer, ICollection 0) + line.Append(nameOfParameter); + if (maxColumnLength - nameOfParameter.Length > 0) { - line.Append(new string(' ', maxColumnLength - nameOfParemeter.Length)); + line.Append(new string(' ', maxColumnLength - nameOfParameter.Length)); } - line.Append(" "); - line.Append(data); - if ((maxColumnLength * 2) - data.Length - 1 > 0) + line.Append($" {data}"); + if (maxColumnLength - data.Length > 0) { - line.Append(new string(' ', (maxColumnLength * 2) - data.Length - 1)); + line.Append(new string(' ', maxColumnLength - data.Length)); } - line.Append(':'); - line.Append(description); + line.Append(new string(' ', maxDataLenght)); + line.Append($":{description}"); writer.WriteLine(line.ToString()); } private void WriteWellParameter(StringWriter writer, string nameOfParemeter, string unit, - string data, string description, int maxColumnLength) + string data, string description, int maxColumnLength, int maxDataLength) { var line = new StringBuilder(); line.Append(nameOfParemeter); @@ -439,19 +453,17 @@ private void WriteWellParameter(StringWriter writer, string nameOfParemeter, str { line.Append(new string(' ', maxColumnLength - nameOfParemeter.Length)); } - line.Append('.'); - line.Append(unit); + line.Append($".{unit}"); if (maxColumnLength - unit.Length - 1 > 0) { line.Append(new string(' ', maxColumnLength - unit.Length - 1)); } line.Append(data); - if (maxColumnLength - data.Length > 0) + if (maxDataLength - data.Length > 0) { - line.Append(new string(' ', maxColumnLength - data.Length)); + line.Append(new string(' ', maxDataLength - data.Length)); } - line.Append(':'); - line.Append(description); + line.Append($" :{description}"); writer.WriteLine(line.ToString()); } @@ -491,5 +503,4 @@ private class LimitValues public string Unit { get; set; } public string LogType { get; set; } } - } From 65fcecb1635167083398d379ab2acc726413987b Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Fri, 15 Nov 2024 12:37:19 +0100 Subject: [PATCH 05/10] test --- .../Workers/DownloadLogDataWorker.cs | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index 5d3edab90..4090d60fb 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -168,18 +168,18 @@ private int CalculateMaxDataLenght(Well well) // long date time string, possible the biggest value var result = 28; Type objType = typeof(Well); - PropertyInfo[] properties = objType.GetProperties(); - foreach (var property in properties) + PropertyInfo[] properties = objType.GetProperties(); + foreach (var property in properties) + { + var value = property.GetValue(well); + if (value != null) { - var value = property.GetValue(well); - if (value != null) + if (value.ToString().Length > result) { - if (value.ToString().Length > result) - { - result = value.ToString().Length; - } + result = value.ToString().Length; } } + } return result; } @@ -280,11 +280,11 @@ private string CalculateStepDepth(string row, string firstValue) private void WriteLogCommonInformation(StringWriter writer, int maxColumnLenght, int maxDataLength) { writer.WriteLine("~VERSION INFORMATION"); - WriteCommonParameter(writer, "VERS.", "2.0", "CWLS LOG ASCII STANDARD - VERSION 2.0", maxColumnLenght ,maxDataLength); - WriteCommonParameter(writer, "WRAP.", "NO", "ONE LINE PER STEP", maxColumnLenght ,maxDataLength); - WriteCommonParameter(writer, "PROD.", "Equinor", "LAS Producer", maxColumnLenght ,maxDataLength); - WriteCommonParameter(writer, "PROG.", "WITSML Explorer", "LAS Program name", maxColumnLenght ,maxDataLength); - WriteCommonParameter(writer, "CREA.", DateTime.Now.ToShortDateString(), "LAS Creation date", maxColumnLenght ,maxDataLength); + WriteCommonParameter(writer, "VERS.", "2.0", "CWLS LOG ASCII STANDARD - VERSION 2.0", maxColumnLenght, maxDataLength); + WriteCommonParameter(writer, "WRAP.", "NO", "ONE LINE PER STEP", maxColumnLenght, maxDataLength); + WriteCommonParameter(writer, "PROD.", "Equinor", "LAS Producer", maxColumnLenght, maxDataLength); + WriteCommonParameter(writer, "PROG.", "WITSML Explorer", "LAS Program name", maxColumnLenght, maxDataLength); + WriteCommonParameter(writer, "CREA.", DateTime.Now.ToShortDateString(), "LAS Creation date", maxColumnLenght, maxDataLength); } private void WriteLogDefinitionSection(StringWriter writer, ICollection curveSpecifications, int maxColumnLenght, int maxDataLenght) { @@ -313,7 +313,7 @@ private void CreateHeader(StringWriter writer, int maxColumnLenght, int maxDataL var secondHeader = new StringBuilder(); header.Append(firstColumn); secondHeader.Append('#'); - secondHeader.Append(new string('-', firstColumn.Length -1)); + secondHeader.Append(new string('-', firstColumn.Length -1 )); if (maxColumnLenght > firstColumn.Length) { header.Append(new string(' ', maxColumnLenght - firstColumn.Length)); @@ -400,7 +400,7 @@ private void WriteWellInformationSection(StringWriter writer, Well well, int max WriteWellParameter(writer, "SDEGT", "", "", "DEGASSER TYPE NAME", maxColumnLength, maxDataLenght); WriteWellParameter(writer, "SDETT", "", "", "DEECTOR TYPE NAME", maxColumnLength, maxDataLenght); WriteWellParameter(writer, "SAPPC", "", "", "APPLIED CORRECTIONS", maxColumnLength, maxDataLenght); - WriteWellParameter(writer, "SDATE", "", $"{DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}", "DATE", maxColumnLength, maxDataLenght);; + WriteWellParameter(writer, "SDATE", "", $"{DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}", "DATE", maxColumnLength, maxDataLenght); WriteWellParameter(writer, "SCLAB", "", "", "County label", maxColumnLength, maxDataLenght); WriteWellParameter(writer, "SSLAB", "", "", "State/Province label", maxColumnLength, maxDataLenght); WriteWellParameter(writer, "SPROV", "", "", "State or Province", maxColumnLength, maxDataLenght); @@ -436,7 +436,7 @@ private void WriteCommonParameter(StringWriter writer, string nameOfParameter, s line.Append(new string(' ', maxColumnLength - nameOfParameter.Length)); } line.Append($" {data}"); - if (maxColumnLength - data.Length > 0) + if (maxColumnLength - data.Length > 0) { line.Append(new string(' ', maxColumnLength - data.Length)); } From 7afc9fecc0fbd32511837a9a95edb4f9e68faa94 Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Fri, 15 Nov 2024 12:39:59 +0100 Subject: [PATCH 06/10] test --- Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index 4090d60fb..3d74c15af 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -313,7 +313,7 @@ private void CreateHeader(StringWriter writer, int maxColumnLenght, int maxDataL var secondHeader = new StringBuilder(); header.Append(firstColumn); secondHeader.Append('#'); - secondHeader.Append(new string('-', firstColumn.Length -1 )); + secondHeader.Append(new string('-', firstColumn.Length - 1)); if (maxColumnLenght > firstColumn.Length) { header.Append(new string(' ', maxColumnLenght - firstColumn.Length)); From 9cf23df86024b4eeab936f9f7818fdf0996bfdc7 Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Fri, 15 Nov 2024 19:20:26 +0100 Subject: [PATCH 07/10] test --- .../Jobs/DownloadLogDataJob.cs | 2 +- .../Workers/DownloadLogDataWorker.cs | 61 ++++++++++--------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Jobs/DownloadLogDataJob.cs b/Src/WitsmlExplorer.Api/Jobs/DownloadLogDataJob.cs index 08575bd24..8c3cd4d37 100644 --- a/Src/WitsmlExplorer.Api/Jobs/DownloadLogDataJob.cs +++ b/Src/WitsmlExplorer.Api/Jobs/DownloadLogDataJob.cs @@ -26,7 +26,7 @@ public record DownloadLogDataJob : Job public bool StartIndexIsInclusive { get; init; } /// - /// If to export to LAS format (default is CVS) + /// If to export to LAS format (default is CSV) /// public bool ExportToLas { get; init; } diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index 3d74c15af..e2f708592 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -10,6 +10,8 @@ using Microsoft.Extensions.Logging; +using Witsml.Data; + using WitsmlExplorer.Api.Jobs; using WitsmlExplorer.Api.Models; using WitsmlExplorer.Api.Models.Reports; @@ -63,36 +65,37 @@ public DownloadLogDataWorker( } var logData = await _logObjectService.ReadLogData(job.LogReference.WellUid, job.LogReference.WellboreUid, job.LogReference.Uid, job.Mnemonics.ToList(), job.StartIndexIsInclusive, job.LogReference.StartIndex, job.LogReference.EndIndex, true, cancellationToken, progressReporter); - var well = await _wellService.GetWell(job.LogReference.WellUid); return (job.ExportToLas) - ? DownloadLogDataResultLasFile(job, logData.Data, - logData.CurveSpecifications, well) - : DownloadLogDataResultCvsFile(job, logData.Data, + ? await DownloadLogDataResultLasFile(job, logData.Data, + logData.CurveSpecifications) + : DownloadLogDataResultCsvFile(job, logData.Data, logData.CurveSpecifications); } - private (WorkerResult, RefreshAction) DownloadLogDataResultCvsFile(DownloadLogDataJob job, ICollection> reportItems, ICollection curveSpecifications) + private (WorkerResult, RefreshAction) DownloadLogDataResultCsvFile(DownloadLogDataJob job, ICollection> reportItems, ICollection curveSpecifications) { - Logger.LogInformation("Download of all data is done. {jobDescription}", job.Description()); + Logger.LogInformation("Download of log data is done. {jobDescription}", job.Description()); string content = GetCsvFileContent(reportItems, curveSpecifications); job.JobInfo.Report = DownloadLogDataReport(job.LogReference, content, "csv"); WorkerResult workerResult = new(GetTargetWitsmlClientOrThrow().GetServerHostname(), true, $"Download of all data is ready, jobId: ", jobId: job.JobInfo.Id); return (workerResult, null); } - private (WorkerResult, RefreshAction) DownloadLogDataResultLasFile(DownloadLogDataJob job, ICollection> reportItems, ICollection curveSpecifications, Well well) + private async Task<(WorkerResult, RefreshAction)> DownloadLogDataResultLasFile(DownloadLogDataJob job, ICollection> reportItems, ICollection curveSpecifications) { - Logger.LogInformation("Download of all data is done. {jobDescription}", job.Description()); + Logger.LogInformation("Download of log data is done. {jobDescription}", job.Description()); + var well = await _wellService.GetWell(job.LogReference.WellUid); + var logObject = await _logObjectService.GetLog(job.LogReference.WellUid, job.LogReference.WellboreUid, job.LogReference.Uid); var columnLengths = CalculateColumnLength(reportItems, curveSpecifications); - var maxDataLenght = CalculateMaxDataLenght(well); + var maxWellDataLength = CalculateMaxWellDataLenght(well); var maxHeaderLength = CalculateMaxHeaderLength(curveSpecifications); - using var writer = new StringWriter(); - WriteLogCommonInformation(writer, maxHeaderLength, maxDataLenght); - var limitValues = GetLimitValues(curveSpecifications, reportItems); - WriteWellInformationSection(writer, well, maxHeaderLength, maxDataLenght, limitValues); - WriteLogDefinitionSection(writer, curveSpecifications, maxHeaderLength, maxDataLenght); + await using var writer = new StringWriter(); + WriteLogCommonInformation(writer, maxHeaderLength, maxWellDataLength); + var limitValues = GetLimitValues(curveSpecifications, reportItems, logObject); + WriteWellInformationSection(writer, well, maxHeaderLength, maxWellDataLength, limitValues); + WriteLogDefinitionSection(writer, curveSpecifications, maxHeaderLength, maxWellDataLength); WriteColumnHeaderSection(writer, curveSpecifications, columnLengths); WriteDataSection(writer, reportItems, curveSpecifications, columnLengths); string content = writer.ToString(); @@ -163,7 +166,7 @@ private Dictionary CalculateColumnLength(ICollection curveSpecifications, - ICollection> data) + ICollection> data, LogObject logObject) { - var curveSpecificationDepth = - curveSpecifications.FirstOrDefault(x => x.Mnemonic.ToLower() == "depth"); - var curveSpecificationTime = curveSpecifications.FirstOrDefault(x => x.Mnemonic.ToLower() == "time"); - var isDepthBasedSeries = curveSpecificationDepth != null; + var curveSpecification = + curveSpecifications.FirstOrDefault(x => string.Equals(x.Mnemonic, logObject.IndexCurve, StringComparison.CurrentCultureIgnoreCase)); + var isDepthBasedSeries = logObject.IndexType == WitsmlLog.WITSML_INDEX_TYPE_MD; var result = new LimitValues(); - if (curveSpecificationDepth == null && curveSpecificationTime == null) + if (curveSpecification == null) return result; var oneColumn = isDepthBasedSeries ? data.Select(row => - row.TryGetValue(curveSpecificationDepth.Mnemonic, out LogDataValue value) + row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) ? value.Value.ToString() : "0" ).ToList() : data.Select(row => - row.TryGetValue(curveSpecificationTime.Mnemonic, out LogDataValue value) + row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) ? value.Value.ToString() : DateTime.Now.ToString(CultureInfo.InvariantCulture) ).ToList(); var firstValue = oneColumn.First(); - var lastValue = oneColumn.Last(); result.Start = firstValue; - result.Stop = lastValue; + result.Stop = oneColumn.Last(); result.Step = CalculateStep(oneColumn, firstValue, isDepthBasedSeries); - result.Unit = isDepthBasedSeries - ? curveSpecificationDepth.Unit - : curveSpecificationTime.Unit; + result.Unit = curveSpecification.Unit; result.LogType = isDepthBasedSeries ? "DEPTH" : "TIME"; @@ -459,7 +458,11 @@ private void WriteWellParameter(StringWriter writer, string nameOfParemeter, str line.Append(new string(' ', maxColumnLength - unit.Length - 1)); } line.Append(data); - if (maxDataLength - data.Length > 0) + if (data == null) + { + line.Append(new string(' ', maxDataLength)); + } + else if (maxDataLength - data.Length > 0) { line.Append(new string(' ', maxDataLength - data.Length)); } From f9f7d7624d5773f8c24c83ce33e6e61056c66067 Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Mon, 18 Nov 2024 13:08:51 +0100 Subject: [PATCH 08/10] test --- .../Workers/DownloadLogDataWorker.cs | 85 +++++++------------ 1 file changed, 31 insertions(+), 54 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index e2f708592..53e6531ff 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; +using Witsml; using Witsml.Data; using WitsmlExplorer.Api.Jobs; @@ -88,16 +89,16 @@ public DownloadLogDataWorker( var logObject = await _logObjectService.GetLog(job.LogReference.WellUid, job.LogReference.WellboreUid, job.LogReference.Uid); var columnLengths = CalculateColumnLength(reportItems, curveSpecifications); - var maxWellDataLength = CalculateMaxWellDataLenght(well); + var maxWellDataLength = CalculateMaxWellDataLength(well, logObject); var maxHeaderLength = CalculateMaxHeaderLength(curveSpecifications); await using var writer = new StringWriter(); WriteLogCommonInformation(writer, maxHeaderLength, maxWellDataLength); var limitValues = GetLimitValues(curveSpecifications, reportItems, logObject); - WriteWellInformationSection(writer, well, maxHeaderLength, maxWellDataLength, limitValues); + WriteWellInformationSection(writer, well, logObject, maxHeaderLength, maxWellDataLength, limitValues); WriteLogDefinitionSection(writer, curveSpecifications, maxHeaderLength, maxWellDataLength); WriteColumnHeaderSection(writer, curveSpecifications, columnLengths); - WriteDataSection(writer, reportItems, curveSpecifications, columnLengths); + WriteDataSection(writer, reportItems, curveSpecifications, columnLengths, limitValues.IsDepthBasedSeries); string content = writer.ToString(); job.JobInfo.Report = DownloadLogDataReport(job.LogReference, content, "las"); WorkerResult workerResult = new(GetTargetWitsmlClientOrThrow().GetServerHostname(), true, $"Download of all data is ready, jobId: ", jobId: job.JobInfo.Id); @@ -155,18 +156,18 @@ private Dictionary CalculateColumnLength(ICollection(); foreach (var curveSpecification in curveSpecifications) { - var oneColumn = data.Select(row => + var indexCurveColumn = data.Select(row => row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) ? value.Value.ToString()!.Length : 0 ).Max(); - result[curveSpecification.Mnemonic] = (curveSpecification.Mnemonic.Length + curveSpecification.Unit.Length + 3) > oneColumn ? curveSpecification.Mnemonic.Length + curveSpecification.Unit.Length + 3 : oneColumn; + result[curveSpecification.Mnemonic] = (curveSpecification.Mnemonic.Length + curveSpecification.Unit.Length + 3) > indexCurveColumn ? curveSpecification.Mnemonic.Length + curveSpecification.Unit.Length + 3 : indexCurveColumn; } return result; } - private int CalculateMaxWellDataLenght(Well well) + private int CalculateMaxWellDataLength(Well well, LogObject logObject) { // long date time string, possible the biggest value var result = 28; @@ -183,6 +184,9 @@ private int CalculateMaxWellDataLenght(Well well) } } } + + if (logObject.ServiceCompany != null && logObject.ServiceCompany.Length > result) + result = logObject.ServiceCompany.Length; return result; } @@ -207,9 +211,10 @@ private LimitValues GetLimitValues(ICollection curveSpecific curveSpecifications.FirstOrDefault(x => string.Equals(x.Mnemonic, logObject.IndexCurve, StringComparison.CurrentCultureIgnoreCase)); var isDepthBasedSeries = logObject.IndexType == WitsmlLog.WITSML_INDEX_TYPE_MD; var result = new LimitValues(); + result.IsDepthBasedSeries = isDepthBasedSeries; if (curveSpecification == null) return result; - var oneColumn = isDepthBasedSeries + var indexCurveColumn = isDepthBasedSeries ? data.Select(row => row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) @@ -221,10 +226,10 @@ private LimitValues GetLimitValues(ICollection curveSpecific ? value.Value.ToString() : DateTime.Now.ToString(CultureInfo.InvariantCulture) ).ToList(); - var firstValue = oneColumn.First(); + var firstValue = indexCurveColumn.First(); result.Start = firstValue; - result.Stop = oneColumn.Last(); - result.Step = CalculateStep(oneColumn, firstValue, isDepthBasedSeries); + result.Stop = indexCurveColumn.Last(); + result.Step = CalculateStep(indexCurveColumn, firstValue, isDepthBasedSeries); result.Unit = curveSpecification.Unit; result.LogType = isDepthBasedSeries ? "DEPTH" @@ -232,10 +237,10 @@ private LimitValues GetLimitValues(ICollection curveSpecific return result; } - private string CalculateStep(List oneColumn, string firstValue, bool isDepthBasedSeries) + private string CalculateStep(List indexCurveColumn, string firstValue, bool isDepthBasedSeries) { var result = string.Empty; - foreach (var row in oneColumn) + foreach (var row in indexCurveColumn) { if (firstValue == row) { @@ -379,51 +384,22 @@ private void WriteColumnHeaderSection(StringWriter writer, ICollection> data, ICollection curveSpecifications, Dictionary columnsLength) + ICollection> data, ICollection curveSpecifications, Dictionary columnsLength, bool isDepthBasedSeries) { foreach (var row in data) { @@ -482,7 +458,7 @@ private void WriteDataSection(StringWriter writer, { var cell = row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) ? value.Value.ToString() - : string.Empty; + : isDepthBasedSeries ? CommonConstants.DepthIndex.NullValue.ToString(CultureInfo.InvariantCulture) : CommonConstants.DateTimeIndex.NullValue; int length = columnsLength[curveSpecification.Mnemonic] - cell!.Length; if (i == 0 && length != 0) @@ -505,5 +481,6 @@ private class LimitValues public string Step { get; set; } public string Unit { get; set; } public string LogType { get; set; } + public bool IsDepthBasedSeries { get; set; } } } From 79bae437def66ea9041fdffea8e4402fd890737a Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Mon, 18 Nov 2024 13:12:17 +0100 Subject: [PATCH 09/10] test --- Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index 53e6531ff..cb77b55a8 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -156,7 +156,7 @@ private Dictionary CalculateColumnLength(ICollection(); foreach (var curveSpecification in curveSpecifications) { - var indexCurveColumn = data.Select(row => + var indexCurveColumn = data.Select(row => row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) ? value.Value.ToString()!.Length @@ -481,6 +481,6 @@ private class LimitValues public string Step { get; set; } public string Unit { get; set; } public string LogType { get; set; } - public bool IsDepthBasedSeries { get; set; } + public bool IsDepthBasedSeries { get; set; } } } From 90e5c2dc99f700cffe93a1f0d74044f0dce66371 Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Wed, 20 Nov 2024 09:51:23 +0100 Subject: [PATCH 10/10] test --- Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs index cb77b55a8..43258b323 100644 --- a/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs @@ -98,7 +98,7 @@ public DownloadLogDataWorker( WriteWellInformationSection(writer, well, logObject, maxHeaderLength, maxWellDataLength, limitValues); WriteLogDefinitionSection(writer, curveSpecifications, maxHeaderLength, maxWellDataLength); WriteColumnHeaderSection(writer, curveSpecifications, columnLengths); - WriteDataSection(writer, reportItems, curveSpecifications, columnLengths, limitValues.IsDepthBasedSeries); + WriteDataSection(writer, reportItems, curveSpecifications, columnLengths); string content = writer.ToString(); job.JobInfo.Report = DownloadLogDataReport(job.LogReference, content, "las"); WorkerResult workerResult = new(GetTargetWitsmlClientOrThrow().GetServerHostname(), true, $"Download of all data is ready, jobId: ", jobId: job.JobInfo.Id); @@ -211,7 +211,6 @@ private LimitValues GetLimitValues(ICollection curveSpecific curveSpecifications.FirstOrDefault(x => string.Equals(x.Mnemonic, logObject.IndexCurve, StringComparison.CurrentCultureIgnoreCase)); var isDepthBasedSeries = logObject.IndexType == WitsmlLog.WITSML_INDEX_TYPE_MD; var result = new LimitValues(); - result.IsDepthBasedSeries = isDepthBasedSeries; if (curveSpecification == null) return result; var indexCurveColumn = isDepthBasedSeries @@ -448,7 +447,7 @@ private void WriteWellParameter(StringWriter writer, string nameOfParemeter, str private void WriteDataSection(StringWriter writer, - ICollection> data, ICollection curveSpecifications, Dictionary columnsLength, bool isDepthBasedSeries) + ICollection> data, ICollection curveSpecifications, Dictionary columnsLength) { foreach (var row in data) { @@ -458,7 +457,7 @@ private void WriteDataSection(StringWriter writer, { var cell = row.TryGetValue(curveSpecification.Mnemonic, out LogDataValue value) ? value.Value.ToString() - : isDepthBasedSeries ? CommonConstants.DepthIndex.NullValue.ToString(CultureInfo.InvariantCulture) : CommonConstants.DateTimeIndex.NullValue; + : CommonConstants.DepthIndex.NullValue.ToString(CultureInfo.InvariantCulture); int length = columnsLength[curveSpecification.Mnemonic] - cell!.Length; if (i == 0 && length != 0) @@ -481,6 +480,5 @@ private class LimitValues public string Step { get; set; } public string Unit { get; set; } public string LogType { get; set; } - public bool IsDepthBasedSeries { get; set; } } }