From b2e2a66101d806d87f965aa93912570858169225 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Mon, 4 Sep 2023 23:25:31 -0700 Subject: [PATCH] Removed both faceDistanceLength.Length.Value / distanceTolerance and confidence / rangeFaceConfidence[1] Removed ReviewLocationContainerDistanceTolerance Added MoveToDecade IFaceDistance.MappingFromFilterPost ISorting.CanReMap --- Distance/Models/_E_Distance.cs | 122 ++++--------------- FaceParts/Models/_D2_FaceParts.cs | 2 +- Instance/DlibDotNet.cs | 58 ++++++--- Instance/Models/Binder/Configuration.cs | 9 +- Instance/Models/Configuration.cs | 2 +- Map/Models/Configuration.cs | 1 - Map/Models/MapLogic.cs | 51 ++++++-- Map/Models/Stateless/MapLogic.cs | 113 ++++++++--------- Map/Models/Stateless/Methods/IMapLogic.cs | 10 ++ Shared/Models/FaceDistance.cs | 12 +- Shared/Models/Mapping.cs | 16 ++- Shared/Models/MappingFromFilterPost.cs | 23 ++++ Shared/Models/MappingFromFilterPre.cs | 23 ++++ Shared/Models/Methods/IDistance.cs | 3 +- Shared/Models/Properties/IFaceDistance.cs | 3 +- Shared/Models/Properties/IMapping.cs | 6 +- Shared/Models/Properties/ISorting.cs | 1 + Shared/Models/Sorting.cs | 8 +- Shared/Models/Stateless/Methods/ILocation.cs | 8 +- Shared/Models/Stateless/Methods/ISorting.cs | 8 +- Shared/Models/Stateless/Methods/Location.cs | 4 +- Shared/Models/Stateless/Methods/Sorting.cs | 9 +- Tests/UnitTestCalculations.cs | 22 ++-- 23 files changed, 275 insertions(+), 239 deletions(-) create mode 100644 Shared/Models/MappingFromFilterPost.cs create mode 100644 Shared/Models/MappingFromFilterPre.cs diff --git a/Distance/Models/_E_Distance.cs b/Distance/Models/_E_Distance.cs index f133b49..82bc0fd 100644 --- a/Distance/Models/_E_Distance.cs +++ b/Distance/Models/_E_Distance.cs @@ -26,7 +26,6 @@ public partial class E_Distance : IDistance private readonly Serilog.ILogger? _Log; private readonly int _FaceConfidencePercent; private readonly bool _DistanceRenameToMatch; - private readonly float[] _RangeFaceConfidence; private readonly bool _DistanceMoveUnableToMatch; private readonly float _RectangleIntersectMinimum; private readonly List _AllMappedFaceFiles; @@ -34,7 +33,7 @@ public partial class E_Distance : IDistance private readonly double _RangeDistanceToleranceAverage; private readonly List _DuplicateMappedFaceFiles; - public E_Distance(bool distanceMoveUnableToMatch, bool distanceRenameToMatch, int faceConfidencePercent, float[] rangeDistanceTolerance, float[] rangeFaceConfidence, float[] rectangleIntersectMinimums) + public E_Distance(bool distanceMoveUnableToMatch, bool distanceRenameToMatch, int faceConfidencePercent, float[] rangeDistanceTolerance, float[] rectangleIntersectMinimums) { _Debug = new(); _Moved = new(); @@ -42,7 +41,6 @@ public partial class E_Distance : IDistance _AllMappedFaceFiles = new(); _AllMappedFaceFileNames = new(); _DuplicateMappedFaceFiles = new(); - _RangeFaceConfidence = rangeFaceConfidence; _Log = Serilog.Log.ForContext(); _DistanceRenameToMatch = distanceRenameToMatch; _FaceConfidencePercent = faceConfidencePercent; @@ -70,14 +68,16 @@ public partial class E_Distance : IDistance { if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) throw new NotSupportedException(); - confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, _RangeFaceConfidence, face.Location.Confidence); + if (face.Mapping?.MappingFromFilterPost is null) + throw new NotSupportedException(); + confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, face.Location.Confidence); wholePercentages = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution); if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding) - faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); + faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); else { faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); - faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); + faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); lock (intersectFaces) face.SetFaceDistance(faceDistance); } @@ -336,7 +336,7 @@ public partial class E_Distance : IDistance File.WriteAllLines(eDistanceContentFileName, results); } - public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, ReadOnlyCollection distinctFilteredFaces) + public static void PreFilterSetFaceDistances(int maxDegreeOfParallelism, long ticks, ReadOnlyCollection distinctFilteredFaces) { List faces = new(); foreach (Face face in distinctFilteredFaces) @@ -362,7 +362,7 @@ public partial class E_Distance : IDistance throw new NotSupportedException(); progressBar.Tick(); faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); - FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); + FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); lock (face) face.SetFaceDistance(faceDistance); }); @@ -419,7 +419,7 @@ public partial class E_Distance : IDistance throw new NotSupportedException(); if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding) continue; - faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); + faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); faceDistanceContainer = new(face, faceDistance); collection.Add(faceDistanceContainer); } @@ -489,90 +489,6 @@ public partial class E_Distance : IDistance return results; } - private static void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, DateTime dateTime, DateTime yesterday, List records) - { - FileInfo fileInfo; - List files = new(); - FaceDistance? faceDistanceEncoding; - List faceDistanceLengths; - List firstPassFailures = new(); - List faceDistanceEncodings = new(); - faceDistanceEncoding = new(records[0].FaceRecognitionDotNetFaceEncoding); - foreach (Record record in records) - { - files.Add(record.File); - faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding)); - } - if (faceDistanceEncoding is null) - throw new NullReferenceException(nameof(faceDistanceEncoding)); - faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding); - if (faceDistanceLengths.Count != files.Count) - throw new Exception(); - for (int i = 0; i < files.Count; i++) - { - if (faceDistanceLengths[i].Length < locationContainerDistanceTolerance) - continue; - firstPassFailures.Add(files[i]); - } - faceDistanceEncoding = new(records[^1].FaceRecognitionDotNetFaceEncoding); - foreach (Record record in records) - { - files.Add(record.File); - faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding)); - } - if (faceDistanceEncoding is null) - throw new NullReferenceException(nameof(faceDistanceEncoding)); - faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding); - if (faceDistanceLengths.Count != files.Count) - throw new Exception(); - for (int i = 0; i < files.Count; i++) - { - fileInfo = new(files[i]); - if (!fileInfo.Exists) - continue; - if (fileInfo.CreationTime > yesterday) - File.SetCreationTime(fileInfo.FullName, yesterday); - if (faceDistanceLengths[i].Length < locationContainerDistanceTolerance) - continue; - if (firstPassFailures.Contains(fileInfo.FullName)) - continue; - File.SetCreationTime(fileInfo.FullName, dateTime); - } - } - - void IDistance.ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, ReadOnlyCollection> locationContainers) - { - string? json; - List records = new(); - int? lastDirectoryNumber = null; - DateTime dateTime = DateTime.Now; - DateTime yesterday = DateTime.Now.AddDays(-1); - Shared.Models.FaceEncoding? modelsFaceEncoding; - FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding; - foreach (LocationContainer locationContainer in locationContainers) - { - if (locationContainer.DirectoryNumber is null) - continue; - if (lastDirectoryNumber is not null && locationContainer.DirectoryNumber.Value != lastDirectoryNumber.Value) - { - if (records.Count > 2) - ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, records); - records.Clear(); - } - json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.Directories); - if (json is null) - continue; - modelsFaceEncoding = JsonSerializer.Deserialize(json); - if (modelsFaceEncoding is null) - throw new NotSupportedException(); - faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding); - records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding)); - lastDirectoryNumber = locationContainer.DirectoryNumber.Value; - } - if (records.Count > 2) - ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, records); - } - private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory) { string json; @@ -622,14 +538,17 @@ public partial class E_Distance : IDistance } } - private static void SaveMappedForOutputResolutions(string eDistanceContentDirectory, float distanceTolerance, string personKeyFormatted, string? displayDirectoryName, List records, string directory) + private static void SaveMappedForOutputResolutions(string eDistanceContentDirectory, float distanceTolerance, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName, List records, string directory) { + int years; string text; string fileName; FileInfo fileInfo; List files = new(); List lines = new(); + List results = new(); List linkedOnce = new(); + long ticks = DateTime.Now.Ticks; string fileNameWithoutExtension; List linkedTwice = new(); List linkedThrice = new(); @@ -639,7 +558,6 @@ public partial class E_Distance : IDistance Uri uri = new(eDistanceContentDirectory); Dictionary keyValuePairs = new(); List faceDistanceEncodings = new(); - List results = new(); foreach (Record record in records) { files.Add(record.File); @@ -689,6 +607,10 @@ public partial class E_Distance : IDistance continue; } } + if (isCounterPersonYear) + (years, _) = Shared.Models.Stateless.Methods.IAge.GetAge(ticks, fileInfo.CreationTime.Ticks); + else + (years, _) = Shared.Models.Stateless.Methods.IAge.GetAge(fileInfo.CreationTime.Ticks, personKey); fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileInfo.Name)); lines.Add("---"); lines.Add("type: \"distance\""); @@ -701,6 +623,10 @@ public partial class E_Distance : IDistance lines.Add(string.Empty); lines.Add($"![0]({uri.MakeRelativeUri(new(record.File)).OriginalString})"); lines.Add($"__{fileNameWithoutExtension}__"); + if (isCounterPersonYear) + lines.Add($"#{years}yrs-ago"); + else + lines.Add($"#{years}yrs-old"); lines.Add(string.Empty); lines.AddRange(results.Select(l => $"{l.Image}{Environment.NewLine}{l.Link}{Environment.NewLine}")); text = string.Join(Environment.NewLine, lines); @@ -710,7 +636,7 @@ public partial class E_Distance : IDistance MoveFiles(keyValuePairs, linkedOnce, linkedTwice, linkedThrice); } - void IDistance.SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float[] rangeDistanceTolerance, ReadOnlyCollection> locationContainers, string personKeyFormatted, string? displayDirectoryName) + void IDistance.SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName) { string? json; List records = new(); @@ -727,13 +653,13 @@ public partial class E_Distance : IDistance faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding); records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding)); } - string directory = Path.Combine(a2PeopleContentDirectory, rangeDistanceTolerance[1].ToString(), personKeyFormatted); + string directory = Path.Combine(a2PeopleContentDirectory, locationContainerDistanceTolerance.ToString(), personKeyFormatted); if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); if (records.Count > 0) { WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory); - SaveMappedForOutputResolutions(eDistanceContentDirectory, rangeDistanceTolerance[1], personKeyFormatted, displayDirectoryName, records, directory); + SaveMappedForOutputResolutions(eDistanceContentDirectory, locationContainerDistanceTolerance, personKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, records, directory); } _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directory); } diff --git a/FaceParts/Models/_D2_FaceParts.cs b/FaceParts/Models/_D2_FaceParts.cs index 8c9c556..d0009b2 100644 --- a/FaceParts/Models/_D2_FaceParts.cs +++ b/FaceParts/Models/_D2_FaceParts.cs @@ -344,7 +344,7 @@ public class D2_FaceParts if (File.Exists(checkFile)) File.Delete(checkFile); } - else if (face.Mapping?.MappingFromFilter.InSkipCollection is not null && face.Mapping.MappingFromFilter.InSkipCollection.Value) + else if (face.Mapping?.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value) { if (File.Exists(checkFile)) File.Delete(checkFile); diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 35d3a3e..d69fdbb 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -39,7 +39,7 @@ public partial class DlibDotNet private readonly Models.Configuration _Configuration; private readonly bool _ArgZeroIsConfigurationRootDirectory; private readonly Map.Models.Configuration _MapConfiguration; - private readonly List<(string, long)> _JLinkResolvedDirectories; + private readonly List<(string Directory, long PersonKey)> _JLinkResolvedDirectories; public DlibDotNet( List args, @@ -107,7 +107,7 @@ public partial class DlibDotNet _FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages); } _MapConfiguration = Get(configuration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension); - _Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RangeFaceConfidence, configuration.RectangleIntersectMinimums); + _Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums); if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory) personContainers = new(new List()); else @@ -256,7 +256,7 @@ public partial class DlibDotNet a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])"); eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), _Configuration.PropertyConfiguration.ResultContent); string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), _Configuration.PropertyConfiguration.ResultSingleton); - _ = Directory.CreateDirectory(Path.Combine(eDistanceContentDirectory, $"({ticks})")); + _ = Directory.CreateDirectory(Path.Combine(eDistanceContentDirectory, $"{ticks}")); if (runToDoCollectionFirst) mapLogic = null; else @@ -338,7 +338,7 @@ public partial class DlibDotNet } _Distance.Clear(); ReadOnlyCollection distinctFilteredFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctFilteredItems); - ReadOnlyCollection distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, containers, mapLogic, distinctItems: true); + ReadOnlyCollection distinctFilteredMappingCollection = SetCreationTimeAndGetMappings(_Configuration.PropertyConfiguration, eDistanceContentDirectory, containers, mapLogic, distinctItems: true); if (runToDoCollectionFirst) { string json = JsonSerializer.Serialize(distinctFilteredMappingCollection); @@ -556,7 +556,7 @@ public partial class DlibDotNet } } - private ReadOnlyCollection GetMappings(Property.Models.Configuration propertyConfiguration, Container[] containers, MapLogic mapLogic, bool distinctItems) + private ReadOnlyCollection SetCreationTimeAndGetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, Container[] containers, MapLogic mapLogic, bool distinctItems) { ReadOnlyCollection results; int count = 0; @@ -602,7 +602,8 @@ public partial class DlibDotNet mappingCollection.Add(face.Mapping); if (face.Mapping.MappingFromPerson is null || face.Mapping.MappingFromPerson.LocationContainersFiles.Count == 0) continue; - if (_Configuration.LocationContainerDistanceTolerance is null) + Map.Models.Stateless.Methods.IMapLogic.SetCreationTime(face.Mapping.MappingFromItem, face.Mapping.MappingFromPerson); + if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null) Map.Models.Stateless.Methods.IMapLogic.MoveToDecade(propertyConfiguration, face.Mapping.MappingFromItem, face.Mapping.MappingFromPerson); } if (!anyValidFaces) @@ -612,6 +613,8 @@ public partial class DlibDotNet } } } + if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null) + _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory); results = new((from l in mappingCollection orderby l.MappingFromItem.Id select l).ToArray()); return results; } @@ -779,6 +782,7 @@ public partial class DlibDotNet double? α; int? eyeα; bool? isUsed; + bool? canReMap; bool? eyeReview; Mapping mapping; int notMapped = 0; @@ -790,8 +794,11 @@ public partial class DlibDotNet string deterministicHashCodeKey; MappingFromFilter mappingFromFilter; MappingFromLocation? mappingFromLocation; + MappingFromFilterPre mappingFromFilterPre; + MappingFromFilterPost mappingFromFilterPost; bool? isFocusModel = GetIsFocusModel(item.Property); bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0; + long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray(); ReadOnlyDictionary>? wholePercentagesToPersonContainers; ReadOnlyCollection locationContainersFiles = new((from l in locationContainers select l.File).ToArray()); foreach (Shared.Models.Face face in faces) @@ -799,10 +806,13 @@ public partial class DlibDotNet wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id); if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) { + canReMap = null; isUsed = null; isFocusPerson = null; inSkipCollection = null; mappingFromLocation = null; + mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson); + mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath); mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed); } else @@ -814,17 +824,21 @@ public partial class DlibDotNet (eyeReview, α) = Shared.Models.Stateless.Methods.IFace.GetEyeα(face.FaceParts); eyeα = α is null ? null : (int)Math.Round(Math.Abs(α.Value)); } - confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, _Configuration.RangeFaceConfidence, face.Location.Confidence); + confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, face.Location.Confidence); faceAreaPermyriad = IMapping.GetAreaPermyriad(_Configuration.FaceAreaPermyriad, face.Location, face.OutputResolution); wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution); deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution); mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle); - isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation); inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation); - isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation); + mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath); + canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); + isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation); + isFocusPerson = mapLogic.IsFocusPersonOld(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation); mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed); + isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); + mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson); } - mapping = new(mappingFromItem, mappingFromFilter, mappingFromLocation, mappingFromPhotoPrismCollection); + mapping = new(mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection); notMapped += mapLogic.UpdateMappingFromPerson(locationContainersFiles, wholePercentagesToPersonContainers, mapping); face.SetMapping(mapping); } @@ -848,7 +862,6 @@ public partial class DlibDotNet configuration.PersonCharacters.ToArray(), configuration.RangeDaysDeltaTolerance, configuration.RangeDistanceTolerance, - configuration.SaveMappedRelations, configuration.SaveSortingWithoutPerson, configuration.SkipNotSkipDirectories, configuration.SortingMaximumPerKey, @@ -863,6 +876,7 @@ public partial class DlibDotNet { Mapping result; bool? isUsed; + bool? canReMap; int? eyeα = null; bool? isFocusPerson; bool? eyeReview = null; @@ -873,15 +887,21 @@ public partial class DlibDotNet string deterministicHashCodeKey; MappingFromFilter mappingFromFilter; MappingFromLocation? mappingFromLocation; + MappingFromFilterPre mappingFromFilterPre; + MappingFromFilterPost mappingFromFilterPost; bool? isFocusModel = GetIsFocusModel(item.Property); bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0; + long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray(); ReadOnlyDictionary>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id); if (item.Property?.Id is null) { isUsed = null; + canReMap = null; isFocusPerson = null; inSkipCollection = null; mappingFromLocation = null; + mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson); + mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath); mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed); } else @@ -889,12 +909,16 @@ public partial class DlibDotNet wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(Shared.Models.Stateless.ILocation.Digits); deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, Shared.Models.Stateless.ILocation.Digits); mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle); - isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation); inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation); - isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation); + mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath); + canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); + isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation); + isFocusPerson = mapLogic.IsFocusPersonOld(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation); mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed); + isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); + mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson); } - result = new(mappingFromItem, mappingFromFilter, mappingFromLocation, mappingFromPhotoPrismCollection: null); + result = new(mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null); int notMapped = mapLogic.UpdateMappingFromPerson(locationContainersFiles, wholePercentagesToPersonContainers, result); return (result, notMapped); } @@ -1144,8 +1168,8 @@ public partial class DlibDotNet { if (_Log is null) throw new NullReferenceException(nameof(_Log)); - DistanceLimits distanceLimits; int? useFiltersCounter = null; + DistanceLimits distanceLimits; SortingContainer[] sortingContainers; FaceDistanceContainer[] filteredFaceDistanceContainers; long? skipOlderThan = _Configuration.SkipOlderThanDays is null ? null : new DateTime(ticks).AddDays(-_Configuration.SkipOlderThanDays.Value).Ticks; @@ -1175,7 +1199,7 @@ public partial class DlibDotNet E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers); if (filteredFaceDistanceContainers.Length > 0) { - int updated = mapLogic.UpdateFromSortingContainers(_Configuration.SaveIndividually, idToWholePercentagesToMapping, distanceLimits, sortingContainers); + int updated = sortingContainers.Length == 0 ? 0 : mapLogic.UpdateFromSortingContainers(_Configuration.SaveIndividually, idToWholePercentagesToMapping, distanceLimits, sortingContainers); List saveContainers = mapLogic.GetSaveContainers(_Configuration.SaveIndividually, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToWholePercentagesToMapping, useFiltersCounter, sortingContainers.Length > 0); mapLogic.SaveContainers(_Configuration.SaveIndividually, updated, saveContainers); } @@ -1184,7 +1208,7 @@ public partial class DlibDotNet private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection distinctFilteredFaces, ReadOnlyCollection mappingCollection, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary> idToWholePercentagesToMapping) { - E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces); + E_Distance.PreFilterSetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces); ReadOnlyCollection faceDistanceContainers = E_Distance.GetFaceDistanceContainers(distinctFilteredFaces); if (faceDistanceContainers.Count > 0) { diff --git a/Instance/Models/Binder/Configuration.cs b/Instance/Models/Binder/Configuration.cs index 7e9fed7..f097109 100644 --- a/Instance/Models/Binder/Configuration.cs +++ b/Instance/Models/Binder/Configuration.cs @@ -42,8 +42,7 @@ public class Configuration public string[]? MixedYearRelativePaths { get; set; } public string? ModelDirectory { get; set; } public string? ModelName { get; set; } - public int? NumberOfJitters { get; set; } - public int? NumberOfTimesToUpsample { get; set; } + public bool? MoveToDecade { get; set; } public string? OutputExtension { get; set; } public int? OutputQuality { get; set; } public string[]? OutputResolutions { get; set; } @@ -75,8 +74,6 @@ public class Configuration public bool? SaveFullYearOfRandomFiles { get; set; } public bool? SaveIndividually { get; set; } public string[]? SaveMappedForOutputResolutions { get; set; } - public bool? SaveMappedRelations { get; set; } - public string[]? SaveMappedRelationsForOutputResolutions { get; set; } public string[]? SavePropertyShortcutsForOutputResolutions { get; set; } public string[]? SaveRandomForOutputResolutions { get; set; } public bool? SaveResizedSubfiles { get; set; } @@ -142,6 +139,7 @@ public class Configuration // if (configuration?.MixedYearRelativePaths is null) throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths)); if (configuration?.ModelDirectory is null) throw new NullReferenceException(nameof(configuration.ModelDirectory)); if (configuration?.ModelName is null) throw new NullReferenceException(nameof(configuration.ModelName)); + if (configuration?.MoveToDecade is null) throw new NullReferenceException(nameof(configuration.MoveToDecade)); if (configuration?.OutputExtension is null) throw new NullReferenceException(nameof(configuration.OutputExtension)); if (configuration?.OutputQuality is null) throw new NullReferenceException(nameof(configuration.OutputQuality)); // if (configuration?.OutputResolutions is null) throw new NullReferenceException(nameof(configuration.OutputResolutions)); @@ -173,7 +171,6 @@ public class Configuration if (configuration?.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); if (configuration?.SaveIndividually is null) throw new NullReferenceException(nameof(configuration.SaveIndividually)); // if (configuration?.SaveMappedForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveMappedForOutputResolutions)); - if (configuration?.SaveMappedRelations is null) throw new NullReferenceException(nameof(configuration.SaveMappedRelations)); // if (configuration?.SavePropertyShortcutsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SavePropertyShortcutsForOutputResolutions)); // if (configuration?.SaveRandomForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveRandomForOutputResolutions)); if (configuration?.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); @@ -226,6 +223,7 @@ public class Configuration configuration.MixedYearRelativePaths ?? Array.Empty(), configuration.ModelDirectory, configuration.ModelName, + configuration.MoveToDecade.Value, configuration.OutputExtension, configuration.OutputQuality.Value, configuration.OutputResolutions ?? Array.Empty(), @@ -257,7 +255,6 @@ public class Configuration configuration.SaveFullYearOfRandomFiles.Value, configuration.SaveIndividually.Value, configuration.SaveMappedForOutputResolutions ?? Array.Empty(), - configuration.SaveMappedRelations.Value, configuration.SavePropertyShortcutsForOutputResolutions ?? Array.Empty(), configuration.SaveRandomForOutputResolutions ?? Array.Empty(), configuration.SaveResizedSubfiles.Value, diff --git a/Instance/Models/Configuration.cs b/Instance/Models/Configuration.cs index ebc78fe..c4747b1 100644 --- a/Instance/Models/Configuration.cs +++ b/Instance/Models/Configuration.cs @@ -36,6 +36,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration, string[] MixedYearRelativePaths, string ModelDirectory, string ModelName, + bool MoveToDecade, string OutputExtension, int OutputQuality, string[] OutputResolutions, @@ -67,7 +68,6 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration, bool SaveFullYearOfRandomFiles, bool SaveIndividually, string[] SaveMappedForOutputResolutions, - bool SaveMappedRelations, string[] SavePropertyShortcutsForOutputResolutions, string[] SaveRandomForOutputResolutions, bool SaveResizedSubfiles, diff --git a/Map/Models/Configuration.cs b/Map/Models/Configuration.cs index 457e08d..82976a9 100644 --- a/Map/Models/Configuration.cs +++ b/Map/Models/Configuration.cs @@ -13,7 +13,6 @@ public record Configuration(bool DeletePossibleDuplicates, char[] PersonCharacters, int[] RangeDaysDeltaTolerance, float[] RangeDistanceTolerance, - bool SaveMappedRelations, bool SaveSortingWithoutPerson, string[] SkipNotSkipDirectories, int SortingMaximumPerKey, diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 1e74062..22f67f6 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -110,6 +110,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic File.SetAttributes(checkFile, FileAttributes.Hidden); } if (updated is null) + { foreach (SaveContainer saveContainer in saveContainers) { if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists) @@ -122,6 +123,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic if (saveContainer.MakeAllHidden) File.SetAttributes(checkFile, FileAttributes.Hidden); } + } foreach (SaveContainer saveContainer in saveContainers) { if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.ShortcutFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists) @@ -308,8 +310,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic ticks, personContainers, readOnlyPersonKeyToCount)); - locationContainers.AddRange(Stateless.MapLogic.GetLocationContainers(distance, - maxDegreeOfParallelism, + locationContainers.AddRange(Stateless.MapLogic.GetLocationContainers(maxDegreeOfParallelism, configuration, ticks, personContainers, @@ -320,7 +321,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic if (lossCount != 0 || unableToMatchCount != 0) if (lossCount != 0 || unableToMatchCount != 0) { } - if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && configuration.SaveMappedRelations) + if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && configuration.LocationContainerDistanceTolerance is not null) Stateless.MapLogic.SaveMappedRelations(configuration, distance, a2PeopleContentDirectory, eDistanceContentDirectory, ticks, locationContainers, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection); } _PersonKeyToCount = readOnlyPersonKeyToCount; @@ -616,8 +617,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic checkFile = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); saveContainer = new(checkFile, directory, faceFileHolder); } - else - if (saveIndividually) + else if (saveIndividually) { facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem); facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}")); @@ -694,7 +694,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic FaceDistance faceDistanceLength; List? wholePercentagesCollection; bool skipNotSkipCollectionAny = _SkipNotSkipCollection.Count > 0; - float distanceTolerance = _Configuration.RangeDistanceTolerance[1]; for (int j = 0; j < faceDistanceLengths.Count; j++) { if (faceDistanceEncoding.WholePercentages is null) @@ -703,9 +702,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic throw new NotSupportedException(); if (j == i) continue; - if (_SkipCollection.TryGetValue(faceDistanceEncoding.Id, out wholePercentagesCollection) && wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value)) + if (faceDistanceEncoding.Id is not null && _SkipCollection.TryGetValue(faceDistanceEncoding.Id.Value, out wholePercentagesCollection) && wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value)) continue; - if (skipNotSkipCollectionAny && (!_SkipNotSkipCollection.TryGetValue(faceDistanceEncoding.Id, out wholePercentagesCollection) || !wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value))) + if (faceDistanceEncoding.Id is not null && skipNotSkipCollectionAny && (!_SkipNotSkipCollection.TryGetValue(faceDistanceEncoding.Id.Value, out wholePercentagesCollection) || !wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value))) continue; if (face.Mapping.MappingFromFilter.IsUsed is not null && face.Mapping.MappingFromFilter.IsUsed.Value) continue; @@ -714,7 +713,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic throw new NotSupportedException(); if (faceDistanceLength.Length == 0) continue; - sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, distanceTolerance, faceDistanceEncoding, faceDistanceLength); + sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, faceDistanceEncoding, faceDistanceLength); if (sorting.DistancePermyriad == 0) continue; if (sorting.Id == faceDistanceEncoding.Id) @@ -1184,7 +1183,39 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic public bool InSkipCollection(int id, MappingFromLocation mappingFromLocation) => _SkipCollection.TryGetValue(id, out List? wholePercentagesCollection) && wholePercentagesCollection.Contains(mappingFromLocation.WholePercentages); - public bool? IsFocusPerson(int? skipPersonWithMoreThen, List<(string Directory, long PersonKey)> jLinkResolvedDirectories, ReadOnlyDictionary>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) + public bool? IsFocusPerson(int? skipPersonWithMoreThen, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) + { + bool? result; + ReadOnlyCollection? personContainers; + if (skipPersonWithMoreThen is null && jLinkResolvedPersonKeys.Length == 0) + result = null; + else if (wholePercentagesToPersonContainers is null) + result = null; + else if (!wholePercentagesToPersonContainers.TryGetValue(mappingFromLocation.WholePercentages, out personContainers)) + result = null; + else + { + result = false; + foreach (PersonContainer personContainer in personContainers) + { + if (personContainer.Key is null) + continue; + if (skipPersonWithMoreThen is not null && _PersonKeyToCount.TryGetValue(personContainer.Key.Value, out int count) && count > 2 && count < skipPersonWithMoreThen.Value) + { + result = true; + break; + } + if (jLinkResolvedPersonKeys.Contains(personContainer.Key.Value)) + { + result = true; + break; + } + } + } + return result; + } + + public bool? IsFocusPersonOld(int? skipPersonWithMoreThen, List<(string Directory, long PersonKey)> jLinkResolvedDirectories, ReadOnlyDictionary>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) { bool? result; ReadOnlyCollection? personContainers; diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index 7ee6ba9..d361a6b 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -231,6 +231,7 @@ internal abstract class MapLogic } } } + _ = IPath.DeleteEmptyDirectories(personKeyDirectory); } private static List GetDisplayDirectoryAllFiles(string fileNameExtension, string personBirthdayFormat, ReadOnlyCollection personContainers) @@ -724,7 +725,7 @@ internal abstract class MapLogic yield return new(l, Path.GetFileName(l)); } - private static List<(string, long)> GetGenealogicalDataCommunicationDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat) + private static List<(string, long)> GetDirectoryAndTicksCollection(string[] jLinks, string personBirthdayFormat, string? rootDirectory) { List<(string, long)> results = new(); string directory; @@ -732,12 +733,11 @@ internal abstract class MapLogic string[] personKeyDirectories; string[] personDisplayDirectoryNames; string personKeyFormattedDirectoryName; - string? genealogicalDataCommunicationDirectory = Path.GetDirectoryName(genealogicalDataCommunicationFile); foreach (string jLink in jLinks) { - if (genealogicalDataCommunicationDirectory is null) + if (rootDirectory is null) continue; - directory = Path.Combine(genealogicalDataCommunicationDirectory, jLink); + directory = Path.Combine(rootDirectory, jLink); if (!Directory.Exists(directory)) continue; personDisplayDirectoryNames = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly); @@ -756,6 +756,14 @@ internal abstract class MapLogic return results; } + private static List<(string, long)> GetGenealogicalDataCommunicationDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat) + { + List<(string, long)> results; + string? genealogicalDataCommunicationDirectory = Path.GetDirectoryName(genealogicalDataCommunicationFile); + results = GetDirectoryAndTicksCollection(jLinks, personBirthdayFormat, genealogicalDataCommunicationDirectory); + return results; + } + private static string? TryToFind(char[] personCharacters, string a2PeopleSingletonDirectory, List<(string Directory, string DirectoryName, string DirectoryNameSplitFirst)> a2PeopleSingletonDirectories, string file, string path) { string? result; @@ -871,7 +879,6 @@ internal abstract class MapLogic int? wholePercentages; string? checkDirectory; ProgressBar progressBar; - string? yearDirectoryName; string[] yearDirectories; string personKeyFormatted; string? personFirstInitial; @@ -927,22 +934,6 @@ internal abstract class MapLogic personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string file in files) File.Delete(file); - yearDirectoryName = Path.GetFileName(yearDirectory); - if (!string.IsNullOrEmpty(yearDirectoryName) && yearDirectoryName.Length != 8) - { - checkDirectory = Path.Combine(personKeyFormattedDirectory, "abcdefgh"); - if (Directory.Exists(checkDirectory)) - { - MoveDirectory(personNameDirectories, checkDirectory); - if (!check) - check = true; - continue; - } - Directory.Move(yearDirectory, checkDirectory); - if (!check) - check = true; - continue; - } foreach (string personNameDirectory in personNameDirectories) { directoryNumber++; @@ -1070,33 +1061,6 @@ internal abstract class MapLogic return results; } - private static void MoveDirectory(string[] personNameDirectories, string destination) - { - string[] files; - string checkFile; - string checkDirectory; - string? personNameDirectoryName; - foreach (string personNameDirectory in personNameDirectories) - { - personNameDirectoryName = Path.GetFileName(personNameDirectory); - checkDirectory = Path.Combine(destination, personNameDirectoryName); - if (personNameDirectory == checkDirectory) - continue; - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string file in files) - { - checkFile = Path.Combine(checkDirectory, Path.GetFileName(file)); - if (checkFile == file) - continue; - if (File.Exists(checkFile)) - continue; - File.Move(file, checkFile); - } - } - } - internal static void SetKeyValuePairsAndAddToCollections(Configuration configuration, ReadOnlyCollection personContainers, Dictionary personKeyToPersonContainer, ReadOnlyCollection personKeyFormattedIdThenWholePercentagesCollection, Dictionary personKeyToCount, Dictionary personKeyFormattedToPersonContainer, Dictionary> personKeyToPersonContainerCollection, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) { PersonBirthday? personBirthday; @@ -1291,7 +1255,7 @@ internal abstract class MapLogic } } - internal static List> GetLocationContainers(Shared.Models.Methods.IDistance distance, int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection personContainers, Dictionary> skipCollection, List records) + internal static List> GetLocationContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection personContainers, Dictionary> skipCollection, List records) { List> results = new(); List mappedFiles = GetMappedFiles(configuration, personContainers, records); @@ -1310,8 +1274,6 @@ internal abstract class MapLogic } ReadOnlyCollection> locationContainers = new(results.OrderBy(l => l.DirectoryNumber).ToArray()); LookForPossibleDuplicates(configuration, locationContainers); - if (configuration.LocationContainerDistanceTolerance is not null) - distance.ReviewLocationContainerDistanceTolerance(configuration.LocationContainerDistanceTolerance.Value, locationContainers); return results; } @@ -1558,7 +1520,10 @@ internal abstract class MapLogic string checkDirectory; WindowsShortcut windowsShortcut; List resolvedDirectories = new(); - results = GetGenealogicalDataCommunicationDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat); + if (string.IsNullOrEmpty(genealogicalDataCommunicationFile)) + results = GetDirectoryAndTicksCollection(jLinks, personBirthdayFormat, a2PeopleContentDirectory); + else + results = GetGenealogicalDataCommunicationDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat); if (results.Count == 0 || results.Count < jLinks.Length) { List<(string, string, string)> a2PeopleSingletonDirectories = new(); @@ -1710,10 +1675,24 @@ internal abstract class MapLogic return new(results); } + internal static void SetCreationTime(MappingFromItem mappingFromItem, MappingFromPerson mappingFromPerson) + { + DateTime dateTime; + FileInfo fileInfo; + foreach (string locationContainersFile in mappingFromPerson.LocationContainersFiles) + { + fileInfo = new(locationContainersFile); + if (!fileInfo.Exists) + continue; + dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value; + if (fileInfo.CreationTime != dateTime) + File.SetCreationTime(locationContainersFile, dateTime); + } + } + internal static void MoveToDecade(Property.Models.Configuration propertyConfiguration, MappingFromItem mappingFromItem, MappingFromPerson mappingFromPerson) { string year; - DateTime dateTime; FileInfo fileInfo; string halfDecade; string checkDirectory; @@ -1744,24 +1723,20 @@ internal abstract class MapLogic break; if (mappingFromItem.DateTimeOriginal is null) { - dateTime = mappingFromItem.MinimumDateTime; year = mappingFromItem.MinimumDateTime.Year.ToString(); halfDecade = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-"; } else { - dateTime = mappingFromItem.DateTimeOriginal.Value; year = mappingFromItem.DateTimeOriginal.Value.Year.ToString(); halfDecade = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-"; } - if (fileInfo.CreationTime != dateTime) - File.SetCreationTime(locationContainersFile, dateTime); if (halfDecade == yearDirectoryName) continue; checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); - File.Move(locationContainersFile, Path.Combine(checkDirectory, Path.Combine(checkDirectory, Path.GetFileName(locationContainersFile)))); + File.Move(locationContainersFile, Path.Combine(checkDirectory, Path.GetFileName(locationContainersFile))); } } @@ -1807,6 +1782,7 @@ internal abstract class MapLogic internal static void SaveMappedRelations(Configuration configuration, Shared.Models.Methods.IDistance distance, string a2PeopleContentDirectory, string eDistanceContentDirectory, long ticks, List> locationContainers, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection) { + bool isCounterPersonYear; string personKeyFormatted; string? displayDirectoryName; int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); @@ -1816,13 +1792,32 @@ internal abstract class MapLogic using ProgressBar progressBar = new(collections.Count, message, options); foreach (ReadOnlyCollection> collection in collections) { + if (configuration.LocationContainerDistanceTolerance is null) + break; progressBar.Tick(); if (collection.Count == 0) continue; personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey); + isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year); displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted); - distance.SaveMappedForOutputResolutions(a2PeopleContentDirectory, eDistanceContentDirectory, configuration.RangeDistanceTolerance, collection, personKeyFormatted, displayDirectoryName); + distance.SaveMappedForOutputResolutions(a2PeopleContentDirectory, eDistanceContentDirectory, configuration.LocationContainerDistanceTolerance.Value, collection, collection[0].PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName); } } + internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) + { + bool? result; + ReadOnlyCollection? personContainers; + if (wholePercentagesToPersonContainers is null) + result = null; + else + { + if (!wholePercentagesToPersonContainers.TryGetValue(mappingFromLocation.WholePercentages, out personContainers)) + result = null; + else + result = personContainers.Any(l => IPerson.IsDefaultName(l) && l.Key is not null && IPersonBirthday.IsCounterPersonYear(new DateTime(l.Key.Value).Year) && !jLinkResolvedPersonKeys.Contains(l.Key.Value)); + } + return result; + } + } \ No newline at end of file diff --git a/Map/Models/Stateless/Methods/IMapLogic.cs b/Map/Models/Stateless/Methods/IMapLogic.cs index 87e3ce4..c4b40d7 100644 --- a/Map/Models/Stateless/Methods/IMapLogic.cs +++ b/Map/Models/Stateless/Methods/IMapLogic.cs @@ -35,9 +35,19 @@ public interface IMapLogic static List<(string, long)> GetJLinkDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat, char[] personCharacters, string a2PeopleSingletonDirectory, string a2PeopleContentDirectory) => MapLogic.GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory); + void TestStatic_SetCreationTime(Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) => + SetCreationTime(mappingFromItem, mappingFromPerson); + static void SetCreationTime(Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) => + MapLogic.SetCreationTime(mappingFromItem, mappingFromPerson); + void TestStatic_MoveToDecade(Property.Models.Configuration propertyConfiguration, Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) => MoveToDecade(propertyConfiguration, mappingFromItem, mappingFromPerson); static void MoveToDecade(Property.Models.Configuration propertyConfiguration, Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) => MapLogic.MoveToDecade(propertyConfiguration, mappingFromItem, mappingFromPerson); + bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) => + CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); + static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) => + MapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); + } \ No newline at end of file diff --git a/Shared/Models/FaceDistance.cs b/Shared/Models/FaceDistance.cs index 1752103..600fd38 100644 --- a/Shared/Models/FaceDistance.cs +++ b/Shared/Models/FaceDistance.cs @@ -9,29 +9,31 @@ public record class FaceDistance : Properties.IFaceDistance public int? ConfidencePercent { init; get; } public DateTime DateTimeOriginalThenMinimumDateTime { init; get; } public object? Encoding { init; get; } - public int Id { init; get; } + public MappingFromFilterPost? MappingFromFilterPost { init; get; } + public int? Id { init; get; } public bool? IsWrongYear { init; get; } public double? Length { init; get; } public int? WholePercentages { init; get; } [JsonConstructor] - public FaceDistance(int? confidencePercent, DateTime dateTimeOriginalThenMinimumDateTime, object? encoding, int id, bool? isWrongYear, double? length, int? wholePercentages) + public FaceDistance(int? confidencePercent, DateTime dateTimeOriginalThenMinimumDateTime, object? encoding, MappingFromFilterPost? mappingFromFilterPost, int? id, bool? isWrongYear, double? length, int? wholePercentages) { ConfidencePercent = confidencePercent; DateTimeOriginalThenMinimumDateTime = dateTimeOriginalThenMinimumDateTime; Encoding = encoding; + MappingFromFilterPost = mappingFromFilterPost; Id = id; IsWrongYear = isWrongYear; Length = length; WholePercentages = wholePercentages; } - public FaceDistance(int? confidencePercent, DateTime dateTimeOriginalThenMinimumDateTime, object? encoding, int id, bool? isWrongYear, int? wholePercentages) : - this(confidencePercent, dateTimeOriginalThenMinimumDateTime, encoding, id, isWrongYear, null, wholePercentages) + public FaceDistance(int? confidencePercent, DateTime dateTimeOriginalThenMinimumDateTime, object? encoding, MappingFromFilterPost? mappingFromFilterPost, int id, bool? isWrongYear, int? wholePercentages) : + this(confidencePercent, dateTimeOriginalThenMinimumDateTime, encoding, mappingFromFilterPost, id, isWrongYear, null, wholePercentages) { } public FaceDistance(FaceDistance faceDistance, double length) : - this(faceDistance.ConfidencePercent, faceDistance.DateTimeOriginalThenMinimumDateTime, null, faceDistance.Id, faceDistance.IsWrongYear, length, faceDistance.WholePercentages) + this(faceDistance.ConfidencePercent, faceDistance.DateTimeOriginalThenMinimumDateTime, null, faceDistance.MappingFromFilterPost, faceDistance.Id, faceDistance.IsWrongYear, length, faceDistance.WholePercentages) { } public FaceDistance(object encoding) => Encoding = encoding; diff --git a/Shared/Models/Mapping.cs b/Shared/Models/Mapping.cs index 39d9d64..b4ab44b 100644 --- a/Shared/Models/Mapping.cs +++ b/Shared/Models/Mapping.cs @@ -12,29 +12,33 @@ public class Mapping : Properties.IMapping public string? _SegmentC; protected SortingContainer? _SortingContainer; public int? By => _By; + public MappingFromFilterPost MappingFromFilterPost { init; get; } + public MappingFromFilterPre MappingFromFilterPre { init; get; } public MappingFromItem MappingFromItem { init; get; } public MappingFromFilter MappingFromFilter { init; get; } public MappingFromLocation? MappingFromLocation { init; get; } - public List? MappingFromPhotoPrismCollection { init; get; } public MappingFromPerson? MappingFromPerson => _MappingFromPerson; + public List? MappingFromPhotoPrismCollection { init; get; } public string? SegmentC => _SegmentC; public SortingContainer? SortingContainer => _SortingContainer; [JsonConstructor] - public Mapping(int? by, MappingFromItem mappingFromItem, MappingFromFilter mappingFromFilter, MappingFromLocation? mappingFromLocation, List? mappingFromPhotoPrismCollection, MappingFromPerson? mappingFromPerson, string? segmentC, SortingContainer? sortingContainer) + public Mapping(int? by, MappingFromFilter mappingFromFilter, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, MappingFromPerson? mappingFromPerson, List? mappingFromPhotoPrismCollection, string? segmentC, SortingContainer? sortingContainer) { _By = by; _SegmentC = segmentC; - MappingFromItem = mappingFromItem; MappingFromFilter = mappingFromFilter; + MappingFromFilterPost = mappingFromFilterPost; + MappingFromFilterPre = mappingFromFilterPre; + MappingFromItem = mappingFromItem; MappingFromLocation = mappingFromLocation; - MappingFromPhotoPrismCollection = mappingFromPhotoPrismCollection; _MappingFromPerson = mappingFromPerson; + MappingFromPhotoPrismCollection = mappingFromPhotoPrismCollection; _SortingContainer = sortingContainer; } - public Mapping(MappingFromItem mappingFromItem, MappingFromFilter mappingFromFilter, MappingFromLocation? mappingFromLocation, List? mappingFromPhotoPrismCollection) : - this(null, mappingFromItem, mappingFromFilter, mappingFromLocation, mappingFromPhotoPrismCollection, null, null, null) + public Mapping(MappingFromFilter mappingFromFilter, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List? mappingFromPhotoPrismCollection) : + this(null, mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null) { } public override string ToString() diff --git a/Shared/Models/MappingFromFilterPost.cs b/Shared/Models/MappingFromFilterPost.cs new file mode 100644 index 0000000..214ca8b --- /dev/null +++ b/Shared/Models/MappingFromFilterPost.cs @@ -0,0 +1,23 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Shared.Models; + +public record MappingFromFilterPost(bool? CanReMap, + bool? InSkipCollection, + bool? IsFocusPerson) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, MappingFromFilterPostGenerationContext.Default.MappingFromFilterPost); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(MappingFromFilterPost))] +public partial class MappingFromFilterPostGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Shared/Models/MappingFromFilterPre.cs b/Shared/Models/MappingFromFilterPre.cs new file mode 100644 index 0000000..b6d4f00 --- /dev/null +++ b/Shared/Models/MappingFromFilterPre.cs @@ -0,0 +1,23 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Shared.Models; + +public record MappingFromFilterPre(bool? InSkipCollection, + bool? IsFocusModel, + bool? IsFocusRelativePath) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, MappingFromFilterPreGenerationContext.Default.MappingFromFilterPre); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(MappingFromFilterPre))] +public partial class MappingFromFilterPreGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Shared/Models/Methods/IDistance.cs b/Shared/Models/Methods/IDistance.cs index 5086d80..bce8852 100644 --- a/Shared/Models/Methods/IDistance.cs +++ b/Shared/Models/Methods/IDistance.cs @@ -5,7 +5,6 @@ namespace View_by_Distance.Shared.Models.Methods; public interface IDistance { - void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, ReadOnlyCollection> locationContainers); - void SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float[] rangeDistanceTolerance, ReadOnlyCollection> locationContainers, string personKeyFormatted, string? displayDirectoryName); + void SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName); } \ No newline at end of file diff --git a/Shared/Models/Properties/IFaceDistance.cs b/Shared/Models/Properties/IFaceDistance.cs index 1cd9b87..0ce82d9 100644 --- a/Shared/Models/Properties/IFaceDistance.cs +++ b/Shared/Models/Properties/IFaceDistance.cs @@ -6,7 +6,8 @@ public interface IFaceDistance public int? ConfidencePercent { init; get; } public DateTime DateTimeOriginalThenMinimumDateTime { init; get; } public object? Encoding { init; get; } - public int Id { init; get; } + public MappingFromFilterPost? MappingFromFilterPost { init; get; } + public int? Id { init; get; } public bool? IsWrongYear { init; get; } public double? Length { init; get; } public int? WholePercentages { init; get; } diff --git a/Shared/Models/Properties/IMapping.cs b/Shared/Models/Properties/IMapping.cs index 5093be5..9851d2f 100644 --- a/Shared/Models/Properties/IMapping.cs +++ b/Shared/Models/Properties/IMapping.cs @@ -4,11 +4,13 @@ public interface IMapping { public int? By { get; } - public string? SegmentC { get; } + public MappingFromFilterPost MappingFromFilterPost { init; get; } + public MappingFromFilterPre MappingFromFilterPre { init; get; } public MappingFromItem MappingFromItem { init; get; } public MappingFromLocation? MappingFromLocation { init; get; } - public List? MappingFromPhotoPrismCollection { init; get; } public MappingFromPerson? MappingFromPerson { get; } + public List? MappingFromPhotoPrismCollection { init; get; } + public string? SegmentC { get; } public SortingContainer? SortingContainer { get; } } \ No newline at end of file diff --git a/Shared/Models/Properties/ISorting.cs b/Shared/Models/Properties/ISorting.cs index c685e91..530fc6c 100644 --- a/Shared/Models/Properties/ISorting.cs +++ b/Shared/Models/Properties/ISorting.cs @@ -3,6 +3,7 @@ namespace View_by_Distance.Shared.Models.Properties; public interface ISorting { + public bool CanReMap { init; get; } public int DaysDelta { init; get; } public int DistancePermyriad { init; get; } public int Id { init; get; } diff --git a/Shared/Models/Sorting.cs b/Shared/Models/Sorting.cs index 2e64359..34695bb 100644 --- a/Shared/Models/Sorting.cs +++ b/Shared/Models/Sorting.cs @@ -6,6 +6,7 @@ namespace View_by_Distance.Shared.Models; public record class Sorting : Properties.ISorting { + public bool CanReMap { init; get; } public int DaysDelta { init; get; } public int DistancePermyriad { init; get; } public int Id { init; get; } @@ -13,17 +14,18 @@ public record class Sorting : Properties.ISorting public int WholePercentages { init; get; } [JsonConstructor] - public Sorting(int daysDelta, int distancePermyriad, int id, bool older, int wholePercentages) + public Sorting(bool canReMap, int daysDelta, int distancePermyriad, int id, bool older, int wholePercentages) { + CanReMap = canReMap; DaysDelta = daysDelta; DistancePermyriad = distancePermyriad; Id = id; - WholePercentages = wholePercentages; Older = older; + WholePercentages = wholePercentages; } public Sorting(Mapping mapping, MappingFromLocation mappingFromLocation) : - this(0, 0, mapping.MappingFromItem.Id, false, mappingFromLocation.WholePercentages) + this(false, 0, 0, mapping.MappingFromItem.Id, false, mappingFromLocation.WholePercentages) { } public override string ToString() diff --git a/Shared/Models/Stateless/Methods/ILocation.cs b/Shared/Models/Stateless/Methods/ILocation.cs index d785784..e88c8d3 100644 --- a/Shared/Models/Stateless/Methods/ILocation.cs +++ b/Shared/Models/Stateless/Methods/ILocation.cs @@ -45,10 +45,10 @@ public interface ILocation static string GetLeftPadded(int locationDigits, string value) => Location.GetLeftPadded(locationDigits, value); - int TestStatic_GetConfidencePercent(int faceConfidencePercent, float[] rangeFaceConfidence, double confidence) => - GetConfidencePercent(faceConfidencePercent, rangeFaceConfidence, confidence); - static int GetConfidencePercent(int faceConfidencePercent, float[] rangeFaceConfidence, double confidence) => - Location.GetConfidencePercent(faceConfidencePercent, rangeFaceConfidence, confidence); + int TestStatic_GetConfidencePercent(int faceConfidencePercent, double confidence) => + GetConfidencePercent(faceConfidencePercent, confidence); + static int GetConfidencePercent(int faceConfidencePercent, double confidence) => + Location.GetConfidencePercent(faceConfidencePercent, confidence); string TestStatic_GetLeftPadded(int locationDigits, int value) => GetLeftPadded(locationDigits, value); diff --git a/Shared/Models/Stateless/Methods/ISorting.cs b/Shared/Models/Stateless/Methods/ISorting.cs index b34b7c4..cd54ff3 100644 --- a/Shared/Models/Stateless/Methods/ISorting.cs +++ b/Shared/Models/Stateless/Methods/ISorting.cs @@ -8,9 +8,9 @@ public interface ISorting static Models.Sorting[] Sort(List collection) => (from l in collection orderby l.DistancePermyriad, l.DaysDelta select l).ToArray(); - Models.Sorting TestStatic_Get(int faceDistancePermyriad, float distanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) => - Get(faceDistancePermyriad, distanceTolerance, faceDistanceEncoding, faceDistanceLength); - static Models.Sorting Get(int faceDistancePermyriad, float distanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) => - Sorting.Get(faceDistancePermyriad, distanceTolerance, faceDistanceEncoding, faceDistanceLength); + Models.Sorting TestStatic_Get(int faceDistancePermyriad, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) => + Get(faceDistancePermyriad, faceDistanceEncoding, faceDistanceLength); + static Models.Sorting Get(int faceDistancePermyriad, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) => + Sorting.Get(faceDistancePermyriad, faceDistanceEncoding, faceDistanceLength); } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/Location.cs b/Shared/Models/Stateless/Methods/Location.cs index e887622..3fd1784 100644 --- a/Shared/Models/Stateless/Methods/Location.cs +++ b/Shared/Models/Stateless/Methods/Location.cs @@ -114,9 +114,9 @@ internal abstract class Location return result; } - internal static int GetConfidencePercent(int faceConfidencePercent, float[] rangeFaceConfidence, double confidence) + internal static int GetConfidencePercent(int faceConfidencePercent, double confidence) { - int result = (int)(confidence / rangeFaceConfidence[1] * faceConfidencePercent); + int result = (int)(confidence * faceConfidencePercent); return result; } diff --git a/Shared/Models/Stateless/Methods/Sorting.cs b/Shared/Models/Stateless/Methods/Sorting.cs index 3b9688f..cc67306 100644 --- a/Shared/Models/Stateless/Methods/Sorting.cs +++ b/Shared/Models/Stateless/Methods/Sorting.cs @@ -3,9 +3,11 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class Sorting { - internal static Models.Sorting Get(int faceDistancePermyriad, float distanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) + internal static Models.Sorting Get(int faceDistancePermyriad, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) { Models.Sorting result; + if (faceDistanceLength.Id is null) + throw new NotSupportedException(); if (faceDistanceLength.Length is null) throw new NotSupportedException(); if (faceDistanceLength.WholePercentages is null) @@ -13,8 +15,9 @@ internal abstract class Sorting TimeSpan timeSpan = new(faceDistanceLength.DateTimeOriginalThenMinimumDateTime.Ticks - faceDistanceEncoding.DateTimeOriginalThenMinimumDateTime.Ticks); bool older = timeSpan.TotalMilliseconds < 0; int daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0); - int distancePermyriad = (int)(faceDistanceLength.Length.Value / distanceTolerance * faceDistancePermyriad); - result = new(daysDelta, distancePermyriad, faceDistanceLength.Id, older, faceDistanceLength.WholePercentages.Value); + int distancePermyriad = (int)(faceDistanceLength.Length.Value * faceDistancePermyriad); + bool canReMap = faceDistanceLength.MappingFromFilterPost?.CanReMap is not null && faceDistanceLength.MappingFromFilterPost.CanReMap.Value; + result = new(canReMap, daysDelta, distancePermyriad, faceDistanceLength.Id.Value, older, faceDistanceLength.WholePercentages.Value); return result; } diff --git a/Tests/UnitTestCalculations.cs b/Tests/UnitTestCalculations.cs index 2609cc3..6a856a5 100644 --- a/Tests/UnitTestCalculations.cs +++ b/Tests/UnitTestCalculations.cs @@ -231,25 +231,19 @@ public partial class UnitTestCalculations public void TestGetConfidencePercent() { int faceConfidencePercent = 100; - float minimum, target, maximum, value, check; - minimum = 0.8f; - target = 0.8f; - maximum = int.MaxValue; + float value, check; value = 0f; - check = ILocation.GetConfidencePercent(faceConfidencePercent, new float[] { minimum, target, maximum }, value); + check = ILocation.GetConfidencePercent(faceConfidencePercent, value); Assert.IsTrue(check == 0); - target = 0.8f; value = 0.4f; - check = ILocation.GetConfidencePercent(faceConfidencePercent, new float[] { minimum, target, maximum }, value); - Assert.IsTrue(check == 50); - target = 0.8f; + check = ILocation.GetConfidencePercent(faceConfidencePercent, value); + Assert.IsTrue(check == 40); value = 0.8f; - check = ILocation.GetConfidencePercent(faceConfidencePercent, new float[] { minimum, target, maximum }, value); - Assert.IsTrue(check == 100); - target = 0.8f; + check = ILocation.GetConfidencePercent(faceConfidencePercent, value); + Assert.IsTrue(check == 80); value = 1.6f; - check = ILocation.GetConfidencePercent(faceConfidencePercent, new float[] { minimum, target, maximum }, value); - Assert.IsTrue(check == 200); + check = ILocation.GetConfidencePercent(faceConfidencePercent, value); + Assert.IsTrue(check == 160); NonThrowTryCatch(); }