straindesign.networktools
Functions for metabolic network extension with GPR rules and strain design module handling.
Compression functions have been moved to straindesign.compression. This module re-exports them for backwards compatibility.
Module Contents
- straindesign.networktools.bound_blocked_or_irrevers_fva(model, **kwargs)[source]
Use FVA to determine the flux ranges. Use this information to update the model bounds
If flux ranges for a reaction are narrower than its bounds in the mode, these bounds can be omitted, since other reactions must constrain the reaction flux. If (upper or lower) flux bounds are found to be zero, the model bounds are updated to reduce the model complexity.
- straindesign.networktools.compress_ki_ko_cost(kocost, kicost, cmp_mapReac)[source]
Compress knockout/addition cost vectors to match with a compressed model
When knockout/addition cost vectors have been specified (as dicts) and the original metabolic model was compressed, one needs to update the knockout/addition cost vectors. This function takes care of this. In particular it makes sure that the resulting costs are calculated correctly.
E.g.: r_ko_a (cost 1) and r_ko_b (cost 2) are lumped parallel: The resulting cost of r_ko_ab is 3 If they are lumped as dependent reactions the resulting cost is 1. If one of the two reactions is an addition candidate, the resulting reaction will be an addition candidate when lumped as dependent reactions and a knockout candidate when lumped in parallel. There are various possible cases that are treated by this function.
Example
kocost, kicost, cmp_mapReac = compress_ki_ko_cost(kocost, kicost, cmp_mapReac)
- Parameters:
- Returns:
Updated vectors of KO costs and KI costs and an updated compression map that contains information on how to expand strain designs and correctly distinguish between knockouts and additions.
- Return type:
(Tuple)
- straindesign.networktools.compress_modules(sd_modules, cmp_mapReac)[source]
Compress strain design modules to match with a compressed model
When a strain design task has been specified with modules and the original metabolic model was compressed, one needs to refit the strain design modules (objects of the SDModule class) to the new compressed model. This function takes a list of modules and a compression map and returns the strain design modules for a compressed network.
Example
comression_map = compress_modules(sd_modules, cmp_mapReac)
- straindesign.networktools.estimate_expansion_size(compressed_sds, cmp_mapReac)[source]
Estimate total expanded solutions without doing the expansion.
Walks cmp_mapReac in reverse for each compressed solution. For each compression step, for each reaction that maps to multiple originals: - KO + parallel -> factor 1 (all ko’d together) - KO + coupled -> factor = count of knockable originals - KI + parallel -> factor = count of KI-able originals - KI + coupled -> factor 1
Returns int (upper bound, exact for single-step compression).
- straindesign.networktools.evaluate_gpr_ast(node, gene_states)[source]
Evaluate a GPR AST node with given gene states.
Supports arbitrary nesting of AND/OR operators (not limited to DNF/CNF). Used by both gene_kos_to_constraints and reduce_gpr.
- Parameters:
node – An ast.Name or ast.BoolOp node from a parsed GPR rule (e.g. reaction.gpr.body).
gene_states (dict) – Maps gene IDs to True, False, or None. Genes not in the dict are treated as None (undetermined).
- Returns:
True if the GPR is satisfied, False if knocked out, None if undetermined.
- straindesign.networktools.expand_sd(sd, cmp_mapReac)[source]
Expand computed strain designs from a compressed to a full model
Needed after computing strain designs in a compressed model
Example
expanded_sd = expand_sd(compressed_sds, cmp_mapReac)
- Parameters:
sd (SDSolutions) – Solutions of a strain design computation that refer to a compressed model
cmp_mapReac (list of dicts) – Compression map obtained from cmp_mapReac = compress_model(model) and updated with kocost, kicost, cmp_mapReac = compress_ki_ko_cost(kocost, kicost, cmp_mapReac)
- Returns:
Strain design solutions that refer to the uncompressed model
- Return type:
- straindesign.networktools.extend_model_gpr(model, use_names=False)[source]
Integrate GPR-rules into a metabolic model as pseudo metabolites and reactions using AST parsing
COBRA modules often have gene-protein-reaction (GPR) rules associated with each reaction. These can be integrated into the metabolic network structure through pseudo reactions and variables. As GPR rules are integrated into the metabolic network, the metabolic flux space does not change. After integration, the gene-pseudoreactions can be fixed to a flux of zero to simulate gene knockouts. Gene pseudoreactions are referenced either by the gene name or the gene identifier (user selected).
GPR-rule integration enables the computation of strain designs based on genetic interventions.
This function now uses AST parsing to handle both DNF (disjunctive normal form) and non-DNF GPR rules. It processes the reaction.gpr.body AST structure directly, enabling proper handling of complex nested boolean expressions.
Example
reac_map = extend_model_gpr(model):
- Parameters:
model (cobra.Model) – A metabolic model that is an instance of the cobra.Model class containing GPR rules
use_names (bool) – (Default: False) If set to True, the gene pseudoreactions will carry the gene name as reaction identifier. If False, the gene identifier will be used. By default this option is turned off because many models do not provide gene names.
- Returns:
A dictionary to reference old and new reaction identifiers, for reversible reactions that were split (when they are associated with GPR rules). Entries have the form: {‘Reaction1’ : {‘Reaction1’ : 1, ‘Reaction1_reverse_a59c’ : -1}}
- Return type:
(dict)
- straindesign.networktools.extend_model_regulatory(model, reg_itv)[source]
Extend a metabolic model to account for regulatory constraints
This function emulates regulatory interventions in a network. These can either be added permanently or linked to a pseudoreation whose boundaries can be fixed to zero used to activate the regulatory constraint.
Accounting for regulatory interventions, such as applying an upper or lower bound to a reaction or gene pseudoreaction, can be achieved by combining different pseudometabolites and reactions. For instance, to introduce the regulatory constraint:
2*r_1 + 3*r_2 <= 4
and make it ‘toggleable’, one adds 1 metabolite ‘m’ and 2 reactions, ‘r_bnd’ to account for the bound/rhs and r_ctl to control whether the regulatory intervention is active or not:
dm/dt = 2*r_1 + 3*r_2 - r_bnd + r_ctl = 0, -inf <= r_bnd <= 4, -inf <= r_ctl <= inf
When r_ctl is fixed to zero, the constraint 2*r_1 + 3*r_2 <= 4 is enforced, otherwise, the constraint is non binding, thus virtually non-existant. To use this mechanism for strain design, we add the metabolite and reactions as described above and tag r_ctl as knockout candidate. If the algorithm decides to knockout r_ctl, this means, it choses to add the regulatory intervention 2*r_1 + 3*r_2 <= 4.
If the constraint is be added permanently, this function completely omits the r_ctl reaction.
Example
reg_itv_costs = extend_model_regulatory(model, {‘1 PDH + 1 PFL <= 5’ : 1, ‘-EX_o2_e <= 2’ : 1.5})
- Parameters:
model (cobra.Model) – A metabolic model that is an instance of the cobra.Model class
reg_itv (dict or list of str or str) – A set of regulatory constraints that should be added to the model. If reg_itv is a string or a list of strings, regulatory constraints are added permanently. If reg_itv is a dict, regulatory interventions are added in a controllable manner. The id of the reaction that controls the constraint is contained in the return variable. The constraint to be added will be parsed from strings, so ensure that you use the correct reaction identifiers. Valid inputs are: reg_itv = ‘-EX_o2_e <= 2’ # A single permanent regulatory constraint reg_itv = [‘1 PDH + 1 PFL <= 5’, ‘-EX_o2_e <= 2’] # Two permanent constraints reg_itv = {‘1 PDH + 1 PFL <= 5’ : 1, ‘-EX_o2_e <= 2’ : 1.5} # Two controllable constraints # one costs ‘1’ and the other one ‘1.5’ to be added. The function returns a dict with # {‘p1_PDH_p1_PFK_le_5’ : 1 ‘nEX_o2_e_le_2’ : 1.5}. Fixing the reaction # p1_PDH_p1_PFK_le_5 to zero will activate the constraint in the model.
- Returns:
A dictionary that contains the cost of adding each constraint; e.g., {‘p1_PDH_p1_PFK_le_5’ : 1 ‘n1EX_o2_e_le_2’ : 1.5}
- Return type:
(dict)
- straindesign.networktools.filter_sd_maxcost(sd, max_cost, kocost, kicost)[source]
Filter out strain designs that exceed the maximum allowed intervention costs
- Returns:
Strain design solutions complying with the intervention costs limit
- Return type:
- straindesign.networktools.gene_kos_to_constraints(model, gene_kos)[source]
Translate gene knockouts to reaction-level constraints.
Given a cobra model and a set of knocked-out genes, evaluates GPR rules (via AST parsing) to determine which reactions become non-functional. Returns a list of constraints (in straindesign list format) that fix those reactions to zero flux.
Supports arbitrary GPR nesting (not limited to DNF/CNF).
Gene identifiers can be gene IDs or gene names (case-sensitive). Unknown identifiers are silently ignored.
- Note on the SD solution grammar:
SDSolutions uses the following convention for intervention values: -1 = knockout (KO), +1 = knock-in (KI), 0 = non-added KI.
When passing gene constraints to
fba()orfva(), bothgene = 0andgene = -1are treated as knockouts, andgene = 1is ignored (the gene is active). This means SD solution values can be used directly as constraints.The returned reaction constraints use the linear constraint format
[{reaction_id: 1}, '=', 0], meaning1 * v = 0.
Example
>>> constraints = gene_kos_to_constraints(model, ['b0727', 'b1241']) >>> fba(model, constraints=constraints)
- straindesign.networktools.modules_coeff2float(sd_modules)[source]
Convert coefficients occurring in SDModule objects to floats
- straindesign.networktools.modules_coeff2rational(sd_modules)[source]
Convert coefficients to rational numbers using sympy.Rational
- straindesign.networktools.reduce_gpr(model, essential_reacs, gkis, gkos)[source]
Simplify GPR rules by removing non-targetable genes and reducing boolean expressions
This function is used in preprocessing of computational strain design computations. Often, certain reactions, for instance, reactions essential for microbial growth can/must not be targeted by interventions. That can be exploited to reduce the set of genes in which interventions need to be considered.
Given a set of essential reactions that is to be maintained operational, some genes can be removed from a metabolic model, either because they only affect only blocked reactions or essential reactions, or because they are essential reactions and must not be removed. As a consequence, the GPR rules of a model can be simplified using AST parsing for both DNF and non-DNF rules.
Example
reduce_gpr(model, essential_reacs, gkis, gkos):
- Parameters:
model (cobra.Model) – A metabolic model that is an instance of the cobra.Model class containing GPR rules
essential_reacs (list of str) – A list of identifiers of essential reactions.
gkis (dict) – Dictionaries that contain the costs for gene knockouts and additions. E.g., gkos={‘adhE’: 1.0, ‘ldhA’ : 1.0 …}
gkos (dict) – Dictionaries that contain the costs for gene knockouts and additions. E.g., gkos={‘adhE’: 1.0, ‘ldhA’ : 1.0 …}
- Returns:
An updated dictionary of the knockout costs in which irrelevant genes are removed.
- Return type:
(dict)
- straindesign.networktools.resolve_gene_constraints(model, constraints)[source]
Scan constraints for gene IDs/names and replace with reaction constraints.
Constraints that reference gene identifiers (rather than reaction IDs) are interpreted using the strain design solution grammar:
gene = -1— knockout (KO)gene = 0— knockout (non-added, absence of knock-in)gene = 1— ignored (knock-in, gene is active)
This is consistent with the SDSolutions convention, so values from solution dicts can be passed directly as constraints.
Non-gene constraints are passed through unchanged.
Accepted gene constraint formats:
'b0727 = 0' # string — KO 'b0727 = -1' # string — KO (SD grammar) 'b1241 = 1' # string — ignored (KI) ['b0727 = 0', 'b1241 = 0'] # list of strings [[{'b0727': 1}, '=', 0]] # list format
Gene identifiers are matched case-sensitively against both gene IDs and gene names in the model.
This function is called automatically by
fba(),fva(), andfva_legacy()before constraint parsing, so users can pass gene knockouts directly:fba(model, constraints='b0727 = 0') fva(model, constraints=['b0727 = 0', 'EX_o2_e <= 5'])
- Parameters:
model (cobra.Model) – A metabolic model.
constraints – Constraints in any format accepted by straindesign (str, list of str, or list of [dict, str, float]).
- Returns:
Constraints with gene entries replaced by reaction entries.
- Return type:
- straindesign.networktools.suppress_lp_context(model)[source]
Context manager that suppresses all solver-touching operations.
Patches both optlang (coefficient/bounds updates) and cobra (property setters, Model.remove_reactions, Model.remove_metabolites) at the class level. On exit, restores originals and rebuilds the solver so it reflects the current model state.
Nests safely: if already suppressed by an outer context, this is a no-op.
- straindesign.networktools.with_suppressed_lp(func)[source]
Decorator that wraps a function in
suppress_lp_context().The first positional argument must be a cobra Model.