diff --git a/.editorconfig b/.editorconfig
index 56b46ef..6a59641 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -80,13 +80,14 @@ dotnet_diagnostic.CA1825.severity = warning # CA1823: Avoid zero-length array al
dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available
dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name
-dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant.
dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2");
+dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant.
dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
dotnet_diagnostic.IDE0060.severity = warning # IDE0060: Remove unused parameter
+dotnet_diagnostic.IDE0270.severity = warning # IDE0270: Null check can be simplified
dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method
diff --git a/.vscode/thunder-tests/thunderCollection.json b/.vscode/thunder-tests/thunderCollection.json
index 717b1a2..58f3d8f 100644
--- a/.vscode/thunder-tests/thunderCollection.json
+++ b/.vscode/thunder-tests/thunderCollection.json
@@ -19,5 +19,12 @@
"created": "2023-03-08T17:31:19.468Z",
"sortNum": 30000,
"folders": []
+ },
+ {
+ "_id": "9ebfb84d-fa73-4c00-a2e0-e9ec69a31a16",
+ "colName": "LocalHost",
+ "created": "2023-05-08T19:34:00.425Z",
+ "sortNum": 40000,
+ "folders": []
}
]
\ No newline at end of file
diff --git a/.vscode/thunder-tests/thunderclient.json b/.vscode/thunder-tests/thunderclient.json
index c1c1e9c..fd6b175 100644
--- a/.vscode/thunder-tests/thunderclient.json
+++ b/.vscode/thunder-tests/thunderclient.json
@@ -417,5 +417,24 @@
"form": []
},
"tests": []
+ },
+ {
+ "_id": "524e5261-69eb-4888-8818-608cde1ce506",
+ "colId": "9ebfb84d-fa73-4c00-a2e0-e9ec69a31a16",
+ "containerId": "",
+ "name": "Inbound-SRP",
+ "url": "http://localhost:5126/api/inbound/SRP",
+ "method": "POST",
+ "sortNum": 10000,
+ "created": "2023-05-08T19:34:14.843Z",
+ "modified": "2023-05-08T19:50:20.646Z",
+ "headers": [],
+ "params": [],
+ "body": {
+ "type": "json",
+ "raw": "{\n \"SentToMetrology\": false,\n \"SentToSPC\": false,\n \"Id\": 0,\n \"Batch\": \"BIORAD#2\",\n \"Cassette\": \"BIORAD2\",\n \"CellName\": \"BIORAD2\",\n \"Date\": \"05/08/2023 12:23:23 AM\",\n \"FilePath\": \"\",\n \"Layer\": \"1\",\n \"MeanThickness\": \"21.8224\",\n \"Op\": \"C\",\n \"PSN\": \"5010\",\n \"PassFail\": \"PASS\",\n \"RDS\": \"588252\",\n \"RVThickness\": \"2.0559\",\n \"Reactor\": \"23\",\n \"Recipe\": \"PROD_8inch\",\n \"StdDev\": \"0.1483\",\n \"Title\": \"Bio-RadQS400MEPI\",\n \"UniqueId\": \"Bio-RadQS400MEPI_23-588252-5010.1_202305080023237034_5.4661928_Point-1\",\n \"Wafer\": \"23-588252-5010.1\",\n \"Zone\": \"-\",\n \"Details\": []\n}",
+ "form": []
+ },
+ "tests": []
}
]
\ No newline at end of file
diff --git a/Archive/OI.Metrology.Archive.csproj b/Archive/OI.Metrology.Archive.csproj
index 7023d0a..d53c73f 100644
--- a/Archive/OI.Metrology.Archive.csproj
+++ b/Archive/OI.Metrology.Archive.csproj
@@ -35,9 +35,9 @@
-
+
-
+
diff --git a/Server/.vscode/format-report.json b/Server/.vscode/format-report.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/Server/.vscode/format-report.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/Server/ApiControllers/SpreadingResistanceProfileController.cs b/Server/ApiControllers/SpreadingResistanceProfileController.cs
new file mode 100644
index 0000000..ac508b6
--- /dev/null
+++ b/Server/ApiControllers/SpreadingResistanceProfileController.cs
@@ -0,0 +1,38 @@
+using Microsoft.AspNetCore.Mvc;
+using OI.Metrology.Shared.Models.Stateless;
+using OI.Metrology.Shared.Services;
+
+namespace OI.Metrology.Server.ApiControllers;
+
+[ApiController]
+[Route("api/[controller]")]
+public partial class SpreadingResistanceProfileController : ControllerBase, ISpreadingResistanceProfileController
+{
+
+ private readonly IAttachmentsService _AttachmentsService;
+ private readonly IMetrologyRepository _MetrologyRepository;
+ private readonly IToolTypesRepository _ToolTypesRepository;
+ private readonly ISpreadingResistanceProfileService _SpreadingResistanceProfileService;
+
+ public SpreadingResistanceProfileController(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, IToolTypesRepository toolTypesRepository, ISpreadingResistanceProfileService spreadingResistanceProfileService)
+ {
+ _MetrologyRepository = metrologyRepository;
+ _AttachmentsService = attachmentsService;
+ _ToolTypesRepository = toolTypesRepository;
+ _SpreadingResistanceProfileService = spreadingResistanceProfileService;
+ }
+
+ [HttpGet]
+ [Route("{toolTypeId}/{tabletype}/files/{attachmentId}/{filename}")]
+ public IActionResult GetAttachment(int toolTypeId, string tabletype, string attachmentId, string filename)
+ {
+ (string? message, string? contenttype, Stream? stream) = _ToolTypesRepository.GetAttachment(_MetrologyRepository, _AttachmentsService, toolTypeId, tabletype, attachmentId, filename);
+ if (message is not null)
+ return Content(message);
+ else if (contenttype is not null && stream is not null)
+ return File(_SpreadingResistanceProfileService.GetImageBytes(stream), "image/jpeg");
+ else
+ throw new Exception();
+ }
+
+}
\ No newline at end of file
diff --git a/Server/OI.Metrology.Server.csproj b/Server/OI.Metrology.Server.csproj
index 4972373..38313fb 100644
--- a/Server/OI.Metrology.Server.csproj
+++ b/Server/OI.Metrology.Server.csproj
@@ -37,12 +37,13 @@
-
-
+
+
+
diff --git a/Server/Program.cs b/Server/Program.cs
index c35a994..716182c 100644
--- a/Server/Program.cs
+++ b/Server/Program.cs
@@ -73,6 +73,7 @@ public class Program
_ = webApplicationBuilder.Services.AddSingleton(_ => new(appSettings.MockRoot));
_ = webApplicationBuilder.Services.AddSingleton(_ => sqlDbConnectionFactory);
_ = webApplicationBuilder.Services.AddSingleton(_ => new(appSettings.MockRoot));
+ _ = webApplicationBuilder.Services.AddSingleton();
_ = webApplicationBuilder.Services.AddSingleton>(_ => appSettingsRepository);
_ = webApplicationBuilder.Services.AddSingleton(_ => new(appSettings.MockRoot, sqlDbConnectionFactory));
_ = webApplicationBuilder.Services.AddSingleton(_ => new(appSettings.MockRoot, sqlDbConnectionFactory));
diff --git a/Server/Repositories/MetrologyRepository.cs b/Server/Repositories/MetrologyRepository.cs
index d745c11..7e626a7 100644
--- a/Server/Repositories/MetrologyRepository.cs
+++ b/Server/Repositories/MetrologyRepository.cs
@@ -314,13 +314,9 @@ public class MetrologyRepository : IMetrologyRepository
internal DataTable GetHeaders(int toolTypeId, DateTime? startTime, DateTime? endTime, int? pageNo, int? pageSize, long? headerId, out long totalRecords)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
- IEnumerable md = GetToolTypeMetadataByToolTypeID(toolTypeId);
- if (md is null)
- throw new Exception("Invalid tool type metadata");
+ IEnumerable md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
DataTable dt = new();
using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
@@ -407,13 +403,9 @@ public class MetrologyRepository : IMetrologyRepository
internal DataTable GetData(int toolTypeId, long headerid)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
- IEnumerable md = GetToolTypeMetadataByToolTypeID(toolTypeId);
- if (md is null)
- throw new Exception("Invalid tool type metadata");
+ IEnumerable md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
DataTable dt = new();
using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
@@ -502,9 +494,7 @@ public class MetrologyRepository : IMetrologyRepository
internal Guid GetHeaderAttachmentID(int toolTypeId, long headerId)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
@@ -514,9 +504,7 @@ public class MetrologyRepository : IMetrologyRepository
}
internal string GetHeaderInsertDate(int toolTypeId, long headerId)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
@@ -546,9 +534,7 @@ public class MetrologyRepository : IMetrologyRepository
internal Guid GetDataAttachmentID(int toolTypeId, long headerId, string title)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
@@ -559,9 +545,7 @@ public class MetrologyRepository : IMetrologyRepository
// J Ouellette Added
internal string GetDataInsertDate(int toolTypeId, long headerId, string title)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = "";
@@ -592,9 +576,7 @@ public class MetrologyRepository : IMetrologyRepository
internal DataSet GetOIExportData(int toolTypeId, long headerid)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (string.IsNullOrWhiteSpace(tt.OIExportSPName))
throw new Exception("OpenInsight export not available for " + tt.ToolTypeName);
@@ -657,9 +639,7 @@ public class MetrologyRepository : IMetrologyRepository
return headers;
}
- ToolType tt = GetToolTypeByID(toolTypeId.Value);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId.Value) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = $"SELECT ID, InsertDate, AttachmentID, Title, [Date], {tt.ID} AS ToolTypeID, '{tt.ToolTypeName}' AS ToolTypeName, Reactor, RDS, PSN FROM {tt.HeaderTableName} ORDER BY [Date] DESC ";
@@ -684,13 +664,9 @@ public class MetrologyRepository : IMetrologyRepository
internal IEnumerable> GetHeaderFields(int toolTypeId, long headerid)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
- IEnumerable md = GetToolTypeMetadataByToolTypeID(toolTypeId);
- if (md is null)
- throw new Exception("Invalid tool type metadata");
+ IEnumerable md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
List> r = new();
@@ -749,9 +725,7 @@ public class MetrologyRepository : IMetrologyRepository
internal int UpdateReviewDate(int toolTypeId, long headerId, bool clearDate)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
if (clearDate)
@@ -771,9 +745,7 @@ public class MetrologyRepository : IMetrologyRepository
internal Guid GetHeaderAttachmentIDByTitle(int toolTypeId, string title)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
@@ -783,9 +755,7 @@ public class MetrologyRepository : IMetrologyRepository
internal Guid GetDataAttachmentIDByTitle(int toolTypeId, string title)
{
- ToolType tt = GetToolTypeByID(toolTypeId);
- if (tt is null)
- throw new Exception("Invalid tool type ID");
+ ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
diff --git a/Server/Repositories/ToolTypesRepository.cs b/Server/Repositories/ToolTypesRepository.cs
index 1fa69a4..57fbc9b 100644
--- a/Server/Repositories/ToolTypesRepository.cs
+++ b/Server/Repositories/ToolTypesRepository.cs
@@ -179,7 +179,8 @@ public class ToolTypesRepository : IToolTypesRepository
Stream? stream = null;
string? message = null;
Guid attachmentIdParsed;
- string? contenttype = null;
+ string? contentType = null;
+ string filenameLowerThenTrim = filename.ToLower().TrimEnd();
ToolType tt = metrologyRepository.GetToolTypeByID(toolTypeId);
bool header = !string.Equals(tabletype.Trim(), "data", StringComparison.OrdinalIgnoreCase);
if (!Guid.TryParse(attachmentId, out attachmentIdParsed))
@@ -189,15 +190,18 @@ public class ToolTypesRepository : IToolTypesRepository
try
{
// figure out what content type to use. this is very simple because there are only two types being used
- contenttype = "application/pdf";
- if (filename.ToLower().TrimEnd().EndsWith(".txt"))
- contenttype = "text/plain";
+ if (filenameLowerThenTrim.EndsWith(".txt"))
+ contentType = "text/plain";
+ else if (filenameLowerThenTrim.EndsWith(".json"))
+ contentType = "application/json";
+ else
+ contentType = "application/pdf";
// Get attachment stream and feed it to the client
stream = attachmentsService.GetAttachmentStreamByAttachmentId(tt, header, attachmentIdParsed, filename);
}
catch (Exception ex) { message = ex.Message; }
}
- return new(message, contenttype, stream);
+ return new(message, contentType, stream);
}
// This endpoint triggers writing of the OI Export file
diff --git a/Server/Services/SpreadingResistanceProfileService.cs b/Server/Services/SpreadingResistanceProfileService.cs
new file mode 100644
index 0000000..f352674
--- /dev/null
+++ b/Server/Services/SpreadingResistanceProfileService.cs
@@ -0,0 +1,300 @@
+using Adaptation.FileHandlers.json;
+using OI.Metrology.Shared.Models.Stateless;
+using System.Drawing;
+using System.Text;
+using System.Text.Json;
+
+namespace OI.Metrology.Server.Services;
+
+public class SpreadingResistanceProfileService : ISpreadingResistanceProfileService
+{
+
+#pragma warning disable CA1416
+
+ private static RectangleF GetRectangleF(double left, double top, double width, double height) =>
+ new((float)left, (float)top, (float)width, (float)height);
+
+ private static void DrawLine(Graphics graphics, Pen pen, double x1, double y1, double x2, double y2) =>
+ graphics.DrawLine(pen, (float)x1, (float)y1, (float)x2, (float)y2);
+
+ private static void DrawString(Graphics graphics, string s, Font font, Brush brush, double x, double y) =>
+ graphics.DrawString(s, font, brush, (float)x, (float)y);
+
+ private static void FillEllipse(Graphics graphics, Brush brush, double x, double y, double width, double height) =>
+ graphics.FillEllipse(brush, (float)x, (float)y, (float)width, (float)height);
+
+ private static void DrawString(Graphics graphics, string s, Font font, Brush brush, double x, double y, StringFormat stringFormat) =>
+ graphics.DrawString(s, font, brush, (float)x, (float)y, stringFormat);
+
+ private static void GetMinMax(List profilePoints, out double decades, out double maxDepth, out double concentrationMin, out double resistanceEditedMin, out double resistivityMin)
+ {
+ double ceilingCD;
+ double ceilingEdited;
+ maxDepth = int.MinValue;
+ double ceilingResistivity;
+ resistivityMin = double.MaxValue;
+ concentrationMin = double.MaxValue;
+ resistanceEditedMin = double.MaxValue;
+ double resistivityMax = double.MinValue;
+ double concentrationMax = double.MinValue;
+ double resistanceEditedMax = double.MinValue;
+ foreach (ProfilePoint profilePoint in profilePoints)
+ {
+ if (profilePoint.Log10?.ResistanceEdited is null || profilePoint.Log10?.Resistivity is null || profilePoint.Log10?.Concentration is null)
+ continue;
+ if (profilePoint.Depth <= 0 || profilePoint.ResistanceRaw == 0)
+ continue;
+ maxDepth = profilePoint.Depth;
+ if (profilePoint.Log10.Resistivity.Value < resistivityMin)
+ resistivityMin = profilePoint.Log10.Resistivity.Value;
+ ceilingResistivity = Math.Ceiling(profilePoint.Log10.Resistivity.Value);
+ if (ceilingResistivity > resistivityMax)
+ resistivityMax = ceilingResistivity;
+ if (profilePoint.Log10.ResistanceEdited.Value < resistanceEditedMin)
+ resistanceEditedMin = profilePoint.Log10.ResistanceEdited.Value;
+ ceilingEdited = Math.Ceiling(profilePoint.Log10.ResistanceEdited.Value);
+ if (ceilingEdited > resistanceEditedMax)
+ resistanceEditedMax = ceilingEdited;
+ if (profilePoint.Log10.Concentration.Value < concentrationMin)
+ concentrationMin = profilePoint.Log10.Concentration.Value;
+ ceilingCD = Math.Ceiling(profilePoint.Log10.Concentration.Value);
+ if (ceilingCD > concentrationMax)
+ concentrationMax = ceilingCD;
+ }
+ decades = resistivityMax - resistivityMin;
+ if (resistanceEditedMax - resistanceEditedMin > decades)
+ decades = resistanceEditedMax - resistanceEditedMin;
+ if (concentrationMax - concentrationMin > decades)
+ decades = concentrationMax - concentrationMin;
+ }
+
+ private static RectangleF[] GetRectangles(double leftChartArea, double widthChartArea, double topChartArea, double sizeOfBlock, double widthOfBlacks)
+ {
+ List rectangles = new()
+ {
+ GetRectangleF(leftChartArea, 10, widthChartArea, 65),
+ // GetRectangleF(leftChartArea + widthChartArea, topChartArea, widthOfBlacks, sizeOfBlock * 5);
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 0, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 1, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 2, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 3, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 4, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 5, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 6, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 7, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 8, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 9, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 10, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 11, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 12, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 13, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 14, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 15, widthOfBlacks, sizeOfBlock),
+ GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 16, widthOfBlacks, sizeOfBlock * 2)
+ };
+ return rectangles.ToArray();
+ }
+
+ private static string[] GetRectanglesDescriptions(Info info, Setup setup, List layers)
+ {
+ List results = new()
+ {
+ string.Empty, // 0
+ string.Empty, // 1
+ string.Empty, // 2
+ string.Empty, // 3
+ string.Empty, // 4
+ string.Empty, // 5
+ string.Empty, // 6
+ string.Empty, // 7
+ string.Empty, // 8
+ string.Concat(info.SystemId, Environment.NewLine, info.SoftwareVersion), // 9
+ string.Concat("SURFACE FINISH", Environment.NewLine, setup.Finish), // 10
+ string.Concat("ORIENTATION", Environment.NewLine, setup.Orientation), // 11
+ string.Concat("BEVEL ANGLE", Environment.NewLine, setup.SineBevelAngle), // 12
+ string.Concat("X-STEP (um)", Environment.NewLine, setup.Steps.First().X), // 13
+ string.Concat("PROBE LOAD (gm)", Environment.NewLine, setup.ProbeLoad), // 14
+ string.Concat("SPACING (um)", Environment.NewLine, setup.ProbeSpacing), // 15
+ string.Concat("OPERATOR", Environment.NewLine, info.Operator), // 16
+ string.Concat("DATE", Environment.NewLine, info.DateTime.ToString("dd MMM yy"), Environment.NewLine, "TIME", Environment.NewLine, info.DateTime.ToString("HH:mm:ss tt")), // 17
+ };
+ StringBuilder stringBuilder = new();
+ foreach (Layer layer in layers)
+ _ = stringBuilder.AppendLine(string.Concat("First Pt. ", layer.FirstPoint, " Last Pt. ", layer.LastPoint, " Type ", layer.Type, " Smoothing ", layer.Smoothing, " Correction ", layer.Correction));
+ _ = stringBuilder.AppendLine(string.Join(" ", info.Comments));
+ results[0] = stringBuilder.ToString();
+ return results.ToArray();
+ }
+
+ internal static byte[] GetImageBytes(CSV csv)
+ {
+ if (csv.Info is null)
+ throw new NullReferenceException(nameof(csv.Info));
+ if (csv.Setup is null)
+ throw new NullReferenceException(nameof(csv.Setup));
+ if (csv.LayerHeader is null)
+ throw new NullReferenceException(nameof(csv.LayerHeader));
+ if (csv.ProfileHeader is null)
+ throw new NullReferenceException(nameof(csv.ProfileHeader));
+
+ double decades, maxDepth, concentrationMin, resistanceEditedMin, resistivityMin;
+ GetMinMax(csv.ProfileHeader.ProfilePoints, out decades, out maxDepth, out concentrationMin, out resistanceEditedMin, out resistivityMin);
+
+ byte[] bytes;
+ int penSize = 1;
+ int width = 694;
+ int height = 714;
+ int ellipseSize = 3;
+ Pen pen = Pens.Black;
+ int blocksOfDepth = 6;
+ RectangleF[] rectangles;
+ double topChartArea = 90;
+ double leftChartArea = 60;
+ double widthOfBlacks = 120;
+ Brush brush = Brushes.Black;
+ double widthChartArea = 500;
+ double heightChartArea = 600;
+ Font consolas = new("Consolas", 9);
+ Color backgroundColor = Color.White;
+ Brush resistivityBrush = Brushes.Green;
+ Font consolasBold = new("Consolas", 9);
+ Brush concentrationBrush = Brushes.Blue;
+ Brush resistanceRawBrush = Brushes.Black;
+ Brush resistanceEditedBrush = Brushes.Red;
+ double sizeOfBlock = heightChartArea / 18;
+ Brush backgroundBrush = Brushes.WhiteSmoke;
+ Pen resistivityPen = new(Color.Green, penSize);
+ Pen concentrationPen = new(Color.Blue, penSize);
+ Pen resistanceRawPen = new(Color.Black, penSize);
+ Pen resistanceEditedPen = new(Color.Red, penSize);
+ double widthOfDepthBlock = Math.Ceiling(maxDepth / 3) * 3 / 6;
+ StringFormat stringFormat = new() { Alignment = StringAlignment.Far };
+
+ Bitmap bitmap = new(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+ Graphics graphics = Graphics.FromImage(bitmap);
+ graphics.Clear(backgroundColor);
+
+ rectangles = new RectangleF[1];
+ rectangles[0] = GetRectangleF(leftChartArea, topChartArea, widthChartArea, heightChartArea);
+ graphics.FillRectangles(backgroundBrush, rectangles);
+
+ rectangles = GetRectangles(leftChartArea, widthChartArea, topChartArea, sizeOfBlock, widthOfBlacks);
+ graphics.FillRectangles(Brushes.White, rectangles);
+ graphics.DrawRectangles(pen, rectangles);
+
+ string[] descriptions = GetRectanglesDescriptions(csv.Info, csv.Setup, csv.LayerHeader.Layers);
+ for (int i = 0; i < descriptions.Length; i++)
+ graphics.DrawString(descriptions[i], consolas, brush, rectangles[i]);
+
+ DrawLine(graphics, concentrationPen, 13, 6, 13, 40);
+ graphics.DrawString("C", consolasBold, concentrationBrush, 8, 41);
+ graphics.DrawString("D", consolasBold, concentrationBrush, 8, 53);
+ DrawLine(graphics, resistivityPen, 28, 6, 28, 40);
+ graphics.DrawString("ρ", consolasBold, resistivityBrush, 21, 41);
+ graphics.DrawString("c", consolasBold, resistivityBrush, 21, 53);
+ graphics.DrawString("m", consolasBold, resistivityBrush, 21, 62);
+ DrawLine(graphics, resistanceRawPen, 39, 7, 39, 41);
+ graphics.DrawString("Ω", consolasBold, resistanceRawBrush, 34, 41);
+ DrawLine(graphics, resistanceEditedPen, 51, 7, 51, 41);
+ graphics.DrawString("Ω", consolasBold, resistanceEditedBrush, 46, 41);
+ graphics.DrawString("E", consolasBold, resistanceEditedBrush, 46, 53);
+
+ for (double i = decades; i >= 0; i += -1)
+ {
+ for (int j = 1; j <= 10; j++)
+ DrawLine(graphics, Pens.LightGray, leftChartArea, topChartArea + heightChartArea - (i * heightChartArea / decades) + heightChartArea / decades * Math.Log10(j), leftChartArea + widthChartArea, topChartArea + heightChartArea - (i * heightChartArea / decades) + heightChartArea / decades * Math.Log10(j));
+ }
+
+ DrawString(graphics, "0", consolas, brush, leftChartArea - 6, topChartArea + heightChartArea + 5);
+
+ double x, x1, x2;
+ for (int i = 0; i <= blocksOfDepth - 1; i++)
+ {
+ for (int j = 1; j <= 10; j++)
+ {
+ x = leftChartArea + 13 + (i + 1) * widthChartArea / blocksOfDepth;
+ x1 = leftChartArea + (i * widthChartArea / blocksOfDepth) + j * widthChartArea / blocksOfDepth / 10;
+ x2 = leftChartArea + (i * widthChartArea / blocksOfDepth) + (j * widthChartArea / blocksOfDepth / 10);
+ DrawLine(graphics, Pens.LightGray, x1, topChartArea, x2, topChartArea + heightChartArea);
+ DrawString(graphics, ((i + 1) * widthOfDepthBlock).ToString("0.0"), consolas, brush, x, topChartArea + heightChartArea + 5, stringFormat);
+ }
+ }
+ DrawString(graphics, "(um)", consolas, brush, leftChartArea + widthChartArea + 12, topChartArea + heightChartArea + 5);
+
+ for (int i = 0; i <= decades; i++)
+ {
+ DrawLine(graphics, pen, leftChartArea, topChartArea + (i * heightChartArea / decades), leftChartArea + widthChartArea, topChartArea + (i * heightChartArea / decades));
+ DrawString(graphics, (decades - i + resistivityMin).ToString("0"), consolasBold, resistivityBrush, 33, topChartArea - 10 + (i * heightChartArea / decades), stringFormat);
+ DrawString(graphics, (decades - i + concentrationMin).ToString("0"), consolasBold, concentrationBrush, 20, topChartArea - 10 + (i * heightChartArea / decades), stringFormat);
+ DrawString(graphics, (decades - i + resistanceEditedMin).ToString("0"), consolasBold, resistanceRawBrush, 45, topChartArea - 10 + (i * heightChartArea / decades), stringFormat);
+ DrawString(graphics, (decades - i + resistanceEditedMin).ToString("0"), consolasBold, resistanceEditedBrush, 58, topChartArea - 10 + (i * heightChartArea / decades), stringFormat);
+ }
+ for (int i = 0; i <= blocksOfDepth; i++)
+ DrawLine(graphics, pen, leftChartArea + (i * widthChartArea / blocksOfDepth), topChartArea, leftChartArea + (i * widthChartArea / blocksOfDepth), topChartArea + heightChartArea);
+ double y, y2;
+ foreach (ProfilePoint profilePoint in csv.ProfileHeader.ProfilePoints)
+ {
+ if (profilePoint.Log10?.ResistanceEdited is null || profilePoint.Log10?.Resistivity is null || profilePoint.Log10?.Concentration is null)
+ continue;
+ if (profilePoint.Depth <= 0 || profilePoint.ResistanceRaw == 0)
+ continue;
+ graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
+ x = leftChartArea + profilePoint.Depth / maxDepth * widthChartArea - ellipseSize;
+ FillEllipse(graphics, concentrationBrush, x, topChartArea + heightChartArea - ((profilePoint.Log10.Concentration.Value - concentrationMin) / decades * heightChartArea) - ellipseSize - ellipseSize, ellipseSize, ellipseSize);
+ FillEllipse(graphics, resistanceRawBrush, x, topChartArea + heightChartArea - ((profilePoint.Log10.ResistanceRaw - resistanceEditedMin) / decades * heightChartArea) - ellipseSize - ellipseSize, ellipseSize, ellipseSize);
+ FillEllipse(graphics, resistivityBrush, x, topChartArea + heightChartArea - ((profilePoint.Log10.Resistivity.Value - resistivityMin) / decades * heightChartArea) - ellipseSize - ellipseSize, ellipseSize, ellipseSize);
+ FillEllipse(graphics, resistanceEditedBrush, x, topChartArea + heightChartArea - ((profilePoint.Log10.ResistanceEdited.Value - resistanceEditedMin) / decades * heightChartArea) - ellipseSize - ellipseSize, ellipseSize, ellipseSize);
+ if (profilePoint.LastProfilePoint?.ResistanceEdited is not null && profilePoint.LastProfilePoint?.Resistivity is not null && profilePoint.LastProfilePoint?.Concentration is not null && profilePoint.LastProfilePoint?.Log10?.ResistanceEdited is not null && profilePoint.LastProfilePoint?.Log10?.Resistivity is not null && profilePoint.LastProfilePoint?.Log10?.Concentration is not null && profilePoint.DeltaPercent is not null && profilePoint.DeltaPercent is >= .2 or <= -.2)
+ {
+ x = leftChartArea + profilePoint.Depth / maxDepth * widthChartArea - penSize;
+ x2 = leftChartArea + profilePoint.LastProfilePoint.Depth / maxDepth * widthChartArea - penSize;
+ y = topChartArea + heightChartArea - ((profilePoint.Log10.Concentration.Value - concentrationMin) / decades * heightChartArea) - penSize;
+ y2 = topChartArea + heightChartArea - ((profilePoint.LastProfilePoint.Log10.Concentration.Value - concentrationMin) / decades * heightChartArea) - penSize;
+ DrawLine(graphics, concentrationPen, x, y, x2, y2);
+ y = topChartArea + heightChartArea - ((profilePoint.Log10.ResistanceRaw - resistanceEditedMin) / decades * heightChartArea) - penSize;
+ y2 = topChartArea + heightChartArea - ((profilePoint.LastProfilePoint.Log10.ResistanceRaw - resistanceEditedMin) / decades * heightChartArea) - penSize;
+ DrawLine(graphics, resistanceRawPen, x, y, x2, y2);
+ y = topChartArea + heightChartArea - ((profilePoint.Log10.Resistivity.Value - resistivityMin) / decades * heightChartArea) - penSize;
+ y2 = topChartArea + heightChartArea - ((profilePoint.LastProfilePoint.Log10.Resistivity.Value - resistivityMin) / decades * heightChartArea) - penSize;
+ DrawLine(graphics, resistivityPen, x, y, x2, y2);
+ y = topChartArea + heightChartArea - ((profilePoint.Log10.ResistanceEdited.Value - resistanceEditedMin) / decades * heightChartArea) - penSize;
+ y2 = topChartArea + heightChartArea - ((profilePoint.LastProfilePoint.Log10.ResistanceEdited.Value - resistanceEditedMin) / decades * heightChartArea) - penSize;
+ DrawLine(graphics, resistanceEditedPen, x, y, x2, y2);
+ }
+ }
+
+ using MemoryStream msMemoryStream = new();
+ bitmap.Save(msMemoryStream, System.Drawing.Imaging.ImageFormat.Png);
+ bytes = new byte[Convert.ToInt32(msMemoryStream.Length) + 1];
+ _ = msMemoryStream.Read(bytes, 0, bytes.Length);
+ bytes = msMemoryStream.ToArray();
+ return bytes;
+ }
+
+ private static byte[] GetImageBytes(string json)
+ {
+ byte[] results;
+ Adaptation.FileHandlers.csv.CSV? csv = JsonSerializer.Deserialize(json);
+ if (csv is null)
+ throw new NullReferenceException(nameof(csv));
+ CSV result = new(csv);
+ results = GetImageBytes(result);
+ return results;
+ }
+
+ byte[] ISpreadingResistanceProfileService.GetImageBytes(string json)
+ {
+ byte[] results = GetImageBytes(json);
+ return results;
+ }
+
+ byte[] ISpreadingResistanceProfileService.GetImageBytes(Stream stream)
+ {
+ byte[] results;
+ using StreamReader streamReader = new(stream, Encoding.UTF8);
+ string json = streamReader.ReadToEnd();
+ results = GetImageBytes(json);
+ return results;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/CSV.cs b/Server/Services/csv/CSV.cs
new file mode 100644
index 0000000..ae0581f
--- /dev/null
+++ b/Server/Services/csv/CSV.cs
@@ -0,0 +1,85 @@
+namespace Adaptation.FileHandlers.csv;
+
+public class CSV
+{
+
+#nullable disable
+
+#nullable enable
+#pragma warning disable CA1834
+
+ public string? FileVersion { get; set; }
+ public Info? Info { get; set; }
+ public Setup? Setup { get; set; }
+ public LayerHeader? LayerHeader { get; set; }
+ public ProfileHeader? ProfileHeader { get; set; }
+ public Calibration? Calibration { get; set; }
+ public RawData? RawData { get; set; }
+
+ internal static CSV GetCSV(string path)
+ {
+ CSV result;
+ int? endInfo = null;
+ int? endSetup = null;
+ int? endLayers = null;
+ int? startInfo = null;
+ int? startSetup = null;
+ int? endProfiles = null;
+ int? startLayers = null;
+ int? startRawData = null;
+ int? startProfiles = null;
+ int? endCalibration = null;
+ int? startCalibration = null;
+#if NET
+ string[] lines = File.ReadAllLines(path, System.Text.Encoding.Latin1); // µ³®
+# else
+ string[] lines = File.ReadAllLines(path, System.Text.Encoding.GetEncoding("ISO-8859-1")); // µ³®
+# endif
+ string? fileVersion = !lines.Any() ? null : GetFileVersion(lines.First());
+ for (int i = 1; i < lines.Length; i++)
+ {
+ if (lines[i].StartsWith("--INFO--"))
+ startInfo = i + 1;
+ else if (lines[i].StartsWith("--SETUP--"))
+ (endInfo, startSetup) = (i, i + 1);
+ else if (lines[i].StartsWith("--LAYERS--"))
+ (endSetup, startLayers) = (i, i + 1);
+ else if (lines[i].StartsWith("--PROFILES--"))
+ (endLayers, startProfiles) = (i, i + 1);
+ else if (lines[i].StartsWith("--CALIBRATION--"))
+ (endProfiles, startCalibration) = (i, i + 1);
+ else if (lines[i].StartsWith("--RAWDATA--"))
+ (endCalibration, startRawData) = (i, i + 1);
+ }
+ RawData? rawData = startRawData is null ? null : RawData.GetRawData(lines, startRawData.Value, lines.Length);
+ Info? info = startInfo is null || endInfo is null ? null : Info.GetInfo(lines, startInfo.Value, endInfo.Value);
+ Setup? setup = startSetup is null || endSetup is null ? null : Setup.GetSetup(lines, startSetup.Value, endSetup.Value);
+ LayerHeader? layerHeader = startLayers is null || endLayers is null ? null : LayerHeader.GetLayerHeader(lines, startLayers.Value, endLayers.Value);
+ ProfileHeader? profileHeader = startProfiles is null || endProfiles is null ? null : ProfileHeader.GetProfileHeader(lines, startProfiles.Value, endProfiles.Value);
+ Calibration? calibration = startCalibration is null || endCalibration is null ? null : Calibration.GetCalibration(lines, startCalibration.Value, endCalibration.Value);
+ result = new()
+ {
+ FileVersion = fileVersion,
+ Info = info,
+ Setup = setup,
+ LayerHeader = layerHeader,
+ ProfileHeader = profileHeader,
+ Calibration = calibration,
+ RawData = rawData,
+
+ };
+ return result;
+ }
+
+ private static string GetFileVersion(string line)
+ {
+ string result;
+ string[] segments = line.Split(',');
+ if (segments.Length < 2)
+ result = string.Empty;
+ else
+ result = segments.Last();
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/Calibration.cs b/Server/Services/csv/Calibration.cs
new file mode 100644
index 0000000..6517f91
--- /dev/null
+++ b/Server/Services/csv/Calibration.cs
@@ -0,0 +1,132 @@
+using System.Text;
+
+namespace Adaptation.FileHandlers.csv;
+
+public class Calibration
+{
+
+#nullable disable
+
+ public string NumberOfCalibrationSets { get; set; }
+ public List DataSets { get; set; }
+
+#nullable enable
+#pragma warning disable CA1834
+
+ internal static Calibration? GetCalibration(string[] lines, int start, int stop)
+ {
+ Calibration? result;
+ string first;
+ DataSet dataSet;
+ Position position;
+ string[] segments;
+ int? thirdStart = null;
+ int? secondStart = null;
+ List positions;
+ List values = new();
+ List dataSets = new();
+ StringBuilder stringBuilder = new();
+ for (int i = start; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ first = segments.First();
+ if (first == "DataSet:")
+ {
+ secondStart = i + 1;
+ break;
+ }
+ _ = stringBuilder.Append(first).Append(",");
+ if (segments.Length > 1)
+ values.Add(segments[1]);
+ else
+ values.Add(string.Empty);
+ }
+ string header = "Number of Calibration Sets,";
+ if (secondStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
+ result = null;
+ else
+ {
+ result = new()
+ {
+ NumberOfCalibrationSets = values[0],
+ DataSets = dataSets,
+ };
+ for (int x = 0; x < int.MaxValue; x++)
+ {
+ values.Clear();
+ _ = stringBuilder.Clear();
+ if (secondStart is null)
+ break;
+ for (int i = secondStart.Value; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ first = segments.First();
+ if (first == "Resistivity(ohm-cm)")
+ {
+ thirdStart = i + 1;
+ break;
+ }
+ if (first == " Sample Set:")
+ continue;
+ _ = stringBuilder.Append(first).Append(",");
+ if (segments.Length > 1)
+ values.Add(segments[1]);
+ else
+ values.Add(string.Empty);
+ }
+ secondStart = null;
+ header = "Operator,Date & Time,Finish,Orientation,North Probe ID,South Probe ID,Polarity,Contact Radius (µm),Probe Spacing (µm),Load (gm),X Step (µm),Name,Plate ID,Type,Points per Sample,Number of Pairs,";
+ if (thirdStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
+ result = null;
+ else
+ {
+ positions = new();
+ dataSet = new()
+ {
+ Operator = values[0],
+ DateTime = values[1],
+ Finish = values[2],
+ Orientation = values[3],
+ NorthProbeID = values[4],
+ SouthProbeID = values[5],
+ Polarity = values[6],
+ ContactRadius = values[7],
+ ProbeSpacing = values[8],
+ Load = values[9],
+ XStep = values[10],
+ Name = values[11],
+ PlateId = values[12],
+ Type = values[13],
+ PointsPerSample = values[14],
+ NumberOfPairs = values[15],
+ Positions = positions,
+ };
+ dataSets.Add(dataSet);
+ for (int i = thirdStart.Value; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ first = segments.First();
+ if (first == "DataSet:")
+ {
+ secondStart = i + 1;
+ break;
+ }
+ if (segments.Length < 5)
+ continue;
+ position = new()
+ {
+ Resistivity = segments[0],
+ Resistance = segments[1],
+ PercentStandardDeviation = segments[2],
+ Number = segments[3],
+ Name = segments[4],
+ };
+ positions.Add(position);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/DataSet.cs b/Server/Services/csv/DataSet.cs
new file mode 100644
index 0000000..2aa20f1
--- /dev/null
+++ b/Server/Services/csv/DataSet.cs
@@ -0,0 +1,27 @@
+namespace Adaptation.FileHandlers.csv;
+
+public class DataSet
+{
+
+#nullable disable
+
+ public string Operator { get; set; }
+ public string DateTime { get; set; }
+ public string Finish { get; set; }
+ public string Orientation { get; set; }
+ public string NorthProbeID { get; set; }
+ public string SouthProbeID { get; set; }
+ public string Polarity { get; set; }
+ public string ContactRadius { get; set; }
+ public string ProbeSpacing { get; set; }
+ public string Load { get; set; }
+ public string XStep { get; set; }
+ // public string SampleSet { get; set; }
+ public string Name { get; set; }
+ public string PlateId { get; set; }
+ public string Type { get; set; }
+ public string PointsPerSample { get; set; }
+ public string NumberOfPairs { get; set; }
+ public List Positions { get; set; }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/Info.cs b/Server/Services/csv/Info.cs
new file mode 100644
index 0000000..9429869
--- /dev/null
+++ b/Server/Services/csv/Info.cs
@@ -0,0 +1,72 @@
+using System.Text;
+
+namespace Adaptation.FileHandlers.csv;
+
+public class Info
+{
+
+#nullable disable
+
+ public string Operator { get; set; }
+ public string SampleName { get; set; }
+ public string SoftwareVersion { get; set; }
+ public string DateTime { get; set; }
+ public string SystemId { get; set; }
+ public string SystemSite { get; set; }
+ public string SamplePosition { get; set; }
+ public string Units { get; set; }
+ public string CommentLength { get; set; }
+ public List Comments { get; set; }
+
+#nullable enable
+#pragma warning disable CA1834
+
+ internal static Info? GetInfo(string[] lines, int start, int stop)
+ {
+ Info? result;
+ string first;
+ string[] segments;
+ int? secondStart = null;
+ List values = new();
+ List comments = new();
+ StringBuilder stringBuilder = new();
+ for (int i = start; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ first = segments.First();
+ if (first == "Comment:")
+ {
+ secondStart = i + 1;
+ break;
+ }
+ _ = stringBuilder.Append(first).Append(",");
+ if (segments.Length > 1)
+ values.Add(segments[1]);
+ else
+ values.Add(string.Empty);
+ }
+ string header = "Operator,Sample Name,Software Version,Date & Time,System ID,System Site,Sample Position,Units,Comment Length,";
+ if (secondStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
+ result = null;
+ else
+ {
+ result = new()
+ {
+ Operator = values[0],
+ SampleName = values[1],
+ SoftwareVersion = values[2],
+ DateTime = values[3],
+ SystemId = values[4],
+ SystemSite = values[5],
+ SamplePosition = values[6],
+ Units = values[7],
+ CommentLength = values[8],
+ Comments = comments,
+ };
+ for (int i = secondStart.Value; i < stop; i++)
+ comments.Add(lines[i]);
+ }
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/Layer.cs b/Server/Services/csv/Layer.cs
new file mode 100644
index 0000000..643b8f1
--- /dev/null
+++ b/Server/Services/csv/Layer.cs
@@ -0,0 +1,24 @@
+namespace Adaptation.FileHandlers.csv;
+
+public class Layer
+{
+
+#nullable disable
+
+ public string FirstPoint { get; set; }
+ public string LastPoint { get; set; }
+ public string Type { get; set; }
+ public string Smoothing { get; set; }
+ public string Apply { get; set; }
+ public string SOrder { get; set; }
+ public string GOrder { get; set; }
+ public string Correction { get; set; }
+ public string Conversion { get; set; }
+ public string JunctionOption { get; set; }
+ public string JunctionConstant { get; set; }
+ public string CurrentDensity { get; set; }
+ public string M1M2Tolerance { get; set; }
+ public string Sheet { get; set; }
+ public string Dose { get; set; }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/LayerHeader.cs b/Server/Services/csv/LayerHeader.cs
new file mode 100644
index 0000000..4ad7dc4
--- /dev/null
+++ b/Server/Services/csv/LayerHeader.cs
@@ -0,0 +1,80 @@
+using System.Text;
+
+namespace Adaptation.FileHandlers.csv;
+
+public class LayerHeader
+{
+
+#nullable disable
+
+ public string NumberOfLayers { get; set; }
+ public List Layers { get; set; }
+
+#nullable enable
+#pragma warning disable CA1834
+
+ internal static LayerHeader? GetLayerHeader(string[] lines, int start, int stop)
+ {
+ LayerHeader? result;
+ Layer layer;
+ string first;
+ string[] segments;
+ int? secondStart = null;
+ List layerCollection = new();
+ List values = new();
+ StringBuilder stringBuilder = new();
+ for (int i = start; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ first = segments.First();
+ if (first == "Layer")
+ {
+ secondStart = i + 1;
+ break;
+ }
+ _ = stringBuilder.Append(first).Append(",");
+ if (segments.Length > 1)
+ values.Add(segments[1]);
+ else
+ values.Add(string.Empty);
+ }
+ string header = "Number of Layers,";
+ if (secondStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
+ result = null;
+ else
+ {
+ result = new()
+ {
+ NumberOfLayers = values[0],
+ Layers = layerCollection,
+ };
+ for (int i = secondStart.Value; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ if (segments.Length < 15)
+ continue;
+ layer = new()
+ {
+ FirstPoint = segments[0],
+ LastPoint = segments[1],
+ Type = segments[2],
+ Smoothing = segments[3],
+ Apply = segments[4],
+ SOrder = segments[5],
+ GOrder = segments[6],
+ Correction = segments[7],
+ Conversion = segments[8],
+ JunctionOption = segments[9],
+ JunctionConstant = segments[10],
+ CurrentDensity = segments[11],
+ M1M2Tolerance = segments[12],
+ Sheet = segments[13],
+ Dose = segments[14],
+ };
+ layerCollection.Add(layer);
+ }
+ }
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/Point.cs b/Server/Services/csv/Point.cs
new file mode 100644
index 0000000..7074ace
--- /dev/null
+++ b/Server/Services/csv/Point.cs
@@ -0,0 +1,16 @@
+namespace Adaptation.FileHandlers.csv;
+
+public class Point
+{
+
+#nullable disable
+
+ public string Number { get; set; }
+ public string Depth { get; set; }
+ public string Resistance { get; set; }
+ public string StageX { get; set; }
+ public string StageY { get; set; }
+ public string StageZ { get; set; }
+ public string StageT { get; set; }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/Position.cs b/Server/Services/csv/Position.cs
new file mode 100644
index 0000000..a3413dd
--- /dev/null
+++ b/Server/Services/csv/Position.cs
@@ -0,0 +1,14 @@
+namespace Adaptation.FileHandlers.csv;
+
+public class Position
+{
+
+#nullable disable
+
+ public string Resistivity { get; set; }
+ public string Resistance { get; set; }
+ public string PercentStandardDeviation { get; set; }
+ public string Number { get; set; }
+ public string Name { get; set; }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/Profile.cs b/Server/Services/csv/Profile.cs
new file mode 100644
index 0000000..83a4b9f
--- /dev/null
+++ b/Server/Services/csv/Profile.cs
@@ -0,0 +1,15 @@
+namespace Adaptation.FileHandlers.csv;
+
+public class Profile
+{
+
+#nullable disable
+
+ public string Id { get; set; }
+ public string Name { get; set; }
+ public string Label { get; set; }
+ public string Allocated { get; set; }
+ public string Used { get; set; }
+ public string List { get; set; }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/ProfileHeader.cs b/Server/Services/csv/ProfileHeader.cs
new file mode 100644
index 0000000..b3e9c2d
--- /dev/null
+++ b/Server/Services/csv/ProfileHeader.cs
@@ -0,0 +1,101 @@
+using System.Text;
+
+namespace Adaptation.FileHandlers.csv;
+
+public class ProfileHeader
+{
+
+#nullable disable
+
+ public string NumberOfProfiles { get; set; }
+ public List Profiles { get; set; }
+ public List ProfilePoints { get; set; }
+
+#nullable enable
+#pragma warning disable CA1834
+
+ internal static ProfileHeader? GetProfileHeader(string[] lines, int start, int stop)
+ {
+ ProfileHeader? result;
+ string first;
+ string[] segments;
+ Profile profileInfo;
+ ProfilePoint profile;
+ int? thirdStart = null;
+ int? secondStart = null;
+ List values = new();
+ List profiles = new();
+ StringBuilder stringBuilder = new();
+ List profilePoints = new();
+ for (int i = start; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ first = segments.First();
+ if (first == "ID")
+ {
+ secondStart = i + 1;
+ break;
+ }
+ _ = stringBuilder.Append(first).Append(",");
+ if (segments.Length > 1)
+ values.Add(segments[1]);
+ else
+ values.Add(string.Empty);
+ }
+ string header = "Number of Profiles,";
+ if (secondStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
+ result = null;
+ else
+ {
+ result = new()
+ {
+ NumberOfProfiles = values[0],
+ Profiles = profiles,
+ ProfilePoints = profilePoints,
+ };
+ for (int i = secondStart.Value; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ first = segments.First();
+ if (first == "Point")
+ {
+ thirdStart = i + 1;
+ break;
+ }
+ if (segments.Length < 6)
+ continue;
+ profileInfo = new()
+ {
+ Id = segments[0],
+ Name = segments[1],
+ Label = segments[2],
+ Allocated = segments[3],
+ Used = segments[4],
+ List = segments[5],
+ };
+ profiles.Add(profileInfo);
+ }
+ if (thirdStart is not null)
+ {
+ for (int i = thirdStart.Value; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ if (segments.Length < 6)
+ continue;
+ profile = new()
+ {
+ Number = segments[0],
+ Depth = segments[1],
+ Raw = segments[2],
+ Edited = segments[3],
+ Resistivity = segments[4],
+ CD = segments[5],
+ };
+ profilePoints.Add(profile);
+ }
+ }
+ }
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/ProfilePoint.cs b/Server/Services/csv/ProfilePoint.cs
new file mode 100644
index 0000000..d077a6d
--- /dev/null
+++ b/Server/Services/csv/ProfilePoint.cs
@@ -0,0 +1,15 @@
+namespace Adaptation.FileHandlers.csv;
+
+public class ProfilePoint
+{
+
+#nullable disable
+
+ public string Number { get; set; }
+ public string Depth { get; set; }
+ public string Raw { get; set; }
+ public string Edited { get; set; }
+ public string Resistivity { get; set; }
+ public string CD { get; set; }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/RawData.cs b/Server/Services/csv/RawData.cs
new file mode 100644
index 0000000..84624a5
--- /dev/null
+++ b/Server/Services/csv/RawData.cs
@@ -0,0 +1,72 @@
+using System.Text;
+
+namespace Adaptation.FileHandlers.csv;
+
+public class RawData
+{
+
+#nullable disable
+
+ public string TotalPoints { get; set; }
+ public List Points { get; set; }
+
+#nullable enable
+#pragma warning disable CA1834
+
+ internal static RawData? GetRawData(string[] lines, int start, int stop)
+ {
+ RawData? result;
+ Point point;
+ string first;
+ string[] segments;
+ int? secondStart = null;
+ List points = new();
+ List values = new();
+ StringBuilder stringBuilder = new();
+ for (int i = start; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ first = segments.First();
+ if (first == "Point")
+ {
+ secondStart = i + 1;
+ break;
+ }
+ _ = stringBuilder.Append(first).Append(",");
+ if (segments.Length > 1)
+ values.Add(segments[1]);
+ else
+ values.Add(string.Empty);
+ }
+ string header = "Total Points,";
+ if (secondStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
+ result = null;
+ else
+ {
+ result = new()
+ {
+ TotalPoints = values[0],
+ Points = points,
+ };
+ for (int i = secondStart.Value; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ if (segments.Length < 4)
+ continue;
+ point = new()
+ {
+ Number = segments[0],
+ Depth = segments[1],
+ Resistance = segments[2],
+ StageX = segments[3],
+ StageY = segments[4],
+ StageZ = segments[5],
+ StageT = segments[6],
+ };
+ points.Add(point);
+ }
+ }
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/Setup.cs b/Server/Services/csv/Setup.cs
new file mode 100644
index 0000000..a869b16
--- /dev/null
+++ b/Server/Services/csv/Setup.cs
@@ -0,0 +1,87 @@
+using System.Text;
+
+namespace Adaptation.FileHandlers.csv;
+
+public class Setup
+{
+
+#nullable disable
+
+ public string Finish { get; set; }
+ public string NorthProbeID { get; set; }
+ public string SouthProbeID { get; set; }
+ public string MeasurementPolarity { get; set; }
+ public string SineBevelAngle { get; set; }
+ public string ContactRadius { get; set; }
+ public string ProbeSpacing { get; set; }
+ public string ProbeLoad { get; set; }
+ public string Orientation { get; set; }
+ public string NumberOfStepSizes { get; set; }
+ public List Steps { get; set; }
+
+#nullable enable
+#pragma warning disable CA1834
+
+ internal static Setup? GetSetup(string[] lines, int start, int stop)
+ {
+ Setup? result;
+ Step step;
+ string first;
+ string[] segments;
+ int? secondStart = null;
+ List steps = new();
+ List values = new();
+ StringBuilder stringBuilder = new();
+ for (int i = start; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ first = segments.First();
+ if (first == "Step")
+ {
+ secondStart = i + 1;
+ break;
+ }
+ _ = stringBuilder.Append(first).Append(",");
+ if (segments.Length > 1)
+ values.Add(segments[1]);
+ else
+ values.Add(string.Empty);
+ }
+ string header = "Finish,North Probe ID,South Probe ID,Measurement Polarity,Sine Bevel Angle,Contact Radius (µm),Probe Spacing (µm),Probe Load (gm),Orientation,Number of Step Sizes,";
+ if (secondStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
+ result = null;
+ else
+ {
+ result = new()
+ {
+ Finish = values[0],
+ NorthProbeID = values[1],
+ SouthProbeID = values[2],
+ MeasurementPolarity = values[3],
+ SineBevelAngle = values[4],
+ ContactRadius = values[5],
+ ProbeSpacing = values[6],
+ ProbeLoad = values[7],
+ Orientation = values[8],
+ NumberOfStepSizes = values[9],
+ Steps = steps,
+ };
+ for (int i = secondStart.Value; i < stop; i++)
+ {
+ segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
+ if (segments.Length < 4)
+ continue;
+ step = new()
+ {
+ Number = segments[0],
+ Points = segments[1],
+ X = segments[2],
+ Y = segments[3],
+ };
+ steps.Add(step);
+ }
+ }
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/csv/Step.cs b/Server/Services/csv/Step.cs
new file mode 100644
index 0000000..cbc48e3
--- /dev/null
+++ b/Server/Services/csv/Step.cs
@@ -0,0 +1,13 @@
+namespace Adaptation.FileHandlers.csv;
+
+public class Step
+{
+
+#nullable disable
+
+ public string Number { get; set; }
+ public string Points { get; set; }
+ public string X { get; set; }
+ public string Y { get; set; }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/CSV.cs b/Server/Services/json/CSV.cs
new file mode 100644
index 0000000..75d8377
--- /dev/null
+++ b/Server/Services/json/CSV.cs
@@ -0,0 +1,27 @@
+namespace Adaptation.FileHandlers.json;
+
+public class CSV
+{
+
+#nullable enable
+
+ public string? FileVersion { get; }
+ public Info? Info { get; }
+ public Setup? Setup { get; }
+ public LayerHeader? LayerHeader { get; }
+ public ProfileHeader? ProfileHeader { get; }
+ public Calibration? Calibration { get; }
+ public RawData? RawData { get; }
+
+ internal CSV(csv.CSV csv)
+ {
+ FileVersion = csv.FileVersion;
+ Info = csv.Info is null ? null : new(csv.Info);
+ Setup = csv.Setup is null ? null : new(csv.Setup);
+ RawData = csv.RawData is null ? null : new(csv.RawData);
+ Calibration = csv.Calibration is null ? null : new(csv.Calibration);
+ LayerHeader = csv.LayerHeader is null ? null : new(csv.LayerHeader);
+ ProfileHeader = csv.ProfileHeader is null ? null : new(csv.ProfileHeader);
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/Calibration.cs b/Server/Services/json/Calibration.cs
new file mode 100644
index 0000000..1d2a93d
--- /dev/null
+++ b/Server/Services/json/Calibration.cs
@@ -0,0 +1,56 @@
+namespace Adaptation.FileHandlers.json;
+
+public class Calibration
+{
+
+ public int NumberOfCalibrationSets { get; }
+ public List DataSets { get; }
+
+ internal Calibration(csv.Calibration calibration)
+ {
+ DataSet dataSet;
+ Position position;
+ List positions;
+ List dataSets = new();
+ NumberOfCalibrationSets = int.Parse(calibration.NumberOfCalibrationSets);
+ DataSets = dataSets;
+ foreach (csv.DataSet csvDataSet in calibration.DataSets)
+ {
+ positions = new();
+ foreach (csv.Position csvPosition in csvDataSet.Positions)
+ {
+ position = new
+ (
+ resistivity: double.Parse(csvPosition.Resistivity),
+ resistance: double.Parse(csvPosition.Resistance),
+ percentStandardDeviation: double.Parse(csvPosition.PercentStandardDeviation),
+ number: int.Parse(csvPosition.Number),
+ name: csvPosition.Name
+ );
+ positions.Add(position);
+ }
+ dataSet = new
+ (
+ @operator: csvDataSet.Operator,
+ dateTime: DateTime.Parse(csvDataSet.DateTime),
+ finish: csvDataSet.Finish,
+ orientation: csvDataSet.Orientation,
+ northProbeID: csvDataSet.NorthProbeID,
+ southProbeID: csvDataSet.SouthProbeID,
+ polarity: csvDataSet.Polarity,
+ contactRadius: double.Parse(csvDataSet.ContactRadius),
+ probeSpacing: double.Parse(csvDataSet.ProbeSpacing),
+ load: double.Parse(csvDataSet.Load),
+ xStep: double.Parse(csvDataSet.XStep),
+ name: csvDataSet.Name,
+ plateId: csvDataSet.PlateId,
+ type: csvDataSet.Type,
+ pointsPerSample: int.Parse(csvDataSet.PointsPerSample),
+ numberOfPairs: int.Parse(csvDataSet.NumberOfPairs),
+ positions: positions
+ );
+ dataSets.Add(dataSet);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/DataSet.cs b/Server/Services/json/DataSet.cs
new file mode 100644
index 0000000..8e6769b
--- /dev/null
+++ b/Server/Services/json/DataSet.cs
@@ -0,0 +1,62 @@
+namespace Adaptation.FileHandlers.json;
+
+public class DataSet
+{
+
+ public string Operator { get; }
+ public DateTime DateTime { get; }
+ public string Finish { get; }
+ public string Orientation { get; }
+ public string NorthProbeID { get; }
+ public string SouthProbeID { get; }
+ public string Polarity { get; }
+ public double ContactRadius { get; }
+ public double ProbeSpacing { get; }
+ public double Load { get; }
+ public double XStep { get; }
+ // public string SampleSet { get; }
+ public string Name { get; }
+ public string PlateId { get; }
+ public string Type { get; }
+ public int PointsPerSample { get; }
+ public int NumberOfPairs { get; }
+ public List Positions { get; }
+
+ public DataSet(string @operator,
+ DateTime dateTime,
+ string finish,
+ string orientation,
+ string northProbeID,
+ string southProbeID,
+ string polarity,
+ double contactRadius,
+ double probeSpacing,
+ double load,
+ double xStep,
+ string name,
+ string plateId,
+ string type,
+ int pointsPerSample,
+ int numberOfPairs,
+ List positions)
+ {
+ Operator = @operator;
+ DateTime = dateTime;
+ Finish = finish;
+ Orientation = orientation;
+ NorthProbeID = northProbeID;
+ SouthProbeID = southProbeID;
+ Polarity = polarity;
+ ContactRadius = contactRadius;
+ ProbeSpacing = probeSpacing;
+ Load = load;
+ XStep = xStep;
+ Name = name;
+ PlateId = plateId;
+ Type = type;
+ PointsPerSample = pointsPerSample;
+ NumberOfPairs = numberOfPairs;
+ Positions = positions;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/Info.cs b/Server/Services/json/Info.cs
new file mode 100644
index 0000000..c1a501a
--- /dev/null
+++ b/Server/Services/json/Info.cs
@@ -0,0 +1,31 @@
+namespace Adaptation.FileHandlers.json;
+
+public class Info
+{
+
+ public string Operator { get; }
+ public string SampleName { get; }
+ public string SoftwareVersion { get; }
+ public DateTime DateTime { get; }
+ public string SystemId { get; }
+ public string SystemSite { get; }
+ public int SamplePosition { get; }
+ public int Units { get; }
+ public int CommentLength { get; }
+ public List Comments { get; }
+
+ internal Info(csv.Info info)
+ {
+ Operator = info.Operator;
+ SampleName = info.SampleName;
+ SoftwareVersion = info.SoftwareVersion;
+ DateTime = DateTime.Parse(info.DateTime);
+ SystemId = info.SystemId;
+ SystemSite = info.SystemSite;
+ SamplePosition = int.Parse(info.SamplePosition);
+ Units = int.Parse(info.Units);
+ CommentLength = int.Parse(info.CommentLength);
+ Comments = info.Comments;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/Layer.cs b/Server/Services/json/Layer.cs
new file mode 100644
index 0000000..1737cb3
--- /dev/null
+++ b/Server/Services/json/Layer.cs
@@ -0,0 +1,55 @@
+namespace Adaptation.FileHandlers.json;
+
+public class Layer
+{
+
+ public int FirstPoint { get; }
+ public int? LastPoint { get; }
+ public string Type { get; }
+ public string Smoothing { get; }
+ public string Apply { get; }
+ public int SOrder { get; }
+ public int GOrder { get; }
+ public string Correction { get; }
+ public string Conversion { get; }
+ public string JunctionOption { get; }
+ public int JunctionConstant { get; }
+ public double CurrentDensity { get; }
+ public string M1M2Tolerance { get; }
+ public string Sheet { get; }
+ public string Dose { get; }
+
+ public Layer(int firstPoint,
+ int? lastPoint,
+ string type,
+ string smoothing,
+ string apply,
+ int sOrder,
+ int gOrder,
+ string correction,
+ string conversion,
+ string junctionOption,
+ int junctionConstant,
+ double currentDensity,
+ string m1M2Tolerance,
+ string sheet,
+ string dose)
+ {
+ FirstPoint = firstPoint;
+ LastPoint = lastPoint;
+ Type = type;
+ Smoothing = smoothing;
+ Apply = apply;
+ SOrder = sOrder;
+ GOrder = gOrder;
+ Correction = correction;
+ Conversion = conversion;
+ JunctionOption = junctionOption;
+ JunctionConstant = junctionConstant;
+ CurrentDensity = currentDensity;
+ M1M2Tolerance = m1M2Tolerance;
+ Sheet = sheet;
+ Dose = dose;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/LayerHeader.cs b/Server/Services/json/LayerHeader.cs
new file mode 100644
index 0000000..f6beafc
--- /dev/null
+++ b/Server/Services/json/LayerHeader.cs
@@ -0,0 +1,39 @@
+namespace Adaptation.FileHandlers.json;
+
+public class LayerHeader
+{
+
+ public int NumberOfLayers { get; }
+ public List Layers { get; }
+
+ internal LayerHeader(csv.LayerHeader layerHeader)
+ {
+ Layer layer;
+ List layers = new();
+ NumberOfLayers = int.Parse(layerHeader.NumberOfLayers);
+ Layers = layers;
+ foreach (csv.Layer csvLayer in layerHeader.Layers)
+ {
+ layer = new
+ (
+ firstPoint: int.Parse(csvLayer.FirstPoint),
+ lastPoint: string.IsNullOrEmpty(csvLayer.LastPoint) ? null : int.Parse(csvLayer.LastPoint),
+ type: csvLayer.Type,
+ smoothing: csvLayer.Smoothing,
+ apply: csvLayer.Apply,
+ sOrder: int.Parse(csvLayer.SOrder),
+ gOrder: int.Parse(csvLayer.GOrder),
+ correction: csvLayer.Correction,
+ conversion: csvLayer.Conversion,
+ junctionOption: csvLayer.JunctionOption,
+ junctionConstant: int.Parse(csvLayer.JunctionConstant),
+ currentDensity: double.Parse(csvLayer.CurrentDensity),
+ m1M2Tolerance: csvLayer.M1M2Tolerance,
+ sheet: csvLayer.Sheet,
+ dose: csvLayer.Dose
+ );
+ layers.Add(layer);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/Log10.cs b/Server/Services/json/Log10.cs
new file mode 100644
index 0000000..4faf5bf
--- /dev/null
+++ b/Server/Services/json/Log10.cs
@@ -0,0 +1,27 @@
+namespace Adaptation.FileHandlers.json;
+
+public class Log10
+{
+
+#nullable enable
+
+ public double Depth { get; }
+ public double ResistanceRaw { get; }
+ public double? ResistanceEdited { get; }
+ public double? Resistivity { get; }
+ public double? Concentration { get; }
+
+ public Log10(double depth,
+ double raw,
+ double? edited,
+ double? resistivity,
+ double? cd)
+ {
+ Depth = Math.Log10(depth);
+ ResistanceRaw = Math.Log10(raw);
+ ResistanceEdited = edited is null ? null : Math.Log10(edited.Value);
+ Resistivity = resistivity is null ? null : Math.Log10(resistivity.Value);
+ Concentration = cd is null ? null : Math.Log10(cd.Value);
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/Point.cs b/Server/Services/json/Point.cs
new file mode 100644
index 0000000..200756e
--- /dev/null
+++ b/Server/Services/json/Point.cs
@@ -0,0 +1,31 @@
+namespace Adaptation.FileHandlers.json;
+
+public class Point
+{
+
+ public double Number { get; }
+ public double Depth { get; }
+ public double Resistance { get; }
+ public double StageX { get; }
+ public double StageY { get; }
+ public double StageZ { get; }
+ public double StageT { get; }
+
+ public Point(double number,
+ double depth,
+ double resistance,
+ double stageX,
+ double stageY,
+ double stageZ,
+ double stageT)
+ {
+ Number = number;
+ Depth = depth;
+ Resistance = resistance;
+ StageX = stageX;
+ StageY = stageY;
+ StageZ = stageZ;
+ StageT = stageT;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/Position.cs b/Server/Services/json/Position.cs
new file mode 100644
index 0000000..75a2533
--- /dev/null
+++ b/Server/Services/json/Position.cs
@@ -0,0 +1,25 @@
+namespace Adaptation.FileHandlers.json;
+
+public class Position
+{
+
+ public double Resistivity { get; }
+ public double Resistance { get; }
+ public double PercentStandardDeviation { get; }
+ public int Number { get; }
+ public string Name { get; }
+
+ public Position(double resistivity,
+ double resistance,
+ double percentStandardDeviation,
+ int number,
+ string name)
+ {
+ Resistivity = resistivity;
+ Resistance = resistance;
+ PercentStandardDeviation = percentStandardDeviation;
+ Number = number;
+ Name = name;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/Profile.cs b/Server/Services/json/Profile.cs
new file mode 100644
index 0000000..02bad1e
--- /dev/null
+++ b/Server/Services/json/Profile.cs
@@ -0,0 +1,28 @@
+namespace Adaptation.FileHandlers.json;
+
+public class Profile
+{
+
+ public string Id { get; }
+ public string Name { get; }
+ public string Label { get; }
+ public int Allocated { get; }
+ public int Used { get; }
+ public string List { get; }
+
+ public Profile(string id,
+ string name,
+ string label,
+ int allocated,
+ int used,
+ string list)
+ {
+ Id = id;
+ Name = name;
+ Label = label;
+ Allocated = allocated;
+ Used = used;
+ List = list;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/ProfileHeader.cs b/Server/Services/json/ProfileHeader.cs
new file mode 100644
index 0000000..0438f77
--- /dev/null
+++ b/Server/Services/json/ProfileHeader.cs
@@ -0,0 +1,52 @@
+namespace Adaptation.FileHandlers.json;
+
+public class ProfileHeader
+{
+
+ public int NumberOfProfiles { get; }
+ public List Profiles { get; }
+ public List ProfilePoints { get; }
+
+ internal ProfileHeader(csv.ProfileHeader profileHeader)
+ {
+ Profile profile;
+ ProfilePoint profilePoint;
+ List profiles = new();
+ csv.ProfilePoint csvProfilePoint;
+ ProfilePoint? lastProfilePoint = null;
+ List profilePoints = new();
+ NumberOfProfiles = int.Parse(profileHeader.NumberOfProfiles);
+ Profiles = profiles;
+ ProfilePoints = profilePoints;
+ foreach (csv.Profile csvProfile in profileHeader.Profiles)
+ {
+ profile = new
+ (
+ id: csvProfile.Id,
+ name: csvProfile.Name,
+ label: csvProfile.Label,
+ allocated: int.Parse(csvProfile.Allocated),
+ used: int.Parse(csvProfile.Used),
+ list: csvProfile.List
+ );
+ profiles.Add(profile);
+ }
+ for (int i = 0; i < profileHeader.ProfilePoints.Count; i++)
+ {
+ csvProfilePoint = profileHeader.ProfilePoints[i];
+ profilePoint = new
+ (
+ number: int.Parse(csvProfilePoint.Number),
+ depth: double.Parse(csvProfilePoint.Depth),
+ raw: double.Parse(csvProfilePoint.Raw),
+ edited: double.Parse(csvProfilePoint.Edited),
+ resistivity: double.Parse(csvProfilePoint.Resistivity),
+ cd: double.Parse(csvProfilePoint.CD),
+ lastProfilePoint: lastProfilePoint
+ );
+ profilePoints.Add(profilePoint);
+ lastProfilePoint = profilePoint;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/ProfilePoint.cs b/Server/Services/json/ProfilePoint.cs
new file mode 100644
index 0000000..ca8aeb1
--- /dev/null
+++ b/Server/Services/json/ProfilePoint.cs
@@ -0,0 +1,44 @@
+namespace Adaptation.FileHandlers.json;
+
+public class ProfilePoint
+{
+
+#nullable enable
+
+ public int Number { get; }
+ public double Depth { get; }
+ public double ResistanceRaw { get; }
+ public double? ResistanceEdited { get; }
+ public double? Resistivity { get; }
+ public double? Concentration { get; }
+ public double? DeltaPercent { get; }
+ public ProfilePoint? LastProfilePoint { get; }
+ public Log10? Log10 { get; }
+
+ public ProfilePoint(int number,
+ double depth,
+ double raw,
+ double? edited,
+ double? resistivity,
+ double? cd,
+ ProfilePoint? lastProfilePoint)
+ {
+ Number = number;
+ Depth = depth;
+ ResistanceRaw = raw;
+ ResistanceEdited = edited;
+ Resistivity = resistivity;
+ Concentration = cd;
+ DeltaPercent = lastProfilePoint is null ? null : (lastProfilePoint.ResistanceRaw - raw) / raw;
+ LastProfilePoint = lastProfilePoint;
+ Log10 = new
+ (
+ depth: depth,
+ raw: raw,
+ edited: edited,
+ resistivity: resistivity,
+ cd: cd
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/RawData.cs b/Server/Services/json/RawData.cs
new file mode 100644
index 0000000..7c718b0
--- /dev/null
+++ b/Server/Services/json/RawData.cs
@@ -0,0 +1,31 @@
+namespace Adaptation.FileHandlers.json;
+
+public class RawData
+{
+
+ public int TotalPoints { get; }
+ public List Points { get; }
+
+ internal RawData(csv.RawData rawData)
+ {
+ Point point;
+ List points = new();
+ TotalPoints = int.Parse(rawData.TotalPoints);
+ Points = points;
+ foreach (csv.Point csvPoint in rawData.Points)
+ {
+ point = new
+ (
+ number: double.Parse(csvPoint.Number),
+ depth: double.Parse(csvPoint.Depth),
+ resistance: double.Parse(csvPoint.Resistance),
+ stageX: double.Parse(csvPoint.StageX),
+ stageY: double.Parse(csvPoint.StageY),
+ stageZ: double.Parse(csvPoint.StageZ),
+ stageT: double.Parse(csvPoint.StageT)
+ );
+ points.Add(point);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/Setup.cs b/Server/Services/json/Setup.cs
new file mode 100644
index 0000000..5b50b58
--- /dev/null
+++ b/Server/Services/json/Setup.cs
@@ -0,0 +1,47 @@
+namespace Adaptation.FileHandlers.json;
+
+public class Setup
+{
+
+ public string Finish { get; }
+ public string NorthProbeID { get; }
+ public string SouthProbeID { get; }
+ public string MeasurementPolarity { get; }
+ public double SineBevelAngle { get; }
+ public double ContactRadius { get; }
+ public double ProbeSpacing { get; }
+ public double ProbeLoad { get; }
+ public string Orientation { get; }
+ public int NumberOfStepSizes { get; }
+ public List Steps { get; }
+
+ internal Setup(csv.Setup setup)
+ {
+ Step step;
+ List steps = new();
+ Finish = setup.Finish;
+ NorthProbeID = setup.NorthProbeID;
+ SouthProbeID = setup.SouthProbeID;
+ MeasurementPolarity = setup.MeasurementPolarity;
+ SineBevelAngle = double.Parse(setup.SineBevelAngle);
+ ContactRadius = double.Parse(setup.ContactRadius);
+ ProbeSpacing = double.Parse(setup.ProbeSpacing);
+ ProbeLoad = double.Parse(setup.ProbeLoad);
+ Orientation = setup.Orientation;
+ NumberOfStepSizes = int.Parse(setup.NumberOfStepSizes);
+ Steps = steps;
+ foreach (csv.Step csvStep in setup.Steps)
+ {
+ Step step1 = new
+ (
+ number: int.Parse(csvStep.Number),
+ points: int.Parse(csvStep.Points),
+ x: double.Parse(csvStep.X),
+ y: double.Parse(csvStep.Y)
+ );
+ step = step1;
+ steps.Add(step);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Services/json/Step.cs b/Server/Services/json/Step.cs
new file mode 100644
index 0000000..a3f4864
--- /dev/null
+++ b/Server/Services/json/Step.cs
@@ -0,0 +1,22 @@
+namespace Adaptation.FileHandlers.json;
+
+public class Step
+{
+
+ public int Number { get; }
+ public int Points { get; }
+ public double X { get; }
+ public double Y { get; }
+
+ public Step(int number,
+ int points,
+ double x,
+ double y)
+ {
+ Number = number;
+ Points = points;
+ X = x;
+ Y = y;
+ }
+
+}
\ No newline at end of file
diff --git a/Server/Views/Pages/RunInfo.cshtml b/Server/Views/Pages/RunInfo.cshtml
index 3ddaf5b..c923f21 100644
--- a/Server/Views/Pages/RunInfo.cshtml
+++ b/Server/Views/Pages/RunInfo.cshtml
@@ -35,6 +35,12 @@
+
+
+
+
-
+
+
+
+
+
+
diff --git a/Server/Views/Shared/_Layout.cshtml b/Server/Views/Shared/_Layout.cshtml
index 17b4a21..8d598cf 100644
--- a/Server/Views/Shared/_Layout.cshtml
+++ b/Server/Views/Shared/_Layout.cshtml
@@ -20,6 +20,8 @@
+
+