forked from amkovkov/GranuSightSoftware2
168 lines
6.7 KiB
C#
168 lines
6.7 KiB
C#
using MathNet.Numerics.Statistics;
|
|
|
|
using GSS2.Core.Analysis.AmineContent.Database;
|
|
using GSS2.Core.Extensions;
|
|
|
|
namespace GSS2.Core.Analysis.AmineContent;
|
|
|
|
public static class ResultsPostProcessor
|
|
{
|
|
public const double UNPROCESSED_THRESHOLD = 0.5;
|
|
public const double HOTSPOT_THRESHOLD = 1.2;
|
|
public const double EPSILON = 1e-10;
|
|
public const double UNPROCESSED_FRACTION_THRESHOLD = 10;
|
|
|
|
|
|
public static (
|
|
int particlesCount,
|
|
List<float[]> values,
|
|
List<double[]> normalizedValues,
|
|
List<double> processedAreas,
|
|
List<double> unprocessedAreas,
|
|
List<double> hotspotAreas,
|
|
List<double> opticalIntegrals,
|
|
List<double> innerStdDevs,
|
|
List<double> innerHeterogeneities,
|
|
double meanProcessedArea,
|
|
double processedAreaP10,
|
|
double processedAreaP50,
|
|
double processedAreaP90,
|
|
double processedAreaStdDev,
|
|
double interHeterogeneity,
|
|
double processedAreaDeltaP90P10,
|
|
double unprocessedFraction,
|
|
double meanInnerHeterogeneity,
|
|
double meanInnerStdDev,
|
|
double meanHotspotArea,
|
|
double meanOpticalIntegral
|
|
) PostProcess(ResultRecord record) => PostProcess(record.ValueData, record.ValueCount, record.MixtureNormalRate);
|
|
|
|
public static (
|
|
int particlesCount,
|
|
List<float[]> values,
|
|
List<double[]> normalizedValues,
|
|
List<double> processedAreas,
|
|
List<double> unprocessedAreas,
|
|
List<double> hotspotAreas,
|
|
List<double> opticalIntegrals,
|
|
List<double> innerStdDevs,
|
|
List<double> innerHeterogeneities,
|
|
double meanProcessedArea,
|
|
double processedAreaP10,
|
|
double processedAreaP50,
|
|
double processedAreaP90,
|
|
double processedAreaStdDev,
|
|
double interHeterogeneity,
|
|
double processedAreaDeltaP90P10,
|
|
double unprocessedFraction,
|
|
double meanInnerHeterogeneity,
|
|
double meanInnerStdDev,
|
|
double meanHotspotArea,
|
|
double meanOpticalIntegral
|
|
) PostProcess(List<float> valueData, List<int> valueCount, double mixtureNormalRate) => PostProcess(valueData.Chunk(valueCount).Select(v => v.ToArray()).ToList(), mixtureNormalRate);
|
|
|
|
public static (
|
|
int particlesCount,
|
|
List<float[]> values,
|
|
List<double[]> normalizedValues,
|
|
List<double> processedAreas,
|
|
List<double> unprocessedAreas,
|
|
List<double> hotspotAreas,
|
|
List<double> opticalIntegrals,
|
|
List<double> innerStdDevs,
|
|
List<double> innerHeterogeneities,
|
|
double meanProcessedArea,
|
|
double processedAreaP10,
|
|
double processedAreaP50,
|
|
double processedAreaP90,
|
|
double processedAreaStdDev,
|
|
double interHeterogeneity,
|
|
double processedAreaDeltaP90P10,
|
|
double unprocessedFraction,
|
|
double meanInnerHeterogeneity,
|
|
double meanInnerStdDev,
|
|
double meanHotspotArea,
|
|
double meanOpticalIntegral
|
|
) PostProcess(List<float[]> values, double mixtureNormalRate)
|
|
{
|
|
var normalizedValues = new List<double[]>();
|
|
var processedAreas = new List<double>();
|
|
var unprocessedAreas = new List<double>();
|
|
var hotspotAreas = new List<double>();
|
|
var opticalIntegrals = new List<double>();
|
|
var innerStdDevs = new List<double>();
|
|
var innerHeterogeneities = new List<double>();
|
|
|
|
var max = values.Max(vs => vs.Max());
|
|
foreach (var value in values)
|
|
{
|
|
// Находим нормализованное значение
|
|
var normalized = new double[value.Count()];
|
|
for (int i = 0; i < value.Count(); i++)
|
|
if (value[i] <= mixtureNormalRate * UNPROCESSED_THRESHOLD)
|
|
normalized[i] = value[i] / (mixtureNormalRate * UNPROCESSED_THRESHOLD);
|
|
else if (value[i] <= mixtureNormalRate * HOTSPOT_THRESHOLD)
|
|
normalized[i] = 1 + (value[i] - (mixtureNormalRate * UNPROCESSED_THRESHOLD)) / ((mixtureNormalRate * HOTSPOT_THRESHOLD) - (mixtureNormalRate * UNPROCESSED_THRESHOLD));
|
|
else
|
|
normalized[i] = 2 + (value[i] - (mixtureNormalRate * HOTSPOT_THRESHOLD)) / (max - (mixtureNormalRate * HOTSPOT_THRESHOLD));
|
|
|
|
// Вычисляем значения
|
|
var area = normalized.Count();
|
|
var processedArea = normalized.Count(v => v > 1) / area * 100;
|
|
var unprocessedArea = normalized.Count(v => v <= 1) / area * 100;
|
|
var hotspotArea = normalized.Count(v => v > 2) / area * 100;
|
|
var opticalIntegral = normalized.Sum() / area * 100;
|
|
var innerStdDev = normalized.StdDev();
|
|
var innerHeterogeneity = innerStdDev / (opticalIntegral + EPSILON);
|
|
|
|
// Добавляем значения в списки
|
|
normalizedValues.Add(normalized);
|
|
processedAreas.Add(processedArea);
|
|
unprocessedAreas.Add(unprocessedArea);
|
|
hotspotAreas.Add(hotspotArea);
|
|
opticalIntegrals.Add(opticalIntegral);
|
|
innerStdDevs.Add(innerStdDev);
|
|
innerHeterogeneities.Add(innerHeterogeneity);
|
|
}
|
|
|
|
// Вычисляем общие значения
|
|
var meanProcessedArea = processedAreas.Mean();
|
|
var processedAreaP10 = processedAreas.Percentile(10);
|
|
var processedAreaP50 = processedAreas.Percentile(50);
|
|
var processedAreaP90 = processedAreas.Percentile(90);
|
|
var processedAreaStdDev = processedAreas.StdDev();
|
|
var interHeterogeneity = processedAreaStdDev / meanProcessedArea * 100;
|
|
var processedAreaDeltaP90P10 = processedAreaP90 - processedAreaP10;
|
|
var unprocessedFraction = (double)unprocessedAreas.Count(v => v > UNPROCESSED_FRACTION_THRESHOLD) / unprocessedAreas.Count() * 100;
|
|
var meanInnerHeterogeneity = innerHeterogeneities.Mean();
|
|
var meanInnerStdDev = innerStdDevs.Mean();
|
|
var meanHotspotArea = hotspotAreas.Mean();
|
|
var meanOpticalIntegral = opticalIntegrals.Mean();
|
|
|
|
return
|
|
(
|
|
values.Count(),
|
|
values,
|
|
normalizedValues,
|
|
processedAreas,
|
|
unprocessedAreas,
|
|
hotspotAreas,
|
|
opticalIntegrals,
|
|
innerStdDevs,
|
|
innerHeterogeneities,
|
|
meanProcessedArea,
|
|
processedAreaP10,
|
|
processedAreaP50,
|
|
processedAreaP90,
|
|
processedAreaStdDev,
|
|
interHeterogeneity,
|
|
processedAreaDeltaP90P10,
|
|
unprocessedFraction,
|
|
meanInnerHeterogeneity,
|
|
meanInnerStdDev,
|
|
meanHotspotArea,
|
|
meanOpticalIntegral
|
|
);
|
|
}
|
|
}
|