This repository has been archived on 2024-06-04. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
thesis-src/Examples/ReportGenerator/ReportGenerator.cs
T
Simon Gruber 1b50b1fe53 Checkpoint
2023-11-22 16:52:12 +01:00

171 lines
4.3 KiB
C#

using ReportGenerator.Generator.Abstract;
using ReportGenerator.Generator.Interface;
using ReportGenerator.Generator.Model;
using ReportGenerator.Models;
namespace ReportGenerator;
public class ReportGenerator : FileSerializableBase
{
/// <inheritdoc />
public override string FileExtension => Document.FileExtension;
private IDocumentGenerator Document { get; }
private ICollection<ImageStats> Images { get; }
public ReportGenerator(
IDocumentGenerator document,
IEnumerable<ImageStats> data
)
{
Document = document;
Images = data.ToArray();
}
public ReportGenerator(
string title,
IDocumentGenerator document,
IEnumerable<ImageStats> data
) : this(document, data)
{
WithTitle(title);
}
/// <inheritdoc />
public override string ToString() => Document.ToString();
#region Report content generation
public ReportGenerator WithTitle(string text)
{
Document.AppendHeading(1, text);
return this;
}
public ReportGenerator AddImageStatsFull(string title)
{
Document.AppendHeading(2, title);
foreach (var stat in Images)
{
Document
.AppendHeading(3, stat.ImageName)
.AppendParagraph(
Document.FormatImage(Path.Combine("img", stat.ImageName), new Bounds(0, 350))
)
.AppendTable(
stat.Reference.Count + 5,
table =>
{
table.AppendHeader(stat
.Reference
.Prepend("Image")
.Prepend("CER (avg)")
.Prepend("WER")
.Prepend("Elapsed")
.Prepend("Processor")
);
var processors = stat.Processors
.OrderBy(s => s.Distance)
.ThenBy(s => s.ProcessingTime);
foreach (var processor in processors)
{
var imgPath = Path.Combine("results", $"{processor.Name}.00.{stat.ImageName}.png");
table.AppendRow(processor.Words
.Select(s => s.ToString() ?? string.Empty)
.Prepend(Document.FormatImage(imgPath, new Bounds(0, 150)))
.Prepend(processor.Words.Average(s => s.Distance).ToString("F2"))
.Prepend($"{processor.Distance * 100:F1}%")
.Prepend($"{processor.ProcessingTime * 1000:F1}ms")
.Prepend(processor.Name)
);
}
})
.AppendParagraph(
$"*Comparison data generated based on {stat.Reference.Count} tagged words.*"
);
}
return this;
}
public ReportGenerator AddComparison(
string title,
Func<IEnumerable<double>, double> evaluationFunc
)
{
var lookup = Images
.SelectMany(s => s.Processors)
.ToLookup(p => p.Name);
Document.AppendHeading(2, title);
var byWer = lookup
.Select(g => (
Name: g.Key,
Value: evaluationFunc(g.Select(p => p.Distance)) * 100
))
.OrderBy(g => g.Value);
Document.AppendHeading(3, "WER");
AppendComparison(("Error", "%"), byWer);
var byCer = lookup
.Select(g => (
Name: g.Key,
Value: evaluationFunc(g.SelectMany(p => p.Words, (_, word) => word.Distance))
))
.OrderBy(g => g.Value);
Document.AppendHeading(3, "CER");
AppendComparison(("Changes", string.Empty), byCer);
var byTime = lookup
.Select(g => (
Name: g.Key,
Value: evaluationFunc(g.Select(p => p.ProcessingTime)) * 1000
))
.OrderBy(g => g.Value);
Document.AppendHeading(3, "Time");
AppendComparison(("Time", "ms"), byTime);
return this;
}
private void AppendComparison(
(string name, string unit)? valueInfo,
IEnumerable<(string, double)> values
)
{
const int context = 5;
var tValues = values.ToArray();
var tContext = Math.Min(tValues.Length / 2, context);
Document.AppendTable(2, table =>
{
table
.AppendHeader(new[] { "Processor", valueInfo?.name ?? "Value" })
.AppendRows(tValues
.Take(tContext)
.Select(MakeRow))
.AppendRow("...")
.AppendRows(
tValues
.TakeLast(tContext)
.Select(MakeRow)
);
return;
string[] MakeRow((string, double) v) =>
new[] { v.Item1, v.Item2.ToString("F2") + valueInfo?.unit };
});
}
#endregion
}