171 lines
4.3 KiB
C#
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
|
|
}
|