Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend validator to check if all required parameters are present in p… #159

Merged
merged 2 commits into from
Dec 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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