Skip to content

Commit

Permalink
Fixes #2638 cannot export HI to snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
msevestre committed May 25, 2023
1 parent 9955af1 commit 84f2c24
Show file tree
Hide file tree
Showing 13 changed files with 390 additions and 161 deletions.
16 changes: 16 additions & 0 deletions src/PKSim.Core/Snapshots/DiseaseState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using OSPSuite.Core.Domain;

namespace PKSim.Core.Snapshots;

public class DiseaseState : IWithName
{
/// <summary>
/// Name of disease state associated with OriginData
/// </summary>
public string Name { get; set; }

/// <summary>
/// List of disease state parameters associated with the selected disease state
/// </summary>
public Parameter[] Parameters { get; set; }
}
5 changes: 4 additions & 1 deletion src/PKSim.Core/Snapshots/ExpressionProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class ExpressionProfile : SnapshotBase, IBuildingBlockSnapshot
public ExpressionContainer[] Expression { get; set; }
public Ontogeny Ontogeny { get; set; }

public PKSimBuildingBlockType BuildingBlockType { get; } =PKSimBuildingBlockType.ExpressionProfile;
public PKSimBuildingBlockType BuildingBlockType { get; } = PKSimBuildingBlockType.ExpressionProfile;

//Null if no disease state defined
public DiseaseState Disease { get; set; }
}
}
112 changes: 112 additions & 0 deletions src/PKSim.Core/Snapshots/Mappers/DiseaseStateMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System.Linq;
using System.Threading.Tasks;
using OSPSuite.Core.Domain;
using OSPSuite.Core.Domain.UnitSystem;
using OSPSuite.Utility.Extensions;
using PKSim.Assets;
using PKSim.Core.Model;
using PKSim.Core.Repositories;

namespace PKSim.Core.Snapshots.Mappers;

using ModelOriginData = Model.OriginData;
using SnapshotDiseaseState = DiseaseState;

public class DiseaseStateContext : SnapshotContext
{
public ModelOriginData OriginData { get; }

public DiseaseStateContext(ModelOriginData originData, SnapshotContext baseContext) : base(baseContext)
{
OriginData = originData;
}
}

public class DiseaseStateMapper : SnapshotMapperBase<ModelOriginData, SnapshotDiseaseState, DiseaseStateContext>
{
private readonly IDiseaseStateRepository _diseaseStateRepository;
private readonly ParameterMapper _parameterMapper;
private readonly IDimensionRepository _dimensionRepository;

public DiseaseStateMapper(
IDiseaseStateRepository diseaseStateRepository,
ParameterMapper parameterMapper,
IDimensionRepository dimensionRepository
)
{
_parameterMapper = parameterMapper;
_dimensionRepository = dimensionRepository;
_diseaseStateRepository = diseaseStateRepository;
}

public override Task<SnapshotDiseaseState> MapToSnapshot(ModelOriginData originData)
{
var diseaseState = originData?.DiseaseState;
if (diseaseState == null || diseaseState.IsHealthy)
return Task.FromResult<SnapshotDiseaseState>(null);

var snapshot = new SnapshotDiseaseState
{
Name = diseaseState.Name,
};

if (originData.DiseaseStateParameters.Any())
snapshot.Parameters = originData.DiseaseStateParameters.Select(namedParameterFrom).ToArray();

return Task.FromResult(snapshot);
}

public override Task<ModelOriginData> MapToModel(SnapshotDiseaseState diseaseStateSnapshot, DiseaseStateContext diseaseStateContext)
{
var originData = diseaseStateContext.OriginData;

if (diseaseStateSnapshot == null)
return Task.FromResult(originData);

var diseaseState = _diseaseStateRepository.AllFor(originData.Population).FindByName(diseaseStateSnapshot.Name);
if (diseaseState == null)
throw new PKSimException(PKSimConstants.Error.CannotFindDiseaseState(diseaseStateSnapshot.Name, originData.Population.DisplayName));

originData.DiseaseState = diseaseState;
diseaseState.Parameters.Each(x =>
{
var diseaseStateParameter = new OriginDataParameter {Name = x.Name, Value = x.Value, Unit = x.DisplayUnitName()};
var snapshotParameter = diseaseStateSnapshot.Parameters.FindByName(x.Name);
if (snapshotParameter != null)
{
diseaseStateParameter.Value = baseParameterValueFrom(snapshotParameter, x.Value);
diseaseStateParameter.Unit = snapshotParameter.Unit;
}

originData.AddDiseaseStateParameter(diseaseStateParameter);
});


return Task.FromResult(originData);
}

private Parameter namedParameterFrom(OriginDataParameter parameter)
{
return parameterFrom(parameter, _dimensionRepository.DimensionForUnit(parameter.Unit)).WithName(parameter.Name);
}

private Parameter parameterFrom(OriginDataParameter parameter, IDimension dimension)
{
if (parameter == null)
return null;

return _parameterMapper.ParameterFrom(parameter.Value, parameter.Unit, dimension);
}

private double baseParameterValueFrom(Parameter snapshot, double defaultValueInBaseUnit) =>
baseParameterValueFrom(snapshot, _dimensionRepository.DimensionForUnit(snapshot.Unit), defaultValueInBaseUnit);

private double baseParameterValueFrom(Parameter snapshot, IDimension dimension, double defaultValueInBaseUnit)
{
if (snapshot?.Value == null)
return defaultValueInBaseUnit;

var unit = dimension.Unit(ModelValueFor(snapshot.Unit));
return dimension.UnitValueToBaseUnitValue(unit, snapshot.Value.Value);
}
}
19 changes: 15 additions & 4 deletions src/PKSim.Core/Snapshots/Mappers/ExpressionProfileMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using OSPSuite.Core.Domain;
using PKSim.Core.Commands;
using PKSim.Core.Model;
using PKSim.Core.Repositories;
using PKSim.Core.Services;
using PKSim.Core.Snapshots.Services;
using ModelIndividual = PKSim.Core.Model.Individual;
Expand All @@ -19,15 +20,17 @@ public class ExpressionProfileMapper : ObjectBaseSnapshotMapperBase<ModelExpress
private readonly IExpressionProfileFactory _expressionProfileFactory;
private readonly IMoleculeParameterTask _moleculeParameterTask;
private readonly OntogenyMapper _ontogenyMapper;
private readonly DiseaseStateMapper _diseaseStateMapper;

public ExpressionProfileMapper(
ParameterMapper parameterMapper,
ExpressionContainerMapper expressionContainerMapper,
OntogenyMapper ontogenyMapper,
DiseaseStateMapper diseaseStateMapper,
IOntogenyTask ontogenyTask,
IMoleculeExpressionTask<ModelIndividual> moleculeExpressionTask,
IExpressionProfileFactory expressionProfileFactory,
IMoleculeParameterTask moleculeParameterTask
IMoleculeParameterTask moleculeParameterTask
)
{
_parameterMapper = parameterMapper;
Expand All @@ -36,13 +39,15 @@ IMoleculeParameterTask moleculeParameterTask
_moleculeExpressionTask = moleculeExpressionTask;
_expressionProfileFactory = expressionProfileFactory;
_moleculeParameterTask = moleculeParameterTask;

_ontogenyMapper = ontogenyMapper;
_diseaseStateMapper = diseaseStateMapper;
}

public override async Task<SnapshotExpressionProfile> MapToSnapshot(ModelExpressionProfile expressionProfile)
{
var (molecule, individual) = expressionProfile;
var originData = individual.OriginData;

//We do not use the base method here as we want to save the name differently using the composite part of the name
var snapshot = new SnapshotExpressionProfile
{
Expand All @@ -53,7 +58,8 @@ public override async Task<SnapshotExpressionProfile> MapToSnapshot(ModelExpress
Description = SnapshotValueFor(expressionProfile.Description),
Ontogeny = await _ontogenyMapper.MapToSnapshot(molecule.Ontogeny),
Expression = await expressionFor(molecule, individual),
Parameters = await allParametersChangedByUserFrom(individual)
Parameters = await allParametersChangedByUserFrom(individual),
Disease = await _diseaseStateMapper.MapToSnapshot(originData)
};

updateMoleculeSpecificPropertiesToSnapshot(snapshot, molecule);
Expand Down Expand Up @@ -92,6 +98,11 @@ public override async Task<ModelExpressionProfile> MapToModel(SnapshotExpression
expressionProfile.Category = snapshot.Category;

var (molecule, individual) = expressionProfile;

//update disease sate if any
var diseaseStateContext = new DiseaseStateContext(individual.OriginData, snapshotContext);
await _diseaseStateMapper.MapToModel(snapshot.Disease, diseaseStateContext);

//Update molecule properties first
updateMoleculePropertiesToMolecule(molecule, snapshot, individual, snapshotContext);

Expand All @@ -102,6 +113,7 @@ public override async Task<ModelExpressionProfile> MapToModel(SnapshotExpression
var ontogeny = await _ontogenyMapper.MapToModel(snapshot.Ontogeny, snapshotWithSubjectContext);
_ontogenyTask.SetOntogenyForMolecule(molecule, ontogeny, individual);


var context = new ExpressionContainerMapperContext(snapshotContext)
{
Molecule = molecule,
Expand Down Expand Up @@ -158,6 +170,5 @@ private Localization retrieveLocalizationFrom(SnapshotExpressionProfile snapshot

return LocalizationConverter.ConvertToLocalization(tissueLocation, membraneLocation, intracellularVascularEndoLocation);
}

}
}
8 changes: 6 additions & 2 deletions src/PKSim.Core/Snapshots/Mappers/ExtendedPropertyMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ private ExtendedPropertyType mapExtendedPropertyType(Type type)

public override Task<ModelExtendedProperty> MapToModel(SnapshotExtendedProperty snapshot, SnapshotContext snapshotContext)
{
if (snapshot?.Value == null)
return Task.FromResult<ModelExtendedProperty>(null);

var snapshotType = snapshot.Type;

var valueAsString = snapshot.Value.ToString();

if (snapshotType.HasValue)
Expand All @@ -64,7 +68,7 @@ public override Task<ModelExtendedProperty> MapToModel(SnapshotExtendedProperty
return mapExtendedPropertyBasedOnValue(snapshot, valueAsString);
}

private Task<ModelExtendedProperty> mapExtendedPropertyBasedOnType(ExtendedProperty snapshot, ExtendedPropertyType snapshotType, string valueAsString)
private Task<ModelExtendedProperty> mapExtendedPropertyBasedOnType(SnapshotExtendedProperty snapshot, ExtendedPropertyType snapshotType, string valueAsString)
{
switch (snapshotType)
{
Expand All @@ -80,7 +84,7 @@ private Task<ModelExtendedProperty> mapExtendedPropertyBasedOnType(ExtendedPrope
}
}

private Task<ModelExtendedProperty> mapExtendedPropertyBasedOnValue(ExtendedProperty snapshot, string valueAsString)
private Task<ModelExtendedProperty> mapExtendedPropertyBasedOnValue(SnapshotExtendedProperty snapshot, string valueAsString)
{
if (double.TryParse(valueAsString, out var doubleResult))
return mapExtendedProperty(snapshot, double.Parse, doubleResult);
Expand Down
58 changes: 19 additions & 39 deletions src/PKSim.Core/Snapshots/Mappers/OriginDataMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,25 @@ public class OriginDataMapper : SnapshotMapperBase<ModelOriginData, SnapshotOrig
{
private readonly IDimensionRepository _dimensionRepository;
private readonly ISpeciesRepository _speciesRepository;
private readonly IDiseaseStateRepository _diseaseStateRepository;
private readonly DiseaseStateMapper _diseaseStateMapper;
private readonly ParameterMapper _parameterMapper;
private readonly IOriginDataTask _originDataTask;
private readonly IIndividualModelTask _individualModelTask;
private readonly CalculationMethodCacheMapper _calculationMethodCacheMapper;
private readonly ValueOriginMapper _valueOriginMapper;

public OriginDataMapper(
ParameterMapper parameterMapper,
public OriginDataMapper(ParameterMapper parameterMapper,
CalculationMethodCacheMapper calculationMethodCacheMapper,
ValueOriginMapper valueOriginMapper,
DiseaseStateMapper diseaseStateMapper,
IOriginDataTask originDataTask,
IDimensionRepository dimensionRepository,
IIndividualModelTask individualModelTask,
ISpeciesRepository speciesRepository,
IDiseaseStateRepository diseaseStateRepository
)
ISpeciesRepository speciesRepository)
{
_dimensionRepository = dimensionRepository;
_speciesRepository = speciesRepository;
_diseaseStateRepository = diseaseStateRepository;
_diseaseStateMapper = diseaseStateMapper;
_parameterMapper = parameterMapper;
_originDataTask = originDataTask;
_individualModelTask = individualModelTask;
Expand Down Expand Up @@ -70,9 +68,7 @@ public override async Task<SnapshotOriginData> MapToSnapshot(ModelOriginData ori
snapshot.ValueOrigin = await _valueOriginMapper.MapToSnapshot(originData.ValueOrigin);
snapshot.CalculationMethods = await _calculationMethodCacheMapper.MapToSnapshot(originData.CalculationMethodCache, originData.Species.Name);

snapshot.DiseaseState = originData.DiseaseState?.Name;
if (originData.DiseaseStateParameters.Any())
snapshot.DiseaseStateParameters = originData.DiseaseStateParameters.Select(namedParameterFrom).ToArray();
snapshot.Disease = await _diseaseStateMapper.MapToSnapshot(originData);

return snapshot;
}
Expand All @@ -91,7 +87,7 @@ private Parameter originDataParameterFor(ModelOriginData originData, Func<ModelO
return parameterFrom(parameter, dimension);
}

public override Task<ModelOriginData> MapToModel(SnapshotOriginData snapshot, SnapshotContext snapshotContext)
public override async Task<ModelOriginData> MapToModel(SnapshotOriginData snapshot, SnapshotContext snapshotContext)
{
var originData = new ModelOriginData {Species = speciesFrom(snapshot)};

Expand All @@ -107,32 +103,24 @@ public override Task<ModelOriginData> MapToModel(SnapshotOriginData snapshot, Sn
updateWeightFromSnapshot(snapshot, originData);
updateHeightFromSnapshot(snapshot, originData);

updateDiseaseStateFromSnapshot(snapshot, originData);
return Task.FromResult(originData);
await updateDiseaseStateFromSnapshot(snapshot, originData, snapshotContext);
return originData;
}

private void updateDiseaseStateFromSnapshot(SnapshotOriginData snapshot, ModelOriginData originData)
private async Task updateDiseaseStateFromSnapshot(SnapshotOriginData snapshot, ModelOriginData originData, SnapshotContext snapshotContext)
{
if (snapshot.DiseaseState == null)
return;

var diseaseState = _diseaseStateRepository.AllFor(originData.Population).FindByName(snapshot.DiseaseState);
if (diseaseState == null)
throw new PKSimException(PKSimConstants.Error.CannotFindDiseaseState(snapshot.DiseaseState, originData.Population.DisplayName));

originData.DiseaseState = diseaseState;
diseaseState.Parameters.Each(x =>
//we might have an old disease state implementation
if (snapshot.DiseaseState != null)
{
var diseaseStateParameter = new OriginDataParameter {Name = x.Name, Value = x.Value, Unit = x.DisplayUnitName()};
var snapshotParameter = snapshot.DiseaseStateParameters.FindByName(x.Name);
if (snapshotParameter != null)
//conversion for older version
snapshot.Disease = new DiseaseState
{
diseaseStateParameter.Value = baseParameterValueFrom(snapshotParameter, x.Value);
diseaseStateParameter.Unit = snapshotParameter.Unit;
}
Name = snapshot.DiseaseState,
Parameters = snapshot.DiseaseStateParameters
};
}

originData.AddDiseaseStateParameter(diseaseStateParameter);
});
await _diseaseStateMapper.MapToModel(snapshot.Disease, new DiseaseStateContext(originData, snapshotContext));
}

private void updateWeightFromSnapshot(SnapshotOriginData snapshot, ModelOriginData originData)
Expand Down Expand Up @@ -205,9 +193,6 @@ private Species speciesFrom(SnapshotOriginData snapshot)
return species ?? throw new PKSimException(PKSimConstants.Error.CouldNotFindSpecies(snapshot.Species, _speciesRepository.AllNames()));
}

private double baseParameterValueFrom(Parameter snapshot, double defaultValueInBaseUnit) =>
baseParameterValueFrom(snapshot, _dimensionRepository.DimensionForUnit(snapshot.Unit), defaultValueInBaseUnit);

private double baseParameterValueFrom(Parameter snapshot, IDimension dimension, double defaultValueInBaseUnit)
{
if (snapshot?.Value == null)
Expand All @@ -217,11 +202,6 @@ private double baseParameterValueFrom(Parameter snapshot, IDimension dimension,
return dimension.UnitValueToBaseUnitValue(unit, snapshot.Value.Value);
}

private Parameter namedParameterFrom(OriginDataParameter parameter)
{
return parameterFrom(parameter, _dimensionRepository.DimensionForUnit(parameter.Unit)).WithName(parameter.Name);
}

private Parameter parameterFrom(OriginDataParameter parameter, IDimension dimension)
{
if (parameter == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ private async Task<ParameterRange[]> snapshotDiseaseStateParameters(Model.Indivi
{
var diseaseStateParameterRanges = individual.OriginData?.DiseaseStateParameters
.Select(x => randomPopulationSettings.ParameterRange(x.Name))
//this can be null if no parameter range is associated with the parameter (e.g. discrete parameters)
.Where(x => x != null)
.ToList();

if (diseaseStateParameterRanges == null)
Expand Down
Loading

0 comments on commit 84f2c24

Please sign in to comment.