Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download log data as a LAS file💡 #2588 #2598

Merged
merged 12 commits into from
Nov 20, 2024
Merged
2 changes: 1 addition & 1 deletion Src/WitsmlExplorer.Api/Jobs/DownloadLogDataJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public record DownloadLogDataJob : Job
public bool StartIndexIsInclusive { get; init; }

/// <summary>
/// If to export to LAS format (default is CVS)
/// If to export to LAS format (default is CSV)
/// </summary>
public bool ExportToLas { get; init; }

Expand Down
61 changes: 32 additions & 29 deletions Src/WitsmlExplorer.Api/Workers/DownloadLogDataWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

using Microsoft.Extensions.Logging;

using Witsml.Data;

using WitsmlExplorer.Api.Jobs;
using WitsmlExplorer.Api.Models;
using WitsmlExplorer.Api.Models.Reports;
Expand Down Expand Up @@ -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<Dictionary<string, LogDataValue>> reportItems, ICollection<CurveSpecification> curveSpecifications)
private (WorkerResult, RefreshAction) DownloadLogDataResultCsvFile(DownloadLogDataJob job, ICollection<Dictionary<string, LogDataValue>> reportItems, ICollection<CurveSpecification> 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<Dictionary<string, LogDataValue>> reportItems, ICollection<CurveSpecification> curveSpecifications, Well well)
private async Task<(WorkerResult, RefreshAction)> DownloadLogDataResultLasFile(DownloadLogDataJob job, ICollection<Dictionary<string, LogDataValue>> reportItems, ICollection<CurveSpecification> 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();
Expand Down Expand Up @@ -163,7 +166,7 @@ private Dictionary<string, int> CalculateColumnLength(ICollection<Dictionary<str
return result;
}

private int CalculateMaxDataLenght(Well well)
private int CalculateMaxWellDataLenght(Well well)
eliasbruvik marked this conversation as resolved.
Show resolved Hide resolved
{
// long date time string, possible the biggest value
var result = 28;
Expand Down Expand Up @@ -198,35 +201,31 @@ private int CalculateMaxHeaderLength(
}

private LimitValues GetLimitValues(ICollection<CurveSpecification> curveSpecifications,
ICollection<Dictionary<string, LogDataValue>> data)
ICollection<Dictionary<string, LogDataValue>> 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)
eliasbruvik marked this conversation as resolved.
Show resolved Hide resolved
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";
Expand Down Expand Up @@ -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));
}
Expand Down