diff --git a/src/OSPSuite.Assets/UIConstants.cs b/src/OSPSuite.Assets/UIConstants.cs index 531a596ba..c2f564cd3 100644 --- a/src/OSPSuite.Assets/UIConstants.cs +++ b/src/OSPSuite.Assets/UIConstants.cs @@ -581,6 +581,30 @@ public class ToolTips } public static readonly string ImportFileFilter = "Excel Files (*.xls, *.xlsx)|*.xls;*.xlsx|Comma Separated Value Files (*.csv)|*.csv|NonMem Files (*.NMdat)|*.NMdat|All Files (*.*)|*.*"; + + public static string UpdatedMappingsMessage(IEnumerable<(string ParameterName, string OutputPath)> updatedMappingsInfo) + { + var sb = new StringBuilder(); + sb.AppendLine("The following parameter identifications and their output mappings were modified:"); + sb.AppendLine(); + + var groupedMappings = updatedMappingsInfo + .GroupBy(mapping => mapping.ParameterName) + .OrderBy(group => group.Key); + + foreach (var group in groupedMappings) + { + sb.AppendLine($"- {group.Key}"); + foreach (var mapping in group) + { + sb.AppendLine($" - Output Path: {mapping.OutputPath}"); + } + sb.AppendLine(); + } + + return sb.ToString(); + } + } public static class Diff diff --git a/src/OSPSuite.Core/Domain/Services/ParameterIdentifications/IParameterIdentificationTask.cs b/src/OSPSuite.Core/Domain/Services/ParameterIdentifications/IParameterIdentificationTask.cs index a7d75b7eb..ec99c0c80 100644 --- a/src/OSPSuite.Core/Domain/Services/ParameterIdentifications/IParameterIdentificationTask.cs +++ b/src/OSPSuite.Core/Domain/Services/ParameterIdentifications/IParameterIdentificationTask.cs @@ -80,5 +80,11 @@ public interface IParameterIdentificationTask /// Returns a clone of the or null if the user cancels the clone action /// ParameterIdentification Clone(ParameterIdentification parameterIdentification); + + /// + /// Updates the s using the + /// Returns an Ienumerable of that have been updated + /// + void UpdateParameterIdentificationsUsing(IEnumerable observedData); } } \ No newline at end of file diff --git a/src/OSPSuite.Core/Events/ObservedDataEvent.cs b/src/OSPSuite.Core/Events/ObservedDataEvent.cs index 382cbd386..8162cf21c 100644 --- a/src/OSPSuite.Core/Events/ObservedDataEvent.cs +++ b/src/OSPSuite.Core/Events/ObservedDataEvent.cs @@ -27,12 +27,12 @@ public ObservedDataTableChangedEvent(DataRepository observedData) { } } + public class ObservedDataMetaDataAddedEvent : ObservedDataEvent { public ObservedDataMetaDataAddedEvent(DataRepository observedData) : base(observedData) { - } } @@ -41,7 +41,6 @@ public class ObservedDataMetaDataRemovedEvent : ObservedDataEvent public ObservedDataMetaDataRemovedEvent(DataRepository observedData) : base(observedData) { - } } diff --git a/src/OSPSuite.Core/Events/WeightObservedDataChangedEvent.cs b/src/OSPSuite.Core/Events/WeightObservedDataChangedEvent.cs new file mode 100644 index 000000000..4b0ce66d6 --- /dev/null +++ b/src/OSPSuite.Core/Events/WeightObservedDataChangedEvent.cs @@ -0,0 +1,18 @@ +using OSPSuite.Core.Domain; +using OSPSuite.Core.Domain.Data; +using System; +using System.Collections.Generic; +using System.Text; + +namespace OSPSuite.Core.Events +{ + public class WeightObservedDataChangedEvent + { + public OutputMapping OutputMapping { get; private set; } + + public WeightObservedDataChangedEvent(OutputMapping outputMapping) + { + OutputMapping = outputMapping; + } + } +} diff --git a/src/OSPSuite.Presentation/Presenters/ParameterIdentifications/ParameterIdentificationDataSelectionPresenter.cs b/src/OSPSuite.Presentation/Presenters/ParameterIdentifications/ParameterIdentificationDataSelectionPresenter.cs index fc7e88606..80f9d5b5a 100644 --- a/src/OSPSuite.Presentation/Presenters/ParameterIdentifications/ParameterIdentificationDataSelectionPresenter.cs +++ b/src/OSPSuite.Presentation/Presenters/ParameterIdentifications/ParameterIdentificationDataSelectionPresenter.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using OSPSuite.Core.Domain; using OSPSuite.Core.Domain.ParameterIdentifications; using OSPSuite.Core.Events; @@ -12,7 +13,8 @@ public interface IParameterIdentificationDataSelectionPresenter : IParameterIden IListener, IListener, IListener, - IListener + IListener, + IListener { event EventHandler SimulationAdded; event EventHandler SimulationRemoved; @@ -127,5 +129,16 @@ public void Handle(SimulationReplacedInParameterAnalyzableEvent eventToHandle) } private bool canHandle(SimulationReplacedInParameterAnalyzableEvent eventToHandle) => Equals(eventToHandle.ParameterAnalysable, _parameterIdentification); + + public void Handle(WeightObservedDataChangedEvent eventToHandle) + { + var existingMapping = _outputMappingPresenter.OutputMappings.Where(x => x.OutputPath == eventToHandle.OutputMapping.OutputPath).FirstOrDefault(); + + if (existingMapping == null) + return; + + _weightedObservedDataPresenter.Edit(eventToHandle.OutputMapping.WeightedObservedData); + } + } } \ No newline at end of file diff --git a/src/OSPSuite.Presentation/Presenters/ParameterIdentifications/ParameterIdentificationOutputMappingPresenter.cs b/src/OSPSuite.Presentation/Presenters/ParameterIdentifications/ParameterIdentificationOutputMappingPresenter.cs index f0e5fa63a..c2c79b38e 100644 --- a/src/OSPSuite.Presentation/Presenters/ParameterIdentifications/ParameterIdentificationOutputMappingPresenter.cs +++ b/src/OSPSuite.Presentation/Presenters/ParameterIdentifications/ParameterIdentificationOutputMappingPresenter.cs @@ -15,6 +15,8 @@ using OSPSuite.Utility; using OSPSuite.Utility.Collections; using OSPSuite.Utility.Extensions; +using static OSPSuite.Assets.Captions; +using ParameterIdentification = OSPSuite.Core.Domain.ParameterIdentifications.ParameterIdentification; namespace OSPSuite.Presentation.Presenters.ParameterIdentifications { @@ -31,6 +33,7 @@ public ObservedDataEventArgs(WeightedObservedData weightedObservedData) public interface IParameterIdentificationOutputMappingPresenter : IPresenter, IParameterIdentificationPresenter, ILatchable { void AddOutputMapping(); + IEnumerable OutputMappings { get; } IEnumerable AllAvailableOutputs { get; } IEnumerable AllObservedDataFor(OutputMappingDTO dto); void ObservedDataSelectionChanged(OutputMappingDTO dto, DataRepository newObservedData, DataRepository oldObservedData); @@ -111,6 +114,14 @@ public void AddOutputMapping() OnStatusChanged(); } + public IEnumerable OutputMappings + { + get + { + return _parameterIdentification.AllOutputMappings; + } + } + private void updateOutputMappingList() { _allOutputMappingDTOs.Clear(); diff --git a/src/OSPSuite.Presentation/Services/ParameterIdentificationTask.cs b/src/OSPSuite.Presentation/Services/ParameterIdentificationTask.cs index 549e265bb..c103c7dbf 100644 --- a/src/OSPSuite.Presentation/Services/ParameterIdentificationTask.cs +++ b/src/OSPSuite.Presentation/Services/ParameterIdentificationTask.cs @@ -242,6 +242,34 @@ public bool SimulationCanBeUsedForIdentification(ISimulation simulation) return _simulationSelector.SimulationCanBeUsedForIdentification(simulation); } + public void UpdateParameterIdentificationsUsing(IEnumerable observedData) + { + var updatedMappingsInfo = new List<(string ParameterName, string OutputPath)>(); + observedData.Each(data => + { + ParameterIdentificationsUsingObservedData(data).Each(parameterIdentification => + { + parameterIdentification.OutputMappingsUsingDataRepository(data).Each(outputMapping => + { + var existingDataCount = outputMapping.WeightedObservedData?.Count ?? 0; + var newDataCount = data.BaseGrid.Count; + if (existingDataCount != newDataCount) + { + outputMapping.WeightedObservedData = new WeightedObservedData(data); + updatedMappingsInfo.Add((parameterIdentification.Name, outputMapping.FullOutputPath)); + _executionContext.PublishEvent(new WeightObservedDataChangedEvent(outputMapping)); + } + }); + }); + }); + + if (updatedMappingsInfo.Any()) + { + var strPaths = Captions.Importer.UpdatedMappingsMessage(updatedMappingsInfo); + _dialogCreator.MessageBoxInfo(strPaths); + } + } + public ParameterIdentification Clone(ParameterIdentification parameterIdentification) { loadParameterIdentification(parameterIdentification); diff --git a/tests/OSPSuite.Presentation.Tests/Services/ParameterIdentificationTaskSpecs.cs b/tests/OSPSuite.Presentation.Tests/Services/ParameterIdentificationTaskSpecs.cs index 0a7884aef..7eda9aa86 100644 --- a/tests/OSPSuite.Presentation.Tests/Services/ParameterIdentificationTaskSpecs.cs +++ b/tests/OSPSuite.Presentation.Tests/Services/ParameterIdentificationTaskSpecs.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using FakeItEasy; +using NUnit.Framework; using OSPSuite.BDDHelper; using OSPSuite.BDDHelper.Extensions; using OSPSuite.Core.Commands; @@ -15,6 +16,7 @@ using OSPSuite.Helpers; using OSPSuite.Presentation.Core; using OSPSuite.Presentation.Presenters; +using OSPSuite.Utility.Collections; using OSPSuite.Utility.Events; namespace OSPSuite.Presentation.Services @@ -77,10 +79,10 @@ protected override void Context() base.Context(); _dataRepository = A.Fake(); _parameterIdentification = new ParameterIdentification(); - _parameterIdentifications = new List {_parameterIdentification, new ParameterIdentification()}; + _parameterIdentifications = new List { _parameterIdentification, new ParameterIdentification() }; A.CallTo(() => _executionContext.Project.AllParameterIdentifications).Returns(_parameterIdentifications); - _parameterIdentification.AddOutputMapping(new OutputMapping {WeightedObservedData = new WeightedObservedData(_dataRepository)}); + _parameterIdentification.AddOutputMapping(new OutputMapping { WeightedObservedData = new WeightedObservedData(_dataRepository) }); } protected override void Because() @@ -112,7 +114,7 @@ protected override void Context() _parameterIdentification = A.Fake(); A.CallTo(() => _applicationController.Start()).Returns(_validationMessagesPresenter); - _validationResult = new ValidationResult(new[] {new ValidationMessage(NotificationType.Warning, "", _parameterIdentification, null)}); + _validationResult = new ValidationResult(new[] { new ValidationMessage(NotificationType.Warning, "", _parameterIdentification, null) }); A.CallTo(() => _simulationSwapValidator.ValidateSwap(_parameterIdentification, _oldSimulation, _newSimulation)).Returns(_validationResult); A.CallTo(() => _validationMessagesPresenter.Display(_validationResult)).Returns(false); @@ -172,7 +174,7 @@ protected override void Context() _parameterIdentification = A.Fake(); A.CallTo(() => _applicationController.Start()).Returns(_validationMessagesPresenter); - _validationResult = new ValidationResult(new[] {new ValidationMessage(NotificationType.Warning, "", _parameterIdentification, null)}); + _validationResult = new ValidationResult(new[] { new ValidationMessage(NotificationType.Warning, "", _parameterIdentification, null) }); A.CallTo(() => _simulationSwapValidator.ValidateSwap(_parameterIdentification, _oldSimulation, _newSimulation)).Returns(_validationResult); A.CallTo(() => _validationMessagesPresenter.Display(_validationResult)).Returns(true); @@ -290,24 +292,24 @@ protected override void Context() _output1 = A.Fake(); - var allOutputs = new PathCacheForSpecs {{_outputPath, _output1}}; + var allOutputs = new PathCacheForSpecs { { _outputPath, _output1 } }; A.CallTo(() => _entitiesInSimulationRetriever.OutputsFrom(_simulation)).Returns(allOutputs); _observedData1 = DomainHelperForSpecs.ObservedData("OBS1"); _observedData2 = DomainHelperForSpecs.ObservedData("OBS2"); _observedData3 = DomainHelperForSpecs.ObservedData("OBS3"); - A.CallTo(() => _observedDataRepository.AllObservedDataUsedBy(_simulation)).Returns(new[] { _observedData2, _observedData3}); + A.CallTo(() => _observedDataRepository.AllObservedDataUsedBy(_simulation)).Returns(new[] { _observedData2, _observedData3 }); var simulationQuantitySelection = A.Fake(); A.CallTo(() => simulationQuantitySelection.Path).Returns(_outputPath); - _parameterIdentification.AddOutputMapping(new OutputMapping {WeightedObservedData = new WeightedObservedData(_observedData2), OutputSelection = simulationQuantitySelection}); + _parameterIdentification.AddOutputMapping(new OutputMapping { WeightedObservedData = new WeightedObservedData(_observedData2), OutputSelection = simulationQuantitySelection }); - _observedData1.ExtendedProperties.Add(new ExtendedProperty {Name = Constants.ObservedData.MOLECULE, Value = "Drug"}); - _observedData1.ExtendedProperties.Add(new ExtendedProperty {Name = Constants.ObservedData.ORGAN, Value = "Liver"}); - _observedData1.ExtendedProperties.Add(new ExtendedProperty {Name = Constants.ObservedData.COMPARTMENT, Value = "Cell"}); + _observedData1.ExtendedProperties.Add(new ExtendedProperty { Name = Constants.ObservedData.MOLECULE, Value = "Drug" }); + _observedData1.ExtendedProperties.Add(new ExtendedProperty { Name = Constants.ObservedData.ORGAN, Value = "Liver" }); + _observedData1.ExtendedProperties.Add(new ExtendedProperty { Name = Constants.ObservedData.COMPARTMENT, Value = "Cell" }); - _observedData3.ExtendedProperties.Add(new ExtendedProperty {Name = Constants.ObservedData.ORGAN, Value = "Kidney"}); + _observedData3.ExtendedProperties.Add(new ExtendedProperty { Name = Constants.ObservedData.ORGAN, Value = "Kidney" }); _outputMapping = new OutputMapping { @@ -443,7 +445,7 @@ protected override void Context() protected override void Because() { - _result = sut.CreateParameterIdentificationBasedOn(new[] {_parameter}); + _result = sut.CreateParameterIdentificationBasedOn(new[] { _parameter }); } [Observation] @@ -489,9 +491,9 @@ protected override void Context() A.CallTo(() => _parameterIdentificationFactory.Create()).Returns(new ParameterIdentification()); A.CallTo(() => _executionContext.Project).Returns(A.Fake()); - var parameterCache = new PathCacheForSpecs {{_parameterPath1, _parameter1}, {_parameterPath2, _parameter2}}; + var parameterCache = new PathCacheForSpecs { { _parameterPath1, _parameter1 }, { _parameterPath2, _parameter2 } }; A.CallTo(() => _entitiesInSimulationRetriever.ParametersFrom(_simulation)).Returns(parameterCache); - A.CallTo(() => _favoriteRepository.All()).Returns(new[] {_parameterPath1, _parameterPath2,}); + A.CallTo(() => _favoriteRepository.All()).Returns(new[] { _parameterPath1, _parameterPath2, }); A.CallTo(() => _entityPathResolver.PathFor(_parameter1)).Returns(_parameterPath1); A.CallTo(() => _entityPathResolver.PathFor(_parameter2)).Returns(_parameterPath2); A.CallTo(() => _parameterAnalysableParameterSelector.CanUseParameter(_parameter1)).Returns(true); @@ -503,7 +505,7 @@ protected override void Context() protected override void Because() { - _result = sut.CreateParameterIdentificationBasedOn(new[] {_simulation}); + _result = sut.CreateParameterIdentificationBasedOn(new[] { _simulation }); } [Observation] @@ -543,7 +545,7 @@ protected override void Context() protected override void Because() { - sut.Delete(new[] {_parameterIdentification}); + sut.Delete(new[] { _parameterIdentification }); } [Observation] @@ -588,7 +590,7 @@ protected override void Context() protected override void Because() { - sut.Delete(new[] {_parameterIdentification}); + sut.Delete(new[] { _parameterIdentification }); } [Observation] @@ -606,7 +608,7 @@ public class When_cloning_a_parameter_identification_from_task : concern_for_Par protected override void Context() { base.Context(); - _parameterIdentification = new ParameterIdentification {IsLoaded = false}; + _parameterIdentification = new ParameterIdentification { IsLoaded = false }; _cloneObjectBasePresenter = A.Fake>(); A.CallTo(_applicationController).WithReturnType>().Returns(_cloneObjectBasePresenter); } @@ -628,4 +630,93 @@ public void The_application_controller_must_start_the_rename_presenter() A.CallTo(() => _cloneObjectBasePresenter.CreateCloneFor(_parameterIdentification)).MustHaveHappened(); } } + + public class When_updating_a_parameter_identification_from_task : concern_for_ParameterIdentificationTask + { + private List _observedData; + + protected override void Context() + { + + base.Context(); + A.CallTo(() => _executionContext.PublishEvent(A.Ignored)).DoesNothing(); + var baseGrid = new BaseGrid("Time", DomainHelperForSpecs.TimeDimensionForSpecs()); + baseGrid.Insert(1); + baseGrid.Insert(2); + var baseGrid2 = new BaseGrid("Time", DomainHelperForSpecs.TimeDimensionForSpecs()); + baseGrid2.Insert(1); + var baseGrid3 = new BaseGrid("Time", DomainHelperForSpecs.TimeDimensionForSpecs()); + baseGrid3.Insert(1); + baseGrid3.Insert(2); + + var standardColumn = new DataColumn("Standard", DomainHelperForSpecs.ConcentrationDimensionForSpecs(), baseGrid) + { + DataInfo = new DataInfo(ColumnOrigins.Observation), + }; + var standardColumn2 = new DataColumn("Standard_2", DomainHelperForSpecs.ConcentrationDimensionForSpecs(), baseGrid2) + { + DataInfo = new DataInfo(ColumnOrigins.Observation), + }; + var standardColumn3 = new DataColumn("Standard_3", DomainHelperForSpecs.ConcentrationDimensionForSpecs(), baseGrid3) + { + DataInfo = new DataInfo(ColumnOrigins.Observation), + }; + + var dataRepository1 = new DataRepository { standardColumn }; + var dataRepository2 = new DataRepository { standardColumn2 }; + var dataRepository3 = new DataRepository { standardColumn3 }; + + dataRepository1.ExtendedProperties.Add(new ExtendedProperty { Name = "ID", Value = 1 }); + dataRepository2.ExtendedProperties.Add(new ExtendedProperty { Name = "ID", Value = 2 }); + dataRepository3.ExtendedProperties.Add(new ExtendedProperty { Name = "ID", Value = 3 }); + + dataRepository1.ExtendedProperties.Add(new ExtendedProperty { Name = "Species", Value = "Human" }); + dataRepository2.ExtendedProperties.Add(new ExtendedProperty { Name = "Species", Value = "Human" }); + dataRepository2.ExtendedProperties.Add(new ExtendedProperty { Name = "NotCommonMetaData", Value = "test" }); + dataRepository3.ExtendedProperties.Add(new ExtendedProperty { Name = "Species", Value = "Dog" }); + + _observedData = new List { dataRepository1, dataRepository2, dataRepository3 }; + + var noDimensionOutputMapping = new OutputMapping + { + WeightedObservedData = new WeightedObservedData(dataRepository1) + }; + + var concentrationOutputMapping = new OutputMapping + { + WeightedObservedData = new WeightedObservedData(dataRepository2) + }; + + var outputMappings = new OutputMappings { noDimensionOutputMapping, concentrationOutputMapping }; + + var parameterIdentification = A.Fake(); + + A.CallTo(() => _executionContext.Project.AllParameterIdentifications) + .Returns(new List { parameterIdentification }); + + A.CallTo(() => parameterIdentification.OutputMappingsUsingDataRepository(A.Ignored)) + .ReturnsLazily(call => outputMappings); + + A.CallTo(() => _executionContext.Load(A.Ignored)).DoesNothing(); + } + + protected override void Because() + { + sut.UpdateParameterIdentificationsUsing(_observedData); + } + + [Observation] + public void it_should_update_mappings_with_different_counts() + { + A.CallTo(() => _executionContext.PublishEvent(A.Ignored)).MustHaveHappened(); + } + + [Observation] + public void it_should_display_a_message_box_with_updated_mappings() + { + A.CallTo(() => _dialogCreator.MessageBoxInfo(A.Ignored)) + .MustHaveHappened(); + } + } + } \ No newline at end of file