diff --git a/src/MoBi.Assets/AppConstants.cs b/src/MoBi.Assets/AppConstants.cs index 3f7a972a8..9a8d5ad50 100644 --- a/src/MoBi.Assets/AppConstants.cs +++ b/src/MoBi.Assets/AppConstants.cs @@ -1059,6 +1059,7 @@ public static class MenuNames public static readonly string ModelParts = "Model Parts"; public static readonly string ImportSBML = "Open SBML Model..."; public static readonly string SaveAsPKML = "Save As PKML..."; + public static readonly string ReloadAll = "Reload all under same settings..."; public static string AddNew(string objectTypeName) => $"Create {objectTypeName}..."; @@ -1900,6 +1901,8 @@ public static string NameIsAlreadyUsedInThisContainer(string containerPath, stri public static readonly string BrowseForFile = "Select File"; public static readonly string Undefined = "Undefined"; public static readonly string PleaseSelectCurveInChartEditor = "Please select a curve from the chart editor to be displayed in the chart"; + public static readonly IReadOnlyList DefaultObservedDataCategories = new[] { Constants.ObservedData.MOLECULE, Constants.ObservedData.COMPARTMENT, Constants.ObservedData.ORGAN}; + public static string PathType(string pathTypeAsString) { diff --git a/src/MoBi.Assets/MoBi.Assets.csproj b/src/MoBi.Assets/MoBi.Assets.csproj index 8dc8fa276..0348f5acf 100644 --- a/src/MoBi.Assets/MoBi.Assets.csproj +++ b/src/MoBi.Assets/MoBi.Assets.csproj @@ -26,9 +26,9 @@ - - - + + + diff --git a/src/MoBi.BatchTool/MoBi.BatchTool.csproj b/src/MoBi.BatchTool/MoBi.BatchTool.csproj index c9e2ef133..cefa78d09 100644 --- a/src/MoBi.BatchTool/MoBi.BatchTool.csproj +++ b/src/MoBi.BatchTool/MoBi.BatchTool.csproj @@ -60,7 +60,7 @@ - + diff --git a/src/MoBi.Core/MoBi.Core.csproj b/src/MoBi.Core/MoBi.Core.csproj index 4e98cf937..67d0920d4 100644 --- a/src/MoBi.Core/MoBi.Core.csproj +++ b/src/MoBi.Core/MoBi.Core.csproj @@ -31,13 +31,13 @@ - - - - - - - + + + + + + + diff --git a/src/MoBi.Core/Services/ModelPartsToExcelExporterTask.cs b/src/MoBi.Core/Services/ModelPartsToExcelExporterTask.cs index ed3c9e00c..365727139 100644 --- a/src/MoBi.Core/Services/ModelPartsToExcelExporterTask.cs +++ b/src/MoBi.Core/Services/ModelPartsToExcelExporterTask.cs @@ -42,15 +42,7 @@ public void ExportModelPartsToExcelFile(string excelFileName, IMoBiSimulation si var moleculeParameterDataTable = _moleculeStartValuesBuildingBlockToParameterDataTableMapper.MapFrom(simulation.MoBiBuildConfiguration.MoleculeStartValues.Where(msv => msv.IsPresent), simulation.MoBiBuildConfiguration.Molecules); var dataTables = new List {reactionDataTable, simulationParameterDataTable, moleculeParameterDataTable}; - //TODO: have to fix the export here - /* - ExportToExcelTask.ExportDataTablesToExcel(dataTables, excelFileName, openExcel: openExcel, workbookConfiguration: (wb, dt) => - { - wb.setSelection(0, 0, 0, dt.Columns.Count); - var rangeStyle = wb.getRangeStyle(); - rangeStyle.FontBold = true; - wb.setRangeStyle(rangeStyle); - });*/ + ExportToExcelTask.ExportDataTablesToExcel(dataTables, excelFileName, openExcel: openExcel); } } } \ No newline at end of file diff --git a/src/MoBi.Engine/MoBi.Engine.csproj b/src/MoBi.Engine/MoBi.Engine.csproj index 95925192e..a47988cd5 100644 --- a/src/MoBi.Engine/MoBi.Engine.csproj +++ b/src/MoBi.Engine/MoBi.Engine.csproj @@ -32,8 +32,8 @@ - - + + diff --git a/src/MoBi.Presentation/MenusAndBars/ContextMenus/ContextMenuForDataRepository.cs b/src/MoBi.Presentation/MenusAndBars/ContextMenus/ContextMenuForDataRepository.cs index c43abde8d..5db085e73 100644 --- a/src/MoBi.Presentation/MenusAndBars/ContextMenus/ContextMenuForDataRepository.cs +++ b/src/MoBi.Presentation/MenusAndBars/ContextMenus/ContextMenuForDataRepository.cs @@ -53,6 +53,7 @@ public IContextMenu InitializeWith(DataRepository dataRepository) editMenuItemFor(dataRepository), renameMenuItemFor(dataRepository), createSaveItemFor(dataRepository), + createReloadItemFor(dataRepository), deleteMenuItemFor(dataRepository), exportToExcel(dataRepository), reportMenuItemFor(dataRepository), @@ -95,6 +96,14 @@ private static IMenuBarButton deleteMenuItemFor(DataRepository dataRepository) .WithIcon(ApplicationIcons.Delete); } + private IMenuBarItem createReloadItemFor(DataRepository dataRepository) + { + return CreateMenuButton.WithCaption(AppConstants.MenuNames.ReloadAll) //ToDo: move to Core, also from PK-Sim + .WithCommandFor(dataRepository) + .AsDisabledIf(string.IsNullOrEmpty(dataRepository.ConfigurationId)) + .WithIcon(ApplicationIcons.Excel); + } + private IMenuBarItem createSaveItemFor(DataRepository dataRepository) { return CreateMenuButton.WithCaption(AppConstants.MenuNames.SaveAsPKML) diff --git a/src/MoBi.Presentation/MoBi.Presentation.csproj b/src/MoBi.Presentation/MoBi.Presentation.csproj index a5bf6ac11..4f8d500b9 100644 --- a/src/MoBi.Presentation/MoBi.Presentation.csproj +++ b/src/MoBi.Presentation/MoBi.Presentation.csproj @@ -26,12 +26,15 @@ - - - + + + + + + diff --git a/src/MoBi.Presentation/Tasks/ObservedDataTask.cs b/src/MoBi.Presentation/Tasks/ObservedDataTask.cs index 1d8ca1ec0..86b77acaa 100644 --- a/src/MoBi.Presentation/Tasks/ObservedDataTask.cs +++ b/src/MoBi.Presentation/Tasks/ObservedDataTask.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; using MoBi.Assets; using MoBi.Core.Commands; using MoBi.Core.Domain.Model; @@ -13,9 +10,14 @@ using OSPSuite.Core.Domain.Data; using OSPSuite.Core.Domain.Services; using OSPSuite.Core.Domain.UnitSystem; +using OSPSuite.Core.Import; using OSPSuite.Core.Services; -using OSPSuite.Infrastructure.Import.Services; using OSPSuite.Utility.Extensions; +using System; +using System.Collections.Generic; +using System.Linq; +using ColumnInfo = OSPSuite.Infrastructure.Import.Core.ColumnInfo; +using OSPSuite.Infrastructure.Import.Services; using Command = OSPSuite.Assets.Command; using CoreConstants = OSPSuite.Core.Domain.Constants; using DimensionInfo = OSPSuite.Infrastructure.Import.Core; @@ -33,6 +35,8 @@ public interface IObservedDataTask : OSPSuite.Core.Domain.Services.IObservedData /// Removes selected from their respective simulations /// void RemoveResultsFromSimulations(IReadOnlyList resultsToRemove); + + void AddAndReplaceObservedDataFromConfigurationToProject(ImporterConfiguration configuration, IReadOnlyList observedDataFromSameFile); } public class ObservedDataTask : OSPSuite.Core.Domain.Services.ObservedDataTask, IObservedDataTask @@ -44,6 +48,7 @@ public class ObservedDataTask : OSPSuite.Core.Domain.Services.ObservedDataTask, private readonly IDimension _molWeightDimension; private readonly IDialogCreator _mobiDialogCreator; + public ObservedDataTask( IDataImporter dataImporter, IDimensionFactory dimensionFactory, @@ -64,26 +69,28 @@ public ObservedDataTask( public void AddObservedDataToProject() { - //maybe the formats are not being registered var data = _dataImporter.ImportDataSets(createMetaData().ToList(), createColumnInfos().ToList(), createDataImportSettings()); + + if (data.DataRepositories == null || data.Configuration == null) return; + foreach (var repository in data.DataRepositories) { - adjustMolWeight(repository); AddObservedDataToProject(repository); adjustRepositoryPaths(repository); } + AddImporterConfigurationToProject(data.Configuration); } private void adjustRepositoryPaths(DataRepository repository) { var baseGrid = repository.BaseGrid; var baseGridName = baseGrid.Name.Replace(ObjectPath.PATH_DELIMITER, "\\"); - baseGrid.QuantityInfo = new QuantityInfo(baseGrid.Name, new[] {repository.Name, baseGridName}, QuantityType.Time); + baseGrid.QuantityInfo = new QuantityInfo(baseGrid.Name, new[] { repository.Name, baseGridName }, QuantityType.Time); foreach (var col in repository.AllButBaseGrid()) { var colName = col.Name.Replace(ObjectPath.PATH_DELIMITER, "\\"); - var quantityInfo = new QuantityInfo(col.Name, new[] {repository.Name, colName}, QuantityType.Undefined); + var quantityInfo = new QuantityInfo(col.Name, new[] { repository.Name, colName }, QuantityType.Undefined); col.QuantityInfo = quantityInfo; } } @@ -151,24 +158,11 @@ private DimensionInfo.DataImporterSettings createDataImportSettings() IconName = ApplicationIcons.MoBi.IconName, Caption = $"{AppConstants.PRODUCT_NAME} - {AppConstants.Captions.ImportObservedData}" }; - settings.AddNamingPatternMetaData(Constants.FILE); + addNamingPatterns(settings); + settings.NameOfMetaDataHoldingMolecularWeightInformation = AppConstants.Parameters.MOLECULAR_WEIGHT; return settings; } - private void adjustMolWeight(DataRepository observedData) - { - if (!observedData.ExtendedProperties.Contains(AppConstants.Parameters.MOLECULAR_WEIGHT)) - return; - - // molweight is provided in default unit should be saved in core unit - var molWeightExtendedProperty = observedData.ExtendedProperties[AppConstants.Parameters.MOLECULAR_WEIGHT].DowncastTo>(); - var molWeight = _molWeightDimension.UnitValueToBaseUnitValue(_molWeightDimension.DefaultUnit, molWeightExtendedProperty.Value); - observedData.AllButBaseGrid().Each(x => x.DataInfo.MolWeight = molWeight); - - //Remove Molweight extended properties - observedData.ExtendedProperties.Remove(AppConstants.Parameters.MOLECULAR_WEIGHT); - } - public override void Rename(DataRepository dataRepository) { var newName = _mobiDialogCreator.AskForInput(AppConstants.Dialog.AskForNewName(dataRepository.Name), @@ -210,6 +204,77 @@ public void RemoveResultsFromSimulations(IReadOnlyList resultsTo _context.AddToHistory(macroCommand.Run(_context)); } + public void AddAndReplaceObservedDataFromConfigurationToProject(ImporterConfiguration configuration, + IReadOnlyList observedDataFromSameFile) + { + var importedObservedData = getObservedDataFromImporter(configuration); + var reloadDataSets = + _dataImporter.CalculateReloadDataSetsFromConfiguration(importedObservedData.ToList(), observedDataFromSameFile.ToList()); + + foreach (var dataSet in reloadDataSets.NewDataSets) + { + AddObservedDataToProject(dataSet); + adjustRepositoryPaths(dataSet); + } + + foreach (var dataSet in reloadDataSets.DataSetsToBeDeleted.ToArray()) //toDo it should be checked if to array solves the deleting problem + { + Delete(dataSet); + } + + foreach (var dataSet in reloadDataSets.OverwrittenDataSets) + { + //TODO this here should be tested + var existingDataSet = findDataRepositoryInList(observedDataFromSameFile, dataSet); + + foreach (var column in dataSet.Columns) + { + var datacolumn = new DataColumn(column.Id, column.Name, column.Dimension, column.BaseGrid) + { + QuantityInfo = column.QuantityInfo, + DataInfo = column.DataInfo, + IsInternal = column.IsInternal, + Values = column.Values + }; + + if (column.IsBaseGrid()) + { + existingDataSet.BaseGrid.Values = datacolumn.Values; + } + else + { + var existingColumn = existingDataSet.FirstOrDefault(x => x.Name == column.Name); + if (existingColumn == null) + existingDataSet.Add(column); + else + existingColumn.Values = column.Values; + } + } + } + } + + private DataRepository findDataRepositoryInList(IEnumerable dataRepositoryList, DataRepository targetDataRepository) + { + return (from dataRepo in dataRepositoryList + let result = targetDataRepository.ExtendedProperties.KeyValues.All(keyValuePair => + dataRepo.ExtendedProperties[keyValuePair.Key].ValueAsObject.ToString() == keyValuePair.Value.ValueAsObject.ToString()) + where result + select dataRepo).FirstOrDefault(); + } + + private IEnumerable getObservedDataFromImporter(ImporterConfiguration configuration) + { + var dataImporterSettings = createDataImportSettings(); + + //do we really need this in MoBi???? + dataImporterSettings.NameOfMetaDataHoldingMoleculeInformation = Constants.ObservedData.MOLECULE; + var colInfos = createColumnInfos().ToList(); + + var importedObservedData = _dataImporter.ImportFromConfiguration(configuration, createMetaData().ToList(), + colInfos, dataImporterSettings); + return importedObservedData; + } + private ICommand removeResultFromSimulationCommand(DataRepository dataRepository) { var parentSimulation = getSimulationWithHistoricResult(dataRepository); @@ -232,7 +297,8 @@ private static ClearResultsCommand clearResultsCommand(IMoBiSimulation parentSim return new ClearResultsCommand(parentSimulation); } - private static RemoveHistoricResultFromSimulationCommand removeHistoricResultFromSimulationCommand(DataRepository repository, IMoBiSimulation parentSimulation) + private static RemoveHistoricResultFromSimulationCommand removeHistoricResultFromSimulationCommand(DataRepository repository, + IMoBiSimulation parentSimulation) { return new RemoveHistoricResultFromSimulationCommand(parentSimulation, repository); } @@ -250,7 +316,7 @@ private static RemoveHistoricResultFromSimulationCommand removeHistoricResultFro NullValuesHandling = DimensionInfo.NullValuesHandlingType.DeleteRow, }; - timeColumn.DimensionInfos.Add(new DimensionInfo.DimensionInfo {Dimension = timeDimension, IsMainDimension = true}); + timeColumn.DimensionInfos.Add(new DimensionInfo.DimensionInfo { Dimension = timeDimension, IsMainDimension = true }); yield return timeColumn; var mainDimension = _dimensionFactory.Dimension(Constants.Dimension.MOLAR_CONCENTRATION); @@ -331,7 +397,7 @@ private void addDimensionsTo(DimensionInfo.ColumnInfo columnInfo, IDimension mai private void addPredefinedMoleculeNames(DimensionInfo.MetaDataCategory metaDataCategory) { - addUndefinedValueTo(metaDataCategory); + metaDataCategory.ShouldListOfValuesBeIncluded = true; allMolecules().OrderBy(molecule => molecule.Name).Each(molecule => addInfoToCategory(metaDataCategory, molecule)); } @@ -348,23 +414,58 @@ private static void addUndefinedValueTo(DimensionInfo.MetaDataCategory metaDataC private void addPredefinedOrganValues(DimensionInfo.MetaDataCategory metaDataCategory) { addUndefinedValueTo(metaDataCategory); + metaDataCategory.ShouldListOfValuesBeIncluded = true; allOrgans().OrderBy(org => org.Name).Each(organ => addInfoToCategory(metaDataCategory, organ)); } + private void addNamingPatterns(DimensionInfo.DataImporterSettings dataImporterSettings) + { + dataImporterSettings.AddNamingPatternMetaData( + Constants.FILE + ); + + dataImporterSettings.AddNamingPatternMetaData( + Constants.FILE, + Constants.SHEET + ); + + dataImporterSettings.AddNamingPatternMetaData( + Constants.ObservedData.MOLECULE, + Constants.ObservedData.SPECIES, + Constants.ObservedData.ORGAN, + Constants.ObservedData.COMPARTMENT + ); + + dataImporterSettings.AddNamingPatternMetaData( + Constants.ObservedData.MOLECULE, + Constants.ObservedData.SPECIES, + Constants.ObservedData.ORGAN, + Constants.ObservedData.COMPARTMENT, + Constants.ObservedData.STUDY_ID, + Constants.ObservedData.GENDER, + Constants.ObservedData.DOSE, + Constants.ObservedData.ROUTE, + Constants.ObservedData.PATIENT_ID + ); + } + private void addPredefinedCompartmentValues(DimensionInfo.MetaDataCategory metaDataCategory) { addUndefinedValueTo(metaDataCategory); + metaDataCategory.ShouldListOfValuesBeIncluded = true; allCompartments().OrderBy(comp => comp.Name).Each(compartment => addInfoToCategory(metaDataCategory, compartment)); } private IEnumerable allOrgans() { - return allTopContainers().SelectMany(allSubContainers).Where(container => container.ContainerType == ContainerType.Organ).DistinctBy(x => x.Name); + return allTopContainers().SelectMany(allSubContainers).Where(container => container.ContainerType == ContainerType.Organ) + .DistinctBy(x => x.Name); } private IEnumerable allCompartments() { - return allTopContainers().SelectMany(allSubContainers).Where(container => container.ContainerType == ContainerType.Compartment).DistinctBy(x => x.Name); + return allTopContainers().SelectMany(allSubContainers).Where(container => container.ContainerType == ContainerType.Compartment) + .DistinctBy(x => x.Name); } private IEnumerable allTopContainers() diff --git a/src/MoBi.Presentation/UICommand/ReloadAllObservedDataCommand.cs b/src/MoBi.Presentation/UICommand/ReloadAllObservedDataCommand.cs new file mode 100644 index 000000000..7eef8c9cd --- /dev/null +++ b/src/MoBi.Presentation/UICommand/ReloadAllObservedDataCommand.cs @@ -0,0 +1,39 @@ +using System.Linq; +using MoBi.Core.Domain.Model; +using MoBi.Presentation.Tasks; +using OSPSuite.Core.Domain.Data; +using OSPSuite.Presentation.UICommands; + +namespace MoBi.Presentation.UICommand +{ + public class ReloadAllObservedDataCommand : ObjectUICommand + { + private readonly IMoBiContext _executionContext; + private readonly IObservedDataTask _observedDataTask; + + public ReloadAllObservedDataCommand( + IMoBiContext executionContext, + IObservedDataTask observedDataTask + ) + { + _executionContext = executionContext; + _observedDataTask = observedDataTask; + } + + protected override void PerformExecute() + { + if (string.IsNullOrEmpty(Subject.ConfigurationId)) + return; + + var project = _executionContext.Project; + var configurationId = Subject.ConfigurationId; + + //we should check this + var observedDataFromSameFile = + project.AllObservedData.Where(r => !string.IsNullOrEmpty(r.ConfigurationId) && r.ConfigurationId == configurationId); //actually the question here is: configID means they come from the same file right? + + var configuration = project.ImporterConfigurationBy(configurationId); + _observedDataTask.AddAndReplaceObservedDataFromConfigurationToProject(configuration, observedDataFromSameFile.ToList()); + } + } +} \ No newline at end of file diff --git a/src/MoBi.UI/MoBi.UI.csproj b/src/MoBi.UI/MoBi.UI.csproj index b1d4261c2..61c23364c 100644 --- a/src/MoBi.UI/MoBi.UI.csproj +++ b/src/MoBi.UI/MoBi.UI.csproj @@ -26,13 +26,15 @@ - - - - - + + + + + + + diff --git a/src/MoBi/MoBi.csproj b/src/MoBi/MoBi.csproj index 14bb1ef77..df0a98da5 100644 --- a/src/MoBi/MoBi.csproj +++ b/src/MoBi/MoBi.csproj @@ -68,13 +68,13 @@ - + - + diff --git a/tests/MoBi.Tests/MoBi.Tests.csproj b/tests/MoBi.Tests/MoBi.Tests.csproj index 3ec7a1d0c..381a8cb8a 100644 --- a/tests/MoBi.Tests/MoBi.Tests.csproj +++ b/tests/MoBi.Tests/MoBi.Tests.csproj @@ -45,10 +45,10 @@ - - - - + + + + diff --git a/tests/MoBi.UI.Tests/MoBi.UI.Tests.csproj b/tests/MoBi.UI.Tests/MoBi.UI.Tests.csproj index 4a7e0840c..78068835a 100644 --- a/tests/MoBi.UI.Tests/MoBi.UI.Tests.csproj +++ b/tests/MoBi.UI.Tests/MoBi.UI.Tests.csproj @@ -17,8 +17,8 @@ - - + +