diff --git a/src/MoBi.Assets/MoBi.Assets.csproj b/src/MoBi.Assets/MoBi.Assets.csproj index db92ff9ab..436491c96 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 4dca74799..019252bc4 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 614decb12..3296173a1 100644 --- a/src/MoBi.Core/MoBi.Core.csproj +++ b/src/MoBi.Core/MoBi.Core.csproj @@ -31,13 +31,13 @@ - - - - - - - + + + + + + + diff --git a/src/MoBi.Engine/MoBi.Engine.csproj b/src/MoBi.Engine/MoBi.Engine.csproj index 52ae2c5b7..e658f0898 100644 --- a/src/MoBi.Engine/MoBi.Engine.csproj +++ b/src/MoBi.Engine/MoBi.Engine.csproj @@ -32,8 +32,8 @@ - - + + diff --git a/src/MoBi.Engine/Sbml/UnitDefinitionImporter.cs b/src/MoBi.Engine/Sbml/UnitDefinitionImporter.cs index 1113bb08c..e0e5988ed 100644 --- a/src/MoBi.Engine/Sbml/UnitDefinitionImporter.cs +++ b/src/MoBi.Engine/Sbml/UnitDefinitionImporter.cs @@ -14,26 +14,36 @@ namespace MoBi.Engine.Sbml { internal class CombinedUnit { - public string Name { get => (_direct?.Name ?? "1") + (_inverse != null ? $"/{_inverse.Name}" : ""); } + public string Name => (_direct?.Name ?? "1") + (_inverse != null ? $"/{_inverse.Name}" : ""); + + // Rate is the factor to convert from the unit used in sbml to the base unit used in sbml. + // This is not necessarily the base unit in the ospsuite (1/s vs 1/min for inversed day for instance) public double Rate { get; private set; } = 1; + + private Unit _direct; + private Unit _inverse; + public void AddUnit(int kind, double exponent, double multiplier, double scale, IDictionary baseUnitsDictionary) { if (!baseUnitsDictionary.ContainsKey(kind)) return; + if (exponent < 0) _inverse = baseUnitsDictionary[kind]; else _direct = baseUnitsDictionary[kind]; + Rate *= multiplier * Math.Pow(10, scale); } - private Unit _direct { get; set; } - private Unit _inverse { get; set; } } - internal class UnitConvertionInfo + internal class UnitConversionInfo { public IDimension Dimension { get; set; } + + //Unit in which the values are stored in SBML Base unit public Unit Unit { get; set; } + public double Rate { get; set; } } @@ -48,37 +58,39 @@ public class UnitDefinitionImporter : SBMLImporter, IStartable, IUnitDefinitionI { private readonly IMoBiDimensionFactory _moBiDimensionFactory; private readonly IDictionary _baseUnitsDictionary; - private readonly IDictionary _unitConvertionDictionary; - private IDimensionFactory _dimensionFactory; - public IReadOnlyDictionary ConvertionDictionary { get => _unitConvertionDictionary.ToDictionary(kv => kv.Key, kv => kv.Value.Dimension); } - private IDictionary _sbmlUnitsSynonyms = new Dictionary() + private readonly IDictionary _unitConversionDictionary; + + public IReadOnlyDictionary ConversionDictionary => _unitConversionDictionary.ToDictionary(kv => kv.Key, kv => kv.Value.Dimension); + + private readonly IDictionary _sbmlUnitsSynonyms = new Dictionary() { - { "litre", "l" } + {"litre", "l"} }; - public UnitDefinitionImporter(IObjectPathFactory objectPathFactory, IObjectBaseFactory objectBaseFactory, IMoBiDimensionFactory mobiDimensionFactory, ASTHandler astHandler, IMoBiContext context, IDimensionFactory dimensionFactory) : base(objectPathFactory, objectBaseFactory, astHandler, context) + public UnitDefinitionImporter(IObjectPathFactory objectPathFactory, IObjectBaseFactory objectBaseFactory, IMoBiDimensionFactory mobiDimensionFactory, ASTHandler astHandler, IMoBiContext context) : + base(objectPathFactory, objectBaseFactory, astHandler, context) { _moBiDimensionFactory = mobiDimensionFactory; _baseUnitsDictionary = new Dictionary(); - _unitConvertionDictionary = new Dictionary(); - _dimensionFactory = dimensionFactory; - InitBaseUnitsDictionary(); + _unitConversionDictionary = new Dictionary(); + initBaseUnitsDictionary(); } public string TranslateUnit(string sbmlUnit) { if (_sbmlUnitsSynonyms.ContainsKey(sbmlUnit)) return _sbmlUnitsSynonyms[sbmlUnit]; + return sbmlUnit; } - private void InitBaseUnitsDictionary() + private void initBaseUnitsDictionary() { _baseUnitsDictionary.Add(libsbml.UNIT_KIND_AMPERE, _moBiDimensionFactory.Dimension("Ampere").Unit("A")); _baseUnitsDictionary.Add(libsbml.UNIT_KIND_BECQUEREL, _moBiDimensionFactory.Dimension("Becquerel").Unit("Bq")); _baseUnitsDictionary.Add(libsbml.UNIT_KIND_CANDELA, _moBiDimensionFactory.Dimension("Candela").Unit("cd")); _baseUnitsDictionary.Add(libsbml.UNIT_KIND_COULOMB, _moBiDimensionFactory.Dimension("Coulomb").Unit("C")); - _baseUnitsDictionary.Add(libsbml.UNIT_KIND_DIMENSIONLESS, _moBiDimensionFactory.NoDimension.DefaultUnit); + _baseUnitsDictionary.Add(libsbml.UNIT_KIND_DIMENSIONLESS, _moBiDimensionFactory.NoDimension.BaseUnit); _baseUnitsDictionary.Add(libsbml.UNIT_KIND_FARAD, _moBiDimensionFactory.Dimension("Becquerel").Unit("Bq")); _baseUnitsDictionary.Add(libsbml.UNIT_KIND_GRAM, _moBiDimensionFactory.Dimension("Mass").Unit("g")); _baseUnitsDictionary.Add(libsbml.UNIT_KIND_GRAY, _moBiDimensionFactory.Dimension("Gray").Unit("Gy")); @@ -111,7 +123,9 @@ private void InitBaseUnitsDictionary() protected override void Import(Model model) { - if (model == null) return; + if (model == null) + return; + if (_sbmlProject == null) return; for (long i = 0; i < model.getNumUnitDefinitions(); i++) @@ -121,7 +135,7 @@ protected override void Import(Model model) } /// - /// Converts a SBML UnitDefinition into a MoBi Unit. + /// Converts a SBML UnitDefinition into a MoBi Unit. /// public IDimension ConvertUnit(UnitDefinition unitDefinition) { @@ -131,7 +145,7 @@ public IDimension ConvertUnit(UnitDefinition unitDefinition) if (dimension != Constants.Dimension.NO_DIMENSION) { _sbmlInformation.MobiDimension[sbmlUnit] = dimension; - _unitConvertionDictionary.Add(sbmlUnit, new UnitConvertionInfo() { Dimension = dimension, Unit = dimension.DefaultUnit, Rate = 1 }); + _unitConversionDictionary.Add(sbmlUnit, new UnitConversionInfo {Dimension = dimension, Unit = dimension.BaseUnit, Rate = 1}); return dimension; } @@ -146,36 +160,40 @@ public IDimension ConvertUnit(UnitDefinition unitDefinition) sbmlUnitDefinition.getScale(), _baseUnitsDictionary); } + var unitName = combinedUnit.Name; - var dimensionAndUnit = _dimensionFactory.FindUnit(unitName); + var dimensionAndUnit = _moBiDimensionFactory.FindUnit(unitName); if (dimensionAndUnit.dimension != Constants.Dimension.NO_DIMENSION) { _sbmlInformation.MobiDimension[sbmlUnit] = dimensionAndUnit.dimension; - _unitConvertionDictionary.Add(sbmlUnit, new UnitConvertionInfo() { Dimension = dimensionAndUnit.dimension, Unit = dimensionAndUnit.unit, Rate = combinedUnit.Rate }); + _unitConversionDictionary.Add(sbmlUnit, new UnitConversionInfo {Dimension = dimensionAndUnit.dimension, Unit = dimensionAndUnit.unit, Rate = combinedUnit.Rate}); return dimensionAndUnit.dimension; } - _unitConvertionDictionary.Add(sbmlUnit, new UnitConvertionInfo() { Dimension = dimension, Unit = dimension.DefaultUnit, Rate = 1 }); + _unitConversionDictionary.Add(sbmlUnit, new UnitConversionInfo {Dimension = dimension, Unit = dimension.BaseUnit, Rate = 1}); return dimension; } - public override void AddToProject() { } + public override void AddToProject() + { + } public IDimension DimensionFor(string sbmlUnit) { - if (_unitConvertionDictionary.ContainsKey(sbmlUnit)) - return _unitConvertionDictionary[sbmlUnit].Dimension; + if (_unitConversionDictionary.ContainsKey(sbmlUnit)) + return _unitConversionDictionary[sbmlUnit].Dimension; return _moBiDimensionFactory.DimensionForUnit(TranslateUnit(sbmlUnit)) ?? _moBiDimensionFactory.NoDimension; } public (double value, IDimension dimension) ToMobiBaseUnit(string unit, double value) { - if (_unitConvertionDictionary.ContainsKey(unit)) + if (_unitConversionDictionary.ContainsKey(unit)) { - var convertionData = _unitConvertionDictionary[unit]; - return (convertionData.Dimension.UnitValueToBaseUnitValue(convertionData.Unit, value * convertionData.Rate), convertionData.Dimension); + var conversionData = _unitConversionDictionary[unit]; + return (conversionData.Dimension.UnitValueToBaseUnitValue(conversionData.Unit, value * conversionData.Rate), conversionData.Dimension); } + var dimension = DimensionFor(unit); return (dimension.UnitValueToBaseUnitValue(dimension.FindUnit(TranslateUnit(unit)), value), dimension); @@ -183,8 +201,7 @@ public IDimension DimensionFor(string sbmlUnit) public void Start() { - _unitConvertionDictionary.Clear(); + _unitConversionDictionary.Clear(); } } - } \ No newline at end of file diff --git a/src/MoBi.Presentation/MoBi.Presentation.csproj b/src/MoBi.Presentation/MoBi.Presentation.csproj index 1a2702ca3..9f431dcb3 100644 --- a/src/MoBi.Presentation/MoBi.Presentation.csproj +++ b/src/MoBi.Presentation/MoBi.Presentation.csproj @@ -28,12 +28,12 @@ - + - + - + diff --git a/src/MoBi.UI/MoBi.UI.csproj b/src/MoBi.UI/MoBi.UI.csproj index dbe9e79d2..46a767b1b 100644 --- a/src/MoBi.UI/MoBi.UI.csproj +++ b/src/MoBi.UI/MoBi.UI.csproj @@ -27,13 +27,13 @@ - - - - + + + + - + diff --git a/src/MoBi.UI/Views/EditEventBuilderView.Designer.cs b/src/MoBi.UI/Views/EditEventBuilderView.Designer.cs index a00da9e3e..8c75d1645 100644 --- a/src/MoBi.UI/Views/EditEventBuilderView.Designer.cs +++ b/src/MoBi.UI/Views/EditEventBuilderView.Designer.cs @@ -413,7 +413,6 @@ private void InitializeComponent() private DevExpress.XtraLayout.LayoutControlItem layoutControlItemOneTime; private DevExpress.XtraEditors.MemoExEdit htmlEditor; private DevExpress.XtraLayout.LayoutControlItem layoutControlItemDescription; - private DevExpress.XtraGrid.GridControl gridControl1; private UxGridView gridViewAssignments; private DevExpress.XtraEditors.SimpleButton btnAddAssignment; private DevExpress.XtraEditors.SplitContainerControl splitContainerControl; diff --git a/src/MoBi/MoBi.csproj b/src/MoBi/MoBi.csproj index 6d02b5d80..1f7487a55 100644 --- a/src/MoBi/MoBi.csproj +++ b/src/MoBi/MoBi.csproj @@ -68,13 +68,13 @@ - + - + diff --git a/tests/MoBi.Tests/Core/SBML/UnitImporterSpecs.cs b/tests/MoBi.Tests/Core/SBML/UnitImporterSpecs.cs index 4da2c293c..4e46fa408 100644 --- a/tests/MoBi.Tests/Core/SBML/UnitImporterSpecs.cs +++ b/tests/MoBi.Tests/Core/SBML/UnitImporterSpecs.cs @@ -1,108 +1,87 @@ using System.Linq; -using OSPSuite.BDDHelper; -using OSPSuite.BDDHelper.Extensions; -using OSPSuite.Utility.Container; using FakeItEasy; using libsbmlcs; using MoBi.Core.Commands; using MoBi.Core.Domain.Model; -using MoBi.Core.Domain.UnitSystem; using MoBi.Engine.Sbml; +using OSPSuite.BDDHelper; +using OSPSuite.BDDHelper.Extensions; using OSPSuite.Core.Domain; -using OSPSuite.Core.Domain.UnitSystem; +using OSPSuite.Utility.Container; using Model = libsbmlcs.Model; -using Unit = libsbmlcs.Unit; namespace MoBi.Core.SBML { public abstract class UnitImporterSpecs : ContextForSBMLIntegration { - private Model _sbmlModel; + public Model _sbmlModel; protected override void Context() { base.Context(); _sbmlModel = new Model(3, 1); } + } + + public class UnitDefinitionImporterTests : UnitImporterSpecs + { + private Unit _unit; + private UnitDefinition _unitDef; + private Unit _unit2; + private UnitDefinition _unitDef2; + private Unit _unit3; + private UnitDefinition _unitDef3; + + protected override void Because() + { + sut = IoC.Resolve(); + //create unit "substance" + _unit = new Unit(3, 1); + _unit.setExponent(1); + _unit.setMultiplier(1.0); + _unit.setScale(0); + _unit.setKind(libsbml.UNIT_KIND_MOLE); + + //create unitdef "substance" + _unitDef = _sbmlModel.createUnitDefinition(); + _unitDef.setId("substance"); + _unitDef.setName("substance"); + _unitDef.addUnit(_unit); + + //create unit "volume" + _unit2 = _sbmlModel.createUnit(); + _unit2.setExponent(1); + _unit2.setMultiplier(1.0); + _unit2.setScale(0); + _unit2.setKind(libsbml.UnitKind_forName("volume")); + + //create unitdef "volume" + _unitDef2 = _sbmlModel.createUnitDefinition(); + _unitDef2.setId("volume"); + _unitDef2.setName("volume"); + _unitDef2.addUnit(_unit2); + + _unit3 = _sbmlModel.createUnit(); + _unit3.setExponent(-1); + _unit3.setMultiplier(1 / 86400.0); //86400 seconds in one day + _unit3.setScale(0); + _unit3.setKind(libsbml.UnitKind_forName("second")); + + _unitDef3 = _sbmlModel.createUnitDefinition(); + _unitDef3.setId("inverse_day"); + _unitDef3.setName("1/d"); + _unitDef3.addUnit(_unit3); + + + _sbmlModel.addUnitDefinition(_unitDef); + sut.DoImport(_sbmlModel, new MoBiProject(), A.Fake(), new MoBiMacroCommand()); + } - public class UnitDefinitionImporterTests : UnitImporterSpecs + [Observation] + public void NewDimensionsTests() { - private Unit _unit; - private UnitDefinition _unitDef; - private Unit _unit2; - private UnitDefinition _unitDef2; - private Unit _unit3; - private UnitDefinition _unitDef3; - private IDimension _volumeDimension; - private IMoBiDimensionFactory _dimensionFactoy; - - protected override void Because() - { - _dimensionFactoy = IoC.Resolve(); - sut = new UnitDefinitionImporter(IoC.Resolve(), IoC.Resolve(), _dimensionFactoy, IoC.Resolve(), A.Fake(), A.Fake()); - //create unit "substance" - _unit = new Unit(3, 1); - _unit.setExponent(1); - _unit.setMultiplier(1.0); - _unit.setScale(0); - _unit.setKind(libsbml.UNIT_KIND_MOLE); - - //create unitdef "substance" - _unitDef = _sbmlModel.createUnitDefinition(); - _unitDef.setId("substance"); - _unitDef.setName("substance"); - _unitDef.addUnit(_unit); - - //create unit "volume" - _unit2 = _sbmlModel.createUnit(); - _unit2.setExponent(1); - _unit2.setMultiplier(1.0); - _unit2.setScale(0); - _unit2.setKind(libsbml.UnitKind_forName("volume")); - - //create unitdef "volume" - _unitDef2 = _sbmlModel.createUnitDefinition(); - _unitDef2.setId("volume"); - _unitDef2.setName("volume"); - _unitDef2.addUnit(_unit2); - - _unit3 = _sbmlModel.createUnit(); - _unit3.setExponent(-1); - _unit3.setMultiplier(86400.0); //86400 seconds in one day - _unit3.setScale(0); - _unit3.setKind(libsbml.UnitKind_forName("second")); - - _unitDef3 = _sbmlModel.createUnitDefinition(); - _unitDef3.setId("inverse_day"); - _unitDef3.setName("1/d"); - _unitDef3.addUnit(_unit3); - - - _sbmlModel.addUnitDefinition(_unitDef); - sut.DoImport(_sbmlModel, new MoBiProject(), A.Fake(), new MoBiMacroCommand()); - _volumeDimension = _dimensionFactoy.Dimension("Volume"); - } - - [Observation] - public void NotNullTest() - { - _volumeDimension.ShouldNotBeNull(); - } - - [Observation] - public void UnitImporterTest() - { - _volumeDimension.ShouldNotBeNull(); - _volumeDimension.Name.ShouldBeEqualTo("Volume"); - _volumeDimension.DefaultUnit.Name.ShouldBeEqualTo("l"); - } - - [Observation] - public void NewDimensionsTests() - { - sut.ToMobiBaseUnit("substance", 3e6).value.ShouldBeEqualTo(3e12); - sut.ToMobiBaseUnit("inverse_day", 0.83).value.ShouldBeEqualTo(0.83/1440); //base unit is in minutes so 1440 minutes in one day - } + sut.ToMobiBaseUnit("substance", 3e6).value.ShouldBeEqualTo(3e12); + sut.ToMobiBaseUnit("inverse_day", 10).value.ShouldBeEqualTo(10.0 / 1440); //base unit is in minutes so 1440 minutes in one day } } @@ -117,7 +96,7 @@ protected override void Context() [Observation] public void ParameterWithVolumeUnitTest() { - var tc = _moBiProject.SpatialStructureCollection.FirstOrDefault().TopContainers.FirstOrDefault(); + var tc = _moBiProject.SpatialStructureCollection.First().TopContainers.First(); var parameter = tc.GetSingleChildByName("k1"); parameter.ShouldNotBeNull(); parameter.DisplayUnit.ToString().ShouldBeEqualTo("l"); @@ -126,7 +105,7 @@ public void ParameterWithVolumeUnitTest() [Observation] public void SpeciesWithAmountUnitTest() { - var mbb = _moBiProject.MoleculeBlockCollection.FirstOrDefault(); + var mbb = _moBiProject.MoleculeBlockCollection.First(); var mol = mbb.FindByName("s1"); mol.ShouldNotBeNull(); mol.Dimension.ShouldNotBeNull(); @@ -136,7 +115,7 @@ public void SpeciesWithAmountUnitTest() [Observation] public void SpeciesWithConcentrationUnitTest() { - var mbb = _moBiProject.MoleculeBlockCollection.FirstOrDefault(); + var mbb = _moBiProject.MoleculeBlockCollection.First(); var mol = mbb.FindByName("s2"); mol.ShouldNotBeNull(); mol.Dimension.ShouldNotBeNull(); @@ -155,8 +134,8 @@ protected override void Context() [Observation] public void should_find_combined_dimensions() { - var tc = _moBiProject.SpatialStructureCollection.FirstOrDefault().TopContainers.FirstOrDefault(); - var parameter = tc.GetSingleChildByName("Vmax_ATPASE"); + var tc = _moBiProject.SpatialStructureCollection.First().TopContainers.First(); + var parameter = tc.Parameter("Vmax_ATPASE"); parameter.ShouldNotBeNull(); parameter.DisplayUnit.ToString().ShouldBeEqualTo("kat"); } diff --git a/tests/MoBi.Tests/MoBi.Tests.csproj b/tests/MoBi.Tests/MoBi.Tests.csproj index bfd3bf8d4..fd0f22c6b 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 0c4014256..813dafbbe 100644 --- a/tests/MoBi.UI.Tests/MoBi.UI.Tests.csproj +++ b/tests/MoBi.UI.Tests/MoBi.UI.Tests.csproj @@ -17,8 +17,8 @@ - - + +