Face => Mapping

This commit is contained in:
Mike Phares 2022-09-30 10:58:05 -07:00
parent 4568d3fbc6
commit b81d9e9862
19 changed files with 310 additions and 249 deletions

View File

@ -163,7 +163,7 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
throw new NotSupportedException();
if (sorting.DaysDelta > sortingDaysDeltaTolerance || sorting.DistancePermyriad > faceDistancePermyriad || face.Mapping.MappingFromLocation.Confidence < faceDistanceMinimumConfidence || face.Mapping.MappingFromLocation.AreaPermille < faceDistanceAreaPermilleTolerance)
continue;
sortingContainer = new(face, sorting);
sortingContainer = new(face.Mapping, sorting);
results.Add(sortingContainer);
if (results.Count >= _SortingMaximumPerFaceShouldBeHigh)
break;
@ -180,13 +180,13 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
return results;
}
private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(Face[] selectedFilteredFaces)
private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(Face[] distinctFilteredFaces)
{
FaceDistanceContainer[] results;
FaceDistance faceDistance;
FaceDistanceContainer faceDistanceContainer;
List<FaceDistanceContainer> collection = new();
foreach (Face face in selectedFilteredFaces)
foreach (Face face in distinctFilteredFaces)
{
if (face.Mapping is null)
throw new NotSupportedException();
@ -212,13 +212,13 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
return faceDistanceEncodings;
}
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, Face[] selectedFilteredFaces, int? useFiltersCounter)
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, Face[] distinctFilteredFaces, int? useFiltersCounter)
{
SortingContainer[] results;
List<SortingContainer> collection = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
FaceDistanceContainer[] faceDistanceContainers = GetOrderedFaceDistanceContainers(selectedFilteredFaces);
FaceDistanceContainer[] faceDistanceContainers = GetOrderedFaceDistanceContainers(distinctFilteredFaces);
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers);
string message = $") {faceDistanceContainers.Length:000} Get Sorting Containers Then Set Face Mapping Sorting Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
@ -249,22 +249,24 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
return results;
}
public static Face[] GetSelectedFilteredFaces(List<Face> distinctFilteredFaces)
public static Mapping[] GetSelectedMappingCollection(Face[] distinctFilteredFaces)
{
Face[] results = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray();
Mapping[] results;
IEnumerable<Mapping> collection = from l in distinctFilteredFaces orderby l.Mapping?.MappingFromItem.MinimumDateTime descending select l.Mapping;
results = (from l in collection where l is not null select l).ToArray();
return results;
}
public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, Face[] selectedFilteredFaces)
public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, Face[] distinctFilteredFaces)
{
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
string message = $") {selectedFilteredFaces.Length:000} Load Face Encoding - {totalSeconds} total second(s)";
string message = $") {distinctFilteredFaces.Length:000} Load Face Encoding - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(selectedFilteredFaces.Length, message, options);
_ = Parallel.For(0, selectedFilteredFaces.Length, parallelOptions, (i, state) =>
using ProgressBar progressBar = new(distinctFilteredFaces.Length, message, options);
_ = Parallel.For(0, distinctFilteredFaces.Length, parallelOptions, (i, state) =>
{
Face face = selectedFilteredFaces[i];
Face face = distinctFilteredFaces[i];
if (face.FaceEncoding is null || face.Mapping is null)
throw new NotSupportedException();
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)

View File

@ -327,12 +327,14 @@ public partial class DlibDotNet
private static Map.Models.Configuration Get(Models.Configuration configuration, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension)
{
Map.Models.Configuration result = new(
configuration.FaceDistanceHiddenImageFactor,
configuration.FaceDistancePermyriad,
configuration.FaceDistanceTolerance,
configuration.MappingDefaultName,
configuration.PersonBirthdayFirstYear,
configuration.PersonBirthdayFormat,
configuration.SortingDaysDeltaTolerance,
configuration.SortingMaximumPerKey,
configuration.SortingMinimumToUseSigma,
facesFileNameExtension,
facesHiddenFileNameExtension,
facePartsFileNameExtension);
@ -833,9 +835,27 @@ public partial class DlibDotNet
}
}
private List<Shared.Models.Face> SetMappingThenGetDistinctFilteredFacesWithMapping(string argZero, Container[] containers)
private bool IsIgnoreRelativePath(string directory)
{
List<Shared.Models.Face> results = new();
bool result = false;
string? checkDirectory = Path.GetFullPath(directory);
for (int i = 0; i < int.MaxValue; i++)
{
if (_Configuration.IgnoreRelativePaths.Contains(Path.GetFileName(checkDirectory)))
{
result = true;
break;
}
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == _Configuration.PropertyConfiguration.RootDirectory)
break;
}
return result;
}
private Shared.Models.Face[] SetMappingThenGetDistinctFilteredFacesWithMapping(string argZero, Container[] containers)
{
Shared.Models.Face[] results;
Mapping mapping;
int areaPermille;
bool? isWrongYear;
@ -846,12 +866,15 @@ public partial class DlibDotNet
MappingFromItem mappingFromItem;
MappingFromPerson mappingFromPerson;
MappingFromLocation mappingFromLocation;
List<Shared.Models.Face> collection = new();
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
if (_Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && IsIgnoreRelativePath(container.SourceDirectory))
continue;
filteredItems = GetFilterItems(container);
if (!filteredItems.Any())
continue;
@ -877,10 +900,11 @@ public partial class DlibDotNet
mappingFromLocation = new(areaPermille, face.Location.Confidence, deterministicHashCodeKey, normalizedPixelPercentage);
mapping = new(mappingFromItem, mappingFromLocation, mappingFromPerson);
face.SetMapping(mapping);
results.Add(face);
collection.Add(face);
}
}
}
results = (from l in collection orderby l.Mapping?.MappingFromItem.Id select l).ToArray();
return results;
}
@ -889,9 +913,8 @@ public partial class DlibDotNet
int? useFiltersCounter = null;
SortingContainer[] sortingContainers;
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
List<Shared.Models.Face> distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
Shared.Models.Face[] selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(distinctFilteredFaces);
E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, selectedFilteredFaces);
Shared.Models.Face[] distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
Mapping[] mappingCollection = E_Distance.GetSelectedMappingCollection(distinctFilteredFaces);
MapLogic mapLogic = new(
_AppSettings.MaxDegreeOfParallelism,
_Configuration.PropertyConfiguration,
@ -900,29 +923,30 @@ public partial class DlibDotNet
personContainers,
a2PeopleSingletonDirectory,
eDistanceContentDirectory,
distinctFilteredFaces,
mappingCollection,
_Distance);
mapLogic.CopyManualFiles(dFacesContentDirectory, distinctFilteredFaces);
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
mapLogic.CopyManualFiles(dFacesContentDirectory, mappingCollection);
int totalNotMapped = mapLogic.AddToMapping(mappingCollection);
if (_Configuration.MappingSaveMapped)
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, totalNotMapped);
sortingContainers = _Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, selectedFilteredFaces, useFiltersCounter);
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, totalNotMapped);
E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces);
sortingContainers = _Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, distinctFilteredFaces, useFiltersCounter);
if (!sortingContainers.Any())
{
for (useFiltersCounter = 1; useFiltersCounter < 11; useFiltersCounter++)
{
sortingContainers = _Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, selectedFilteredFaces, useFiltersCounter);
sortingContainers = _Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, distinctFilteredFaces, useFiltersCounter);
if (sortingContainers.Any())
break;
}
}
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
if (totalNotMapped > 0)
mapLogic.ForceSingleImageThenSaveSorting(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, sortingContainers, useFiltersCounter, totalNotMapped);
mapLogic.ForceSingleImageThenSaveSorting(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, sortingContainers, useFiltersCounter, totalNotMapped);
if (_Configuration.MappingSaveNotMapped)
mapLogic.SaveNotMappedTicks();
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
mapLogic.SaveShortcuts(_Configuration.JuliePhares, distinctFilteredFaces);
mapLogic.SaveShortcuts(_Configuration.JuliePhares, mappingCollection);
}
private static Container? AreAllSameEndsWith(string argZero, Container[] containers)

View File

@ -73,7 +73,7 @@ public class Configuration
[Display(Name = "Sorting Days Delta Tolerance"), Required] public int? SortingDaysDeltaTolerance { get; set; }
[Display(Name = "SortingMaximumPerFaceShould be High"), Required] public int? SortingMaximumPerFaceShouldBeHigh { get; set; }
[Display(Name = "Sorting Maximum Per Key"), Required] public int? SortingMaximumPerKey { get; set; }
[Display(Name = "Sorting Sigma"), Required] public int? SortingSigma { get; set; }
[Display(Name = "Sorting Minimum to use Sigma"), Required] public int? SortingMinimumToUseSigma { get; set; }
[Display(Name = "Test Distance Results"), Required] public bool? TestDistanceResults { get; set; }
[Display(Name = "Valid Resolutions"), Required] public string[] ValidResolutions { get; set; }
@ -202,8 +202,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.SortingMaximumPerFaceShouldBeHigh));
if (configuration.SortingMaximumPerKey is null)
throw new NullReferenceException(nameof(configuration.SortingMaximumPerKey));
if (configuration.SortingSigma is null)
throw new NullReferenceException(nameof(configuration.SortingSigma));
if (configuration.SortingMinimumToUseSigma is null)
throw new NullReferenceException(nameof(configuration.SortingMinimumToUseSigma));
if (configuration.TestDistanceResults is null)
throw new NullReferenceException(nameof(configuration.TestDistanceResults));
if (configuration.ValidResolutions is null)
@ -216,6 +216,7 @@ public class Configuration
configuration.SaveFaceLandmarkForOutputResolutions = Array.Empty<string>();
if (configuration.SaveShortcutsForOutputResolutions is null)
configuration.SaveShortcutsForOutputResolutions = Array.Empty<string>();
_ = DateTime.Now.AddDays(-configuration.SortingDaysDeltaTolerance.Value);
result = new(configuration.PropertyConfiguration,
configuration.CheckDFaceAndUpWriteDates.Value,
configuration.CheckJsonForDistanceResults.Value,
@ -279,7 +280,7 @@ public class Configuration
configuration.SortingDaysDeltaTolerance.Value,
configuration.SortingMaximumPerFaceShouldBeHigh.Value,
configuration.SortingMaximumPerKey.Value,
configuration.SortingSigma.Value,
configuration.SortingMinimumToUseSigma.Value,
configuration.TestDistanceResults.Value,
configuration.ValidResolutions);
return result;

View File

@ -71,7 +71,7 @@ public class Configuration
public int SortingDaysDeltaTolerance { init; get; }
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
public int SortingMaximumPerKey { init; get; }
public int SortingSigma { init; get; }
public int SortingMinimumToUseSigma { init; get; }
public bool TestDistanceResults { init; get; }
public string[] ValidResolutions { init; get; }
@ -206,7 +206,7 @@ public class Configuration
SortingDaysDeltaTolerance = sortingDaysDeltaTolerance;
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
SortingMaximumPerKey = sortingMaximumPerKey;
SortingSigma = sortingSigma;
SortingMinimumToUseSigma = sortingSigma;
TestDistanceResults = testDistanceResults;
ValidResolutions = validResolutions;
}

View File

@ -57,7 +57,7 @@ internal class F_Random
File.Delete(file);
foreach (KeyValuePair<string, string> keyValuePair in fileKeyValuePairs)
{
if (!(from l in _Configuration.IgnoreRelativePaths where keyValuePair.Key.Contains(l) && IsIgnoreRelativePath(keyValuePair.Key) select true).Any())
if (!_Configuration.IgnoreRelativePaths.Any(l => keyValuePair.Key.Contains(l)) || !IsIgnoreRelativePath(keyValuePair.Key))
relativePaths.Add(keyValuePair.Value);
else
ignoreRelativePaths.Add(keyValuePair.Value);

View File

@ -119,7 +119,7 @@
"SortingDaysDeltaTolerance": 700,
"SortingMaximumPerFaceShouldBeHigh": 1000,
"SortingMaximumPerKey": 7,
"SortingSigma": 3,
"SortingMinimumToUseSigma": 10,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
@ -546,7 +546,66 @@
"Trip to Colorado 10 2002",
"Trip to Colorado June 2002",
"Tub 2002",
"Vericruz 2011"
"Vericruz 2011",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz GrandPrix",
"zzz Motorcycles",
"zzz Motorcycles",
"zzz Motorcycles",
"zzz Parents Yard",
"zzz Phares Family Pictures",
"zzz Phares Slides ####",
"zzz Portrait Innovations April",
"zzz Portrait Innovations Files",
"zzz Portrait Innovations June",
"zzz Portrait Innovations March",
"zzz Rex Memorial ####",
"zzz Scanned Grandma's Quilt ####",
"zzz Scanned Pictures Of Kids ####",
"zzz Scanned Prints ####",
"zzz Slide in Name Order Originals (622) ####",
"zzz Tub",
"zzz Vericruz"
]
}
}

View File

@ -117,7 +117,7 @@
"SortingDaysDeltaTolerance": 700,
"SortingMaximumPerFaceShouldBeHigh": 1000,
"SortingMaximumPerKey": 7,
"SortingSigma": 3,
"SortingMinimumToUseSigma": 10,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [

View File

@ -117,7 +117,7 @@
"SortingDaysDeltaTolerance": 700,
"SortingMaximumPerFaceShouldBeHigh": 1000,
"SortingMaximumPerKey": 7,
"SortingSigma": 3,
"SortingMinimumToUseSigma": 10,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [

View File

@ -11,7 +11,9 @@ public class Configuration
public string MappingDefaultName { init; get; }
public int PersonBirthdayFirstYear { init; get; }
public string PersonBirthdayFormat { init; get; }
public int SortingDaysDeltaTolerance { init; get; }
public int SortingMaximumPerKey { init; get; }
public int SortingMinimumToUseSigma { init; get; }
public string FacesFileNameExtension { init; get; }
public string FacePartsFileNameExtension { init; get; }
public string FacesHiddenFileNameExtension { init; get; }
@ -22,7 +24,9 @@ public class Configuration
string mappingDefaultName,
int personBirthdayFirstYear,
string personBirthdayFormat,
int sortingDaysDeltaTolerance,
int sortingMaximumPerKey,
int sortingMinimumToUseSigma,
string facesFileNameExtension,
string facesHiddenFileNameExtension,
string facePartsFileNameExtension)
@ -34,6 +38,8 @@ public class Configuration
FaceDistanceTolerance = faceDistanceTolerance;
FacesFileNameExtension = facesFileNameExtension;
PersonBirthdayFirstYear = personBirthdayFirstYear;
SortingMinimumToUseSigma = sortingMinimumToUseSigma;
SortingDaysDeltaTolerance = sortingDaysDeltaTolerance;
FacePartsFileNameExtension = facePartsFileNameExtension;
FacesHiddenFileNameExtension = facesHiddenFileNameExtension;
}

View File

@ -25,7 +25,7 @@ public class MapLogic
private readonly Configuration? _Configuration;
private readonly string _EDistanceContentTicksDirectory;
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? faceDistance)
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, Mapping[] mappingCollection, Shared.Models.Methods.IFaceDistance? faceDistance)
{
_Ticks = ticks;
_Configuration = configuration;
@ -65,7 +65,7 @@ public class MapLogic
personContainerCollection,
a2PeopleSingletonDirectory,
eDistanceContentDirectory,
distinctFilteredFaces,
mappingCollection,
faceDistance,
personKeyToPersonContainer,
personKeyToRanges,
@ -96,7 +96,7 @@ public class MapLogic
}
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) :
this(maxDegreeOfParallelism, propertyConfiguration, configuration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, new(), null)
this(maxDegreeOfParallelism, propertyConfiguration, configuration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, Array.Empty<Mapping>(), null)
{ }
public override string ToString()
@ -105,7 +105,7 @@ public class MapLogic
return result;
}
public int AddToMapping(List<Face> distinctFilteredFaces)
public int AddToMapping(Mapping[] mappingCollection)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -117,16 +117,14 @@ public class MapLogic
int by = Stateless.IMapLogic.Mapping;
List<PersonContainer> personContainers = new();
Dictionary<int, PersonContainer[]>? keyValuePairs;
foreach (Face face in distinctFilteredFaces)
foreach (Mapping mapping in mappingCollection)
{
personContainers.Clear();
if (face.Mapping is null)
throw new NotSupportedException();
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(face.Mapping.MappingFromItem.Id, out keyValuePairs))
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out keyValuePairs))
result += 1;
else
{
if (!keyValuePairs.TryGetValue(face.Mapping.MappingFromLocation.NormalizedPixelPercentage, out collection))
if (!keyValuePairs.TryGetValue(mapping.MappingFromLocation.NormalizedPixelPercentage, out collection))
result += 1;
else
personContainers.AddRange(collection);
@ -136,8 +134,8 @@ public class MapLogic
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem);
face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem);
mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
}
}
return result;
@ -217,14 +215,14 @@ public class MapLogic
}
}
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> distinctFilteredFaces, int totalNotMapped)
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, int totalNotMapped)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int? updated = null;
int? useFiltersCounter = null;
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Stateless.IMapLogic.Mapping));
List<SaveContainer> saveContainers = Stateless.MapLogic.GetMappingSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, useFiltersCounter, saveMapped: true);
List<SaveContainer> saveContainers = Stateless.MapLogic.GetSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, useFiltersCounter, saveMapped: true);
SaveContainers(totalNotMapped, updated, saveContainers);
if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory);
@ -324,12 +322,11 @@ public class MapLogic
const int zero = 0;
string mappingSegmentB;
string personKeyFormatted;
List<Mapping> checkCollection;
PersonBirthday personBirthday;
PersonContainer[] personContainers;
const int by = Stateless.IMapLogic.Sorting;
List<int> normalizedPixelPercentageCollection;
Dictionary<string, List<Mapping>> checkKeyValuePairs = new();
Dictionary<string, int> checkKeyValuePairs = new();
Dictionary<int, List<int>> idToNormalizedPixelPercentageCollection = new();
Dictionary<int, PersonContainer[]>? normalizedPixelPercentageToPersonContainers;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
@ -339,16 +336,16 @@ public class MapLogic
foreach (SortingContainer sortingContainer in sortingContainers)
{
progressBar.Tick();
if (sortingContainer.Face.Mapping is null)
if (sortingContainer.Mapping is null)
throw new NotSupportedException();
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(sortingContainer.Sorting.Id, out normalizedPixelPercentageToPersonContainers))
throw new NotSupportedException();
if (!normalizedPixelPercentageToPersonContainers.ContainsKey(sortingContainer.Sorting.NormalizedPixelPercentage))
throw new NotSupportedException();
if (!idToNormalizedPixelPercentageCollection.ContainsKey(sortingContainer.Face.Mapping.MappingFromItem.Id))
idToNormalizedPixelPercentageCollection.Add(sortingContainer.Face.Mapping.MappingFromItem.Id, new());
normalizedPixelPercentageCollection = idToNormalizedPixelPercentageCollection[sortingContainer.Face.Mapping.MappingFromItem.Id];
if (normalizedPixelPercentageCollection.Contains(sortingContainer.Face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
if (!idToNormalizedPixelPercentageCollection.ContainsKey(sortingContainer.Mapping.MappingFromItem.Id))
idToNormalizedPixelPercentageCollection.Add(sortingContainer.Mapping.MappingFromItem.Id, new());
normalizedPixelPercentageCollection = idToNormalizedPixelPercentageCollection[sortingContainer.Mapping.MappingFromItem.Id];
if (normalizedPixelPercentageCollection.Contains(sortingContainer.Mapping.MappingFromLocation.NormalizedPixelPercentage))
continue;
personContainers = normalizedPixelPercentageToPersonContainers[sortingContainer.Sorting.NormalizedPixelPercentage];
foreach (PersonContainer personContainer in personContainers)
@ -357,16 +354,16 @@ public class MapLogic
continue;
personBirthday = personContainer.Birthdays[zero];
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, sortingContainer.Face.Mapping.MappingFromItem);
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, sortingContainer.Mapping.MappingFromItem);
key = string.Concat(personKeyFormatted, '\t', mappingSegmentB);
if (!checkKeyValuePairs.ContainsKey(key))
checkKeyValuePairs.Add(key, new());
checkCollection = checkKeyValuePairs[key];
if (checkCollection.Count > _Configuration.SortingMaximumPerKey)
checkKeyValuePairs[key]++;
if (checkKeyValuePairs[key] > _Configuration.SortingMaximumPerKey)
continue;
normalizedPixelPercentageCollection.Add(sortingContainer.Face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
sortingContainer.Face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
checkCollection.Add(sortingContainer.Face.Mapping);
normalizedPixelPercentageCollection.Add(sortingContainer.Mapping.MappingFromLocation.NormalizedPixelPercentage);
sortingContainer.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
sortingContainer.Mapping.SetSortingContainer(sortingContainer);
result += 1;
break;
}
@ -374,7 +371,7 @@ public class MapLogic
return result;
}
internal void ForceSingleImage(IEnumerable<Face> distinctFilteredFaces)
internal void ForceSingleImage(Mapping[] mappingCollection)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -384,16 +381,14 @@ public class MapLogic
List<int>? normalizedPixelPercentages;
int by = Stateless.IMapLogic.ForceSingleImage;
string displayDirectoryName = _Configuration.MappingDefaultName;
Face[] orderedDistinctFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromLocation.Confidence descending select l).ToArray();
foreach (Face face in orderedDistinctFilteredFaces)
Mapping[] mappingCollectionOrderedConfidence = (from l in mappingCollection orderby l.MappingFromLocation.Confidence descending select l).ToArray();
foreach (Mapping mapping in mappingCollectionOrderedConfidence)
{
if (face.Mapping is null)
throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.PersonBirthday is not null)
if (mapping.MappingFromPerson.PersonBirthday is not null)
continue;
if (_SkipCollection.TryGetValue(face.Mapping.MappingFromItem.Id, out normalizedPixelPercentages))
if (_SkipCollection.TryGetValue(mapping.MappingFromItem.Id, out normalizedPixelPercentages))
{
if (normalizedPixelPercentages.Contains(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
if (normalizedPixelPercentages.Contains(mapping.MappingFromLocation.NormalizedPixelPercentage))
continue;
}
foreach (PersonContainer personContainer in _NotMappedPersonContainers)
@ -401,15 +396,15 @@ public class MapLogic
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, face.Mapping.MappingFromItem);
face.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem);
mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
break;
}
break;
}
}
public void ForceSingleImageThenSaveSorting(string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> distinctFilteredFaces, SortingContainer[] sortingContainers, int? useFiltersCounter, int totalNotMapped)
public void ForceSingleImageThenSaveSorting(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, SortingContainer[] sortingContainers, int? useFiltersCounter, int totalNotMapped)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -418,25 +413,25 @@ public class MapLogic
if (!sortingContainers.Any())
{
updated = 0;
ForceSingleImage(distinctFilteredFaces);
saveContainers = Stateless.MapLogic.GetMappingSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, useFiltersCounter, saveMapped: false);
ForceSingleImage(mappingCollection);
saveContainers = Stateless.MapLogic.GetSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, useFiltersCounter, saveMapped: false);
}
else
{
updated = UpdateFromSortingContainers(sortingContainers);
if (useFiltersCounter is null && totalNotMapped - updated > 0)
ForceSingleImage(distinctFilteredFaces);
saveContainers = Stateless.MapLogic.GetMappingSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces, useFiltersCounter, saveMapped: false);
ForceSingleImage(mappingCollection);
saveContainers = Stateless.MapLogic.GetSaveContainers(_Configuration, _EDistanceContentTicksDirectory, dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, useFiltersCounter, saveMapped: false);
}
SaveContainers(totalNotMapped, updated, saveContainers);
}
public void CopyManualFiles(string dFacesContentDirectory, List<Face> distinctFilteredFaces)
public void CopyManualFiles(string dFacesContentDirectory, Mapping[] mappingCollection)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int? id;
Face face;
Mapping mapping;
string faceFile;
string checkFile;
string directory;
@ -456,9 +451,9 @@ public class MapLogic
WindowsShortcut windowsShortcut;
Dictionary<int, PersonContainer[]>? keyValuePairs;
string by = nameof(Stateless.IMapLogic.ManualCopy);
Dictionary<int, Face>? normalizedPixelPercentageToFace;
Dictionary<int, Mapping>? normalizedPixelPercentageToMapping;
string successfull = $"_ {nameof(Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title)} Successfull";
Dictionary<int, Dictionary<int, Face>> idToNormalizedPixelPercentageToFace = Stateless.MapLogic.GetKeyValuePairs(distinctFilteredFaces);
Dictionary<int, Dictionary<int, Mapping>> idToNormalizedPixelPercentageToFace = Stateless.MapLogic.GetKeyValuePairs(mappingCollection);
foreach (KeyValuePair<long, PersonContainer> keyValuePair in _PersonKeyToPersonContainer)
{
if (keyValuePair.Value.Key is null || keyValuePair.Value.Birthdays is null || !keyValuePair.Value.Birthdays.Any())
@ -485,21 +480,19 @@ public class MapLogic
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, keyValuePair.Value.ApproximateYears, fileInfo.CreationTime, isWrongYear: null);
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mappingSegmentB);
personDirectory = Path.Combine(directory, keyValuePair.Value.DisplayDirectoryName, "lnk");
if (!idToNormalizedPixelPercentageToFace.TryGetValue(id.Value, out normalizedPixelPercentageToFace))
if (!idToNormalizedPixelPercentageToFace.TryGetValue(id.Value, out normalizedPixelPercentageToMapping))
continue;
if (!normalizedPixelPercentageToFace.ContainsKey(normalizedPixelPercentage.Value))
if (!normalizedPixelPercentageToMapping.ContainsKey(normalizedPixelPercentage.Value))
continue;
face = idToNormalizedPixelPercentageToFace[id.Value][normalizedPixelPercentage.Value];
if (face.Mapping is null)
throw new NotSupportedException();
mapping = idToNormalizedPixelPercentageToFace[id.Value][normalizedPixelPercentage.Value];
if (string.IsNullOrEmpty(personDisplayDirectory))
throw new NotSupportedException();
directoryName = Path.GetDirectoryName(face.RelativePath);
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
if (string.IsNullOrEmpty(directoryName))
throw new NotSupportedException();
shortcutFile = Path.Combine(personDisplayDirectory, $"{personDisplayFileName}.lnk");
facesDirectory = Path.Combine($"{dFacesContentDirectory}{directoryName}", face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
faceFileName = $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}";
facesDirectory = Path.Combine($"{dFacesContentDirectory}{directoryName}", mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
faceFileName = $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}";
checkFile = Path.Combine(directory, fileInfo.Name);
if (!Directory.Exists(personDirectory))
_ = Directory.CreateDirectory(personDirectory);
@ -522,7 +515,7 @@ public class MapLogic
windowsShortcut.Dispose();
if (!File.Exists(shortcutFile))
continue;
File.SetLastWriteTime(shortcutFile, face.Mapping.MappingFromItem.MinimumDateTime);
File.SetLastWriteTime(shortcutFile, mapping.MappingFromItem.MinimumDateTime);
}
}
}
@ -553,11 +546,11 @@ public class MapLogic
SaveContainers(totalNotMapped, updated, saveContainers);
}
private List<(Face, List<(string?, string, string?, string?, string)>)> GetCollection(List<Face> distinctFilteredFaces)
private List<(Mapping, List<(string?, string, string?, string?, string)>)> GetCollection(Mapping[] mappingCollection)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<(Face, List<(string?, string, string?, string?, string)>)> results = new();
List<(Mapping, List<(string?, string, string?, string?, string)>)> results = new();
int years;
string directory;
TimeSpan? timeSpan;
@ -572,29 +565,27 @@ public class MapLogic
PersonContainer[] personContainers;
Dictionary<int, PersonContainer[]>? idToPersonContainers;
List<(string?, string, string?, string?, string)> collection;
foreach (Face face in distinctFilteredFaces)
foreach (Mapping mapping in mappingCollection)
{
if (face.Mapping is null)
throw new NotSupportedException();
collection = new();
copyFileName = null;
copyDirectory = null;
relativePath = Path.GetDirectoryName($"C:{face.RelativePath}");
relativePath = Path.GetDirectoryName($"C:{mapping.MappingFromItem.RelativePath}");
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
continue;
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(face.Mapping.MappingFromItem.Id, out idToPersonContainers))
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out idToPersonContainers))
{
directory = Path.Combine(_EDistanceContentTicksDirectory, $"Unnamed{relativePath[2..]}");
shortcutFileName = Path.Combine(directory, $"{face.Mapping.MappingFromItem.Id}.lnk");
shortcutFileName = Path.Combine(directory, $"{mapping.MappingFromItem.Id}.lnk");
collection.Add(new(null, directory, copyDirectory, copyFileName, shortcutFileName));
}
else
{
if (!idToPersonContainers.ContainsKey(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
if (!idToPersonContainers.ContainsKey(mapping.MappingFromLocation.NormalizedPixelPercentage))
continue;
isWrongYearFlag = IItem.GetWrongYearFlag(face.Mapping.MappingFromItem.IsWrongYear);
subDirectoryName = $"{isWrongYearFlag}{face.Mapping.MappingFromItem.MinimumDateTime:yyyy}";
personContainers = idToPersonContainers[face.Mapping.MappingFromLocation.NormalizedPixelPercentage];
isWrongYearFlag = IItem.GetWrongYearFlag(mapping.MappingFromItem.IsWrongYear);
subDirectoryName = $"{isWrongYearFlag}{mapping.MappingFromItem.MinimumDateTime:yyyy}";
personContainers = idToPersonContainers[mapping.MappingFromLocation.NormalizedPixelPercentage];
foreach (PersonContainer personContainer in personContainers)
{
if (personContainers.Length != 1)
@ -603,7 +594,7 @@ public class MapLogic
continue;
foreach (PersonBirthday personBirthday in personContainer.Birthdays)
{
timeSpan = IPersonBirthday.GetTimeSpan(face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromItem.IsWrongYear, personBirthday);
timeSpan = IPersonBirthday.GetTimeSpan(mapping.MappingFromItem.MinimumDateTime, mapping.MappingFromItem.IsWrongYear, personBirthday);
if (timeSpan.HasValue)
{
if (timeSpan.Value.Ticks < 0)
@ -616,12 +607,9 @@ public class MapLogic
}
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
directory = Path.Combine(_EDistanceContentTicksDirectory, "Shortcuts", personKeyFormatted, subDirectoryName);
if (face.FaceEncoding is not null)
copyDirectory = Path.Combine(_EDistanceContentTicksDirectory, "Images", personKeyFormatted, subDirectoryName);
else
copyDirectory = Path.Combine(_EDistanceContentTicksDirectory, "ImagesBut", personKeyFormatted, subDirectoryName);
copyFileName = Path.Combine(copyDirectory, $"{face.Mapping.MappingFromItem.Id}{face.Mapping.MappingFromItem.ResizedFileHolder.ExtensionLowered}");
shortcutFileName = Path.Combine(directory, $"{face.Mapping.MappingFromItem.Id}.lnk");
copyDirectory = Path.Combine(_EDistanceContentTicksDirectory, "Images", personKeyFormatted, subDirectoryName);
copyFileName = Path.Combine(copyDirectory, $"{mapping.MappingFromItem.Id}{mapping.MappingFromItem.ResizedFileHolder.ExtensionLowered}");
shortcutFileName = Path.Combine(directory, $"{mapping.MappingFromItem.Id}.lnk");
collection.Add(new(personKeyFormatted, directory, copyDirectory, copyFileName, shortcutFileName));
}
}
@ -630,28 +618,26 @@ public class MapLogic
copyFileName = null;
copyDirectory = null;
directory = Path.Combine(_EDistanceContentTicksDirectory, $"Not Supported{relativePath[2..]}", subDirectoryName);
shortcutFileName = Path.Combine(directory, $"{face.Mapping.MappingFromItem.Id}.lnk");
shortcutFileName = Path.Combine(directory, $"{mapping.MappingFromItem.Id}.lnk");
collection.Add(new(null, directory, copyDirectory, copyFileName, shortcutFileName));
}
}
results.Add(new(face, collection));
results.Add(new(mapping, collection));
}
return results;
}
public void SaveShortcuts(string[] juliePhares, List<Face> distinctFilteredFaces)
public void SaveShortcuts(string[] juliePhares, Mapping[] mappingCollection)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<(Face, List<(string?, string, string?, string?, string)>)> facesToCollection = GetCollection(distinctFilteredFaces);
foreach ((Face face, List<(string? PersonKeyFormatted, string, string?, string?, string)> collection) in facesToCollection)
List<(Mapping, List<(string?, string, string?, string?, string)>)> facesToCollection = GetCollection(mappingCollection);
foreach ((Mapping mapping, List<(string? PersonKeyFormatted, string, string?, string?, string)> collection) in facesToCollection)
{
if (collection.Any(l => l.PersonKeyFormatted is not null and "1501-04-10_00"))
continue;
foreach ((string? personKeyFormatted, string directory, string? copyDirectory, string? copyFileName, string _) in collection)
{
if (face.Mapping is null)
throw new NotSupportedException();
if (personKeyFormatted is null)
continue;
if (!Directory.Exists(directory))
@ -663,7 +649,7 @@ public class MapLogic
if (!Directory.Exists(copyDirectory))
_ = Directory.CreateDirectory(copyDirectory);
if (!File.Exists(copyFileName))
File.Copy(face.Mapping.MappingFromItem.ResizedFileHolder.FullName, copyFileName);
File.Copy(mapping.MappingFromItem.ResizedFileHolder.FullName, copyFileName);
break;
}
}

View File

@ -240,7 +240,7 @@ internal abstract class MapLogic
return results.ToArray();
}
private static void SetKeyValuePairs(Configuration configuration, long ticks, List<PersonContainer> personContainers, List<Face> distinctFilteredFaces, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges)
private static void SetKeyValuePairs(Configuration configuration, long ticks, List<PersonContainer> personContainers, Mapping[] mappingCollection, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges)
{
PersonBirthday? personBirthday;
PersonContainer[] distinctPersonContainers;
@ -288,7 +288,7 @@ internal abstract class MapLogic
idThenNormalizedPixelPercentageToPersonContainers[keyValuePair.Key].Add(innerKeyValuePair.Key, distinctPersonContainers);
}
};
SetPersonTicks(ticks, distinctFilteredFaces, personKeyToRanges, idThenNormalizedPixelPercentageToPersonContainers);
SetPersonTicks(configuration, ticks, mappingCollection, personKeyToRanges, idThenNormalizedPixelPercentageToPersonContainers);
if (incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection.Any())
{
PersonContainer personContainer;
@ -346,20 +346,18 @@ internal abstract class MapLogic
return results;
}
private static (int, int) SetCollectionsAndGetUnableToMatchCount(Configuration configuration, long ticks, Dictionary<int, List<Face>> idToFaces, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, string[], string)> collection)
private static (int, int) SetCollectionsAndGetUnableToMatchCount(Configuration configuration, long ticks, Dictionary<int, List<Mapping>> idToMappingCollection, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, string[], string)> collection)
{
int result = 0;
int? id;
bool debugCheck;
List<Face>? faces;
List<int> debugChecks = new();
List<Face> checkFaces = new();
int? normalizedPixelPercentage;
string newestPersonKeyFormatted;
List<Mapping>? mappingCollection;
string personDisplayDirectoryName;
bool idToFacesAny = idToFaces.Any();
List<int> normalizedPixelPercentages;
List<Mapping> checkMappingCollection = new();
List<string> duplicateMappedFaceFiles = new();
bool idToMappingCollectionAny = idToMappingCollection.Any();
Dictionary<int, List<int>> idToNormalizedPixelPercentages = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {collection.Count:000} join from ticks Director(ies) - C - {totalSeconds} total second(s)";
@ -368,11 +366,7 @@ internal abstract class MapLogic
foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection)
{
progressBar.Tick();
(id, normalizedPixelPercentage, faces) = IMapping.GetReversedDeterministicHashCodeKey(
configuration.FacesFileNameExtension,
idToFacesAny,
idToFaces,
mappedFaceFile);
(id, normalizedPixelPercentage, mappingCollection) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, mappedFaceFile);
if (id is null || normalizedPixelPercentage is null)
{
result++;
@ -381,37 +375,29 @@ internal abstract class MapLogic
if (!idToNormalizedPixelPercentages.ContainsKey(id.Value))
idToNormalizedPixelPercentages.Add(id.Value, new());
normalizedPixelPercentages = idToNormalizedPixelPercentages[id.Value];
if (faces is null)
if (mappingCollection is null)
{
result++;
continue;
}
debugCheck = false;
checkFaces.Clear();
debugChecks.Clear();
foreach (Face face in faces)
checkMappingCollection.Clear();
foreach (Mapping mapping in mappingCollection)
{
if (face.Mapping is null)
throw new NotSupportedException();
debugChecks.Add(face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
if (normalizedPixelPercentage.Value != face.Mapping.MappingFromLocation.NormalizedPixelPercentage)
if (normalizedPixelPercentage.Value != mapping.MappingFromLocation.NormalizedPixelPercentage)
continue;
if (normalizedPixelPercentages.Contains(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
if (normalizedPixelPercentages.Contains(mapping.MappingFromLocation.NormalizedPixelPercentage))
{
duplicateMappedFaceFiles.Add(mappedFaceFile);
continue;
}
debugCheck = true;
checkFaces.Add(face);
if (!debugCheck)
debugChecks.Add(face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
checkMappingCollection.Add(mapping);
}
if (!checkFaces.Any())
if (!checkMappingCollection.Any())
{
result++;
continue;
}
if (checkFaces.Count != 1)
if (checkMappingCollection.Count != 1)
{
result++;
continue;
@ -447,7 +433,7 @@ internal abstract class MapLogic
return result;
}
private static void SetPersonKeysRanges(long ticks, Dictionary<long, List<long>> personTicks, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges)
private static void SetPersonKeysRanges(Configuration configuration, long ticks, Dictionary<long, List<long>> personKeyToMinimumDateTimeTicks, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges)
{
long lcl;
long ucl;
@ -456,13 +442,13 @@ internal abstract class MapLogic
double average;
long[] collection;
double standardDeviation;
foreach (KeyValuePair<long, List<long>> keyValuePair in personTicks)
foreach (KeyValuePair<long, List<long>> keyValuePair in personKeyToMinimumDateTimeTicks)
{
minimum = keyValuePair.Value.Min();
if (keyValuePair.Value.Count < 3)
if (keyValuePair.Value.Count < configuration.SortingMinimumToUseSigma)
{
maximum = keyValuePair.Value.Max();
personKeyToRanges.Add(keyValuePair.Key, new(new DateTime(minimum).AddYears(-1).Ticks, minimum, maximum, new DateTime(maximum).AddYears(1).Ticks));
personKeyToRanges.Add(keyValuePair.Key, new(new DateTime(minimum).AddDays(-configuration.SortingDaysDeltaTolerance).Ticks, minimum, maximum, new DateTime(maximum).AddDays(configuration.SortingDaysDeltaTolerance).Ticks));
}
else
{
@ -481,34 +467,32 @@ internal abstract class MapLogic
}
}
private static void SetPersonTicks(long ticks, List<Face> distinctFilteredFaces, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers)
private static void SetPersonTicks(Configuration configuration, long ticks, Mapping[] mappingCollection, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers)
{
PersonContainer[]? personContainers;
Dictionary<int, PersonContainer[]>? keyValuePairs;
Dictionary<long, List<long>> personTicks = new();
Dictionary<long, List<long>> personKeyToMinimumDateTimeTicks = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {distinctFilteredFaces.Count:000} Set Person Ticks - {totalSeconds} total second(s)";
string message = $") {mappingCollection.Length:000} Set Person Ticks - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(distinctFilteredFaces.Count, message, options);
foreach (Face face in distinctFilteredFaces)
using ProgressBar progressBar = new(mappingCollection.Length, message, options);
foreach (Mapping mapping in mappingCollection)
{
progressBar.Tick();
if (face.Mapping is null)
throw new NotSupportedException();
if (!idThenNormalizedPixelPercentageToPersonContainers.TryGetValue(face.Mapping.MappingFromItem.Id, out keyValuePairs))
if (!idThenNormalizedPixelPercentageToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out keyValuePairs))
continue;
if (!keyValuePairs.TryGetValue(face.Mapping.MappingFromLocation.NormalizedPixelPercentage, out personContainers))
if (!keyValuePairs.TryGetValue(mapping.MappingFromLocation.NormalizedPixelPercentage, out personContainers))
continue;
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null)
continue;
if (!personTicks.ContainsKey(personContainer.Key.Value))
personTicks.Add(personContainer.Key.Value, new());
personTicks[personContainer.Key.Value].Add(face.Mapping.MappingFromItem.MinimumDateTime.Ticks);
if (!personKeyToMinimumDateTimeTicks.ContainsKey(personContainer.Key.Value))
personKeyToMinimumDateTimeTicks.Add(personContainer.Key.Value, new());
personKeyToMinimumDateTimeTicks[personContainer.Key.Value].Add(mapping.MappingFromItem.MinimumDateTime.Ticks);
}
}
SetPersonKeysRanges(ticks, personTicks, personKeyToRanges);
SetPersonKeysRanges(configuration, ticks, personKeyToMinimumDateTimeTicks, personKeyToRanges);
}
private static List<PersonContainer> GetNotMappedPersonContainers(Configuration configuration, List<PersonContainer> personContainers, long[] personKeyCollection)
@ -583,7 +567,7 @@ internal abstract class MapLogic
}
}
internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, List<PersonContainer> personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance faceDistance, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers)
internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, List<PersonContainer> personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, Mapping[] mappingCollection, Shared.Models.Methods.IFaceDistance faceDistance, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers)
{
if (configuration is null)
throw new NullReferenceException(nameof(configuration));
@ -592,7 +576,7 @@ internal abstract class MapLogic
List<long> personKeys = new();
List<long?> nullablePersonKeyCollection = new();
List<string> personKeyFormattedCollection = new();
Dictionary<int, List<Face>> keyValuePairs = new();
Dictionary<int, List<Mapping>> idToMappingCollection = new();
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = new();
List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new();
List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection = new();
@ -600,22 +584,18 @@ internal abstract class MapLogic
Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers = new();
SetPersonCollections(configuration, personContainers, personKeys, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection);
personContainers.AddRange(AddToPersonKeysThenGetNonSpecificPeopleCollection(configuration, personKeys));
foreach (Face face in distinctFilteredFaces)
foreach (Mapping mapping in mappingCollection)
{
if (face.FaceEncoding is null || face.Location is null)
throw new NotSupportedException();
if (face.Mapping is null)
throw new NotSupportedException();
if (!keyValuePairs.ContainsKey(face.Mapping.MappingFromItem.Id))
keyValuePairs.Add(face.Mapping.MappingFromItem.Id, new());
keyValuePairs[face.Mapping.MappingFromItem.Id].Add(face);
if (!idToMappingCollection.ContainsKey(mapping.MappingFromItem.Id))
idToMappingCollection.Add(mapping.MappingFromItem.Id, new());
idToMappingCollection[mapping.MappingFromItem.Id].Add(mapping);
}
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message);
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(configuration, ticks, keyValuePairs, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, collection);
SetKeyValuePairs(configuration, ticks, personContainers, distinctFilteredFaces, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, personKeyToPersonContainer, idThenNormalizedPixelPercentageToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, incorrectIdThenNormalizedPixelPercentageToPersonContainers, personKeyToRanges);
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(configuration, ticks, idToMappingCollection, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, collection);
SetKeyValuePairs(configuration, ticks, personContainers, mappingCollection, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, personKeyToPersonContainer, idThenNormalizedPixelPercentageToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, incorrectIdThenNormalizedPixelPercentageToPersonContainers, personKeyToRanges);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") {collection.Count:000} message from ticks Director(ies) - D - {duplicateCount} Duplicate Count {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
@ -674,25 +654,23 @@ internal abstract class MapLogic
return result;
}
internal static Dictionary<int, Dictionary<int, Face>> GetKeyValuePairs(List<Face> distinctFilteredFaces)
internal static Dictionary<int, Dictionary<int, Mapping>> GetKeyValuePairs(Mapping[] mappingCollection)
{
Dictionary<int, Dictionary<int, Face>> results = new();
Dictionary<int, Face> keyValuePairs;
foreach (Face face in distinctFilteredFaces)
Dictionary<int, Dictionary<int, Mapping>> results = new();
Dictionary<int, Mapping> keyValuePairs;
foreach (Mapping mapping in mappingCollection)
{
if (face.Mapping is null)
if (!results.ContainsKey(mapping.MappingFromItem.Id))
results.Add(mapping.MappingFromItem.Id, new());
keyValuePairs = results[mapping.MappingFromItem.Id];
if (keyValuePairs.ContainsKey(mapping.MappingFromLocation.NormalizedPixelPercentage))
throw new NotSupportedException();
if (!results.ContainsKey(face.Mapping.MappingFromItem.Id))
results.Add(face.Mapping.MappingFromItem.Id, new());
keyValuePairs = results[face.Mapping.MappingFromItem.Id];
if (keyValuePairs.ContainsKey(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
throw new NotSupportedException();
keyValuePairs.Add(face.Mapping.MappingFromLocation.NormalizedPixelPercentage, face);
keyValuePairs.Add(mapping.MappingFromLocation.NormalizedPixelPercentage, mapping);
}
return results;
}
internal static List<SaveContainer> GetMappingSaveContainers(Configuration configuration, string eDistanceContentTicksDirectory, string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> filteredFaces, int? useFiltersCounter, bool saveMapped)
internal static List<SaveContainer> GetSaveContainers(Configuration configuration, string eDistanceContentTicksDirectory, string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, int? useFiltersCounter, bool saveMapped)
{
List<SaveContainer> results = new();
string by;
@ -710,33 +688,31 @@ internal abstract class MapLogic
FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder;
string forceSingleImageHumanized = nameof(IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
foreach (Face face in filteredFaces)
foreach (Mapping mapping in mappingCollection)
{
if (face.Mapping is null)
throw new NotSupportedException();
directoryName = Path.GetDirectoryName(face.RelativePath);
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.PersonBirthday is null)
if (mapping.MappingFromPerson.PersonBirthday is null)
continue;
if (string.IsNullOrEmpty(face.Mapping.MappingFromPerson.SegmentB))
if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB))
throw new NotSupportedException();
if (face.Mapping.MappingFromPerson.By is null)
if (mapping.MappingFromPerson.By is null)
{
isByMapping = false;
by = $"{nameof(IMapLogic.Mapping)}Null";
}
else if (useFiltersCounter.HasValue && face.Mapping.MappingFromPerson.By.Value == IMapLogic.Sorting)
else if (useFiltersCounter.HasValue && mapping.MappingFromPerson.By.Value == IMapLogic.Sorting)
{
isByMapping = false;
by = $"{nameof(IMapLogic.Sorting)} Modified Filters - {useFiltersCounter.Value}";
}
else
{
isByMapping = face.Mapping.MappingFromPerson.By == IMapLogic.Mapping;
isByMapping = mapping.MappingFromPerson.By == IMapLogic.Mapping;
if (isByMapping && !saveMapped)
continue;
by = face.Mapping.MappingFromPerson.By.Value switch
by = mapping.MappingFromPerson.By.Value switch
{
IMapLogic.Mapping => nameof(IMapLogic.Mapping),
IMapLogic.Sorting => nameof(IMapLogic.Sorting),
@ -744,31 +720,31 @@ internal abstract class MapLogic
_ => throw new NotImplementedException()
};
}
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, face.Mapping.MappingFromPerson.PersonBirthday);
directory = Path.Combine(eDistanceContentTicksDirectory, by, personKeyFormatted, face.Mapping.MappingFromPerson.SegmentB);
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
directory = Path.Combine(eDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB);
if (isByMapping)
personDirectory = Path.Combine(directory, face.Mapping.MappingFromPerson.DisplayDirectoryName);
else if (face.Mapping.MappingFromPerson.By is not null)
personDirectory = Path.Combine(directory, face.Mapping.MappingFromPerson.DisplayDirectoryName, "lnk");
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
else if (mapping.MappingFromPerson.By is not null)
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, "lnk");
else
personDirectory = Path.Combine(directory, face.Mapping.MappingFromPerson.DisplayDirectoryName[..1], "lnk");
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName[..1], "lnk");
saveContainer = new(personDirectory);
results.Add(saveContainer);
facesDirectory = Path.Combine($"{dFacesContentDirectory}{directoryName}", face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
faceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{configuration.FacesFileNameExtension}"));
facesDirectory = Path.Combine($"{dFacesContentDirectory}{directoryName}", mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
faceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{configuration.FacesFileNameExtension}"));
if (isByMapping)
{
checkFile = Path.Combine(personDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
checkFile = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
saveContainer = new(checkFile, directory, faceFileHolder);
}
else
{
facePartsDirectory = Path.Combine($"{d2FacePartsContentDirectory}{directoryName}", face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
checkFile = Path.Combine(directory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
shortcutFile = Path.Combine(personDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{configuration.FacePartsFileNameExtension}"));
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, face.Mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
facePartsDirectory = Path.Combine($"{d2FacePartsContentDirectory}{directoryName}", mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
shortcutFile = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{configuration.FacePartsFileNameExtension}"));
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
}
results.Add(saveContainer);
}

View File

@ -88,18 +88,25 @@ public class Mapping : Properties.IMapping
{
protected MappingFromPerson _MappingFromPerson;
protected SortingContainer? _SortingContainer;
public MappingFromItem MappingFromItem { init; get; }
public MappingFromLocation MappingFromLocation { init; get; }
public MappingFromPerson MappingFromPerson => _MappingFromPerson;
public SortingContainer? SortingContainer => _SortingContainer;
[JsonConstructor]
public Mapping(MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, MappingFromPerson mappingFromPerson)
public Mapping(MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, MappingFromPerson mappingFromPerson, SortingContainer? sortingContainer)
{
MappingFromItem = mappingFromItem;
MappingFromLocation = mappingFromLocation;
_MappingFromPerson = mappingFromPerson;
_SortingContainer = sortingContainer;
}
public Mapping(MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, MappingFromPerson mappingFromPerson) :
this(mappingFromItem, mappingFromLocation, mappingFromPerson, null)
{ }
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
@ -108,4 +115,6 @@ public class Mapping : Properties.IMapping
public void UpdateMappingFromPerson(int? approximateYears, int? by, string displayDirectoryName, PersonBirthday personBirthday, string segmentB) => _MappingFromPerson = new(approximateYears, by, displayDirectoryName, personBirthday, segmentB);
public void SetSortingContainer(SortingContainer sortingContainer) => _SortingContainer = sortingContainer;
}

View File

@ -39,5 +39,6 @@ public interface IMapping
public MappingFromItem MappingFromItem { init; get; }
public MappingFromLocation MappingFromLocation { init; get; }
public MappingFromPerson MappingFromPerson { get; }
public SortingContainer? SortingContainer { get; }
}

View File

@ -3,7 +3,7 @@ namespace View_by_Distance.Shared.Models.Properties;
public interface ISortingContainer
{
public Face Face { init; get; }
public Mapping Mapping { init; get; }
public Sorting Sorting { init; get; }
}

View File

@ -5,19 +5,19 @@ namespace View_by_Distance.Shared.Models;
public record class SortingContainer : Properties.ISortingContainer
{
public Face Face { init; get; }
public Mapping Mapping { init; get; }
public Sorting Sorting { init; get; }
[JsonConstructor]
public SortingContainer(Face face, Sorting sorting)
public SortingContainer(Mapping mapping, Sorting sorting)
{
Face = face;
Mapping = mapping;
Sorting = sorting;
}
public override string ToString()
{
string result = string.Concat(Face.Mapping?.MappingFromItem.Id, '\t', Face.Mapping?.MappingFromLocation.NormalizedPixelPercentage, '\t', Sorting.Id, '\t', Sorting.NormalizedPixelPercentage, '\t', Sorting.Older, '\t', Sorting.WithinRange, '\t', Sorting.DistancePermyriad, '\t', Sorting.DaysDelta);
string result = string.Concat(Mapping.MappingFromItem.Id, '\t', Mapping.MappingFromLocation.NormalizedPixelPercentage, '\t', Sorting.Id, '\t', Sorting.NormalizedPixelPercentage, '\t', Sorting.Older, '\t', Sorting.WithinRange, '\t', Sorting.DistancePermyriad, '\t', Sorting.DaysDelta);
return result;
}

View File

@ -28,14 +28,14 @@ public interface IMapping
static string GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution)
=> $"{id}.{ILocation.GetLeftPadded(locationDigits, ILocation.GetNormalizedPixelPercentage(location, locationDigits, locationFactor, outputResolution))}";
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(string facesFileNameExtension, string file) =>
(int?, int?, List<Models.Mapping>?) TestStatic_GetReversedDeterministicHashCodeKey(string facesFileNameExtension, string file) =>
GetReversedDeterministicHashCodeKey(facesFileNameExtension, file);
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(string facesFileNameExtension, string file) =>
static (int?, int?, List<Models.Mapping>?) GetReversedDeterministicHashCodeKey(string facesFileNameExtension, string file) =>
Mapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, false, new(), file);
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string file) =>
GetReversedDeterministicHashCodeKey(facesFileNameExtension, idToFacesAny, idToFaces, file);
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string file) =>
Mapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, idToFacesAny, idToFaces, file);
(int?, int?, List<Models.Mapping>?) TestStatic_GetReversedDeterministicHashCodeKey(string facesFileNameExtension, bool idToMappingCollectionAny, Dictionary<int, List<Models.Mapping>> idToMappingCollection, string file) =>
GetReversedDeterministicHashCodeKey(facesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, file);
static (int?, int?, List<Models.Mapping>?) GetReversedDeterministicHashCodeKey(string facesFileNameExtension, bool idToMappingCollectionAny, Dictionary<int, List<Models.Mapping>> idToMappingCollection, string file) =>
Mapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, file);
}

View File

@ -27,55 +27,51 @@ internal abstract class Mapping
return new(id, normalizedPixelPercentage, extensionLowered, needsFacesFileNameExtension);
}
private static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKeysFromSegments(string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string fileName)
private static (int?, int?, List<Models.Mapping>?) GetReversedDeterministicHashCodeKeysFromSegments(string facesFileNameExtension, bool idToMappingCollectionAny, Dictionary<int, List<Models.Mapping>> idToMappingCollection, string fileName)
{
int? id;
List<Models.Face>? faces;
int? normalizedPixelPercentage;
List<Models.Mapping>? mappingCollection;
(string? Id, string? NormalizedPixelPercentage, string? ExtensionLowered, bool? Check) segments = GetSegments(facesFileNameExtension, fileName);
if (string.IsNullOrEmpty(segments.Id) || string.IsNullOrEmpty(segments.NormalizedPixelPercentage) || string.IsNullOrEmpty(segments.ExtensionLowered) || segments.Check is null)
{
id = null;
faces = null;
mappingCollection = null;
normalizedPixelPercentage = null;
}
else if (!int.TryParse(segments.Id, out int idValue) || !int.TryParse(segments.NormalizedPixelPercentage, out int normalizedPixelPercentageValue))
{
id = null;
faces = null;
mappingCollection = null;
normalizedPixelPercentage = null;
}
else
{
id = idValue;
normalizedPixelPercentage = normalizedPixelPercentageValue;
if (!idToFacesAny || !idToFaces.ContainsKey(idValue))
faces = null;
if (!idToMappingCollectionAny || !idToMappingCollection.ContainsKey(idValue))
mappingCollection = null;
else
faces = idToFaces[idValue];
mappingCollection = idToMappingCollection[idValue];
}
return new(id, normalizedPixelPercentage, faces);
return new(id, normalizedPixelPercentage, mappingCollection);
}
internal static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string file)
internal static (int?, int?, List<Models.Mapping>?) GetReversedDeterministicHashCodeKey(string facesFileNameExtension, bool idToMappingCollectionAny, Dictionary<int, List<Models.Mapping>> idToMappingCollection, string file)
{
int? id;
List<Models.Face>? faces;
int? normalizedPixelPercentage;
List<Models.Mapping>? mappingCollection;
string fileName = Path.GetFileName(file);
if (fileName.Length < 2 || fileName[1..].Contains('-'))
{
id = null;
faces = null;
mappingCollection = null;
normalizedPixelPercentage = null;
}
else
(id, normalizedPixelPercentage, faces) = GetReversedDeterministicHashCodeKeysFromSegments(
facesFileNameExtension,
idToFacesAny,
idToFaces,
fileName);
return new(id, normalizedPixelPercentage, faces);
(id, normalizedPixelPercentage, mappingCollection) = GetReversedDeterministicHashCodeKeysFromSegments(facesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, fileName);
return new(id, normalizedPixelPercentage, mappingCollection);
}
internal static int GetAreaPermille(int bottom, int height, int left, int right, int top, int width)

View File

@ -73,7 +73,7 @@ public class Configuration
[Display(Name = "Sorting Days Delta Tolerance"), Required] public int? SortingDaysDeltaTolerance { get; set; }
[Display(Name = "SortingMaximumPerFaceShould be High"), Required] public int? SortingMaximumPerFaceShouldBeHigh { get; set; }
[Display(Name = "Sorting Maximum Per Key"), Required] public int? SortingMaximumPerKey { get; set; }
[Display(Name = "Sorting Sigma"), Required] public int? SortingSigma { get; set; }
[Display(Name = "Sorting Minimum to use Sigma"), Required] public int? SortingMinimumToUseSigma { get; set; }
[Display(Name = "Test Distance Results"), Required] public bool? TestDistanceResults { get; set; }
[Display(Name = "Valid Resolutions"), Required] public string[] ValidResolutions { get; set; }
@ -202,8 +202,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.SortingMaximumPerFaceShouldBeHigh));
if (configuration.SortingMaximumPerKey is null)
throw new NullReferenceException(nameof(configuration.SortingMaximumPerKey));
if (configuration.SortingSigma is null)
throw new NullReferenceException(nameof(configuration.SortingSigma));
if (configuration.SortingMinimumToUseSigma is null)
throw new NullReferenceException(nameof(configuration.SortingMinimumToUseSigma));
if (configuration.TestDistanceResults is null)
throw new NullReferenceException(nameof(configuration.TestDistanceResults));
if (configuration.ValidResolutions is null)
@ -216,6 +216,7 @@ public class Configuration
configuration.SaveFaceLandmarkForOutputResolutions = Array.Empty<string>();
if (configuration.SaveShortcutsForOutputResolutions is null)
configuration.SaveShortcutsForOutputResolutions = Array.Empty<string>();
_ = DateTime.Now.AddDays(-configuration.SortingDaysDeltaTolerance.Value);
result = new(configuration.PropertyConfiguration,
configuration.CheckDFaceAndUpWriteDates.Value,
configuration.CheckJsonForDistanceResults.Value,
@ -279,7 +280,7 @@ public class Configuration
configuration.SortingDaysDeltaTolerance.Value,
configuration.SortingMaximumPerFaceShouldBeHigh.Value,
configuration.SortingMaximumPerKey.Value,
configuration.SortingSigma.Value,
configuration.SortingMinimumToUseSigma.Value,
configuration.TestDistanceResults.Value,
configuration.ValidResolutions);
return result;

View File

@ -71,7 +71,7 @@ public class Configuration
public int SortingDaysDeltaTolerance { init; get; }
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
public int SortingMaximumPerKey { init; get; }
public int SortingSigma { init; get; }
public int SortingMinimumToUseSigma { init; get; }
public bool TestDistanceResults { init; get; }
public string[] ValidResolutions { init; get; }
@ -206,7 +206,7 @@ public class Configuration
SortingDaysDeltaTolerance = sortingDaysDeltaTolerance;
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
SortingMaximumPerKey = sortingMaximumPerKey;
SortingSigma = sortingSigma;
SortingMinimumToUseSigma = sortingSigma;
TestDistanceResults = testDistanceResults;
ValidResolutions = validResolutions;
}