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 values, List normalizedValues, List processedAreas, List unprocessedAreas, List hotspotAreas, List opticalIntegrals, List innerStdDevs, List 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 values, List normalizedValues, List processedAreas, List unprocessedAreas, List hotspotAreas, List opticalIntegrals, List innerStdDevs, List 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 valueData, List valueCount, double mixtureNormalRate) => PostProcess(valueData.Chunk(valueCount).Select(v => v.ToArray()).ToList(), mixtureNormalRate); public static ( int particlesCount, List values, List normalizedValues, List processedAreas, List unprocessedAreas, List hotspotAreas, List opticalIntegrals, List innerStdDevs, List 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 values, double mixtureNormalRate) { var normalizedValues = new List(); var processedAreas = new List(); var unprocessedAreas = new List(); var hotspotAreas = new List(); var opticalIntegrals = new List(); var innerStdDevs = new List(); var innerHeterogeneities = new List(); 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 ); } }