Skip to content

Commit

Permalink
Fixes #2643 when to show global pk analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
msevestre committed May 27, 2023
1 parent 84e0c77 commit d1523df
Show file tree
Hide file tree
Showing 4 changed files with 293 additions and 213 deletions.
74 changes: 45 additions & 29 deletions src/PKSim.Core/Services/PKAnalysesTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ public interface IPKAnalysesTask : OSPSuite.Core.Domain.Services.IPKAnalysesTask
/// Starts the calculation of the Auc DDI Ratio for all compounds /> by switching off all other applications
/// </summary>
void CalculateDDIRatioFor(Simulation simulation);

/// <summary>
/// Returns true if global pk-analysis can be calculated for the given <paramref name="protocol" /> otherwise false
/// </summary>
/// <param name="protocol"></param>
/// <returns></returns>
bool CanCalculateGlobalPKFor(Protocol protocol);
}

public class PKAnalysesTask : OSPSuite.Core.Domain.Services.PKAnalysesTask, IPKAnalysesTask
Expand Down Expand Up @@ -356,13 +363,13 @@ private IContainer calculateGlobalPKAnalysisFor(Simulation simulation, string co
vssPlasma.Value *= bioAvailabilityValue;
vdPlasma.Value *= bioAvailabilityValue;
totalPlasmaCL.Value *= bioAvailabilityValue;
fractionAbsorbedWarningParameters.AddRange(new[] { vssPlasma, vdPlasma });
pkValues.AddRange(new[] { vssPlasma, vdPlasma, totalPlasmaCL, bioAvailability });
fractionAbsorbedWarningParameters.AddRange(new[] {vssPlasma, vdPlasma});
pkValues.AddRange(new[] {vssPlasma, vdPlasma, totalPlasmaCL, bioAvailability});
}
else
{
fractionAbsorbedWarningParameters.AddRange(new[] { vssPlasmaOverF, vdPlasmaOverF });
pkValues.AddRange(new[] { vssPlasmaOverF, vdPlasmaOverF, totalPlasmaCLOverF, bioAvailability });
fractionAbsorbedWarningParameters.AddRange(new[] {vssPlasmaOverF, vdPlasmaOverF});
pkValues.AddRange(new[] {vssPlasmaOverF, vdPlasmaOverF, totalPlasmaCLOverF, bioAvailability});
}


Expand Down Expand Up @@ -396,13 +403,7 @@ private static IEnumerable<QuantityPKParameter> mapQuantityPKParametersFromIndiv
// use the first in series as a template to retrieve from all individual results.
// The list of parameters should be identical for all the individual global analyses.
var aPKAnalysis = globalIndividualPKParameterCache.FirstOrDefault();
aPKAnalysis?.AllPKParameters.GroupBy(moleculeNameFrom).Each(group =>
{
group.Each(pKParameter =>
{
quantityPKList.Add(quantityPKParameterFor(globalIndividualPKParameterCache, pKParameter, group.Key));
});
});
aPKAnalysis?.AllPKParameters.GroupBy(moleculeNameFrom).Each(group => { group.Each(pKParameter => { quantityPKList.Add(quantityPKParameterFor(globalIndividualPKParameterCache, pKParameter, group.Key)); }); });

return quantityPKList;
}
Expand All @@ -420,9 +421,9 @@ private static QuantityPKParameter quantityPKParameterFor(ICache<int, GlobalPKAn
if (firstParameter == null)
return new QuantityPKParameter();

var quantityPKParameter = new QuantityPKParameter { Dimension = firstParameter.Dimension, Name = firstParameter.Name, QuantityPath = quantityPath };
var quantityPKParameter = new QuantityPKParameter {Dimension = firstParameter.Dimension, Name = firstParameter.Name, QuantityPath = quantityPath};

pKValuesForPKParameter.Each(pKValue => { quantityPKParameter.SetValue(pKValuesForPKParameter.IndexOf(pKValue), (float)pKValue.Value); });
pKValuesForPKParameter.Each(pKValue => { quantityPKParameter.SetValue(pKValuesForPKParameter.IndexOf(pKValue), (float) pKValue.Value); });
return quantityPKParameter;
}

Expand Down Expand Up @@ -528,7 +529,7 @@ public void CalculateBioavailabilityFor(Simulation simulation, string compoundNa
// We know this is a valid cast because it is cloned from simulation
var populationSimulation = simulation.DowncastTo<PopulationSimulation>();
CalculateFor(ivPopulationSimulation, ivCompoundPKContext);
var contextForPopulationSimulation = createContextForPopulationSimulation(ivCompoundPKContext, mapFromBioavailabilityCompoundPK, compoundName, populationSimulation, new[] { Bioavailability });
var contextForPopulationSimulation = createContextForPopulationSimulation(ivCompoundPKContext, mapFromBioavailabilityCompoundPK, compoundName, populationSimulation, new[] {Bioavailability});
populationSimulation.PKAnalyses = CalculateFor(populationSimulation, contextForPopulationSimulation);
}
else if (ivSimulation is IndividualSimulation ivIndividualSimulation)
Expand Down Expand Up @@ -574,7 +575,7 @@ public void CalculateDDIRatioFor(Simulation simulation)

// First calculate the compound context. We will know the AucInf and CMax when DDI is turned off
CalculateFor(ddiPopulationSimulation, ddiCompoundPKContext);
var parameterNames = new[] { AUCRatio, C_maxRatio };
var parameterNames = new[] {AUCRatio, C_maxRatio};

// From the ddi context, create the context from the original simulation and the ddi simulation for calculating ddi ratio parameters
var contextForPopulationSimulation = createContextForPopulationSimulation(ddiCompoundPKContext, mapFromDDISimulationCompoundPK, compoundName, populationSimulation, parameterNames);
Expand All @@ -592,6 +593,21 @@ public void CalculateDDIRatioFor(Simulation simulation)
simulation.HasChanged = true;
}

public bool CanCalculateGlobalPKFor(Protocol protocol)
{
var schemaItems = _protocolToSchemaItemsMapper.MapFrom(protocol);
if (schemaItems == null || schemaItems.Count == 0)
return false;

//only one item, supported for IV or ORAL
var schemaItem = schemaItems[0];
if (schemaItems.Count == 1)
return isOral(schemaItem) || isIntravenous(schemaItem);

//two items. Only ok if all are ORAL
return schemaItems.All(isOral);
}

private CompoundPKContext createContextForPopulationSimulation(CompoundPKContext contextCompoundPK, Func<CompoundPK, CompoundPK> compoundPKMapper, string compoundName, PopulationSimulation populationSimulation, string[] parameterNames)
{
var contextForPopulationSimulation = new CompoundPKContext();
Expand All @@ -603,14 +619,14 @@ private CompoundPKContext createContextForPopulationSimulation(CompoundPKContext

private CompoundPK mapFromBioavailabilityCompoundPK(CompoundPK bioAvailabilitySimulationCompoundPK)
{
var compoundPK = new CompoundPK { CompoundName = bioAvailabilitySimulationCompoundPK.CompoundName };
var compoundPK = new CompoundPK {CompoundName = bioAvailabilitySimulationCompoundPK.CompoundName};
bioAvailabilitySimulationCompoundPK.AllBioAvailabilityAucInf.KeyValues.Each(bioAvailability => { compoundPK.AddBioavailability(bioAvailability.Key, bioAvailability.Value); });
return compoundPK;
}

private CompoundPK mapFromDDISimulationCompoundPK(CompoundPK ddiSimulationCompoundPK)
{
var compoundPK = new CompoundPK { CompoundName = ddiSimulationCompoundPK.CompoundName };
var compoundPK = new CompoundPK {CompoundName = ddiSimulationCompoundPK.CompoundName};
ddiSimulationCompoundPK.AllDDIAucInf.KeyValues.Each(aucInf => compoundPK.AddDDIAucInf(aucInf.Key, aucInf.Value));
ddiSimulationCompoundPK.AllDDICMax.KeyValues.Each(cMax => compoundPK.AddDDICMax(cMax.Key, cMax.Value));
return compoundPK;
Expand Down Expand Up @@ -705,7 +721,7 @@ public IEnumerable<PopulationPKAnalysis> CalculateFor(IPopulationDataCollector p
return pkAnalyses; // there are no analyses to calculate

var allColumns = timeProfileChartData.Panes.SelectMany(x => x.Curves).SelectMany(x =>
columnsFor(x, populationDataCollector).Select(column => new { curveData = x, column }))
columnsFor(x, populationDataCollector).Select(column => new {curveData = x, column}))
.Where(c => c.column.IsConcentration());

var columnsByMolecules = allColumns.GroupBy(x => x.column.MoleculeName());
Expand Down Expand Up @@ -748,7 +764,7 @@ public IEnumerable<IndividualPKAnalysis> CalculateFor(IReadOnlyList<Simulation>

private IEnumerable<DataColumn> columnsFor(CurveData<TimeProfileXValue, TimeProfileYValue> curveData, IPopulationDataCollector populationDataCollector)
{
var baseGrid = new BaseGrid(Constants.TIME, curveData.XAxis.Dimension) { Values = curveData.XValues.Select(x => x.X).ToList() };
var baseGrid = new BaseGrid(Constants.TIME, curveData.XAxis.Dimension) {Values = curveData.XValues.Select(x => x.X).ToList()};

if (curveData.IsRange())
{
Expand All @@ -758,14 +774,14 @@ private IEnumerable<DataColumn> columnsFor(CurveData<TimeProfileXValue, TimeProf
new DataColumn(lowerRange, curveData.YAxis.Dimension, baseGrid)
{
Values = curveData.YValues.Select(y => y.LowerValue).ToList(),
DataInfo = { MolWeight = populationDataCollector.MolWeightFor(curveData.QuantityPath) },
QuantityInfo = { Path = curveData.QuantityPath.ToPathArray() }
DataInfo = {MolWeight = populationDataCollector.MolWeightFor(curveData.QuantityPath)},
QuantityInfo = {Path = curveData.QuantityPath.ToPathArray()}
},
new DataColumn(upperRange, curveData.YAxis.Dimension, baseGrid)
{
Values = curveData.YValues.Select(y => y.UpperValue).ToList(),
DataInfo = { MolWeight = populationDataCollector.MolWeightFor(curveData.QuantityPath) },
QuantityInfo = { Path = curveData.QuantityPath.ToPathArray() }
DataInfo = {MolWeight = populationDataCollector.MolWeightFor(curveData.QuantityPath)},
QuantityInfo = {Path = curveData.QuantityPath.ToPathArray()}
}
};
}
Expand All @@ -775,8 +791,8 @@ private IEnumerable<DataColumn> columnsFor(CurveData<TimeProfileXValue, TimeProf
new DataColumn(curveData.Caption, curveData.YAxis.Dimension, baseGrid)
{
Values = curveData.YValues.Select(y => y.Y).ToList(),
DataInfo = { MolWeight = populationDataCollector.MolWeightFor(curveData.QuantityPath) },
QuantityInfo = { Path = curveData.QuantityPath.ToPathArray() }
DataInfo = {MolWeight = populationDataCollector.MolWeightFor(curveData.QuantityPath)},
QuantityInfo = {Path = curveData.QuantityPath.ToPathArray()}
}
};
}
Expand All @@ -786,7 +802,7 @@ public IndividualPKAnalysis CalculateFor(Simulation simulation, DataColumn dataC
if (dataColumn == null)
return new NullIndividualPKAnalysis();

return CalculateFor(new[] { simulation }, new[] { dataColumn }).FirstOrDefault() ?? new NullIndividualPKAnalysis();
return CalculateFor(new[] {simulation}, new[] {dataColumn}).FirstOrDefault() ?? new NullIndividualPKAnalysis();
}

private PKValues calculatePK(DataColumn column, PKCalculationOptions options)
Expand Down Expand Up @@ -863,13 +879,13 @@ public PKAnalysis CreatePKAnalysisFromValues(PKValues pkValues, Simulation simul
/// </returns>
private (string lowerRange, string upperRange) rangeDescriptions(string text)
{
var splitStrings = text.Split(new[] { "Range" }, StringSplitOptions.None);
var splitStrings = text.Split(new[] {"Range"}, StringSplitOptions.None);
var match = splitStrings.Length == 2;

if (!match)
return (text, text);

var upperAndLowerRange = splitStrings.Last().Split(new[] { "to" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToArray();
var upperAndLowerRange = splitStrings.Last().Split(new[] {"to"}, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToArray();

return ($"{splitStrings[0]}{upperAndLowerRange[0]}", $"{splitStrings[0]}{upperAndLowerRange[1]}");
}
Expand Down Expand Up @@ -918,7 +934,7 @@ private string correctNameFromMetric(string originalText, bool multipleValues, b
suffix = isLowerValue ? lowerRange : upperRange;
}

return (new[] { captionPrefix, suffix }).ToCaption();
return (new[] {captionPrefix, suffix}).ToCaption();
}

private CurveData<TimeProfileXValue, TimeProfileYValue> buildCurveData(QuantityPKParameter quantityPKParameter, string caption)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,16 @@ private void loadPreferredUnitsForPKAnalysis()
{
if (_settings == null)
return;

GlobalPKAnalysis.AllPKParameterNames.Each(updateParameterDisplayUnits);
}

private void updateParameterDisplayUnits(string parameterName)
{
GlobalPKAnalysis.PKParameters(parameterName).Each(parameter => { parameter.DisplayUnit = parameter.Dimension.Unit(_settings.GetSetting(parameterName, DisplayUnitFor(parameterName).Name)); });
GlobalPKAnalysis.PKParameters(parameterName).Each(parameter =>
{
parameter.DisplayUnit = parameter.Dimension.Unit(_settings.GetSetting(parameterName, DisplayUnitFor(parameterName).Name));
});
}

private Simulation firstSimulation => _simulations.FirstOrDefault();
Expand All @@ -141,20 +145,11 @@ public void ChangeUnit(string parameterName, Unit newUnit)
updateView();
}

public Unit DisplayUnitFor(string parameterName)
{
return pkParameterNamed(parameterName).DisplayUnit;
}
public Unit DisplayUnitFor(string parameterName) => pkParameterNamed(parameterName).DisplayUnit;

public IEnumerable<Unit> AvailableUnitsFor(string parameterName)
{
return pkParameterNamed(parameterName).Dimension.Units;
}
public IEnumerable<Unit> AvailableUnitsFor(string parameterName) => pkParameterNamed(parameterName).Dimension.Units;

private IParameter pkParameterNamed(string parameterName)
{
return GlobalPKAnalysis.PKParameters(parameterName).First();
}
private IParameter pkParameterNamed(string parameterName) => GlobalPKAnalysis.PKParameters(parameterName).First();

public string DisplayNameFor(string parameterName)
{
Expand All @@ -175,12 +170,9 @@ public bool CanCalculateGlobalPK()
{
return firstSimulation.Compounds.Select(compound => firstSimulation.CompoundPropertiesFor(compound).ProtocolProperties.Protocol)
.Where(p => p != null)
.Select(_protocolToSchemaItemsMapper.MapFrom)
.Any(x => !isMultipleIV(x));
.Any(_pkAnalysesTask.CanCalculateGlobalPKFor);
}

private bool isMultipleIV(IReadOnlyList<SchemaItem> schemaItems) => schemaItems.Count(x => x.IsIV) > 1;

public void LoadSettingsForSubject(IWithId subject)
{
_settings = _presentationSettingsTask.PresentationSettingsFor<DefaultPresentationSettings>(this, subject);
Expand Down
Loading

0 comments on commit d1523df

Please sign in to comment.