Skip to content

Commit

Permalink
Extend validator to check if all required parameters are present in p…
Browse files Browse the repository at this point in the history
…arameter table (Closes #43)
  • Loading branch information
dweindl committed Dec 1, 2019
1 parent 8fab85e commit e2ef2a1
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 30 deletions.
67 changes: 39 additions & 28 deletions petab/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from . import lint
from . import sbml
from . import parameter_mapping
from typing import Optional, List, Union, Iterable
from typing import Optional, List, Union, Iterable, Set
import warnings


Expand Down Expand Up @@ -668,6 +668,43 @@ def create_parameter_df(sbml_model: libsbml.Model,
lower_bound: lower bound for parameter value
upper_bound: upper bound for parameter value
"""
parameter_ids = list(get_required_parameters_for_parameter_table(
sbml_model, condition_df, measurement_df))

df = pd.DataFrame(
data={
'parameterId': parameter_ids,
'parameterName': parameter_ids,
'parameterScale': parameter_scale,
'lowerBound': lower_bound,
'upperBound': upper_bound,
'nominalValue': np.nan,
'estimate': 1,
'priorType': '',
'priorParameters': ''
})
df.set_index(['parameterId'], inplace=True)

# For SBML model parameters set nominal values as defined in the model
for parameter_id in df.index:
try:
parameter = sbml_model.getParameter(parameter_id)
if parameter:
df.loc[parameter_id, 'nominalValue'] = parameter.getValue()
except ValueError:
# parameter was introduced as condition-specific override and
# is potentially not present in the model
pass
return df


def get_required_parameters_for_parameter_table(
sbml_model: libsbml.Model,
condition_df: pd.DataFrame,
measurement_df: pd.DataFrame) -> Set[str]:
"""
Get set of parameters which need to go into the parameter table
"""

observables = get_observables(sbml_model)
sigmas = get_sigmas(sbml_model)
Expand Down Expand Up @@ -727,33 +764,7 @@ def append_overrides(overrides):
for overrider in overrides:
parameter_ids[overrider] = None

parameter_ids = list(parameter_ids.keys())

df = pd.DataFrame(
data={
'parameterId': parameter_ids,
'parameterName': parameter_ids,
'parameterScale': parameter_scale,
'lowerBound': lower_bound,
'upperBound': upper_bound,
'nominalValue': np.nan,
'estimate': 1,
'priorType': '',
'priorParameters': ''
})
df.set_index(['parameterId'], inplace=True)

# For SBML model parameters set nominal values as defined in the model
for parameter_id in df.index:
try:
parameter = sbml_model.getParameter(parameter_id)
if parameter:
df.loc[parameter_id, 'nominalValue'] = parameter.getValue()
except ValueError:
# parameter was introduced as condition-specific override and
# is potentially not present in the model
pass
return df
return parameter_ids.keys()


def get_priors_from_df(parameter_df: pd.DataFrame):
Expand Down
41 changes: 39 additions & 2 deletions petab/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import logging
import libsbml
import pandas as pd
from typing import Optional

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -68,7 +69,11 @@ def check_measurement_df(df):
_check_df(df, req_cols, "measurement")


def check_parameter_df(df):
def check_parameter_df(
df: pd.DataFrame,
sbml_model: Optional[libsbml.Model],
measurement_df: Optional[pd.DataFrame],
condition_df: Optional[pd.DataFrame]):
req_cols = [
"parameterName", "parameterScale",
"lowerBound", "upperBound", "nominalValue", "estimate"
Expand All @@ -94,6 +99,37 @@ def check_parameter_df(df):
assert_parameter_id_is_unique(df)
check_parameter_bounds(df)

if sbml_model and measurement_df is not None \
and condition_df is not None:
assert_all_parameters_present_in_parameter_df(
df, sbml_model, measurement_df, condition_df)


def assert_all_parameters_present_in_parameter_df(
parameter_df: pd.DataFrame,
sbml_model: libsbml.Model,
measurement_df: pd.DataFrame,
condition_df: pd.DataFrame):
"""Ensure all required parameters are contained in the parameter table
with no additional ones"""

expected = core.get_required_parameters_for_parameter_table(
sbml_model=sbml_model, condition_df=condition_df,
measurement_df=measurement_df)

actual = set(parameter_df.index)

missing = expected - actual
extraneous = actual - expected

if missing:
raise AssertionError('Missing parameter(s) in parameter table: '
+ str(missing))

if extraneous:
raise AssertionError('Extraneous parameter(s) in parameter table: '
+ str(extraneous))


def assert_measured_observables_present_in_model(measurement_df, sbml_model):
"""Check if all observables in measurement files have been specified in
Expand Down Expand Up @@ -400,7 +436,8 @@ def lint_problem(problem: 'core.Problem'):
if problem.parameter_df is not None:
logger.info("Checking parameter table...")
try:
check_parameter_df(problem.parameter_df)
check_parameter_df(problem.parameter_df, problem.sbml_model,
problem.measurement_df, problem.condition_df)
except AssertionError as e:
logger.error(e)
errors_occurred = True
Expand Down

0 comments on commit e2ef2a1

Please sign in to comment.