Source code for pharmpy.modeling.metabolite
"""
:meta private:
"""
from __future__ import annotations
from pharmpy.basic import Expr
from pharmpy.model import (
Assignment,
Compartment,
CompartmentalSystem,
CompartmentalSystemBuilder,
Model,
get_and_check_odes,
output,
)
from .error import set_proportional_error_model
from .odes import _find_noncov_theta, add_individual_parameter, set_first_order_absorption
from .parameters import set_initial_estimates, set_lower_bounds, set_upper_bounds
[docs]
def add_metabolite(model: Model, drug_dvid: int = 1, presystemic: bool = False) -> Model:
"""Adds a metabolite compartment to a model
The flow from the central compartment to the metabolite compartment
will be unidirectional.
Presystemic indicate that the metabolite compartment will be
directly connected to the DEPOT. If a depot compartment is not present,
one will be created.
Parameters
----------
model : Model
Pharmpy model
drug_dvid : int
DVID for drug (assuming all other DVIDs being for metabolites)
presystemic : bool
Decide wether or not to add metabolite as a presystemetic fixed drug.
Return
------
Model
Pharmpy model object
Examples
--------
>>> from pharmpy.modeling import *
>>> model = load_example_model("pheno")
>>> model = add_metabolite(model)
"""
if presystemic:
odes = get_and_check_odes(model)
depot = odes.find_depot(model.statements)
if not depot:
model = set_first_order_absorption(model)
odes = get_and_check_odes(model)
depot = odes.find_depot(model.statements)
if not depot:
transits = odes.find_transit_compartments(model.statements)
if transits:
depot = transits[-1]
else:
raise ValueError(
"Pre-systemic metabolite model is not compatible with input model."
)
else:
depot = None
# TODO: Implement possibility of converting plain metabolite to presystemic
clm = Expr.symbol('CLM')
model = add_individual_parameter(model, clm.name)
vm = Expr.symbol('VM')
model = add_individual_parameter(model, vm.name)
odes = get_and_check_odes(model)
central = odes.central_compartment
ke = odes.get_flow(central, output)
if ke.is_symbol():
ke_ass = model.statements.find_assignment(ke)
if ke_ass is not None:
ke = ke_ass.expression
cl, vc = ke.as_numer_denom()
if vc != 1:
pop_cl = _find_noncov_theta(model, cl)
pop_vc = _find_noncov_theta(model, vc)
pop_clm_init = model.parameters[pop_cl].init * 2.0
pop_vm_init = model.parameters[pop_vc].init * 0.5
model = set_initial_estimates(model, {'POP_CLM': pop_clm_init, 'POP_VM': pop_vm_init})
cb = CompartmentalSystemBuilder(odes)
metacomp = Compartment.create(name="METABOLITE")
cb.add_compartment(metacomp)
cb.add_flow(metacomp, output, clm / vm)
cb.add_flow(central, metacomp, ke)
cb.remove_flow(central, output)
amount = metacomp.amount
if presystemic:
assert isinstance(depot, Compartment)
fpre = Expr.symbol('FPRE')
model = add_individual_parameter(model, fpre.name)
model = set_lower_bounds(model, {'POP_FPRE': 0.0})
model = set_upper_bounds(model, {'POP_FPRE': 1.0})
ka = odes.get_flow(depot, central)
if ka.is_symbol():
ka_ass = model.statements.find_assignment(ka)
if ka_ass is not None:
ka = ka_ass.expression
cb.add_flow(depot, metacomp, fpre * ka)
cb.remove_flow(depot, central)
cb.add_flow(depot, central, ka * (1 - fpre))
# FIXME: drug_dvid is never used, use it here?
# dvid_col = model.datainfo.typeix['dvid'][0]
# dvids = dvid_col.categories
# QUESTION: Add bioavailability to depot?
cb.set_bioavailability(depot, 1 / (1 - fpre))
model = model.replace(
statements=model.statements.before_odes
+ CompartmentalSystem(cb)
+ model.statements.after_odes
)
model = model.update_source()
cs = get_and_check_odes(model)
bio = cs.find_compartment(depot.name).bioavailability
conc = Assignment(Expr.symbol('CONC_M'), amount / vm / bio)
else:
cs = CompartmentalSystem(cb)
conc = Assignment(Expr.symbol('CONC_M'), amount / vm)
y_m = Expr.symbol('Y_M')
y = Assignment(y_m, conc.symbol)
original_y = next(iter(model.dependent_variables))
ind = model.statements.after_odes.find_assignment_index(original_y)
old_after = model.statements.after_odes
new_after = old_after[: ind + 1] + y + old_after[ind + 1 :]
error = conc + new_after
dvs = model.dependent_variables.replace(y_m, 2) # FIXME: Should be next DVID in categories
statements = model.statements.before_odes + cs + error
model = model.replace(statements=statements, dependent_variables=dvs)
model = set_proportional_error_model(model, dv=2, zero_protection=False)
return model
[docs]
def has_presystemic_metabolite(model: Model):
"""Checks whether a model has a presystemic metabolite
If pre-systemic drug there will be a flow from DEPOT to METABOLITE as well
as being a flow from the CENTRAL to METABOLITE
Parameters
----------
model : Model
Pharmpy model
Return
------
bool
Whether a model has presystemic metabolite
Examples
--------
>>> from pharmpy.modeling import *
>>> model = load_example_model("pheno")
>>> model = add_metabolite(model, presystemic=True)
>>> has_presystemic_metabolite(model)
True
"""
odes = model.statements.ode_system
if odes is None:
return False
central = odes.central_compartment
metabolite = odes.find_compartment("METABOLITE")
depot = odes.find_depot(model.statements)
CM = odes.get_flow(central, metabolite)
DM = odes.get_flow(depot, metabolite)
if CM != Expr.integer(0) and DM != Expr.integer(0):
return True
else:
return False