Skip to content

Commit ab525b9

Browse files
authored
Merge pull request #3420 from Open-Systems-Pharmacology/2278-create-expression-profile-from-r
Fixes #3421 Enable PK-Sim ExpressionProfile from MoBi.R
2 parents 4403830 + 3fad03d commit ab525b9

File tree

3 files changed

+149
-34
lines changed

3 files changed

+149
-34
lines changed

src/PKSim.Assets/PKSimConstants.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,10 @@ public static string CouldNotFindMoleculeType(string moleculeType) =>
868868

869869
public static string EffectiveMolWeightMustBeGreaterThan(double valueInDisplayUnit, string displayUnit) =>
870870
$"Effective mol weight must be greater than or equal to {valueInDisplayUnit} {displayUnit}";
871+
872+
public static string InvalidProteinCategory(string category) => $"The category '{category}' is not a valid expression category";
873+
874+
public static string CouldNotFindValidSpecies(string speciesName) => $"Could not find a valid species named '{speciesName}'";
871875
}
872876

873877
public static class Information

src/PKSim.R/Exchange/BuildingBlockCreator.cs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,25 @@
22
using OSPSuite.Core.Snapshots;
33
using OSPSuite.Core.Snapshots.Mappers;
44
using OSPSuite.R.Domain;
5+
using PKSim.Assets;
56
using PKSim.Core.Mappers;
67
using PKSim.Core.Model;
8+
using PKSim.Core.Repositories;
9+
using PKSim.Core.Services;
710
using PKSim.Core.Snapshots.Mappers;
11+
using System;
12+
using static PKSim.Assets.PKSimConstants.UI;
813

914
namespace PKSim.R.Exchange;
1015

1116
/// <summary>
12-
/// The class is intended to allow MoBi to dynamically load and call the method and receive a serialized individual building block
13-
/// We exchange data between PK-Sim and MoBi domains only through serializing and deserializing due to differences in the dimension systems.
14-
/// The systems are different in the sense that they each rely on dimensions being singular in the app, but by exchanging objects, that will not be the case.
15-
/// You will have two Mass dimension objects for example.
17+
/// The class is intended to allow MoBi to dynamically load and call the method and receive a serialized
18+
/// building blocks. We exchange data between PK-Sim and MoBi domains only through serializing and deserializing
19+
/// due to differences in the dimension systems. The systems are different in the sense that they each rely on
20+
/// dimensions being singular in the app, but by exchanging objects, that will not be the case.
21+
/// You will have two Mass dimension objects for example.
1622
/// </summary>
17-
public class BuildingBlockCreator
23+
public static class BuildingBlockCreator
1824
{
1925
public static string CreateIndividual(IndividualCharacteristics individualCharacteristics)
2026
{
@@ -26,4 +32,37 @@ public static string CreateIndividual(IndividualCharacteristics individualCharac
2632

2733
return serializer.Serialize(mapper.MapFrom(buildingBlock));
2834
}
35+
36+
public static string CreateExpressionProfile(string category, string moleculeName, string speciesName)
37+
{
38+
var (serializer, mapper) = Api.ResolveTasks<IPKMLPersistor, IExpressionProfileToExpressionProfileBuildingBlockMapper>();
39+
ExpressionProfile buildingBlock;
40+
41+
if (string.Equals(category, TransportProtein))
42+
buildingBlock = createExpressionProfile<IndividualTransporter>(category, moleculeName, speciesName);
43+
else if (string.Equals(category, ProteinBindingPartner))
44+
buildingBlock = createExpressionProfile<IndividualOtherProtein>(category, moleculeName, speciesName);
45+
else if (string.Equals(category, MetabolizingEnzyme))
46+
buildingBlock = createExpressionProfile<IndividualEnzyme>(category, moleculeName, speciesName);
47+
else
48+
throw new ArgumentException(PKSimConstants.Error.InvalidProteinCategory(category));
49+
50+
return serializer.Serialize(mapper.MapFrom(buildingBlock));
51+
}
52+
53+
private static ExpressionProfile createExpressionProfile<T>(string category, string moleculeName, string speciesName) where T : IndividualMolecule
54+
{
55+
var (expressionProfileFactory, moleculeParameterTask, speciesRepository) = Api.ResolveTasks<IExpressionProfileFactory, IMoleculeParameterTask, ISpeciesRepository>();
56+
57+
var species = speciesRepository.FindByName(speciesName);
58+
if (species == null)
59+
throw new ArgumentException(PKSimConstants.Error.CouldNotFindValidSpecies(speciesName));
60+
61+
var expressionProfile = expressionProfileFactory.Create<T>(species, moleculeName);
62+
expressionProfile.Category = category;
63+
64+
moleculeParameterTask.SetDefaultFor(expressionProfile);
65+
66+
return expressionProfile;
67+
}
2968
}

tests/PKSim.R.Tests/BuildingBlockCreatorSpecs.cs

Lines changed: 101 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,118 @@
1-
using OSPSuite.BDDHelper;
1+
using System;
2+
using OSPSuite.BDDHelper;
23
using OSPSuite.BDDHelper.Extensions;
34
using OSPSuite.Core.Snapshots;
45
using OSPSuite.R.Domain;
6+
using PKSim.Assets;
57
using PKSim.Core;
68
using PKSim.R.Exchange;
9+
using static PKSim.Assets.PKSimConstants.UI;
710

8-
namespace PKSim.R
11+
namespace PKSim.R;
12+
13+
internal class CreateExchangeIndividual : ContextForStaticIntegration
914
{
10-
internal class CreateExchangeIndividual : ContextForStaticIntegration
15+
private IndividualCharacteristics _individualCharacteristics;
16+
private string _result;
17+
18+
protected override void Context()
1119
{
12-
private IndividualCharacteristics _individualCharacteristics;
13-
private string _result;
20+
base.Context();
21+
_individualCharacteristics = new IndividualCharacteristics
22+
{
23+
Species = CoreConstants.Species.HUMAN,
24+
Population = CoreConstants.Population.ICRP,
25+
Age = new Parameter
26+
{
27+
Value = 30,
28+
Unit = "year(s)",
29+
},
30+
Weight = new Parameter
31+
{
32+
Value = 75,
33+
Unit = "kg",
34+
},
35+
Height = new Parameter
36+
{
37+
Value = 175,
38+
Unit = "cm",
39+
},
40+
Gender = CoreConstants.Gender.MALE
41+
};
42+
}
43+
44+
protected override void Because()
45+
{
46+
_result = BuildingBlockCreator.CreateIndividual(_individualCharacteristics);
47+
}
48+
49+
[Observation]
50+
public void an_exchangeable_string_is_created()
51+
{
52+
_result.ShouldNotBeNull();
53+
}
54+
}
55+
56+
internal class CreateExchangeMetabolizingEnzyme : ContextForStaticIntegration
57+
{
58+
private string _result;
59+
60+
protected override void Because()
61+
{
62+
_result = BuildingBlockCreator.CreateExpressionProfile(MetabolizingEnzyme, "CYP3A4", CoreConstants.Species.HUMAN);
63+
}
1464

15-
protected override void Context()
65+
[Observation]
66+
public void an_exchangeable_string_is_created()
67+
{
68+
_result.ShouldNotBeNull();
69+
}
70+
}
71+
72+
internal class CreateExchangeExpressionProfileWithInvalidSpecies : ContextForStaticIntegration
73+
{
74+
[Observation]
75+
public void should_throw_an_argument_exception_with_species_not_found_message()
76+
{
77+
var message = string.Empty;
78+
The.Action(() =>
1679
{
17-
base.Context();
18-
_individualCharacteristics = new IndividualCharacteristics
80+
try
1981
{
20-
Species = CoreConstants.Species.HUMAN,
21-
Population = CoreConstants.Population.ICRP,
22-
Age = new Parameter
23-
{
24-
Value = 30,
25-
Unit = "year(s)",
26-
},
27-
Weight = new Parameter
28-
{
29-
Value = 75,
30-
Unit = "kg",
31-
},
32-
Height = new Parameter
33-
{
34-
Value = 175,
35-
Unit = "cm",
36-
},
37-
Gender = CoreConstants.Gender.MALE
38-
};
39-
}
82+
BuildingBlockCreator.CreateExpressionProfile(MetabolizingEnzyme, "CYP3A4", "InvalidSpecies");
83+
}
84+
catch (Exception e)
85+
{
86+
message = e.Message;
87+
throw;
88+
}
89+
}).ShouldThrowAn<ArgumentException>();
90+
message.ShouldBeEqualTo(PKSimConstants.Error.CouldNotFindValidSpecies("InvalidSpecies"));
91+
}
92+
}
93+
94+
internal class CreateExchangeTransportProtein : ContextForStaticIntegration
95+
{
96+
private string _result;
97+
98+
protected override void Because()
99+
{
100+
_result = BuildingBlockCreator.CreateExpressionProfile(TransportProtein, "CYP3A4", CoreConstants.Species.HUMAN);
101+
}
102+
103+
[Observation]
104+
public void an_exchangeable_string_is_created()
105+
{
106+
_result.ShouldNotBeNull();
107+
}
108+
109+
internal class CreateExchangeProteinBindingPartner : ContextForStaticIntegration
110+
{
111+
private string _result;
40112

41113
protected override void Because()
42114
{
43-
_result = BuildingBlockCreator.CreateIndividual(_individualCharacteristics);
115+
_result = BuildingBlockCreator.CreateExpressionProfile(ProteinBindingPartner, "CYP3A4", CoreConstants.Species.HUMAN);
44116
}
45117

46118
[Observation]

0 commit comments

Comments
 (0)