Skip to content

Commit

Permalink
Coherence computation in range.
Browse files Browse the repository at this point in the history
- introduction of additional results => result that is computed after all the com values are computed and all analysis is done.
- the only aditional result is coherence measurement consisting of minHz, maxHz and average value. We can now compute multiple coherance averages in range
- multiple values for coherence, all are saved
- delete values for cohere
- new file on internal save
- extended export for coherenece measurement
  • Loading branch information
tesar-tech committed Jun 27, 2024
1 parent 33fce7d commit b747162
Show file tree
Hide file tree
Showing 13 changed files with 473 additions and 140 deletions.
4 changes: 2 additions & 2 deletions TremAn3.Core/Coherence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public Coherence(double frameRate, List<List<double>> comXAllRois, List<List<dou

}
double frameRate;
private List<List<double>> ComXAllRois { get; set; } = new List<List<double>>();
private List<List<double>> ComYAllRois { get; set; } = new List<List<double>>();
private List<List<double>> ComXAllRois { get; set; }
private List<List<double>> ComYAllRois { get; set; }

public DataResult Compute()
{
Expand Down
26 changes: 25 additions & 1 deletion TremAn3.Core/MeasurementModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public MeasurementModel(IEnumerable<CenterOfMotionAlgorithm> comAlgs)
public VectorsDataModel VectorsDataModel { get; set; }


[JsonIgnore]
public AdditionalResultsModel AdditionalResultsModel { get; set; } = new AdditionalResultsModel();

public double FrameRate { get; set; }
public double Maxrange { get; set; }
Expand All @@ -38,11 +40,15 @@ public MeasurementModel(IEnumerable<CenterOfMotionAlgorithm> comAlgs)
public int FreqProgressSegmnetSize { get; set; }
public int FreqProgressStep { get; set; }

public void GetResults(IEnumerable<CenterOfMotionAlgorithm> algs, Dictionary<DataSeriesType, DataResult> dataResultsDict)
public void GetResults(IEnumerable<CenterOfMotionAlgorithm> algs, Dictionary<DataSeriesType, DataResult> dataResultsDict, AdditionalResultsModel additionalResultsModel)
{
VectorsDataModel = new VectorsDataModel(algs,dataResultsDict);
AdditionalResultsModel = AdditionalResultsModel;
}




//public int FftSegmentSize { get; set; }
}

Expand Down Expand Up @@ -131,4 +137,22 @@ public class ResultsModel
public List<double> ComY { get; private set; } = new List<double>();

}


public class AdditionalResultsModel
{

public List<CoherenceAverageResultModel> CoherenceAverageResults { get; set; } = new List<CoherenceAverageResultModel>();

}

public class CoherenceAverageResultModel
{
public double MinHz { get; set; }
public double MaxHz { get; set; }

public double Average { get; set; }


}
}
4 changes: 4 additions & 0 deletions TremAn3/Helpers/StaticConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ public static double SpectralAnalysisBiggerToggleToSizeOfPlot(bool? IsChecked)

public static string DoubleFormatter(double val) => $"{val:0.00}";

public static string DoubleToStringHz(double val) => $"{val:00.000} Hz ";
public static string DoubleToString3Decimals(double val) => $"{val:00.000}";





Expand Down
53 changes: 37 additions & 16 deletions TremAn3/Services/DataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,22 @@ internal async Task<StorageFile> GetFileByFalToken(string falToken)
return (mruToken, falToken);
}



internal async Task<StorageFolder> SaveMeasurementResults(MeasurementModel measurementModel, VideoFileModel vfm)
{
//resultsViewModel.Id = resultsViewModel.Id == Guid.Empty ? Guid.NewGuid(): resultsViewModel.Id;
var allMeasurementsFolder = await GetFolder_AllMeasurements();
StorageFolder measurementsFolderForVideo = await GetFolderForVideo(allMeasurementsFolder, vfm);
string measurementFolderAndFIleName = $"m_{DateTime.Now:yyyy-MM-dd_HH-mm-ss.ff}_{measurementModel.Id.ToString().Substring(0,8)}";
string measurementFolderAndFIleName = $"m_{DateTime.Now:yyyy-MM-dd_HH-mm-ss.ff}_{measurementModel.Id.ToString().Substring(0, 8)}";
StorageFolder folderForMeasurement = await measurementsFolderForVideo.CreateFolderAsync(measurementFolderAndFIleName, CreationCollisionOption.OpenIfExists);
await SaveMeasurementResults(measurementModel, folderForMeasurement);//csvs will have similar structure of filename
return folderForMeasurement;
return folderForMeasurement;
}






/// <summary>
Expand All @@ -114,21 +114,31 @@ internal async Task<StorageFolder> SaveMeasurementResults(MeasurementModel measu
/// <param name="measurementModel"></param>
/// <param name="folderForMeasurement"></param>
/// <returns></returns>
internal static async Task SaveMeasurementResults(MeasurementModel measurementModel, StorageFolder folderForMeasurement,bool saveOnlyTopLevelData = false)
internal static async Task SaveMeasurementResults(MeasurementModel measurementModel, StorageFolder folderForMeasurement, bool saveOnlyTopLevelData = false)
{
await JsonServices.WriteToJsonFile(folderForMeasurement, GetMeasurementFileName(folderForMeasurement), measurementModel);//saves toplevel
//saves vector data to special folder
if(!saveOnlyTopLevelData)
await JsonServices.WriteToJsonFile(folderForMeasurement, GetMeasurementVectorDataFileName(folderForMeasurement), measurementModel.VectorsDataModel);
if (!saveOnlyTopLevelData)
{
await JsonServices.WriteToJsonFile(folderForMeasurement, GetMeasurementVectorDataFileName(folderForMeasurement), measurementModel.VectorsDataModel);
await SaveAdditionalResults( measurementModel.AdditionalResultsModel, folderForMeasurement);
}
}

private static string GetMeasurementFileName (StorageFolder continerFolder) => $"{continerFolder.Name}.json";
private static string GetVideoModelFileName (StorageFolder videoFolder) => $"{videoFolder.Name}.json";
private static string GetMeasurementVectorDataFileName (StorageFolder continerFolder) => $"{continerFolder.Name}_vectorData.json";
public static async Task SaveAdditionalResults( AdditionalResultsModel additionalResultsModel,StorageFolder folderForMeasurement)
{
await JsonServices.WriteToJsonFile(folderForMeasurement, GetMeasurementAdditionalResultsFileName(folderForMeasurement), additionalResultsModel);
}

private static string GetMeasurementFileName(StorageFolder continerFolder) => $"{continerFolder.Name}.json";
private static string GetVideoModelFileName(StorageFolder videoFolder) => $"{videoFolder.Name}.json";
private static string GetMeasurementVectorDataFileName(StorageFolder continerFolder) => $"{continerFolder.Name}_vectorData.json";
private static string GetMeasurementAdditionalResultsFileName(StorageFolder continerFolder) => $"{continerFolder.Name}_additionalResults.json";


internal async Task DeleteAllMeasurements()
{
await (await GetFolder_AllMeasurements()).DeleteAsync();
await (await GetFolder_AllMeasurements()).DeleteAsync();
}


Expand All @@ -149,6 +159,17 @@ internal async Task LoadVectorDataToModel(MeasurementModel model, StorageFolder
model.VectorsDataModel = vectorsDataModels;
}


internal async Task LoadAdditionalResultsToModel(MeasurementModel model, StorageFolder folderForMeasurement)
{
StorageFile jsonFile;
jsonFile = await folderForMeasurement.GetFileAsync(GetMeasurementAdditionalResultsFileName(folderForMeasurement));
if (jsonFile is null) throw new FileNotFoundException($"No vectorData file ({jsonFile}) in {folderForMeasurement.Name} folder");
var vectorsDataModels = await JsonServices.ReadFromJsonFile<AdditionalResultsModel>(jsonFile);
model.AdditionalResultsModel = vectorsDataModels?? new();
}


private StorageFolder _measurementsFolderForVideo;
//public async Task<List<MeasurementViewModel>> GetPastMeasurementsForVideo(StorageFile currentStorageFile, VideoFileModel videoFileModel)
//{
Expand All @@ -173,7 +194,7 @@ public async Task<List<MeasurementViewModel>> GetAllPastMeasurements()
{
var measurementsViewModels = new List<MeasurementViewModel>();
var allMeasurementsFolder = await GetFolder_AllMeasurements();
var videoFolders =await allMeasurementsFolder.GetFoldersAsync();
var videoFolders = await allMeasurementsFolder.GetFoldersAsync();

foreach (var videoFolder in videoFolders)
{
Expand All @@ -187,7 +208,7 @@ public async Task<List<MeasurementViewModel>> GetAllPastMeasurements()
var jsonFile = await mesFolder.GetFileAsync(GetMeasurementFileName(mesFolder));
if (jsonFile is null) continue;
MeasurementModel measModel = await JsonServices.ReadFromJsonFile<MeasurementModel>(jsonFile);
MeasurementViewModel vm = new MeasurementViewModel(measModel,vfm);
MeasurementViewModel vm = new MeasurementViewModel(measModel, vfm);
measurementsViewModels.Add(vm);
vm.FolderForMeasurement = mesFolder;
}
Expand All @@ -206,15 +227,15 @@ public async Task<List<MeasurementViewModel>> GetAllPastMeasurements()
/// </summary>
private async Task<StorageFolder> GetFolderForVideo(StorageFolder measurementsFolder, VideoFileModel videoFileModel)
{
string videoFolderName = $"v_{GetPathToSourceForFileName(videoFileModel.Name)}_{videoFileModel.FalToken.ToString().Trim(new char[] {'{','}' })}";
string videoFolderName = $"v_{GetPathToSourceForFileName(videoFileModel.Name)}_{videoFileModel.FalToken.ToString().Trim(new char[] { '{', '}' })}";
StorageFolder videoFolder = await measurementsFolder.CreateFolderAsync(videoFolderName, CreationCollisionOption.OpenIfExists);

//when getting folder, also check for video file. This file is used for loading basic video properties
//withour reaching the video file itself. Also stores fal token (future access list), so we can retrieve the video file
var videoFile = await videoFolder.TryGetItemAsync(GetVideoModelFileName(videoFolder));
if (videoFile is null)//do nothing when already created
{
var vf = await videoFolder.CreateFileAsync(GetVideoModelFileName(videoFolder), CreationCollisionOption.FailIfExists);
var vf = await videoFolder.CreateFileAsync(GetVideoModelFileName(videoFolder), CreationCollisionOption.FailIfExists);
await JsonServices.WriteToJsonFile(vf, videoFileModel);
}

Expand Down Expand Up @@ -249,7 +270,7 @@ public async Task DeleteStoredViewModel(MeasurementViewModel vm)
await vm.FolderForMeasurement.DeleteAsync();
}



}

Expand Down
19 changes: 16 additions & 3 deletions TremAn3/Services/ExportService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,28 @@ public async Task ExportFreqAnalysisToCsvAsync()
headers.Add($"{dataSeriesType}__{roi}");
}
}
var roi1Roi2Coherence = ViewModelLocator.Current.MainViewModel.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel.DataResultsDict[DataSeriesType.Coherence];
var currentGlobal = ViewModelLocator.Current.MainViewModel.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel;
var roi1Roi2Coherence = currentGlobal.DataResultsDict[DataSeriesType.Coherence];
if (roi1Roi2Coherence.IsOk)
{
values.Add(roi1Roi2Coherence.X);
headers.Add("freq[Hz]_coherence_roi1_roi2");

values.Add(roi1Roi2Coherence.Y);
headers.Add("coherence_roi1_roi2");
values.Add([ViewModelLocator.Current.MainViewModel.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel.CoherenceAverage]);
headers.Add("coherence_roi1_roi2_average");


values.Add(currentGlobal.CoherenceMeasurementResults.Select(x => x.MinHz).ToList());
headers.Add("coherence_minFreq[Hz]");

values.Add(currentGlobal.CoherenceMeasurementResults.Select(x => x.MaxHz).ToList());
headers.Add("coherence_maxFreq[Hz]");

values.Add(currentGlobal.CoherenceMeasurementResults.Select(x => x.Average).ToList());
headers.Add("coherence_average");

// values.Add([ViewModelLocator.Current.MainViewModel.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel.CoherenceAverage]);
// headers.Add("coherence_roi1_roi2_average");

}

Expand Down
35 changes: 29 additions & 6 deletions TremAn3/Services/StoringMeasurementsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public MeasurementsService(DataService ds)
DataService _DataService;
/// <summary>
/// this is called when model is loaded from file and we want display rresults from model.
/// here the data gets from model to vm
/// </summary>
/// <param name="measurementModel"></param>
/// <returns></returns>
Expand All @@ -44,6 +45,7 @@ public async Task DisplayMeasurementByModelAsync(MeasurementModel measurementMod
selvm.ComputationViewModel.Algorithm = new CenterOfMotionAlgorithm(roiRes, measurementModel.FrameRate);
}
ResultsViewModel rvm = new ResultsViewModel();
rvm.AddedToCollection = mainVm.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel.AddedToCollection;

foreach (var gsdm in measurementModel.VectorsDataModel.GlobalScopedDataResultsModels)
{
Expand All @@ -53,11 +55,29 @@ public async Task DisplayMeasurementByModelAsync(MeasurementModel measurementMod
X = gsdm.X,
ErrorMessage = gsdm.ErrorMessage
};
rvm.DataResultsDict.Add(gsdm.DataSeriesType, dr);
rvm.DataResultsDict.Add(gsdm.DataSeriesType, dr);
}
rvm.CoherenceMeasurementResults.Clear();
foreach (var item in measurementModel.AdditionalResultsModel.CoherenceAverageResults)
rvm.CoherenceMeasurementResults.Add(new CoherenceMeasurementResults() { Average = item.Average, MaxHz = item.MaxHz, MinHz = item.MinHz });


if (rvm.CoherenceMeasurementResults.Any())
{
rvm.CoherenceMinHz = rvm.CoherenceMeasurementResults.Last().MinHz;
rvm.CoherenceMaxHz = rvm.CoherenceMeasurementResults.Last().MaxHz;
}
else
{
rvm.CoherenceMinHz = 0;
rvm.CoherenceMaxHz = mainVm.MediaPlayerViewModel.VideoPropsViewModel.FrameRate / 2;
}


mainVm.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel = rvm;
await mainVm.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel.ComputeAdditionalResults();
rvm.SetIsCoherenceOk();
rvm.IsComputationPaused = false;
//await mainVm.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel.ComputeAdditionalResults();


await mainVm.FreqCounterViewModel.DisplayPlots(false);
Expand All @@ -69,17 +89,20 @@ public async Task DisplayMeasurementByModelAsync(MeasurementModel measurementMod
/// </summary>
/// <param name="vm"></param>
/// <returns></returns>
public async Task GetModelFromVmAndSaveItToFile(MeasurementViewModel vm)
public async Task GetModelFromVmAndSaveItToFile(MeasurementViewModel vm)
{
var mainVm = ViewModelLocator.Current.MainViewModel;
var algs = ViewModelLocator.Current.DrawingRectanglesViewModel.SelectionRectanglesViewModels.Select(x => x.ComputationViewModel.Algorithm);
vm.Model.GetResults(algs,mainVm.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel.DataResultsDict);


var currentGlobalResults = mainVm.FreqCounterViewModel.CurrentGlobalScopedResultsViewModel;
vm.Model.GetResults(algs, currentGlobalResults.DataResultsDict, currentGlobalResults.GetAdditionalResultsModel());
vm.Model.FreqProgressSegmnetSize = mainVm.FreqCounterViewModel.FreqProgressViewModel.SegmnetSize;
vm.Model.FreqProgressStep = mainVm.FreqCounterViewModel.FreqProgressViewModel.Step;
if (vm.FolderForMeasurement == null)
vm.FolderForMeasurement = await _DataService.SaveMeasurementResults(vm.Model, mainVm.MediaPlayerViewModel.VideoFileModel);
vm.FolderForMeasurement = await _DataService.SaveMeasurementResults(vm.Model, mainVm.MediaPlayerViewModel.VideoFileModel);
else
await DataService.SaveMeasurementResults(vm.Model, vm.FolderForMeasurement );
await DataService.SaveMeasurementResults(vm.Model, vm.FolderForMeasurement);
}


Expand Down
Loading

0 comments on commit b747162

Please sign in to comment.