MetabolicModel.jl 9.58 KB
Newer Older
1
2

"""
3
    abstract type MetabolicModel end
4
5

A helper supertype that wraps everything usable as a linear-like model for
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
6
COBREXA functions.
St. Elmo's avatar
St. Elmo committed
7

Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
8
If you want your model type to work with COBREXA, add the `MetabolicModel` as
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
9
10
11
12
its supertype, and implement the accessor functions. Accessors
[`reactions`](@ref), [`metabolites`](@ref), [`stoichiometry`](@ref),
[`bounds`](@ref) and [`objective`](@ref) must be implemented; others are not
mandatory and default to safe "empty" values.
13
"""
14
abstract type MetabolicModel end
15

Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
16
const SparseMat = SparseMatrixCSC{Float64,Int}
17
const SparseVec = SparseVector{Float64,Int}
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
18
19
20
21
22
const MatType = AbstractMatrix{Float64}
const VecType = AbstractVector{Float64}
const StringVecType = AbstractVector{String}

"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
23
    GeneAssociation = Vector{Vector{String}}
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
24
25
26
27
28
29

An association to genes, represented as a logical formula in a positive
disjunctive normal form (DNF). (The 2nd-level vectors of strings are connected
by "and" to form conjunctions, and the 1st-level vectors of these conjunctions
are connected by "or" to form the DNF.)
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
30
const GeneAssociation = Vector{Vector{String}}
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
31
32

"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
33
    MetaboliteFormula = Dict{String,Int}
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
34
35
36

Dictionary of atoms and their abundances in a molecule.
"""
St. Elmo's avatar
St. Elmo committed
37
const MetaboliteFormula = Dict{String,Int}
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
38
39

"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
40
    Annotations = Dict{String,Vector{String}}
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
41
42
43
44
45
46
47
48
49

Dictionary used to store (possible multiple) standardized annotations of
something, such as a [`Metabolite`](@ref) and a [`Reaction`](@ref).

# Example
```
Annotations("PubChem" => ["CID12345", "CID54321"])
```
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
50
const Annotations = Dict{String,Vector{String}}
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
51
52

"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
53
    Notes = Dict{String,Vector{String}}
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
54

Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
55
56
Free-form notes about something (e.g. a [`Gene`](@ref)), categorized by
"topic".
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
57
"""
St. Elmo's avatar
St. Elmo committed
58
const Notes = Dict{String,Vector{String}}
59

60
_missing_impl_error = (m, a) -> throw(MethodError(m, a))
61

62
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
63
    reactions(a::MetabolicModel)::Vector{String}
64
65
66

Return a vector of reaction identifiers in a model.
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
67
function reactions(a::MetabolicModel)::Vector{String}
68
    _missing_impl_error(reactions, (a,))
69
70
end

71
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
72
    metabolites(a::MetabolicModel)::Vector{String}
73
74
75

Return a vector of metabolite identifiers in a model.
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
76
function metabolites(a::MetabolicModel)::Vector{String}
77
    _missing_impl_error(metabolites, (a,))
78
79
end

80
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
81
    n_reactions(a::MetabolicModel)::Int
82
83
84

Get the number of reactions in a model.
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
85
function n_reactions(a::MetabolicModel)::Int
86
87
88
    length(reactions(a))
end

89
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
90
    n_metabolites(a::MetabolicModel)::Int
91
92
93

Get the number of metabolites in a model.
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
94
function n_metabolites(a::MetabolicModel)::Int
95
96
97
    length(metabolites(a))
end

98
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
99
    stoichiometry(a::MetabolicModel)::SparseMat
100
101
102

Get the sparse stoichiometry matrix of a model.
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
103
function stoichiometry(a::MetabolicModel)::SparseMat
104
    _missing_impl_error(stoichiometry, (a,))
105
106
end

107
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
108
    bounds(a::MetabolicModel)::Tuple{SparseVec,SparseVec}
109
110
111

Get the lower and upper flux bounds of a model.
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
112
function bounds(a::MetabolicModel)::Tuple{SparseVec,SparseVec}
113
    _missing_impl_error(bounds, (a,))
114
115
end

116
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
117
    balance(a::MetabolicModel)::SparseVec
118
119
120

Get the sparse balance vector of a model (ie. the `b` from `S x = b`).
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
121
function balance(a::MetabolicModel)::SparseVec
122
    return spzeros(n_metabolites(a))
123
124
end

125
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
126
    objective(a::MetabolicModel)::SparseVec
127
128
129

Get the objective vector of a model.
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
130
function objective(a::MetabolicModel)::SparseVec
131
    _missing_impl_error(objective, (a,))
132
133
end

134
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
135
    coupling(a::MetabolicModel)::SparseMat
136

137
138
Get a matrix of coupling constraint definitions of a model. By default, there
is no coupling in the models.
139
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
140
function coupling(a::MetabolicModel)::SparseMat
141
    return spzeros(0, n_reactions(a))
142
143
end

144
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
145
    n_coupling_constraints(a::MetabolicModel)::Int
146
147
148

Get the number of coupling constraints in a model.
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
149
function n_coupling_constraints(a::MetabolicModel)::Int
150
151
152
    size(coupling(a), 1)
end

153
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
154
    coupling_bounds(a::MetabolicModel)::Tuple{SparseVec,SparseVec}
155
156

Get the lower and upper bounds for each coupling bound in a model, as specified
157
by `coupling`. By default, the model does not have any coupling bounds.
158
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
159
function coupling_bounds(a::MetabolicModel)::Tuple{SparseVec,SparseVec}
160
    return (spzeros(0), spzeros(0))
161
end
162
163
164
165
166
167

"""
    genes(a::MetabolicModel)::Vector{String}

Return identifiers of all genes contained in the model. By default, there are
no genes.
168
169
170

In SBML, these are usually called "gene products" but we write `genes` for
simplicity.
171
172
173
174
175
"""
function genes(a::MetabolicModel)::Vector{String}
    return []
end

Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
176
177
178
179
180
181
182
183
184
185
186
"""
    n_genes(a::MetabolicModel)::Int

Return the number of genes in the model (as returned by [`genes`](@ref)). If
you just need the number of the genes, this may be much more efficient than
calling [`genes`](@ref) and measuring the array.
"""
function n_genes(a::MetabolicModel)::Int
    return length(genes(a))
end

187
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
188
    reaction_gene_association(a::MetabolicModel, gene_id::String)::Maybe{GeneAssociation}
189
190
191
192
193
194
195

Returns the sets of genes that need to be present so that the reaction can work
(technically, a DNF on gene availability, with positive atoms only).

For simplicity, `nothing` may be returned, meaning that the reaction always
takes place. (in DNF, that would be equivalent to returning `[[]]`.)
"""
196
function reaction_gene_association(
197
198
    a::MetabolicModel,
    reaction_id::String,
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
199
)::Maybe{GeneAssociation}
200
201
    return nothing
end
202
203

"""
St. Elmo's avatar
St. Elmo committed
204
    metabolite_formula(
205
206
        a::MetabolicModel,
        metabolite_id::String,
St. Elmo's avatar
St. Elmo committed
207
    )::Maybe{MetaboliteFormula}
208

St. Elmo's avatar
St. Elmo committed
209
210
211
212
213
214
215
216
217
Return the formula of metabolite `metabolite_id` in `model`. 
Return `nothing` in case the formula is not known or irrelevant.
"""
function metabolite_formula(
    model::MetabolicModel,
    metabolite_id::String,
)::Maybe{MetaboliteFormula}
    return nothing
end
218
219

"""
St. Elmo's avatar
St. Elmo committed
220
221
222
223
224
metabolite_charge(model::MetabolicModel, metabolite_id::String)::Maybe{Int}

Return the charge associated with metabolite `metabolite_id` in `model`. 
Returns `nothing` if charge not present.
"""
cylon-x's avatar
cylon-x committed
225
function metabolite_charge(model::MetabolicModel, metabolite_id::String)::Maybe{Int}
226
227
    return nothing
end
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

"""
    reaction_annotations(a::MetabolicModel, reaction_id::String)::Annotations

Return standardized names that may help identifying the reaction. The
dictionary assigns vectors of possible identifiers to identifier system names,
e.g. `"Reactome" => ["reactomeID123"]`.
"""
function reaction_annotations(a::MetabolicModel, reaction_id::String)::Annotations
    return Dict()
end

"""
    metabolite_annotations(a::MetabolicModel, metabolite_id::String)::Annotations

Return standardized names that may help to reliably identify the metabolite. The
dictionary assigns vectors of possible identifiers to identifier system names,
e.g. `"ChEMBL" => ["123"]` or `"PubChem" => ["CID123", "CID654645645"]`.
"""
function metabolite_annotations(a::MetabolicModel, metabolite_id::String)::Annotations
    return Dict()
end

"""
    gene_annotations(a::MetabolicModel, gene_id::String)::Annotations

Return standardized names that identify the corresponding gene or product. The
dictionary assigns vectors of possible identifiers to identifier system names,
e.g. `"PDB" => ["PROT01"]`.
"""
function gene_annotations(a::MetabolicModel, gene_id::String)::Annotations
    return Dict()
end
St. Elmo's avatar
St. Elmo committed
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

"""
    reaction_notes(model::MetabolicModel, reaction_id::String)::Notes

Return the notes associated with reaction `reaction_id` in `model`.
"""
function reaction_notes(model::MetabolicModel, reaction_id::String)::Notes
    return Dict()
end

"""
    metabolite_notes(model::MetabolicModel, metabolite_id::String)::Notes

Return the notes associated with metabolite `reaction_id` in `model`.
"""
function metabolite_notes(model::MetabolicModel, metabolite_id::String)::Notes
    return Dict()
end

"""
    gene_notes(model::MetabolicModel, gene_id::String)::Notes

Return the notes associated with the gene `gene_id` in `model`.
"""
function gene_notes(model::MetabolicModel, gene_id::String)::Notes
    return Dict()
end

"""
    metabolite_compartment(model::MetabolicModel, metabolite_id::String)::Maybe{String}

Return the compartment of metabolite `metabolite_id` in `model` if it is assigned. If not, 
return `nothing`. 
"""
function metabolite_compartment(model::MetabolicModel, metabolite_id::String)::Maybe{String}
    return nothing
end

"""
    reaction_subsystem(model::MetabolicModel, reaction_id::String)::Maybe{String}

Return the subsystem of reaction `reaction_id` in `model` if it is assigned. If not,
return `nothing`.
"""
function reaction_subsystem(model::MetabolicModel, reaction_id::String)::Maybe{String}
    return nothing
end
308

St. Elmo's avatar
St. Elmo committed
309
310
311
312
313
314
"""
    reaction_stoichiometry(model::MetaboliteModel, rxn_id::String)::Dict{String, Float64}

Return the reaction equation of reaction with id `rxn_id` in model. The reaction
equation maps metabolite ids to their stoichiometric coefficients.
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
315
function reaction_stoichiometry(m::MetabolicModel, rxn_id::String)::Dict{String,Float64}
St. Elmo's avatar
St. Elmo committed
316
    mets = metabolites(m)
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
317
318
319
320
    Dict(
        mets[k] => v for (k, v) in
        zip(findnz(stoichiometry(m)[:, first(indexin([rxn_id], reactions(m)))])...)
    )
St. Elmo's avatar
St. Elmo committed
321
322
end

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
"""
    precache!(a::MetabolicModel)::Nothing

Do whatever is feasible to get the model into a state that can be read from
as-quickly-as-possible. This may include e.g. generating helper index
structures and loading delayed parts of the model from disk. The model should
be modified "transparently" in-place. Analysis functions call this right before
applying modifications or converting the model to the optimization model using
[`make_optimization_model`](@ref); usually on the same machine where the
optimizers (and, generally, the core analysis algorithms) will run. The calls
are done in a good hope that the performance will be improved.

By default, it should be safe to do nothing.
"""
function precache!(a::MetabolicModel)::Nothing
    nothing
end