diff --git a/src/PKSim.Core/Model/SimulationFactory.cs b/src/PKSim.Core/Model/SimulationFactory.cs
index 0c8f5cae8..8f84597e7 100644
--- a/src/PKSim.Core/Model/SimulationFactory.cs
+++ b/src/PKSim.Core/Model/SimulationFactory.cs
@@ -109,6 +109,7 @@ public Simulation CreateFrom(ISimulationSubject simulationSubject, IReadOnlyList
_simulationBuildingBlockUpdater.UpdateUsedBuildingBlockInSimulationFromTemplate(simulation, simulationSubject, PKSimBuildingBlockType.SimulationSubject);
_simulationBuildingBlockUpdater.UpdateMultipleUsedBuildingBlockInSimulationFromTemplate(simulation, compounds, PKSimBuildingBlockType.Compound);
+ _simulationBuildingBlockUpdater.UpdateMultipleUsedBuildingBlockInSimulationFromTemplate(simulation, simulationSubject.AllExpressionProfiles(), PKSimBuildingBlockType.ExpressionProfile);
//set basic properties
if (originalSimulation != null)
diff --git a/src/PKSim.Core/Services/BuildingBlockParametersToSimulationUpdater.cs b/src/PKSim.Core/Services/BuildingBlockParametersToSimulationUpdater.cs
index 51b6dc27d..bc22207bd 100644
--- a/src/PKSim.Core/Services/BuildingBlockParametersToSimulationUpdater.cs
+++ b/src/PKSim.Core/Services/BuildingBlockParametersToSimulationUpdater.cs
@@ -1,19 +1,20 @@
using System.Collections.Generic;
using System.Linq;
-using PKSim.Assets;
using OSPSuite.Core.Commands.Core;
+using OSPSuite.Core.Domain;
+using OSPSuite.Core.Domain.Services;
+using OSPSuite.Core.Events;
using OSPSuite.Utility.Collections;
+using PKSim.Assets;
using PKSim.Core.Commands;
using PKSim.Core.Model;
-using OSPSuite.Core.Domain;
-using OSPSuite.Core.Domain.Services;
namespace PKSim.Core.Services
{
public interface IBuildingBlockParametersToSimulationUpdater
{
///
- /// Updates the parameter values into the building block given as parameter in the simulation
+ /// Updates the parameter values from the building block given as parameter into the simulation
///
/// Template building block containing the original values
/// Simulation whose parameter will be updated
@@ -25,12 +26,18 @@ public class BuildingBlockParametersToSimulationUpdater : IBuildingBlockParamete
private readonly IExecutionContext _executionContext;
private readonly IContainerTask _containerTask;
private readonly IParameterSetUpdater _parameterSetUpdater;
+ private readonly IExpressionProfileUpdater _expressionProfileUpdater;
- public BuildingBlockParametersToSimulationUpdater(IExecutionContext executionContext, IContainerTask containerTask, IParameterSetUpdater parameterSetUpdater)
+ public BuildingBlockParametersToSimulationUpdater(
+ IExecutionContext executionContext,
+ IContainerTask containerTask,
+ IParameterSetUpdater parameterSetUpdater,
+ IExpressionProfileUpdater expressionProfileUpdater)
{
_executionContext = executionContext;
_containerTask = containerTask;
_parameterSetUpdater = parameterSetUpdater;
+ _expressionProfileUpdater = expressionProfileUpdater;
}
public ICommand UpdateParametersFromBuildingBlockInSimulation(IPKSimBuildingBlock templateBuildingBlock, Simulation simulation)
@@ -38,7 +45,7 @@ public ICommand UpdateParametersFromBuildingBlockInSimulation(IPKSimBuildingBloc
//Update the building block in the simulation based on the same template
var usedBuildingBlock = simulation.UsedBuildingBlockByTemplateId(templateBuildingBlock.Id);
//Template was not used in the simulation...return
- if (usedBuildingBlock == null)
+ if (usedBuildingBlock == null)
return null;
var buildingBlockType = _executionContext.TypeFor(templateBuildingBlock);
@@ -65,9 +72,28 @@ public ICommand UpdateParametersFromBuildingBlockInSimulation(IPKSimBuildingBloc
updateCommands.CommandType = PKSimConstants.Command.CommandTypeUpdate;
updateCommands.Description = PKSimConstants.Command.UpdateBuildingBlockCommandDescription(buildingBlockType, templateBuildingBlock.Name, simulation.Name);
_executionContext.UpdateBuildingBlockPropertiesInCommand(updateCommands, simulation);
+
+ synchronizeBuildingBlocks(templateBuildingBlock, simulation);
return updateCommands;
}
+ ///
+ /// We need to make sure that once the simulation has been updated with the building block, depending building blocks
+ /// are also updated
+ /// For instance, if we update the individual in the simulation, we will also update all expression profile (since
+ /// expression profile are linked to the individual)
+ ///
+ private void synchronizeBuildingBlocks(IPKSimBuildingBlock templateBuildingBlock, Simulation simulation)
+ {
+ if (templateBuildingBlock is not ISimulationSubject simulationSubject)
+ return;
+
+ _expressionProfileUpdater.SynchronizeExpressionProfilesUsedInSimulationSubjectWithSimulation(simulationSubject, simulation);
+
+ //we need to raise an event here to ensure that the UI reflects the fact that we have synchronized our building blocks
+ _executionContext.PublishEvent(new SimulationStatusChangedEvent(simulation));
+ }
+
///
/// Update parameter values from the used building block into the simulation
///
@@ -88,9 +114,9 @@ private IEnumerable updateParameterValues(IEnumerable used
}
return from parameter in usedBuildingBlockParameters.OrderBy(x => x.IsDistributed())
- let simParams = simulationParameterCache[parameter.Id]
- from simParam in simParams
- select _parameterSetUpdater.UpdateValue(parameter, simParam);
+ let simParams = simulationParameterCache[parameter.Id]
+ from simParam in simParams
+ select _parameterSetUpdater.UpdateValue(parameter, simParam);
}
private ICommand updateParameterValues(PathCache sourceParameters, PathCache targetParameters)
@@ -99,6 +125,5 @@ private ICommand updateParameterValues(PathCache sourceParameters, P
}
private PathCache parametersToUpdateFrom(IPKSimBuildingBlock buildingBlock) => _containerTask.CacheAllChildren(buildingBlock);
-
}
}
\ No newline at end of file
diff --git a/src/PKSim.Core/Services/ExpressionProfileUpdater.cs b/src/PKSim.Core/Services/ExpressionProfileUpdater.cs
index 5912524ed..658191d5f 100644
--- a/src/PKSim.Core/Services/ExpressionProfileUpdater.cs
+++ b/src/PKSim.Core/Services/ExpressionProfileUpdater.cs
@@ -53,6 +53,19 @@ public interface IExpressionProfileUpdater
/// Expression profile to update used as source
/// Expression profile to update
void SynchronizeExpressionProfileWithExpressionProfile(ExpressionProfile sourceExpressionProfile, ExpressionProfile targetExpressionProfile);
+
+ ///
+ /// Updates the values from all expression profiles used by the into the
+ ///
+ /// This is required for instance when synchronizing and individual with a simulation=>Underlying building block may
+ /// need to be updated as well
+ ///
+ ///
+ /// Template simulation subject (building block) that should be used to update the
+ /// expression profile in the simulation
+ ///
+ /// Simulation to update
+ void SynchronizeExpressionProfilesUsedInSimulationSubjectWithSimulation(ISimulationSubject templateSimulationSubject, Simulation simulation);
}
public class ExpressionProfileUpdater : IExpressionProfileUpdater
@@ -170,6 +183,21 @@ public void SynchronizeExpressionProfileWithExpressionProfile(ExpressionProfile
synchronizeExpressionProfiles(sourceMolecule, sourceIndividual, targetMolecule, targetIndividual, updateParameterOriginId: false);
}
+ public void SynchronizeExpressionProfilesUsedInSimulationSubjectWithSimulation(ISimulationSubject templateSimulationSubject, Simulation simulation)
+ {
+ templateSimulationSubject.AllExpressionProfiles().Each(template =>
+ {
+ var usedBuildingBlock = simulation.UsedBuildingBlockByTemplateId(template.Id);
+ if (usedBuildingBlock?.BuildingBlock is not ExpressionProfile simulationExpressionProfile)
+ return;
+
+ SynchronizeExpressionProfileWithExpressionProfile(template, simulationExpressionProfile);
+ //They are supposed to be the same => same version
+ simulationExpressionProfile.Version = template.Version;
+ usedBuildingBlock.Version = template.Version;
+ });
+ }
+
private void updateMoleculeParameters(IndividualMolecule sourceMolecule, ISimulationSubject sourceSimulationSubject, IndividualMolecule targetMolecule, ISimulationSubject targetSimulationSubject, bool updateParameterOriginId)
{
var allTargetMoleculeParameters = allMoleculeParametersFor(targetSimulationSubject, targetMolecule);
diff --git a/src/PKSim.Core/Services/SimulationParametersToBuildingBlockUpdater.cs b/src/PKSim.Core/Services/SimulationParametersToBuildingBlockUpdater.cs
index c7206ae7e..e5fcdb0ee 100644
--- a/src/PKSim.Core/Services/SimulationParametersToBuildingBlockUpdater.cs
+++ b/src/PKSim.Core/Services/SimulationParametersToBuildingBlockUpdater.cs
@@ -69,7 +69,7 @@ public ICommand UpdateParametersFromSimulationInBuildingBlock(Simulation simulat
updateCommands.Add(updateTemplateParametersCommand);
//Last, see if we have some special cases to handle
- var synchronizeCommand = synchronizeBuildingBlocks(templateBuildingBlock, updateTemplateParametersCommand);
+ var synchronizeCommand = synchronizeBuildingBlocks(templateBuildingBlock, updateTemplateParametersCommand, simulation);
updateCommands.Add(synchronizeCommand);
//now make sure that the used building block is updated with the template building block info
@@ -79,11 +79,10 @@ public ICommand UpdateParametersFromSimulationInBuildingBlock(Simulation simulat
return updateCommands;
}
- private ICommand synchronizeBuildingBlocks(IPKSimBuildingBlock templateBuildingBlock, IPKSimMacroCommand updateTemplateParametersCommand)
+ private ICommand synchronizeBuildingBlocks(IPKSimBuildingBlock templateBuildingBlock, IPKSimMacroCommand updateTemplateParametersCommand, Simulation simulation)
{
- var simulationSubject = templateBuildingBlock as ISimulationSubject;
//For now, deal with update from Individual or Population into Expression Profile
- if (simulationSubject == null)
+ if (templateBuildingBlock is not ISimulationSubject simulationSubject)
return new PKSimEmptyCommand();
var allExpressionProfileParameterValueCommand = updateTemplateParametersCommand.All()
@@ -126,6 +125,8 @@ private ICommand synchronizeBuildingBlocks(IPKSimBuildingBlock templateBuildingB
//Now that our expression profile are updated, we need to trigger the synchronization in all building blocks
expressionProfilesToUpdate.Each(x => _expressionProfileUpdater.SynchronizeAllSimulationSubjectsWithExpressionProfile(x));
+ //last, synchronize the expression profile in the simulation as well
+ _expressionProfileUpdater.SynchronizeExpressionProfilesUsedInSimulationSubjectWithSimulation(simulationSubject, simulation);
return macroCommand;
}
diff --git a/src/PKSim.Infrastructure/Services/LazyLoadTask.cs b/src/PKSim.Infrastructure/Services/LazyLoadTask.cs
index 5c4abf1cf..462ac7dcd 100644
--- a/src/PKSim.Infrastructure/Services/LazyLoadTask.cs
+++ b/src/PKSim.Infrastructure/Services/LazyLoadTask.cs
@@ -1,11 +1,11 @@
-using PKSim.Assets;
+using OSPSuite.Core.Domain;
+using OSPSuite.Core.Domain.ParameterIdentifications;
+using OSPSuite.Core.Domain.SensitivityAnalyses;
using OSPSuite.Utility.Events;
using OSPSuite.Utility.Extensions;
+using PKSim.Assets;
using PKSim.Core.Model;
using PKSim.Core.Services;
-using OSPSuite.Core.Domain;
-using OSPSuite.Core.Domain.ParameterIdentifications;
-using OSPSuite.Core.Domain.SensitivityAnalyses;
namespace PKSim.Infrastructure.Services
{
@@ -22,12 +22,12 @@ public class LazyLoadTask : ILazyLoadTask
private readonly ISensitivityAnalysisContentLoader _sensitivityAnalysisContentLoader;
public LazyLoadTask(
- IContentLoader contentLoader,
- ISimulationResultsLoader simulationResultsLoader,
+ IContentLoader contentLoader,
+ ISimulationResultsLoader simulationResultsLoader,
ISimulationChartsLoader simulationChartsLoader,
- ISimulationComparisonContentLoader simulationComparisonContentLoader,
+ ISimulationComparisonContentLoader simulationComparisonContentLoader,
ISimulationAnalysesLoader simulationAnalysesLoader,
- IParameterIdentificationContentLoader parameterIdentificationContentLoader,
+ IParameterIdentificationContentLoader parameterIdentificationContentLoader,
ISensitivityAnalysisContentLoader sensitivityAnalysisContentLoader,
IRegistrationTask registrationTask,
IProgressManager progressManager)
@@ -69,7 +69,7 @@ public void LoadResults(TSimulation simulation) where TSimulation :
{
if (simulation == null)
return;
-
+
Load(simulation);
if (simulation.HasResults)
@@ -113,7 +113,7 @@ private void loadSimulations(Simulation simulation)
//updating results may triggered update of has changed flag that is not accurate. We save the original state and update it at the end
var hasChanged = simulation.HasChanged;
-
+
//Only load results for individual simulations
if (simulation.IsAnImplementationOf())
_simulationResultsLoader.LoadResultsFor(simulation.DowncastTo());
@@ -121,6 +121,13 @@ private void loadSimulations(Simulation simulation)
else if (simulation.IsAnImplementationOf())
_simulationAnalysesLoader.LoadAnalysesFor(simulation.DowncastTo());
+ //make sure each individual gets the expression profile defined in the simulation)
+ var simulationSubject = simulation.BuildingBlock();
+
+ //this can happen for an imported simulation
+ if (simulationSubject != null)
+ simulation.AllBuildingBlocks().Each(simulationSubject.AddExpressionProfile);
+
//in all cases, load the charts
_simulationChartsLoader.LoadChartsFor(simulation);
diff --git a/src/PKSim.Presentation/Presenters/ContextMenus/UsedBuildingBlockInSimulationTreeNodeContextMenuFactory.cs b/src/PKSim.Presentation/Presenters/ContextMenus/UsedBuildingBlockInSimulationTreeNodeContextMenuFactory.cs
index 5d75f3290..476550eca 100644
--- a/src/PKSim.Presentation/Presenters/ContextMenus/UsedBuildingBlockInSimulationTreeNodeContextMenuFactory.cs
+++ b/src/PKSim.Presentation/Presenters/ContextMenus/UsedBuildingBlockInSimulationTreeNodeContextMenuFactory.cs
@@ -45,6 +45,19 @@ protected override IContextMenu CreateFor(Simulation simulation, UsedBuildingBlo
}
}
+
+ public class UsedExpressionProfileInSimulationTreeNodeContextMenuFactory : UsedBuildingBlockInSimulationTreeNodeContextMenuFactory
+ {
+ public UsedExpressionProfileInSimulationTreeNodeContextMenuFactory(IContainer container) : base(container)
+ {
+ }
+
+ protected override IContextMenu CreateFor(Simulation simulation, UsedBuildingBlock usedBuildingBlock, ExpressionProfile expressionProfile)
+ {
+ return new UsedBuildingBlockInSimulationContextMenu(simulation, usedBuildingBlock, expressionProfile, _container);
+ }
+ }
+
public class UsedCompoundInSimulationTreeNodeContextMenuFactory : UsedBuildingBlockInSimulationTreeNodeContextMenuFactory
{
public UsedCompoundInSimulationTreeNodeContextMenuFactory(IContainer container) : base(container)
diff --git a/src/PKSim.Presentation/Presenters/Main/SimulationExplorerPresenter.cs b/src/PKSim.Presentation/Presenters/Main/SimulationExplorerPresenter.cs
index 2549bfc6c..bce4b888e 100644
--- a/src/PKSim.Presentation/Presenters/Main/SimulationExplorerPresenter.cs
+++ b/src/PKSim.Presentation/Presenters/Main/SimulationExplorerPresenter.cs
@@ -184,6 +184,7 @@ private void addUsedBuildingBlockNodes(Simulation simulation, ITreeNode simulati
.Under(simulationNode);
addUsedBuildingBlock(simulation, simulationNode, PKSimBuildingBlockType.SimulationSubject);
+ //Used for debug purposes for now addUsedBuildingBlock(simulation, simulationNode, PKSimBuildingBlockType.ExpressionProfile);
addUsedBuildingBlock(simulation, simulationNode, PKSimBuildingBlockType.Compound);
addUsedBuildingBlock(simulation, simulationNode, PKSimBuildingBlockType.Protocol);
addUsedBuildingBlock(simulation, simulationNode, PKSimBuildingBlockType.Formulation);
diff --git a/src/PKSim.Presentation/Presenters/Simulations/SimulationWizardPresenter.cs b/src/PKSim.Presentation/Presenters/Simulations/SimulationWizardPresenter.cs
index bb0f9176d..2fcfb826d 100644
--- a/src/PKSim.Presentation/Presenters/Simulations/SimulationWizardPresenter.cs
+++ b/src/PKSim.Presentation/Presenters/Simulations/SimulationWizardPresenter.cs
@@ -35,6 +35,7 @@ protected SimulationWizardPresenter(TView view, ISubPresenterItemManager();
_simulationComparisonContentLoader = A.Fake();
_simulationAnalysesLoader = A.Fake();
- _parameterIdentificationContentendLoader = A.Fake();
+ _parameterIdentificationContentLoader = A.Fake();
_sensitivityAnalysisContentLoader = A.Fake();
A.CallTo(() => _progressManager.Create()).Returns(_progressUpdater);
sut = new LazyLoadTask(_contentLoader, _simulationResultsLoader, _simulationChartsLoader,
- _simulationComparisonContentLoader, _simulationAnalysesLoader, _parameterIdentificationContentendLoader, _sensitivityAnalysisContentLoader,
+ _simulationComparisonContentLoader, _simulationAnalysesLoader, _parameterIdentificationContentLoader, _sensitivityAnalysisContentLoader,
_registrationTask, _progressManager);
_objectToLoad = A.Fake();
_objectToLoad.Id = "objectId";
@@ -141,11 +142,29 @@ public void should_register_the_object_in_the_factory()
public class When_loading_an_individual_simulation : concern_for_LazyLoadTask
{
private IndividualSimulation _individualSimulation;
+ private Individual _individual;
+ private ExpressionProfile _exp1;
+ private ExpressionProfile _exp2;
protected override void Context()
{
base.Context();
- _individualSimulation = A.Fake();
+ _individualSimulation = new IndividualSimulation();
+ _individual = new Individual();
+ _exp1 = new ExpressionProfile();
+ _exp2 = new ExpressionProfile();
+ _individualSimulation.AddUsedBuildingBlock(new UsedBuildingBlock("ind", PKSimBuildingBlockType.Individual)
+ {
+ BuildingBlock = _individual
+ });
+ _individualSimulation.AddUsedBuildingBlock(new UsedBuildingBlock("exp1", PKSimBuildingBlockType.ExpressionProfile)
+ {
+ BuildingBlock = _exp1
+ });
+ _individualSimulation.AddUsedBuildingBlock(new UsedBuildingBlock("exp2", PKSimBuildingBlockType.ExpressionProfile)
+ {
+ BuildingBlock = _exp2
+ });
}
protected override void Because()
@@ -158,6 +177,12 @@ public void should_also_load_the_simulation_results()
{
A.CallTo(() => _simulationResultsLoader.LoadResultsFor(_individualSimulation)).MustHaveHappened();
}
+
+ [Observation]
+ public void should_add_all_expression_profiles_defined_as_used_building_block_as_building_block_of_the_individual()
+ {
+ _individual.AllExpressionProfiles().ShouldOnlyContain(_exp1, _exp2);
+ }
}
public class When_loading_a_population_simulation : concern_for_LazyLoadTask
diff --git a/tests/PKSim.Tests/IntegrationTests/BuildingBlockParametersToSimulationUpdaterSpecs.cs b/tests/PKSim.Tests/IntegrationTests/BuildingBlockParametersToSimulationUpdaterSpecs.cs
index 53b9cf4f1..79f3e1119 100644
--- a/tests/PKSim.Tests/IntegrationTests/BuildingBlockParametersToSimulationUpdaterSpecs.cs
+++ b/tests/PKSim.Tests/IntegrationTests/BuildingBlockParametersToSimulationUpdaterSpecs.cs
@@ -15,11 +15,19 @@ public abstract class concern_for_BuildingBlockParametersToSimulationUpdater : C
{
protected Individual _templateIndividual;
private ICoreWorkspace _workspace;
+ protected ExpressionProfile _templateExpressionProfile;
+ private IMoleculeExpressionTask _moleculeExpressionTask;
public override void GlobalContext()
{
base.GlobalContext();
+ _moleculeExpressionTask = IoC.Resolve>();
+
_templateIndividual = DomainFactoryForSpecs.CreateStandardIndividual();
+ _templateExpressionProfile = DomainFactoryForSpecs.CreateExpressionProfile();
+ _moleculeExpressionTask.AddExpressionProfile(_templateIndividual, _templateExpressionProfile);
+
+
var compound = DomainFactoryForSpecs.CreateStandardCompound();
var protocol = DomainFactoryForSpecs.CreateStandardIVBolusProtocol();
_simulation = DomainFactoryForSpecs.CreateSimulationWith(_templateIndividual, compound, protocol) as IndividualSimulation;
@@ -29,6 +37,7 @@ public override void GlobalContext()
project.AddBuildingBlock(protocol);
project.AddBuildingBlock(_simulation);
project.AddBuildingBlock(_templateIndividual);
+ project.AddBuildingBlock(_templateExpressionProfile);
_workspace.Project = project;
}
}
@@ -42,6 +51,9 @@ public override void GlobalContext()
base.GlobalContext();
var templateParameter = _templateIndividual.Organism.Organ(CoreConstants.Organ.LIVER).Parameter(CoreConstants.Parameters.ALLOMETRIC_SCALE_FACTOR);
templateParameter.Value = 3;
+
+ var templateExpressionProfileParameter = _templateExpressionProfile.Molecule.HalfLifeLiver;
+ templateExpressionProfileParameter.Value = 5;
}
protected override void Because()
@@ -59,6 +71,15 @@ public void should_have_updated_the_parameter_values_in_the_simulation_and_in_th
//now parameter in simulation
var simParameter = _simulation.All().First(x => string.Equals(x.Origin.ParameterId, parameter.Id));
simParameter.Value.ShouldBeEqualTo(3);
+
+ }
+
+ [Observation]
+ public void should_have_synchronized_value_in_the_expression_profile()
+ {
+ var simExpressionProfile = _simulation.BuildingBlockByTemplateId(_templateExpressionProfile.Id);
+ var parameter = simExpressionProfile.Molecule.HalfLifeLiver;
+ parameter.Value.ShouldBeEqualTo(5);
}
[Observation]
diff --git a/tests/PKSim.Tests/IntegrationTests/ExpressionProfileUpdaterSpecs.cs b/tests/PKSim.Tests/IntegrationTests/ExpressionProfileUpdaterSpecs.cs
index c21260fef..59390810c 100644
--- a/tests/PKSim.Tests/IntegrationTests/ExpressionProfileUpdaterSpecs.cs
+++ b/tests/PKSim.Tests/IntegrationTests/ExpressionProfileUpdaterSpecs.cs
@@ -155,4 +155,57 @@ public void should_synchronize_transporter_direction()
_individualTransporter.BloodCellsContainer.TransportDirection.ShouldBeEqualTo(TransportDirectionId.EffluxBloodCellsToPlasma);
}
}
+
+ public class When_synchronizing_all_expression_profile_used_in_a_simulation_subject_with_a_simulation : concern_for_ExpressionProfileUpdater
+ {
+ private Simulation _simulation;
+ private Individual _individualInSimulation;
+ private ExpressionProfile _expressionProfileForEnzymeInSimulation;
+ private IndividualEnzyme _expressionProfileEnzymeInSimulation;
+ private UsedBuildingBlock _usedIndividualBuildingBLock;
+ private UsedBuildingBlock _usedExpressionProfileBuildingBlock;
+
+ protected override void Context()
+ {
+ base.Context();
+ _simulation = new IndividualSimulation();
+
+ _individualInSimulation = DomainFactoryForSpecs.CreateStandardIndividual();
+ _expressionProfileForEnzymeInSimulation = DomainFactoryForSpecs.CreateExpressionProfile();
+ _moleculeExpressionTask.AddExpressionProfile(_individualInSimulation, _expressionProfileForEnzymeInSimulation);
+ _expressionProfileEnzymeInSimulation = _expressionProfileForEnzymeInSimulation.Molecule.DowncastTo();
+ _usedIndividualBuildingBLock = new UsedBuildingBlock(_individual.Id, PKSimBuildingBlockType.Individual)
+ {
+ BuildingBlock = _individualInSimulation
+ };
+ _usedExpressionProfileBuildingBlock = new UsedBuildingBlock(_expressionProfileForEnzyme.Id, PKSimBuildingBlockType.ExpressionProfile)
+ {
+ BuildingBlock = _expressionProfileForEnzymeInSimulation
+ };
+
+ _simulation.AddUsedBuildingBlock(_usedIndividualBuildingBLock);
+ _simulation.AddUsedBuildingBlock(_usedExpressionProfileBuildingBlock);
+
+ _expressionProfileForEnzyme.Version = 10;
+ _expressionProfileEnzyme.HalfLifeLiver.Value = 50;
+
+ }
+ protected override void Because()
+ {
+ sut.SynchronizeExpressionProfilesUsedInSimulationSubjectWithSimulation(_individual, _simulation );
+ }
+
+ [Observation]
+ public void should_have_updated_all_values_of_the_expression_profiles_in_the_simulation_with_those_of_the_corresponding_template_expression_profile()
+ {
+ _expressionProfileEnzymeInSimulation.HalfLifeLiver.Value.ShouldBeEqualTo(50);
+ }
+
+ [Observation]
+ public void should_have_updated_the_version_of_the_building_block_in_the_simulation_to_the_one_used_in_the_template()
+ {
+ _expressionProfileForEnzymeInSimulation.Version.ShouldBeEqualTo(_expressionProfileForEnzyme.Version);
+ _usedExpressionProfileBuildingBlock.Version.ShouldBeEqualTo(_expressionProfileForEnzyme.Version);
+ }
+ }
}
\ No newline at end of file