Skip to content

Commit 52fdffb

Browse files
authored
Add Blasi model selection problem for motif-specific parameters (#157)
1 parent 975f198 commit 52fdffb

16 files changed

Lines changed: 1721 additions & 0 deletions
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mkdir -p output/model
2+
mkdir output/petab
3+
mkdir output/select
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import libsbml
2+
3+
from model_info import (
4+
all_species_dict,
5+
reactions_dict,
6+
parameters_dict,
7+
)
8+
9+
10+
# Create model
11+
sbml_document = libsbml.SBMLDocument(3, 2)
12+
sbml_model = sbml_document.createModel()
13+
sbml_model.setId('Blasi_CellSystems2016__select_motif_specific')
14+
sbml_model.setName('Blasi_CellSystems2016__select_motif_specific')
15+
16+
# Add compartment
17+
compartment_id = 'compartment'
18+
compartment = sbml_model.createCompartment()
19+
compartment.setId(compartment_id)
20+
compartment.setName(compartment_id)
21+
compartment.setSize(1)
22+
compartment.setConstant(True)
23+
24+
# Add species
25+
for species_dict in all_species_dict.values():
26+
species = sbml_model.createSpecies()
27+
species.setId(species_dict['id'])
28+
species.setName(species_dict['name'])
29+
species.setInitialConcentration(species_dict['initialConcentration'])
30+
species.setCompartment(compartment_id)
31+
species.setConstant(False)
32+
species.setBoundaryCondition(False)
33+
species.setHasOnlySubstanceUnits(False)
34+
35+
# Add parameters
36+
for parameter_dict in parameters_dict.values():
37+
parameter = sbml_model.createParameter()
38+
parameter.setId(parameter_dict['id'])
39+
parameter.setName(parameter_dict['name'])
40+
parameter.setValue(parameter_dict['value'])
41+
parameter.setConstant(True)
42+
43+
# Add reactions
44+
for reaction_dict in reactions_dict.values():
45+
# Create reaction
46+
reaction = sbml_model.createReaction()
47+
reaction.setId(reaction_dict['id'])
48+
reaction.setName(reaction_dict['name'])
49+
reaction.setReversible(False)
50+
51+
# Add reactant
52+
reactant = reaction.createReactant()
53+
reactant.setSpecies(reaction_dict['reactant_id'])
54+
reactant.setConstant(True)
55+
56+
# Add product
57+
product = reaction.createProduct()
58+
product.setSpecies(reaction_dict['product_id'])
59+
product.setConstant(True)
60+
61+
# Add kinetic
62+
math_ast = libsbml.parseL3Formula(reaction_dict['formula'])
63+
kinetic_law = reaction.createKineticLaw()
64+
kinetic_law.setMath(math_ast)
65+
66+
libsbml.writeSBMLToFile(sbml_document, 'output/model/model.xml')
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import pandas as pd
2+
import petab
3+
import shutil
4+
5+
from petab import (
6+
CONDITION_ID,
7+
OBSERVABLE_ID,
8+
MEASUREMENT,
9+
OBSERVABLE_NAME,
10+
OBSERVABLE_FORMULA,
11+
NOISE_FORMULA,
12+
OBSERVABLE_TRANSFORMATION,
13+
NOISE_DISTRIBUTION,
14+
LOG,
15+
LOG10,
16+
NORMAL,
17+
SIMULATION_CONDITION_ID,
18+
TIME,
19+
PARAMETER_ID,
20+
PARAMETER_NAME,
21+
LIN,
22+
PARAMETER_SCALE,
23+
LOWER_BOUND,
24+
UPPER_BOUND,
25+
NOMINAL_VALUE,
26+
ESTIMATE,
27+
)
28+
29+
30+
from model_info import (
31+
get_ac_state,
32+
get_motif,
33+
get_species_id,
34+
lysines,
35+
motif_specific_parameters,
36+
# switch_parameters,
37+
common_parameters,
38+
)
39+
40+
41+
petab_problem0 = petab.Problem.from_yaml('../Blasi_CellSystems2016.yaml')
42+
measurements0 = dict(zip(petab_problem0.measurement_df[OBSERVABLE_ID], petab_problem0.measurement_df[MEASUREMENT]))
43+
44+
condition_id = 'condition'
45+
noise = 'sigma'
46+
47+
48+
def convert_observable_id(id0: str) -> str:
49+
motif0 = id0[len('observable_'):]
50+
if motif0 == '0ac':
51+
ac_state = tuple()
52+
elif motif0 == '4ac':
53+
ac_state = get_ac_state(lysines)
54+
else:
55+
ac_state = get_ac_state([f'k{i:0>2}' for i in motif0.split('k') if i])
56+
species_id = get_species_id(ac_state)
57+
observable_id = 'observable_' + species_id
58+
observable_dict = {
59+
OBSERVABLE_ID: 'observable_' + species_id,
60+
OBSERVABLE_NAME: 'y_{' + get_motif(ac_state) + '}',
61+
OBSERVABLE_FORMULA: species_id,
62+
OBSERVABLE_TRANSFORMATION: LOG,
63+
NOISE_FORMULA: noise,
64+
NOISE_DISTRIBUTION: NORMAL,
65+
}
66+
return observable_dict
67+
68+
69+
# Create observables
70+
observable_dicts = []
71+
observable_id_mapping = {}
72+
observable_ids0 = sorted(set(measurements0))
73+
for observable_id0 in observable_ids0:
74+
observable_dict = convert_observable_id(observable_id0)
75+
observable_id_mapping[observable_id0] = observable_dict[OBSERVABLE_ID]
76+
observable_dicts.append(observable_dict)
77+
78+
# Create measurements
79+
measurement_dicts = []
80+
for observable_id0, value0 in measurements0.items():
81+
observable_id = observable_id_mapping[observable_id0]
82+
measurement_dict = {
83+
OBSERVABLE_ID: observable_id,
84+
SIMULATION_CONDITION_ID: condition_id,
85+
TIME: 'inf',
86+
MEASUREMENT: value0,
87+
}
88+
measurement_dicts.append(measurement_dict)
89+
90+
# Create parameters
91+
parameter_dicts = []
92+
## Motif-specific
93+
for parameter_dict0 in motif_specific_parameters.values():
94+
parameter_dict = {
95+
PARAMETER_ID: parameter_dict0['id'],
96+
PARAMETER_NAME: parameter_dict0['name'],
97+
PARAMETER_SCALE: LOG10,
98+
LOWER_BOUND: '1e-12',
99+
UPPER_BOUND: '1e3',
100+
NOMINAL_VALUE: 1,
101+
ESTIMATE: 0,
102+
}
103+
parameter_dicts.append(parameter_dict)
104+
# ## Switch
105+
# for parameter_dict0 in switch_parameters.values():
106+
# parameter_dict = {
107+
# PARAMETER_ID: parameter_dict0['id'],
108+
# PARAMETER_NAME: parameter_dict0['name'],
109+
# PARAMETER_SCALE: LIN,
110+
# NOMINAL_VALUE: 0,
111+
# ESTIMATE: 0,
112+
# }
113+
# parameter_dicts.append(parameter_dict)
114+
## Basal
115+
for parameter_dict0 in common_parameters.values():
116+
if parameter_dict0['id'] == 'a_b':
117+
parameter_dict = {
118+
PARAMETER_ID: parameter_dict0['id'],
119+
PARAMETER_NAME: parameter_dict0['name'],
120+
PARAMETER_SCALE: LOG10,
121+
LOWER_BOUND: '1e-12',
122+
UPPER_BOUND: '1e3',
123+
NOMINAL_VALUE: 0,
124+
ESTIMATE: 1,
125+
}
126+
elif parameter_dict0['id'] == 'da_b':
127+
parameter_dict = {
128+
PARAMETER_ID: parameter_dict0['id'],
129+
PARAMETER_NAME: parameter_dict0['name'],
130+
PARAMETER_SCALE: LIN,
131+
NOMINAL_VALUE: 1,
132+
ESTIMATE: 0,
133+
}
134+
else:
135+
raise NotImplementedError(parameter_dict0['id'])
136+
parameter_dicts.append(parameter_dict)
137+
## Noise
138+
parameter_dicts.append(
139+
{
140+
PARAMETER_ID: noise,
141+
PARAMETER_NAME: noise,
142+
PARAMETER_SCALE: LOG10,
143+
LOWER_BOUND: '1e-12',
144+
UPPER_BOUND: '1e3',
145+
NOMINAL_VALUE: 0.1,
146+
ESTIMATE: 1,
147+
}
148+
)
149+
150+
condition_df = petab.get_condition_df(pd.DataFrame({CONDITION_ID:[condition_id]}))
151+
observable_df = petab.get_observable_df(pd.DataFrame(observable_dicts))
152+
measurement_df = petab.get_measurement_df(pd.DataFrame(measurement_dicts))
153+
parameter_df = petab.get_parameter_df(pd.DataFrame(parameter_dicts))
154+
155+
petab.write_condition_df(condition_df, 'output/petab/conditions.tsv')
156+
petab.write_observable_df(observable_df, 'output/petab/observables.tsv')
157+
petab.write_measurement_df(measurement_df, 'output/petab/measurements.tsv')
158+
petab.write_parameter_df(parameter_df, 'output/petab/parameters.tsv')
159+
shutil.copy('input/petab_problem.yaml', 'output/petab/petab_problem.yaml')
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from model_info import (
2+
acetylation_reactions,
3+
get_parameter_id,
4+
)
5+
import shutil
6+
import pandas as pd
7+
8+
9+
import petab_select
10+
from petab_select.constants import (
11+
MODEL_SUBSPACE_ID,
12+
PETAB_YAML,
13+
ESTIMATE,
14+
PARAMETER_VALUE_DELIMITER,
15+
)
16+
17+
18+
parameter_ids = [get_parameter_id(*reaction) for reaction in acetylation_reactions]
19+
20+
# The value to "turn off" the parameter. Since it's a multiplier, `1` is the identity.
21+
default_motif_value = '1.0'
22+
23+
model_subspace = {
24+
MODEL_SUBSPACE_ID: 'M',
25+
PETAB_YAML: '../petab/petab_problem.yaml',
26+
**{
27+
parameter_id: PARAMETER_VALUE_DELIMITER.join([default_motif_value, ESTIMATE])
28+
for parameter_id in parameter_ids
29+
}
30+
}
31+
32+
df = petab_select.get_model_space_df(pd.DataFrame([model_subspace]))
33+
34+
petab_select.write_model_space_df(df, filename='output/select/model_space.tsv')
35+
shutil.copy('input/petab_select_problem.yaml', 'output/select/petab_select_problem.yaml')
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Model selection problem for `Blasi_CellSystems2016`
2+
This is a fresh implementation of the model from `Blasi_CellSystems2016`, to faciliate model selection with PEtab and PEtab Select. The implementation can be found in the `output/` directory.
3+
4+
Specifically, this model contains parameters to enable model selection with motif-specific acetylation rates. These additional parameters are implemented as multipliers of the basal acetylation rate `a_b`.
5+
Note that this means any motif-specific parameter `a_*` (except the basal acetylation rate `a_b`) can be fixed to 1 to "turn off" the motif-specific acetylation rate, or estimated to "turn on" the motif-specific acetylation rate.
6+
7+
The only thing taken from the main PEtab problem are the measurements, the remaining PEtab (Select) files and the model were generated with the provided scripts.
8+
9+
# Python requirements
10+
The following should be sufficient to run the provided scripts. If using a system that doesn't support the bash `*.sh` script, then simply create the folders manually.
11+
- a Python 3 virtual environment with PEtab Select (`pip install petab-select`) installed.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
format_version: 1
2+
parameter_file: parameters.tsv
3+
problems:
4+
- condition_files:
5+
- conditions.tsv
6+
measurement_files:
7+
- measurements.tsv
8+
observable_files:
9+
- observables.tsv
10+
sbml_files:
11+
- ../model/model.xml
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
format_version: beta_1
2+
criterion: BIC
3+
method: forward
4+
model_space_files:
5+
- model_space.tsv

0 commit comments

Comments
 (0)