diff --git a/nuget_to_mobi.bat b/nuget_to_mobi.bat new file mode 100644 index 000000000..f68c270ea --- /dev/null +++ b/nuget_to_mobi.bat @@ -0,0 +1,4 @@ +@echo off +cls +rake create_local_nuget[-m] +pause \ No newline at end of file diff --git a/nuget_to_pksim.bat b/nuget_to_pksim.bat new file mode 100644 index 000000000..2f5bab19e --- /dev/null +++ b/nuget_to_pksim.bat @@ -0,0 +1,4 @@ +@echo off +cls +rake create_local_nuget[-p] +pause \ No newline at end of file diff --git a/rakefile.rb b/rakefile.rb index 735a43b62..e3aa93dbd 100644 --- a/rakefile.rb +++ b/rakefile.rb @@ -26,32 +26,88 @@ Coverage.cover(filter, targetProjects) end - task :copy_to_pksim do - copy_to_app '../PK-Sim/src/PKSim/bin/Debug/net472' +task :copy_to_pksim do + copy_to_app '../PK-Sim/src/PKSim/bin/Debug/net472' +end + +task :copy_to_mobi do + copy_to_app '../MoBi/src/MoBi/bin/Debug/net472' +end + +task :create_local_nuget, [:arg1, :arg2] do |t, args| + FileUtils.rm_f Dir.glob("./nuget_repo/*.nupkg") + versionId = "12.0.0-" + generate_code(5) + puts("Your version is " + versionId.red) + system("dotnet", "pack", "-p:PackageVersion="+ versionId, "--configuration", "Debug", "--output", "nuget_repo", "--no-build") + + if args.to_hash.values.include? "-m" + update_mobi(versionId) end - - task :copy_to_mobi do - copy_to_app '../MoBi/src/MoBi/bin/Debug/net472' + if args.to_hash.values.include? "-p" + update_pksim(versionId) end - - private - - def copy_to_app(app_target_relative_path) - app_target_path = File.join(solution_dir, app_target_relative_path) - source_dir = File.join(tests_dir, 'OSPSuite.Starter', 'bin', 'Debug', "net472") - - copy_dependencies source_dir, app_target_path do - copy_file 'OSPSuite.*.dll' - copy_file 'OSPSuite.*.pdb' - end - + +end + +private +def find_token(file, regex) + file_content = str = IO.read(file) + matches = file_content.match(regex) + + if(matches.nil?) + return nil end - - def solution_dir - File.dirname(__FILE__) + return matches[1] +end + +def update_mobi(versionId) + puts("updating MoBi") + token = find_token("../MoBi/src/MoBi/MoBi.csproj", / versionId}, file) end + +end + +def update_pksim(versionId) + puts("updating PKSim") + token = find_token("../PK-Sim/src/PKSim/PKSim.csproj", / versionId}, file) + end +end + +def generate_code(number) + charset = Array('A'..'Z') + Array('a'..'z') + Array.new(number) { charset.sample }.join +end + +def copy_to_app(app_target_relative_path) + app_target_path = File.join(solution_dir, app_target_relative_path) + source_dir = File.join(tests_dir, 'OSPSuite.Starter', 'bin', 'Debug', "net472") + + copy_dependencies source_dir, app_target_path do + copy_file 'OSPSuite.*.dll' + copy_file 'OSPSuite.*.pdb' +end + +end + +def solution_dir + File.dirname(__FILE__) +end + +def tests_dir + File.join(solution_dir, 'tests') +end \ No newline at end of file diff --git a/src/OSPSuite.Assets/IconNames.cs b/src/OSPSuite.Assets/IconNames.cs index 9fcee828a..8337c74da 100644 --- a/src/OSPSuite.Assets/IconNames.cs +++ b/src/OSPSuite.Assets/IconNames.cs @@ -55,5 +55,8 @@ public static class IconNames public const string MOBI = "MoBi"; public const string PARAMETER_IDENTIFICATION = "ParameterIdentification"; public const string SENSITIVITY_ANALYSIS = "SensitivityAnalysis"; + public static string Transporter = "Transporter"; + public static string Protein = "Protein"; + public static string Enzyme = "Enzyme"; } } \ No newline at end of file diff --git a/src/OSPSuite.Assets/UIConstants.cs b/src/OSPSuite.Assets/UIConstants.cs index 0fd31f7a9..0b27ed655 100644 --- a/src/OSPSuite.Assets/UIConstants.cs +++ b/src/OSPSuite.Assets/UIConstants.cs @@ -18,6 +18,11 @@ public static class SizeAndLocation public static class Captions { + public static readonly string Transporter = "Transporter"; + public static readonly string Protein = "Protein"; + public static readonly string Enzyme = "Enzyme"; + public static readonly string Species = "Species"; + public static readonly string Category = "Category"; public static readonly string ConfirmationDialog = "Confirmation"; public static readonly string Excel = "Excel®"; public static readonly string EmptyColumn = " "; @@ -2294,6 +2299,7 @@ public static class ObjectTypes public static readonly string Formulation = "Formulation"; public static readonly string SensitivityParameter = "Sensitivity Parameter"; public static readonly string SensitivityAnalysis = "Sensitivity Analysis"; + public static readonly string ExpressionProfileBuildingBlock = "Expression Profile Building Block"; } public static class ToolTips diff --git a/src/OSPSuite.Core/Comparison/BuildingBlockDiffBuilder.cs b/src/OSPSuite.Core/Comparison/BuildingBlockDiffBuilder.cs index 13c29b011..4dd25d4ee 100644 --- a/src/OSPSuite.Core/Comparison/BuildingBlockDiffBuilder.cs +++ b/src/OSPSuite.Core/Comparison/BuildingBlockDiffBuilder.cs @@ -4,15 +4,15 @@ namespace OSPSuite.Core.Comparison { - public abstract class BuildingBlockDiffBuilder : DiffBuilder> where T : class, IObjectBase + public abstract class BuildingBlockDiffBuilder : DiffBuilder where TBuildingBlock : class, IBuildingBlock where TBuilder : class, IObjectBase { private readonly ObjectBaseDiffBuilder _objectBaseDiffBuilder; private readonly EnumerableComparer _enumerableComparer; - private readonly Func _equalityProperty; - protected Func _presentObjectDetailsFunc; + private readonly Func _equalityProperty; + protected Func _presentObjectDetailsFunc; protected BuildingBlockDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, - EnumerableComparer enumerableComparer, Func equalityProperty) + EnumerableComparer enumerableComparer, Func equalityProperty) { _objectBaseDiffBuilder = objectBaseDiffBuilder; _equalityProperty = equalityProperty; @@ -24,21 +24,21 @@ protected BuildingBlockDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, { } - public override void Compare(IComparison> comparison) + public override void Compare(IComparison comparison) { _objectBaseDiffBuilder.Compare(comparison); _enumerableComparer.CompareEnumerables(comparison, x => x, _equalityProperty, _presentObjectDetailsFunc); } } - public class MoleculeBuildingBlockDiffBuilder : BuildingBlockDiffBuilder + public class MoleculeBuildingBlockDiffBuilder : BuildingBlockDiffBuilder { public MoleculeBuildingBlockDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, EnumerableComparer enumerableComparer) : base(objectBaseDiffBuilder, enumerableComparer) { } } - public class SpatialStructureDiffBuilder : BuildingBlockDiffBuilder + public class SpatialStructureDiffBuilder : BuildingBlockDiffBuilder { public SpatialStructureDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, EnumerableComparer enumerableComparer) : base(objectBaseDiffBuilder, enumerableComparer) @@ -46,14 +46,14 @@ public SpatialStructureDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, } } - public class ReactionBuildingBlockDiffBuilder : BuildingBlockDiffBuilder + public class ReactionBuildingBlockDiffBuilder : BuildingBlockDiffBuilder { public ReactionBuildingBlockDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, EnumerableComparer enumerableComparer) : base(objectBaseDiffBuilder, enumerableComparer) { } } - public class PassiveTransportBuildingBlockDiffBuilder : BuildingBlockDiffBuilder + public class PassiveTransportBuildingBlockDiffBuilder : BuildingBlockDiffBuilder { public PassiveTransportBuildingBlockDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, EnumerableComparer enumerableComparer) : base(objectBaseDiffBuilder, enumerableComparer) @@ -61,7 +61,7 @@ public PassiveTransportBuildingBlockDiffBuilder(ObjectBaseDiffBuilder objectBase } } - public class EventGroupBuildingBlocksDiffBuilder : BuildingBlockDiffBuilder + public class EventGroupBuildingBlocksDiffBuilder : BuildingBlockDiffBuilder { public EventGroupBuildingBlocksDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, EnumerableComparer enumerableComparer) : base(objectBaseDiffBuilder, enumerableComparer) @@ -69,7 +69,7 @@ public EventGroupBuildingBlocksDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffB } } - public class ObserverBuildingBlocksDiffBuilder : BuildingBlockDiffBuilder + public class ObserverBuildingBlocksDiffBuilder : BuildingBlockDiffBuilder { public ObserverBuildingBlocksDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, EnumerableComparer enumerableComparer) : base(objectBaseDiffBuilder, enumerableComparer) @@ -77,7 +77,7 @@ public ObserverBuildingBlocksDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBui } } - public abstract class StartValueBuildingBlockDiffBuilder : BuildingBlockDiffBuilder where TStartValue : class, IStartValue + public abstract class StartValueBuildingBlockDiffBuilder : BuildingBlockDiffBuilder where TStartValue : class, IStartValue where TBuildingBlock : class, IBuildingBlock { private readonly UnitFormatter _unitFormatter = new UnitFormatter(); @@ -101,14 +101,14 @@ private string startValueDisplayFor(TStartValue startValue) } } - public class MoleculeStartValueBuildingBlockDiffBuilder : StartValueBuildingBlockDiffBuilder + public class MoleculeStartValueBuildingBlockDiffBuilder : StartValueBuildingBlockDiffBuilder { public MoleculeStartValueBuildingBlockDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, EnumerableComparer enumerableComparer) : base(objectBaseDiffBuilder, enumerableComparer) { } } - public class ParameterStartValueBuildingBlockDiffBuilder : StartValueBuildingBlockDiffBuilder + public class ParameterStartValueBuildingBlockDiffBuilder : StartValueBuildingBlockDiffBuilder { public ParameterStartValueBuildingBlockDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, EnumerableComparer enumerableComparer) : base(objectBaseDiffBuilder, enumerableComparer) { diff --git a/src/OSPSuite.Core/Comparison/ExpressionProfileDiffBuilder.cs b/src/OSPSuite.Core/Comparison/ExpressionProfileDiffBuilder.cs new file mode 100644 index 000000000..a45c8ea48 --- /dev/null +++ b/src/OSPSuite.Core/Comparison/ExpressionProfileDiffBuilder.cs @@ -0,0 +1,27 @@ +using OSPSuite.Core.Domain.Builder; + +namespace OSPSuite.Core.Comparison +{ + public class ExpressionProfileBuildingBlockDiffBuilder : BuildingBlockDiffBuilder + { + public ExpressionProfileBuildingBlockDiffBuilder(ObjectBaseDiffBuilder objectBaseDiffBuilder, EnumerableComparer enumerableComparer) : base(objectBaseDiffBuilder, enumerableComparer) + { + + } + + public override void Compare(IComparison comparison) + { + base.Compare(comparison); + CompareValues(x => x.PKSimVersion, x => x.PKSimVersion, comparison); + CompareStringValues(x => x.Name, x => x.Name, comparison); + CompareValues(x => x.Type, x => x.Type, comparison); + } + } + + internal class ExpressionParameterDiffBuilder : StartValueDiffBuilder + { + public ExpressionParameterDiffBuilder(IObjectComparer objectComparer, EntityDiffBuilder entityDiffBuilder, WithValueOriginComparison valueOriginComparison) : base(objectComparer, entityDiffBuilder, valueOriginComparison) + { + } + } +} diff --git a/src/OSPSuite.Core/Domain/Builder/ExpressionParameter.cs b/src/OSPSuite.Core/Domain/Builder/ExpressionParameter.cs new file mode 100644 index 000000000..cb7814211 --- /dev/null +++ b/src/OSPSuite.Core/Domain/Builder/ExpressionParameter.cs @@ -0,0 +1,22 @@ +using OSPSuite.Core.Domain.Services; + +namespace OSPSuite.Core.Domain.Builder +{ + public class ExpressionParameter : PathAndValueEntity, IStartValue + { + /// + /// Do not use! When refactoring on promotion to core, this should be removed + /// + public double? StartValue { get; set; } + + public override void UpdatePropertiesFrom(IUpdatable source, ICloneManager cloneManager) + { + base.UpdatePropertiesFrom(source, cloneManager); + + if (!(source is ExpressionParameter sourceExpressionParameter)) + return; + + StartValue = sourceExpressionParameter.StartValue; + } + } +} \ No newline at end of file diff --git a/src/OSPSuite.Core/Domain/Builder/ExpressionProfileBuildingBlock.cs b/src/OSPSuite.Core/Domain/Builder/ExpressionProfileBuildingBlock.cs new file mode 100644 index 000000000..6545a15a6 --- /dev/null +++ b/src/OSPSuite.Core/Domain/Builder/ExpressionProfileBuildingBlock.cs @@ -0,0 +1,55 @@ +using OSPSuite.Core.Domain.Services; +using static OSPSuite.Core.Domain.Constants.ContainerName; + +namespace OSPSuite.Core.Domain.Builder +{ + public class ExpressionProfileBuildingBlock : StartValueBuildingBlock + { + public override string Icon => Type.IconName; + + public virtual string MoleculeName { get; private set; } + + public string Species { get; private set; } + + public ExpressionType Type { set; get; } + + public string PKSimVersion { set; get; } + + public virtual string Category { get; private set; } + + public override string Name + { + get => ExpressionProfileName(MoleculeName, Species, Category); + set + { + if (string.Equals(Name, value)) + { + return; + } + + var (moleculeName, species, category) = NamesFromExpressionProfileName(value); + if (string.IsNullOrEmpty(moleculeName)) + return; + + Species = species; + Category = category; + MoleculeName = moleculeName; + OnPropertyChanged(() => Name); + } + } + + public override void UpdatePropertiesFrom(IUpdatable source, ICloneManager cloneManager) + { + base.UpdatePropertiesFrom(source, cloneManager); + var sourceExpressionProfile = source as ExpressionProfileBuildingBlock; + if (sourceExpressionProfile == null) return; + + Type = sourceExpressionProfile.Type; + PKSimVersion = sourceExpressionProfile.PKSimVersion; + + // Name is required because our base objects will the private property + // But in this case the name is decomposed and stored in 3 other properties + Name = sourceExpressionProfile.Name; + } + } +} \ No newline at end of file diff --git a/src/OSPSuite.Core/Domain/Builder/ExpressionTypes.cs b/src/OSPSuite.Core/Domain/Builder/ExpressionTypes.cs new file mode 100644 index 000000000..a018e5dec --- /dev/null +++ b/src/OSPSuite.Core/Domain/Builder/ExpressionTypes.cs @@ -0,0 +1,50 @@ +using OSPSuite.Utility.Collections; + +namespace OSPSuite.Core.Domain.Builder +{ + + public enum ExpressionTypesId + { + Transport, + Enzyme, + BindingPartner + } + + public static class ExpressionTypes + { + public static ExpressionType TransportProtein = new ExpressionType(ExpressionTypesId.Transport, Assets.IconNames.Transporter, Assets.Captions.Transporter); + public static ExpressionType MetabolizingEnzyme = new ExpressionType(ExpressionTypesId.Enzyme, Assets.IconNames.Enzyme, Assets.Captions.Enzyme); + public static ExpressionType ProteinBindingPartner = new ExpressionType(ExpressionTypesId.BindingPartner, Assets.IconNames.Protein, Assets.Captions.Protein); + + private static readonly ICache _typesCache = new Cache(x => x.Id) + { + TransportProtein, + MetabolizingEnzyme, + ProteinBindingPartner + }; + + public static ExpressionType ById(ExpressionTypesId expressionTypeId) + { + return _typesCache[expressionTypeId]; + } + } + + public class ExpressionType + { + public ExpressionTypesId Id { get; } + public string IconName { get; } + public string DisplayName { get; } + public ExpressionType(ExpressionTypesId expressionTypesId, string iconName, string displayName) + { + Id = expressionTypesId; + IconName = iconName; + DisplayName = displayName; + } + + public override string ToString() + { + return DisplayName; + } + + } +} diff --git a/src/OSPSuite.Core/Domain/Builder/PathAndValueEntity.cs b/src/OSPSuite.Core/Domain/Builder/PathAndValueEntity.cs new file mode 100644 index 000000000..8afb73efc --- /dev/null +++ b/src/OSPSuite.Core/Domain/Builder/PathAndValueEntity.cs @@ -0,0 +1,151 @@ +using System; +using System.Linq; +using OSPSuite.Core.Domain.Formulas; +using OSPSuite.Core.Domain.Services; +using OSPSuite.Core.Domain.UnitSystem; + +namespace OSPSuite.Core.Domain.Builder +{ + public abstract class PathAndValueEntity : Entity, IUsingFormula, IWithDisplayUnit, IWithValueOrigin + { + private IObjectPath _containerPath; + protected IFormula _formula; + private Unit _displayUnit; + private IDimension _dimension; + private double? _value; + + protected PathAndValueEntity() + { + Dimension = Constants.Dimension.NO_DIMENSION; + Value = null; + ContainerPath = ObjectPath.Empty; + ValueOrigin = new ValueOrigin(); + } + + private void entityFullPathToComponents(IObjectPath fullPath) + { + if (fullPath.Any()) + { + Name = fullPath.Last(); + ContainerPath = fullPath.Clone(); + if (ContainerPath.Count > 0) + ContainerPath.RemoveAt(ContainerPath.Count - 1); + } + else + { + Name = string.Empty; + ContainerPath = ObjectPath.Empty; + } + } + + public IObjectPath ContainerPath + { + get => _containerPath; + set => SetProperty(ref _containerPath, value); + } + + public IFormula Formula + { + get => _formula; + set => SetProperty(ref _formula, value); + } + + public IDimension Dimension + { + get => _dimension; + set => SetProperty(ref _dimension, value); + } + + public Unit DisplayUnit + { + get => _displayUnit ?? Dimension.DefaultUnit; + set => SetProperty(ref _displayUnit, value); + } + + public ValueOrigin ValueOrigin { get; } + + public IObjectPath Path + { + get => ContainerPath.Clone().AndAdd(Name); + set => entityFullPathToComponents(value); + } + + public void UpdateValueOriginFrom(ValueOrigin sourceValueOrigin) + { + if (Equals(ValueOrigin, sourceValueOrigin)) + return; + + ValueOrigin.UpdateFrom(sourceValueOrigin); + OnPropertyChanged(() => ValueOrigin); + } + + /// + /// Tests whether or not the value is public-member-equivalent to the target + /// + /// The comparable object + /// True if all the public members are equal, otherwise false + protected bool IsEquivalentTo(PathAndValueEntity target) + { + if (ReferenceEquals(this, target)) + return true; + + return + NullableEqualsCheck(ContainerPath, target.ContainerPath) && + NullableEqualsCheck(Path, target.Path) && + Value.HasValue == target.Value.HasValue && + (!Value.HasValue || ValueComparer.AreValuesEqual(Value.GetValueOrDefault(), target.Value.GetValueOrDefault())) && + NullableEqualsCheck(Formula, target.Formula, x => x.ToString()) && + NullableEqualsCheck(Dimension, target.Dimension, x => x.ToString()) && + NullableEqualsCheck(Icon, target.Icon) && + NullableEqualsCheck(Description, target.Description) && + NullableEqualsCheck(Name, target.Name); + } + + /// + /// Compares two objects of the same type first checking for null, then for .Equals + /// + /// The type being compared + /// The first element being compared + /// The second element being compared + /// + /// An optional transform done on the parameter before .Equals. Often this is .ToString + /// making the the comparison the same as first.ToString().Equals(second.ToString()) + /// + /// + /// The result of the transform and .Equals calls as outlined if first is not null. If first is null, returns true + /// if second is null + /// + protected bool NullableEqualsCheck(T first, T second, Func transform = null) where T : class + { + if (first == null) + return second == null; + + if (second == null) + return false; + + return transform?.Invoke(first).Equals(transform(second)) ?? first.Equals(second); + } + + public double? Value + { + get => _value; + set => SetProperty(ref _value, value); + } + + public override void UpdatePropertiesFrom(IUpdatable source, ICloneManager cloneManager) + { + base.UpdatePropertiesFrom(source, cloneManager); + var sourcePathAndValueEntity = source as PathAndValueEntity; + if (sourcePathAndValueEntity == null) return; + + Value = sourcePathAndValueEntity.Value; + ContainerPath = sourcePathAndValueEntity.ContainerPath.Clone(); + DisplayUnit = sourcePathAndValueEntity.DisplayUnit; + Dimension = sourcePathAndValueEntity.Dimension; + Formula = cloneManager.Clone(sourcePathAndValueEntity.Formula); + ValueOrigin.UpdateAllFrom(sourcePathAndValueEntity.ValueOrigin); + } + + public override string ToString() => $"Path={ContainerPath}, Name={Name}"; + } +} \ No newline at end of file diff --git a/src/OSPSuite.Core/Domain/Constants.cs b/src/OSPSuite.Core/Domain/Constants.cs index 973351675..e44fecc62 100644 --- a/src/OSPSuite.Core/Domain/Constants.cs +++ b/src/OSPSuite.Core/Domain/Constants.cs @@ -3,6 +3,7 @@ using System.Linq; using OSPSuite.Core.Domain.UnitSystem; using OSPSuite.Core.Serialization; +using OSPSuite.Utility.Extensions; namespace OSPSuite.Core.Domain { @@ -486,6 +487,41 @@ public static class RemoveLLOQMode public const string ALWAYS = "Always"; } + public static class ContainerName + { + public static string ExpressionProfileName(string moleculeName, string species, string category) + => compositeNameFor(char.Parse(ObjectPath.PATH_DELIMITER), moleculeName, species, category); + + public static (string moleculeName, string speciesName, string category) NamesFromExpressionProfileName(string expressionProfileName) + { + var names = NamesFromCompositeName(expressionProfileName, char.Parse(ObjectPath.PATH_DELIMITER)); + if (names.Count != 3) + return (string.Empty, string.Empty, string.Empty); + + return (names[0], names[1], names[2]); + } + } + + public const char COMPOSITE_SEPARATOR = '-'; + + public static IReadOnlyList NamesFromCompositeName(string compositeName, char separator = COMPOSITE_SEPARATOR) + { + return compositeName.Split(separator); + } + + private static string compositeNameFor(char separator, params string[] names) + { + if (names == null || names.Length == 0) + return string.Empty; + + var nonEmptyNames = names.ToList(); + nonEmptyNames.RemoveAll(string.IsNullOrEmpty); + + return nonEmptyNames.Select(x => x.Trim()).ToString($"{separator}"); + } + + public static string CompositeNameFor(params string[] names) => compositeNameFor(COMPOSITE_SEPARATOR, names); + public static class Serialization { public const string MACRO_COMMAND = "MacroCommand"; diff --git a/src/OSPSuite.Core/Serialization/Xml/BuildingBlockXmlSerializer.cs b/src/OSPSuite.Core/Serialization/Xml/BuildingBlockXmlSerializer.cs index f49ceac5c..bb165e678 100644 --- a/src/OSPSuite.Core/Serialization/Xml/BuildingBlockXmlSerializer.cs +++ b/src/OSPSuite.Core/Serialization/Xml/BuildingBlockXmlSerializer.cs @@ -98,6 +98,15 @@ public override void PerformMapping() } } + public class ExpressionProfileBuildingBlockXmlSerializer : StartValuesBuildingBlockXmlSerializer + { + public override void PerformMapping() + { + base.PerformMapping(); + Map(x => x.Type); + } + } + public class MoleculeStartValuesBuildingBlockXmlSerializer : StartValuesBuildingBlockXmlSerializer { } diff --git a/src/OSPSuite.Core/Serialization/Xml/ExpressionParameterXmlSerializer.cs b/src/OSPSuite.Core/Serialization/Xml/ExpressionParameterXmlSerializer.cs new file mode 100644 index 000000000..1a1888938 --- /dev/null +++ b/src/OSPSuite.Core/Serialization/Xml/ExpressionParameterXmlSerializer.cs @@ -0,0 +1,13 @@ +using OSPSuite.Core.Domain.Builder; + +namespace OSPSuite.Core.Serialization.Xml +{ + public class ExpressionParameterXmlSerializer : PathAndValueEntityXmlSerializer + { + public override void PerformMapping() + { + base.PerformMapping(); + Map(x => x.StartValue); + } + } +} \ No newline at end of file diff --git a/src/OSPSuite.Core/Serialization/Xml/ExpressionTypeXmlAttributeMapper.cs b/src/OSPSuite.Core/Serialization/Xml/ExpressionTypeXmlAttributeMapper.cs new file mode 100644 index 000000000..f2ef86661 --- /dev/null +++ b/src/OSPSuite.Core/Serialization/Xml/ExpressionTypeXmlAttributeMapper.cs @@ -0,0 +1,20 @@ +using OSPSuite.Core.Domain.Builder; +using OSPSuite.Serializer.Attributes; +using OSPSuite.Utility; + +namespace OSPSuite.Core.Serialization.Xml +{ + public class ExpressionTypeXmlAttributeMapper : AttributeMapper + { + public override string Convert(ExpressionType valueToConvert, SerializationContext context) + { + return valueToConvert.Id.ToString(); + } + + public override object ConvertFrom(string attributeValue, SerializationContext context) + { + var expressionTypeId = EnumHelper.ParseValue(attributeValue); + return ExpressionTypes.ById(expressionTypeId); + } + } +} \ No newline at end of file diff --git a/src/OSPSuite.Core/Serialization/Xml/OSPSuiteXmlSerializerRepository.cs b/src/OSPSuite.Core/Serialization/Xml/OSPSuiteXmlSerializerRepository.cs index a44c3e9f0..48ddf103c 100644 --- a/src/OSPSuite.Core/Serialization/Xml/OSPSuiteXmlSerializerRepository.cs +++ b/src/OSPSuite.Core/Serialization/Xml/OSPSuiteXmlSerializerRepository.cs @@ -58,8 +58,9 @@ protected override void AddInitialMappers() AttributeMapperRepository.AddAttributeMapper(new ValueOriginSourceXmlAttributeMapper()); AttributeMapperRepository.AddAttributeMapper(new ValueOriginDeterminationMethodXmlAttributeMapper()); AttributeMapperRepository.AddAttributeMapper(new RunStatusXmlAttributeMapper()); + AttributeMapperRepository.AddAttributeMapper(new ExpressionTypeXmlAttributeMapper()); + - AttributeMapperRepository.ReferenceMapper = new ObjectReferenceMapper(); } diff --git a/src/OSPSuite.Core/Serialization/Xml/PathAndValueEntityXmlSerializer.cs b/src/OSPSuite.Core/Serialization/Xml/PathAndValueEntityXmlSerializer.cs new file mode 100644 index 000000000..779edc6f1 --- /dev/null +++ b/src/OSPSuite.Core/Serialization/Xml/PathAndValueEntityXmlSerializer.cs @@ -0,0 +1,15 @@ +using OSPSuite.Core.Domain.Builder; + +namespace OSPSuite.Core.Serialization.Xml +{ + public abstract class PathAndValueEntityXmlSerializer : EntityXmlSerializer where T : PathAndValueEntity + { + public override void PerformMapping() + { + base.PerformMapping(); + Map(x => x.Dimension); + Map(x => x.ContainerPath); + MapReference(x => x.Formula); + } + } +} \ No newline at end of file diff --git a/tests/OSPSuite.Core.IntegrationTests/Helpers/AssertForSpecs.cs b/tests/OSPSuite.Core.IntegrationTests/Helpers/AssertForSpecs.cs index bb7fca8ab..da7943f03 100644 --- a/tests/OSPSuite.Core.IntegrationTests/Helpers/AssertForSpecs.cs +++ b/tests/OSPSuite.Core.IntegrationTests/Helpers/AssertForSpecs.cs @@ -1071,6 +1071,17 @@ public static void AreEqualParameterStartValue(IParameterStartValue x1, IParamet AreEqualFormula(x1.Formula, x2.Formula); } + public static void AreEqualExpressionParameters(ExpressionParameter x1, ExpressionParameter x2) + { + if (!AssertBothNotNull(x1, x2)) return; + AreEqualObjectPath(x1.Path, x2.Path); + AssertAreEqualNullableDouble(x1.StartValue, x2.StartValue); + AreEqualUnit(x1.DisplayUnit, x2.DisplayUnit); + AreEqualDimension(x1.Dimension, x2.Dimension); + AssertAreEqual(x1.ValueOrigin, x2.ValueOrigin); + AreEqualFormula(x1.Formula, x2.Formula); + } + public static void AreEqualBuildingBlock(IBuildingBlock x1, IBuildingBlock x2) { if (!AssertBothNotNull(x1, x2)) return; diff --git a/tests/OSPSuite.Core.IntegrationTests/Serializers/ExpressionParameterXmlSerializerSpecs.cs b/tests/OSPSuite.Core.IntegrationTests/Serializers/ExpressionParameterXmlSerializerSpecs.cs new file mode 100644 index 000000000..f75a5ca0a --- /dev/null +++ b/tests/OSPSuite.Core.IntegrationTests/Serializers/ExpressionParameterXmlSerializerSpecs.cs @@ -0,0 +1,31 @@ +using NUnit.Framework; +using OSPSuite.BDDHelper; +using OSPSuite.Core.Domain; +using OSPSuite.Core.Domain.Builder; +using OSPSuite.Core.Domain.Formulas; +using OSPSuite.Core.Helpers; + +namespace OSPSuite.Core.Serializers +{ + public class ExpressionParameterXmlSerializerSpecs : ModellingXmlSerializerBaseSpecs + { + [Observation] + public void TestSerialization() + { + var formula = CreateObject().WithName("F.Erika").WithDimension(DimensionLength).WithFormulaString("A * 2"); + var fup = new FormulaUsablePath("aa", "bb").WithAlias("b").WithDimension(DimensionLength); + formula.AddObjectPath(fup); + + + var x1 = new ExpressionParameter + { + StartValue = 2.0, + Formula = formula + }; + + var x2 = SerializeAndDeserialize(x1); + AssertForSpecs.AreEqualExpressionParameters(x2, x1); + } + + } +} diff --git a/tests/OSPSuite.Core.Tests/Domain/ExpressionParameterSpecs.cs b/tests/OSPSuite.Core.Tests/Domain/ExpressionParameterSpecs.cs new file mode 100644 index 000000000..ee10de109 --- /dev/null +++ b/tests/OSPSuite.Core.Tests/Domain/ExpressionParameterSpecs.cs @@ -0,0 +1,134 @@ +using OSPSuite.BDDHelper; +using OSPSuite.BDDHelper.Extensions; +using OSPSuite.Core.Domain.Builder; + +namespace OSPSuite.Core.Domain +{ + public abstract class concern_for_ExpressionParameter : ContextSpecification + { + protected override void Context() + { + sut = new ExpressionParameter() { ContainerPath = new ObjectPath("Path1", "Path2"), Name = "Name" }; + } + } + + public class When_instantiating_new_ExpressionParameter : concern_for_ExpressionParameter + { + [Observation] + public void name_should_be_last_element_in_ObjectPath() + { + sut.Name.ShouldBeEqualTo("Name"); + } + + [Observation] + public void container_path_should_be_equal_to_all_but_last_element() + { + sut.ContainerPath.ShouldOnlyContainInOrder("Path1", "Path2"); + } + + [Observation] + public void parameter_path_should_be_equal_to_container_path_plus_parameter_name() + { + sut.Path.ShouldOnlyContainInOrder("Path1", "Path2", "Name"); + } + } + + public class When_setting_expression_parameter_name : concern_for_MoleculeStartValue + { + protected override void Because() + { + sut.Name = "Name2"; + } + + [Observation] + public void parameter_name_should_be_updated() + { + sut.MoleculeName.ShouldBeEqualTo("Name2"); + } + + [Observation] + public void container_path_is_not_affected() + { + sut.ContainerPath.ShouldOnlyContainInOrder("Path1", "Path2"); + } + + [Observation] + public void parameter_path_should_reflect_new_name() + { + sut.Path.ShouldOnlyContainInOrder("Path1", "Path2", "Name2"); + } + } + + public abstract class When_testing_equivalency_in_expression_parameters : concern_for_MoleculeStartValue + { + protected MoleculeStartValue _comparable; + protected bool _result; + + protected override void Context() + { + sut = new MoleculeStartValue(); + _comparable = new MoleculeStartValue(); + + sut.IsPresent = true; + _comparable.IsPresent = true; + + sut.Path = new ObjectPath("A", "B", "MoleculeName"); + _comparable.Path = new ObjectPath("A", "B", "MoleculeName"); + + sut.ScaleDivisor = 1.0; + _comparable.ScaleDivisor = 1.0; + } + + protected override void Because() + { + _result = sut.IsEquivalentTo(_comparable); + } + } + + public abstract class expression_parameter_equivalency_should_test_negative : When_testing_equivalency_in_expression_parameters + { + [Observation] + public void should_not_be_equivalent() + { + _result.ShouldBeFalse(); + } + } + + public class When_testing_expression_parameters_with_different_scale_factor : equivalency_should_test_negative + { + protected override void Context() + { + base.Context(); + sut.ScaleDivisor = _comparable.ScaleDivisor * 1.1; + } + } + + public class When_testing_expression_parameters_with_different_moleculename : equivalency_should_test_negative + { + protected override void Context() + { + base.Context(); + sut.Path = new ObjectPath("A", "B", "NewName"); + } + } + + public class When_testing_expression_parameters_with_different_isPresent : equivalency_should_test_negative + { + protected override void Context() + { + base.Context(); + sut.IsPresent = !_comparable.IsPresent; + } + + + } + + public class When_testing_equivalent_expression_parameters : When_testing_equivalency_in_expression_parameters + { + [Observation] + public void empty_expression_parameters_should_be_equivalent() + { + _result.ShouldBeTrue(); + } + } +} diff --git a/tests/OSPSuite.Core.Tests/Domain/ExpressionProfileBuildingBlockSpecs.cs b/tests/OSPSuite.Core.Tests/Domain/ExpressionProfileBuildingBlockSpecs.cs new file mode 100644 index 000000000..ccf0f331e --- /dev/null +++ b/tests/OSPSuite.Core.Tests/Domain/ExpressionProfileBuildingBlockSpecs.cs @@ -0,0 +1,90 @@ +using System.Linq; +using OSPSuite.BDDHelper; +using OSPSuite.BDDHelper.Extensions; +using OSPSuite.Core.Domain.Builder; +using OSPSuite.Core.Domain.Services; +using OSPSuite.Core.Domain.UnitSystem; +using OSPSuite.Helpers; + +namespace OSPSuite.Core.Domain +{ + public class concern_for_ExpressionProfileBuildingBlock : ContextSpecification + { + protected override void Context() + { + sut = new ExpressionProfileBuildingBlock(); + } + } + + public class when_updating_properties_of_building_block : concern_for_ExpressionProfileBuildingBlock + { + private ExpressionProfileBuildingBlock _expressionProfileBuildingBlock; + private ICloneManager _cloneManager; + private IObjectBaseFactory _objectBaseFactory; + private IDataRepositoryTask _repositoryTask; + private IDimensionFactory _dimensionFactory; + + protected override void Context() + { + base.Context(); + _dimensionFactory = new DimensionFactoryForIntegrationTests(); + _dimensionFactory.AddDimension(DomainHelperForSpecs.NoDimension()); + _objectBaseFactory = new ObjectBaseFactoryForSpecs(_dimensionFactory); + _repositoryTask = new DataRepositoryTask(); + _expressionProfileBuildingBlock = new ExpressionProfileBuildingBlock(); + _cloneManager = new CloneManagerForBuildingBlock(_objectBaseFactory, _repositoryTask); + _expressionProfileBuildingBlock.Name = "Molecule|Species|Name"; + _expressionProfileBuildingBlock.Type = ExpressionTypes.MetabolizingEnzyme; + _expressionProfileBuildingBlock.Type = ExpressionTypes.MetabolizingEnzyme; + _expressionProfileBuildingBlock.PKSimVersion = "11.1"; + _expressionProfileBuildingBlock.Add(new ExpressionParameter().WithName("name1")); + } + + protected override void Because() + { + sut.UpdatePropertiesFrom(_expressionProfileBuildingBlock, _cloneManager); + } + + [Observation] + public void the_updated_expression_profile_should_have_properties_set() + { + sut.Name.ShouldBeEqualTo("Molecule|Species|Name"); + sut.Type.ShouldBeEqualTo(ExpressionTypes.MetabolizingEnzyme); + sut.PKSimVersion.ShouldBeEqualTo("11.1"); + sut.Count().ShouldBeEqualTo(1); + } + } + + + public class when_reading_the_icon_name_for_the_building_block : concern_for_ExpressionProfileBuildingBlock + { + [Observation] + public void icon_name_translated_for_each_expression_type() + { + sut.Type = ExpressionTypes.MetabolizingEnzyme; + sut.Icon.ShouldBeEqualTo("Enzyme"); + + sut.Type = ExpressionTypes.TransportProtein; + sut.Icon.ShouldBeEqualTo("Transporter"); + + sut.Type = ExpressionTypes.ProteinBindingPartner; + sut.Icon.ShouldBeEqualTo("Protein"); + } + } + + public class when_setting_the_name_of_the_building_block : concern_for_ExpressionProfileBuildingBlock + { + protected override void Because() + { + sut.Name = "Molecule|Species|Phenotype"; + } + + [Observation] + public void the_name_should_set_the_category_of_the_building_block() + { + sut.Category.ShouldBeEqualTo("Phenotype"); + sut.MoleculeName.ShouldBeEqualTo("Molecule"); + sut.Species.ShouldBeEqualTo("Species"); + } + } +} \ No newline at end of file diff --git a/tests/OSPSuite.HelpersForTests/ModelHelperForSpecs.cs b/tests/OSPSuite.HelpersForTests/ModelHelperForSpecs.cs index f3dd2c522..c6a1dd120 100644 --- a/tests/OSPSuite.HelpersForTests/ModelHelperForSpecs.cs +++ b/tests/OSPSuite.HelpersForTests/ModelHelperForSpecs.cs @@ -1174,6 +1174,9 @@ public T CreateObjectBaseFrom(T sourceObject) if (sourceObject.IsAnImplementationOf()) return new NormalDistributionFormula().WithDimension(_dimensionFactory.NoDimension).WithId(id).DowncastTo(); + if (sourceObject.IsAnImplementationOf()) + return new ExpressionParameter().WithDimension(_dimensionFactory.NoDimension).WithId(id).DowncastTo(); + return default(T); }