Constraint system builders
Generic constraints
Comparisons
COBREXA.all_equal_constraints
— Methodall_equal_constraints(
a,
tree::ConstraintTrees.Tree{ConstraintTrees.Constraint}
) -> Any
A constriant tree that makes sure that all values in tree
are the same as the value of a
.
Names in the output ConstraintTree
match the names in the tree
.
COBREXA.difference_constraint
— Methoddifference_constraint(
a,
b,
difference_bound
) -> ConstraintTrees.Constraint
A constraint that makes sure that the difference from a
to b
is within the difference_bound
. For example, difference_constraint(-1, 1, 2)
will always be valid. Any type of ConstraintTree.Bound
can be supplied.
COBREXA.equal_value_constraint
— Methodequal_value_constraint(a, b) -> ConstraintTrees.Constraint
A constraint that makes sure that the values of a
and b
are the same.
COBREXA.greater_or_equal_constraint
— Methodgreater_or_equal_constraint(
a,
b
) -> ConstraintTrees.Constraint
A constraint that makes sure that the value of a
is greater than or equal to the the value of b
.
COBREXA.less_or_equal_constraint
— Methodless_or_equal_constraint(a, b) -> ConstraintTrees.Constraint
A constraint that makes sure that the value of a
is less than or equal to the the value of b
.
Constraint scaling
COBREXA.scale_bounds
— Methodscale_bounds(
tree::ConstraintTrees.Tree{ConstraintTrees.Constraint},
factor
) -> Any
Linearly scale all bounds in a constraint tree by the factor
. This actually changes the model semantics, and may not work in surprising/improper ways with some constraint systems, esp. the MILP and QP ones.
See also scale_constraints
.
COBREXA.scale_constraints
— Methodscale_constraints(
tree::ConstraintTrees.Tree{ConstraintTrees.Constraint},
factor
) -> Any
Linearly scale all constraints in a constraint tree by the factor
.
See also scale_bounds
.
Sign splitting
COBREXA.positive_bound_contribution
— Methodpositive_bound_contribution(
b::ConstraintTrees.EqualTo
) -> ConstraintTrees.EqualTo
Clamp all negative values in the bound to zero, leaving only the "positive contribution" to the overall value of the constraint. Used in unsigned_positive_contribution_variables
and unsigned_negative_contribution_variables
to allocate unidirectional variables.
COBREXA.sign_split_constraints
— Methodsign_split_constraints(; positive, negative, signed)
A constraint tree that bound the values present in signed
to be sums of pairs of positive
and negative
contributions to the individual values.
Keys in the result are the same as the keys of signed
constraints.
Typically, this can be used to create "unidirectional" fluxes together with unsigned_negative_contribution_variables
and unsigned_positive_contribution_variables
.
Use sign_split_variables
to allocate the variables easily.
COBREXA.sign_split_variables
— Methodsign_split_variables(
constraints::ConstraintTrees.Tree{ConstraintTrees.Constraint};
positive,
negative
) -> ConstraintTrees.Tree{ConstraintTrees.Constraint}
Shortcut for making a pair of named variable groups created by unsigned_positive_contribution_variables
and unsigned_negative_contribution_variables
, in subtrees named by positive
and negative
.
Use sign_split_constraints
to bind the new variables to existing values.
COBREXA.unsigned_negative_contribution_constraints
— Methodunsigned_negative_contribution_constraints(
cs::ConstraintTrees.Tree{ConstraintTrees.Constraint},
positive::ConstraintTrees.Tree{ConstraintTrees.Constraint}
) -> Any
A constraint tree that connects positive unsigned variable contributions to signed ones, while acting as negative contributions.
COBREXA.unsigned_negative_contribution_variables
— Methodunsigned_negative_contribution_variables(
cs::ConstraintTrees.Tree{ConstraintTrees.Constraint}
) -> Any
A constraint tree of variables with negative contributions to the values in cs
.
COBREXA.unsigned_positive_contribution_constraints
— Methodunsigned_positive_contribution_constraints(
cs::ConstraintTrees.Tree{ConstraintTrees.Constraint},
negative::ConstraintTrees.Tree{ConstraintTrees.Constraint}
) -> Any
A constraint tree that connects negative unsigned variable contributions to signed ones, while acting as positive contributions.
COBREXA.unsigned_positive_contribution_variables
— Methodunsigned_positive_contribution_variables(
cs::ConstraintTrees.Tree{ConstraintTrees.Constraint}
) -> Any
A constraint tree of variables with positive contributions to the values in cs
.
Objectives
COBREXA.squared_sum_error_value
— Methodsquared_sum_error_value(
constraints::ConstraintTrees.Tree{ConstraintTrees.Constraint},
target
) -> Any
Construct a ConstraintTrees.Value
out of squared error (in the RMSE-like squared-error sense) between the values in the constraint tree and the reference target
.
target
is a function that takes a symbol (key) and returns either a Float64
reference value, or nothing
if the error of given key should not be considered.
COBREXA.squared_sum_value
— Methodsquared_sum_value(
x::ConstraintTrees.Tree{ConstraintTrees.Constraint}
) -> Any
Construct a ConstraintTrees.Value
out of squared sum of all values directly present in a given constraint tree.
COBREXA.sum_value
— Methodsum_value(
x...
) -> Union{ConstraintTrees.LinearValue, ConstraintTrees.QuadraticValue}
Construct a ConstraintTrees.Value
out of a sum of all values directly present in a given constraint tree.
Analysis-specific constriants
COBREXA.loopless_constraints
— Methodloopless_constraints(
;
fluxes,
loopless_direction_indicators,
loopless_driving_forces,
internal_reactions,
internal_nullspace,
flux_infinity_bound,
driving_force_nonzero_bound,
driving_force_infinity_bound
)
Construct the loopless constraint system that binds fluxes
of all internal_reactions
to direction of loopless_direction_indicators
and connects them to loopless_driving_forces
. The solution is bounded to lie in internal_nullspace
(which is a sufficient algebraic condition for loop-less-ness).
The indicators must be discrete variables, valued 1
if the reaction flux goes forward, or 0
if the reaction flux is reversed.
The simplest (but by no means the fastest) way to obtain a good internal_nullspace
is to use LinearAlgebra.nullspace
with the internal reactions' stoichiometry matrix. Rows of internal_nullspace
must correspond to internal_reactions
.
flux_infinity_bound
is used as the maximal bound for fluxes (for constraints that connect them to indicator variables); it should optimally be greater than the maximum possible absolute value of any flux in the original model.
driving_force_nonzero_bound
and driving_force_infinity_bound
are similarly used to limit the individual reaction's driving forces.
COBREXA.knockout_constraints
— Methodknockout_constraints(
knockout_test::Function,
fluxes::ConstraintTrees.Tree{ConstraintTrees.Constraint}
) -> ConstraintTrees.Tree{ConstraintTrees.Constraint}
Make a ConstraintTree
that knocks out fluxes given by the predicate knockout_test
. The predicate function is called with a single parameter (the key of the flux in tree fluxes
) and must return a boolean. Returning true
means that the corresponding flux (usually a reaction flux) will be knocked out.
COBREXA.enzyme_constraints
— Methodenzyme_constraints(
;
fluxes_forward,
fluxes_reverse,
isozyme_forward_amounts,
isozyme_reverse_amounts,
kcat_forward,
kcat_reverse,
isozyme_gene_product_stoichiometry,
gene_product_molar_mass,
capacity_limits,
isozyme_flux_forward_balance_name,
isozyme_flux_reverse_balance_name,
gene_product_amounts_name,
gene_product_capacity_name
)
Connect variables returned by enzyme_variables
to unidirectional fluxes. This is used to construct the contraint system for enzyme_constrained_flux_balance_constraints
.
Parameters fluxes_forward
, fluxes_reverse
, isozyme_forward_amounts
, isozyme_reverse_amounts
and gene_product_amounts
should correspond to parameters and results of enzyme_variables
.
Further, parameter functions kcat_forward
and kcat_reverse
specify the turnover numbers for reaction and isozyme IDs given in parameters; isozyme_gene_product_stoichiometry
specifies the composition of the reaction-isozyme IDs given in parameter by returning an interable mapping of gene product IDs to numbers (such as Dict{Symbol, Float64}
), and gene_product_molar_mass
specifies a numeric mass for a given gene product ID. All parameter functions may return nothing
, at which point the given object is considered nonexistent and is omitted from constraints.
capacity_limits
is an interable container of triples (limit_id, gene_product_ids, capacity_bound)
which are converted to a constraint identified by the limit_id
that limits the total mass of gene_product_ids
(which is any iterable container) by capacity_bound
.
COBREXA.enzyme_variables
— Methodenzyme_variables(
;
fluxes_forward,
fluxes_reverse,
isozyme_ids,
isozyme_forward_ids,
isozyme_reverse_ids,
isozyme_forward_amounts_name,
isozyme_reverse_amounts_name
)
Returns a constraint tree with enzyme capacity constraints, added for reactions in fluxes_forward
and fluxes_reverse
. This is used to construct the constraint system in enzyme_constrained_flux_balance_constraints
.
Parameter function isozyme_ids
takes a reaction ID and returns nothing
if the reaction does not have isozymes associated with it, or an iterable container of all the isozyme IDs for that reaction (as Symbol
s).
Parameters isozyme_forward_ids
and isozyme_reverse_ids
can be used to fine-tune the generated isozymes in either direction; both default to isozyme_ids
.
The keys in the output constraint tree can be customized by setting isozyme_forward_amounts_name
, isozyme_reverse_amounts_name
and gene_product_amounts_name
.
COBREXA.isozyme_amount_variables
— Methodisozyme_amount_variables(
fluxes,
flux_isozymes
) -> ConstraintTrees.Tree{ConstraintTrees.Constraint}
Create a ConstraintTree
with variables for isozyme contributions to reaction fluxes. The tree has 2 levels: the first contains all reaction flux IDs that have isozymes, the second contains the isozyme IDs for each reaction flux.
fluxes
should be anything that can be iterated to give reaction flux IDs.
flux_isozymes
is a function that, for a given reaction flux ID, returns anything iterable that contains the isozyme IDs for the given reaction flux. Returning an empty iterable prevents allocating the subtree for the given flux.
COBREXA.isozyme_flux_constraints
— Methodisozyme_flux_constraints(
isozyme_amounts::ConstraintTrees.Tree{ConstraintTrees.Constraint},
fluxes::ConstraintTrees.Tree{ConstraintTrees.Constraint},
kcat
) -> ConstraintTrees.Tree{ConstraintTrees.Constraint}
A constraint tree that sums up partial contributions of reaction isozymes to the fluxes of reactions.
For practical purposes, both fluxes and isozymes are here considered to be unidirectional, i.e., one would typically apply this twice to constraint both "forward" and "reverse" fluxes.
Function kcat
should return the kcat value for a given reaction and isozyme (IDs of which respectively form the 2 parameters for each call).
COBREXA.isozyme_gene_product_amount_constraints
— Methodisozyme_gene_product_amount_constraints(
isozyme_amounts,
isozyme_stoichiometry
) -> ConstraintTrees.Tree{ConstraintTrees.Constraint}
A constraint tree that computes the gene product amounts from given isozyme amounts their multiplicities (aka. stoichiometries, protein units, ...) given by isozyme_stoichiometry
.
Values in ConstraintTree gene_product_amounts
should describe the gene product allocations. Allocation for the isozyme is ignored if the gene product is missing in gene_product_amounts
.
isozyme_amounts
is an iterable that contains several ConstraintTree
s that describe the allocated isozyme amounts (typically these would be created by isozyme_amount_variables
. The multiple trees may describe several different kinds of isozyme use, e.g., you can use it to pass in both forward- and reverse-direction amounts at once. To only use a single tree, use an uni-tuple: isozyme_amounts = tuple(my_tree)
.
Parameter function isozyme_stoichiometry
gets called with a reaction and isozyme IDs as given by the isozyme amount trees. It should return nothing
in case there's no information – in such case, the isozyme is not going to be included in the calculation of gene product mass.
COBREXA.simplified_enzyme_constraints
— Methodsimplified_enzyme_constraints(
;
fluxes_forward,
fluxes_reverse,
mass_cost_forward,
mass_cost_reverse,
capacity_limits
)
Build a constraint system that bounds fluxes according to their enzyme mass requirements, with respect to per-reaction enzyme mass costs.
Parameter functions mass_cost_forward
and mass_cost_reverse
take a flux ID (corresponding to a flux in fluxes_forward
and fluxes_reverse
) and return the enzyme mass required to catalyze one "unit" of reaction in the forward or reverse direction, respectively. Returning nothing
ignores the mass cost.
capacity_limits
is an iterable container of triples (limit_id, flux_ids, bound)
, which creates the capacity bounds over groups of fluxes (in the same manner as for gene products in enzyme_constraints
).
COBREXA.simplified_isozyme_gene_product_amount_constraints
— Methodsimplified_isozyme_gene_product_amount_constraints(
x...
) -> ConstraintTrees.Tree{ConstraintTrees.Constraint}
Like isozyme_gene_product_amount_constraints
, but works with the "simplified" view where each reaction has an uniquely determined catalytic isozyme, as with simplified_enzyme_constraints
.
As the main difference, the arguments are tuples that contain first the constraint tree without the "isozyme" layer (i.e., fluxes), and second a function that returns the gene product stoichiometry and the turnover number (again in a tuple) for the given flux identifier.
Interfacing of constraint systems
COBREXA.interface_constraints
— Methodinterface_constraints(
kv;
kwargs...
) -> ConstraintTrees.Tree{ConstraintTrees.Constraint}
Overload of interface_constraints
for general key-value containers.
COBREXA.interface_constraints
— Methodinterface_constraints(
ps::Pair...;
default_interface,
out_interface,
out_balance,
ignore,
bound
) -> ConstraintTrees.Tree{ConstraintTrees.Constraint}
Join multiple constraint tree modules with interfaces into a bigger module with an interface.
Modules are like usual constraint trees, but contain an explicitly declared interface
part, marked properly in arguments using e.g. a tuple (the parameters should form a dictionary constructor that would generally look such as :module_name => (module, module.interface)
; the second tuple member may also be specified just by name as e.g. :interface
, or omitted while relying on default_interface
).
Interface parts get merged and constrained to create a new interface; networks are intact with disjoint variable sets.
Compatible modules with ready-made interfaces may be created e.g. by flux_balance_constraints
.
ignore
may be used to selectively ignore parts of interfaces given the "module name" identifier and constraint path in the interface (these form 2 parameters passed to ignore
). Similarly, bound
may be used to specify bounds for the new interface, if required.