From a8beaf9bd7dd90e54917e327b1fd52029c85829b Mon Sep 17 00:00:00 2001 From: <> Date: Sat, 28 Aug 2021 11:07:30 +0000 Subject: [PATCH] Deployed 881c208 with MkDocs version: 1.2.2 --- references/miom/index.html | 13 ++++++++----- search/search_index.json | 2 +- sitemap.xml | 14 +++++++------- sitemap.xml.gz | Bin 264 -> 263 bytes 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/references/miom/index.html b/references/miom/index.html index 1be8296..0947a07 100644 --- a/references/miom/index.html +++ b/references/miom/index.html @@ -21,7 +21,7 @@ for c in constraints: self.add_constraint(c) return len(constraints) > 0 -

exclude(self, indicator_values=None)

Exclude a solution from the set of feasible solutions.

If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730

Parameters:

Name Type Description Default
values list

List of values for each indicator variable. Defaults to None.

required

Returns:

Type Description
BaseModel

instance of BaseModel with the modifications applied.

Source code in miom/miom.py
@_composable
+

exclude(self, indicator_values=None)

Exclude a solution from the set of feasible solutions.

If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730

Parameters:

Name Type Description Default
indicator_values list

List of values for each indicator variable. Defaults to None.

None

Returns:

Type Description
BaseModel

instance of BaseModel with the modifications applied.

Source code in miom/miom.py
@_composable
 def exclude(self, indicator_values=None):
     """Exclude a solution from the set of feasible solutions.
 
@@ -32,7 +32,7 @@
 
 
     Args:
-        values (list, optional): List of values for each indicator variable. Defaults to None.
+        indicator_values (list, optional): List of values for each indicator variable. Defaults to None.
 
     Returns:
         BaseModel: instance of BaseModel with the modifications applied.
@@ -427,7 +427,10 @@
         comparator=Comparator.LESS_OR_EQUAL,
         value=0.5
     ).network
-

Solvers

Solvers supported by the miom module.

Please refer to https://picos-api.gitlab.io/picos/introduction.html to see the list of supported solvers using the PICOS backend. The Python-MIP backend only supports the GUROBI and CBC solvers.

Note that in some cases, the Python-MIP backend (GUROBI/CBC) might be faster setting up the problem than the PICOS backend since it has less overhead.

Attributes:

Name Type Description
GUROBI_PYMIP str

Recommended solver for most problems (LP, MIP). It uses the Python-MIP backend. Note that GUROBI is a commercial software which require a license. Free academic licenses are also available at https://gurobi.com/free/.

GUROBI str

For using GUROBI with the PICOS backend instead of Python-MIP.

COIN_OR_CBC str

Free LP/MIP solver with good performance, provided with Python-MIP.

CPLEX str

Commercial solver with a performance similar to GUROBI. Only supported by the PICOS backend.

SCIP str

Free academic solver, supported by the PICOS backend.

GLPK str

Open source solver, supported by the PICOS backend.

MOSEK str

Commercial solver, supported by the PICOS backend.

Status

An enumeration.

load(network, solver=None)

Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend).

Examples:

Example of how to perform FBA to maximize flux through the BIOMASS_reaction in the iMM1865 model:

>>> import miom
+

Solvers

Solvers supported by the miom module.

Please refer to https://picos-api.gitlab.io/picos/introduction.html to see the list of supported solvers using the PICOS backend. The Python-MIP backend only supports the GUROBI and CBC solvers.

Note that in some cases, the Python-MIP backend (GUROBI/CBC) might be faster setting up the problem than the PICOS backend since it has less overhead.

Attributes:

Name Type Description
GUROBI_PYMIP str

Recommended solver for most problems (LP, MIP). It uses the Python-MIP backend. Note that GUROBI is a commercial software which require a license. Free academic licenses are also available at https://gurobi.com/free/.

GUROBI str

For using GUROBI with the PICOS backend instead of Python-MIP.

COIN_OR_CBC str

Free LP/MIP solver with good performance, provided with Python-MIP.

CPLEX str

Commercial solver with a performance similar to GUROBI. Only supported by the PICOS backend.

SCIP str

Free academic solver, supported by the PICOS backend.

GLPK str

Open source solver, supported by the PICOS backend.

MOSEK str

Commercial solver, supported by the PICOS backend.

Status

Subset of PICOS solver status codes.

This subset of states offers compatibility between Python-MIP and PICOS. Status codes can be obtained after solving an optimization problem with the property status. For example:

>>> import miom
+>>> miom.load('@iMM1865').steady_state().set_rxn_objective('BIOMASS_reaction').solve().status
+{'status': 'optimal', 'objective_value': 798.811, 'elapsed_seconds': 0.479}
+

load(network, solver=None)

Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend).

Examples:

Example of how to perform FBA to maximize flux through the BIOMASS_reaction in the iMM1865 model:

>>> import miom
 >>> network = miom.load_gem("@iMM1865")
 >>> flx = (miom
             .load(network)
@@ -468,7 +471,7 @@
     """
     if solver is None:
         solver = Solvers.COIN_OR_CBC
-        if _PICOS_AVAILABLE:
+        if _picos_backend_available:
             solvers = pc.solvers.available_solvers()
             if "gurobi" in solvers:
                 solver = Solvers.GUROBI
@@ -482,7 +485,7 @@
         return PythonMipModel(miom_network=network, solver_name=solver)
     if solver == 'gurobi_pymip':
         return PythonMipModel(miom_network=network, solver_name='gurobi')
-    if _PICOS_AVAILABLE:
+    if _picos_backend_available:
         return PicosModel(miom_network=network, solver_name=solver)
     else:
         raise Exception("""PICOS is not installed. Please install it with pip, 
diff --git a/search/search_index.json b/search/search_index.json
index e99813a..7e84c25 100644
--- a/search/search_index.json
+++ b/search/search_index.json
@@ -1 +1 @@
-{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Introduction Warning This library is functional but still in a very early stage. API is still not stable and might be changed in future versions. MIOM (Mixed Integer Optimization for Metabolism) is a python library for creating and solving complex optimization problems using genome-scale metabolic networks, in just a few lines. MIOM offers a high-level API that leverages the power of modern Mixed Integer Optimization (MIO) solvers to easily define steady-state metabolic optimization problems, from simple Flux Balance Analysis (FBA) simulations, to more complex problems, such as sparse FBA or context-specific reconstruction algorithms, and solve them the required level of optimality . It supports many free and commercial solvers thanks to the integration with the PICOS and the Python-MIP . It is also compatible and complementary to cobrapy . Here is a simple example of the differences of implementing from scratch a simple Flux Balance Analysis (FBA), which is typically implemented as a Linear Program (LP) problem, and the Sparse FBA problem which is an Integer Programmming (IP) problem that solves the same FBA problem but minimizing the number of active reactions: FBA (LP) import miom model = ( miom . load ( '@BiGG/Recon3D.miom' ) . steady_state () . set_rxn_objective ( 'biomass_reaction' ) . solve ( verbosity = 1 )) print ( \"Optimal flux:\" , model . get_fluxes ( 'biomass_reaction' )) print ( \"Number of active reactions:\" , sum ( abs ( model . get_fluxes ()) > 1e-8 )) Sparse FBA (MIP) import miom model = ( miom . load ( '@BiGG/Recon3D.miom' ) . setup ( opt_tol = 0.05 , verbosity = 1 ) . steady_state () . set_rxn_objective ( 'biomass_reaction' ) . solve () . set_fluxes_for ( 'biomass_reaction' ) . subset_selection ( - 1 ) . solve ()) print ( \"Optimal flux:\" , model . get_fluxes ( 'biomass_reaction' )) print ( \"Number of active reactions:\" , sum ( abs ( model . get_fluxes ()) > 1e-8 )) Note To better understand the meaning of each step, please read the documentation of the BaseModel class , and the complete example in examples/sparse_fba.py . Installation Recommended installation The recommended installation with pip using the option all includes PICOS and Python-MIP backends, and the interfaces for GLPK , Gurobi and Mosek : pip install miom[all] Minimal installation By default, MIOM comes only with the Python-MIP backend and the COIN-OR CBC solver. The minimal installation is perfect to use in online notebooks and for sharing minimal reproducible examples. To install MIOM with minimal dependencies, run: pip install miom Full installation The full install option of miom comes with all the packages included with the all option, and the additional COBRA package. This adds also support for importing any kind of genome-scale metabolic network supported by cobra with the miom.load_gem() method: pip install miom[full] Installing CPLEX CPLEX is also supported but requires a prior installation of CPLEX in the system with a valid license that cannot be configured through pip . To install MIOM with CPLEX support, follow the instructions on the CPLEX page to install your current version of cplex in your python environment. Quick start Importing a Genome-Scale Metabolic Network (GEMs) First step is to import a Genome-Scale Metabolic Network. The method load_gem() can be used to import a network from a local file or a URL. This method requires the cobrapy and scipy packages to import networks in the SBML, YAML, JSON, and Matlab formats (see Full install ). Here is an example of importing the BiGG Recon3D network: import miom network = miom . load_gem ( 'https://github.com/SBRG/bigg_models_data/raw/master/models/Recon3D.mat' ) print ( \"Number of reactions in the network:\" , network . num_reactions ) By default, MIOM uses its own format (.miom) which is a lightweight, compressed and portable format based on numpy structured arrays to store only the essential information required to perform common tasks. To improve reproducibility of experiments, a repository of already converted models is available at pablormier/miom-gems . Any model from this repository can be imported using shorthand links in the following forma: @relative/path/to/model . For example, in order to import the Human-GEM v1.9.0 , you only need to run: network = miom . load_gem ( '@SysBioChalmers/Human-Gem/v1.9.0' ) This is a very convenient way of importing models and sharing reproducible experiments , making sure that other users are going to test the same models. Managing Metabolic Networks MIOM is not intended to provide functions for creating and managing metabolic networks, since there are already other libraries for this purpose (e.g. cobrapy ). If you rely on cobrapy for model manipulation, you can still use MIOM for the optimization after you prepare your metabolic network, as MIOM is nicely integrated with COBRA: from cobra.test import create_test_model network = create_test_model ( \"textbook\" ) medium = network . medium medium [ \"EX_o2_e\" ] = 0.0 network . medium = medium # Use MIOM for optimization flux = ( miom . load ( miom . mio . cobra_to_miom ( network )) . steady_state () . set_rxn_objective ( 'Biomass_Ecoli_core' ) . solve () . get_fluxes ( 'Biomass_Ecoli_core' )) Metabolic Networks in MIOM are represented by a miom.mio.MiomNetwork class. This class encodes the network into three matrices: R (reactions), S (stoichiometry), and M (metabolites). The R matrix is a numpy structured array that contains the list of the reactions defined in the network, including the reaction ID, the reaction name, the reaction bounds, the subsystem and the Gene-Protein-Rules: >>> miom . load_gem ( '@BiGG/Recon3D.miom' ) . R [: 5 ] array ([( '10FTHF5GLUtl' , '5-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' ), ( '10FTHF5GLUtm' , '5-Glutamyl-10Fthf Transport, Mitochondrial' , 0. , 1000. , 'Transport, mitochondrial' , '' ), ( '10FTHF6GLUtl' , '6-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' ), ( '10FTHF6GLUtm' , '6-Glutamyl-10Fthf Transport, Mitochondrial' , 0. , 1000. , 'Transport, mitochondrial' , '' ), ( '10FTHF7GLUtl' , '7-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' )], dtype = [( 'id' , 'O' ), ( 'name' , 'O' ), ( 'lb' , '= 0 ) # Add the constraint that the sum through all non-reversible reactions is less than or equal to 10 # (note that both PICOS and Python-MIP are symbolic, and expressions involving the variables are allowed) constraint = sum ( model . variables . fluxvars [ i ] for i in non_reversible ) <= 10 # Add to the model and solve model . add_constraint ( constraint ) . solve ( verbosity = 1 ) Starting solution of the Linear programming problem using Dual Simplex Coin0506I Presolve 2242 (-3594) rows, 6144 (-4456) columns and 33659 (-12128) elements Clp0014I Perturbing problem by 0.001% of 1.9797539 - largest nonzero change 1.4130091e-06 ( 7.1372964e-05%) - largest zero change 1.412981e-06 Clp0006I 0 Obj 0.0015868455 Primal inf 3303572.7 (1175) Dual inf 1.9797525 (1) Clp0000I Optimal - objective value 9.062223 Coin0511I After Postsolve, objective 9.062223, infeasibilities - dual 0 (0), primal 0 (0) Clp0032I Optimal objective 9.062223036 - 1675 iterations time 0.142, Presolve 0.07 By default, an optimization model is mutable. This means that every time a method that modifies the model is invoked, the original model is modified. For example, the set_flux_bounds() method modifies the bounds of the reactions in the model. If you want to create a copy of the model, you can use the copy() method to create a full copy of the model. Mixed Integer Optimization Many constraint-based metabolic problems consist of selecting a subset of reactions from a generic metabolic network, subject to some biological-based constraints. For example, Sparse FBA consists of selecting the minimum number of active reactions that lead to a desired optimal flux. Context-specific network reconstruction methods such as iMAT, Fastcore, mCADRE, MBA, etc., have also the same purpose: select a subset of reactions from a network based on some experimental data and some objective function. All these problems are instances of a more general problem, known as best subset selection problem , which can be modelled using Mixed Integer Optimization (MIO) . However, instances of this problem are usually hard to solve, and some implementations like Fastcore or MBA use different heuristics or relaxations to find sub-optimal solutions in short time. Unfortunately, there are a few problems with these type of approximations. First, we don't know how good is the solution obtained, and in practice many studies that use those methods assume that the solution they obtained is the best one. Second, even though most of these techniques solve the same type of problem, they look very different or hard to understand for practitioners. Third, many of these implementations do not exploit the potential of the modern MIO solvers which are nowadays able to solve very large problems in a short time, and to adjust the desired level of optimality, which gives the user an idea of how good is the solution obtained. MIOM incorporates specific methods to easily model and solve such problems. Just by calling the method subset_selection() , which takes as input a weight for all reactions or a list of weights for each reaction, it transforms the current problem into a best subset selection problem, in which the objective function is the sum of the weights of the reactions in the solution (where positive weighted reactions contribute to the objective function if they are selected, and negative weighted reactions contribute to the objective function if they are not selected). This simple method makes it possible to model a wide variety of complex constraint-based optimization problems. See for example how easy it is to implement the exact version of the weighted Fastcore with MIOM: import miom import numpy as np # Use the flux-consistent subnetwork (fcm) of the Human1 GEM model # NOTE: Fastcore requires that reactions in the core are flux consistent, # otherwise the problem would be infeasible. m = miom . load_gem ( '@homo_sapiens_human1_fcm.miom' ) # Select reactions from the cholesterol metabolism as the core reactions to keep core_rxn = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) # Assign a negative weight for reactions not in the core weights = - 1 * np . ones ( m . num_reactions ) weights [ core_rxn == 1 ] = 1 fmc = ( miom . load ( m ) . setup ( opt_tol = 0.05 , verbosity = 1 ) . steady_state () . subset_selection ( weights ) . keep ( core_rxn == 1 ) . solve () . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( fmc . num_reactions ) Advantages It's flexible: MIOM uses the PICOS and the Python-MIP libraries, which means you can use any solver supported by those libraries. It's easy to extend: MIOM is written in pure python, so you can easily extend it to solve more complex optimization problems. It makes the problem explicit: MIOM uses a declarative way to express the problem, so you can easily read and understand what you are solving and differences between algorithms. It's fast: MIOM leverages the power of MIO solvers to solve complex optimization problems. You can control the quality and speed of the solutions for your problem and get better solutions that the approximations (LP) of the original problem available in other constraint-based modeling libraries. It's lightweight: The library has a small number of dependencies, so it's easy to install and distribute also in HPC environments. It includes a compressed GEM format : MIOM can load and save the minimal information of the metabolic networks required for performing simulations into a compressed file compatible with numpy. The small size of the files allows you to quickly run online experiments so other people can reproduce your results. It also supports SBML and matlab formats if cobratoolbox is installed. It's open-source: MIOM is open-source and free to use. You can contribute to the development of MIOM by forking the repository and sending pull requests. Documentation The documentation of the library can be found at https://metexplore.github.io/miom/ How to cite Manuscript in progress License GNU General Public License v3.0","title":"Home"},{"location":"#introduction","text":"Warning This library is functional but still in a very early stage. API is still not stable and might be changed in future versions. MIOM (Mixed Integer Optimization for Metabolism) is a python library for creating and solving complex optimization problems using genome-scale metabolic networks, in just a few lines. MIOM offers a high-level API that leverages the power of modern Mixed Integer Optimization (MIO) solvers to easily define steady-state metabolic optimization problems, from simple Flux Balance Analysis (FBA) simulations, to more complex problems, such as sparse FBA or context-specific reconstruction algorithms, and solve them the required level of optimality . It supports many free and commercial solvers thanks to the integration with the PICOS and the Python-MIP . It is also compatible and complementary to cobrapy . Here is a simple example of the differences of implementing from scratch a simple Flux Balance Analysis (FBA), which is typically implemented as a Linear Program (LP) problem, and the Sparse FBA problem which is an Integer Programmming (IP) problem that solves the same FBA problem but minimizing the number of active reactions: FBA (LP) import miom model = ( miom . load ( '@BiGG/Recon3D.miom' ) . steady_state () . set_rxn_objective ( 'biomass_reaction' ) . solve ( verbosity = 1 )) print ( \"Optimal flux:\" , model . get_fluxes ( 'biomass_reaction' )) print ( \"Number of active reactions:\" , sum ( abs ( model . get_fluxes ()) > 1e-8 )) Sparse FBA (MIP) import miom model = ( miom . load ( '@BiGG/Recon3D.miom' ) . setup ( opt_tol = 0.05 , verbosity = 1 ) . steady_state () . set_rxn_objective ( 'biomass_reaction' ) . solve () . set_fluxes_for ( 'biomass_reaction' ) . subset_selection ( - 1 ) . solve ()) print ( \"Optimal flux:\" , model . get_fluxes ( 'biomass_reaction' )) print ( \"Number of active reactions:\" , sum ( abs ( model . get_fluxes ()) > 1e-8 )) Note To better understand the meaning of each step, please read the documentation of the BaseModel class , and the complete example in examples/sparse_fba.py .","title":"Introduction"},{"location":"#installation","text":"","title":"Installation"},{"location":"#recommended-installation","text":"The recommended installation with pip using the option all includes PICOS and Python-MIP backends, and the interfaces for GLPK , Gurobi and Mosek : pip install miom[all]","title":"Recommended installation"},{"location":"#minimal-installation","text":"By default, MIOM comes only with the Python-MIP backend and the COIN-OR CBC solver. The minimal installation is perfect to use in online notebooks and for sharing minimal reproducible examples. To install MIOM with minimal dependencies, run: pip install miom","title":"Minimal installation"},{"location":"#full-installation","text":"The full install option of miom comes with all the packages included with the all option, and the additional COBRA package. This adds also support for importing any kind of genome-scale metabolic network supported by cobra with the miom.load_gem() method: pip install miom[full]","title":"Full installation"},{"location":"#installing-cplex","text":"CPLEX is also supported but requires a prior installation of CPLEX in the system with a valid license that cannot be configured through pip . To install MIOM with CPLEX support, follow the instructions on the CPLEX page to install your current version of cplex in your python environment.","title":"Installing CPLEX"},{"location":"#quick-start","text":"","title":"Quick start"},{"location":"#importing-a-genome-scale-metabolic-network-gems","text":"First step is to import a Genome-Scale Metabolic Network. The method load_gem() can be used to import a network from a local file or a URL. This method requires the cobrapy and scipy packages to import networks in the SBML, YAML, JSON, and Matlab formats (see Full install ). Here is an example of importing the BiGG Recon3D network: import miom network = miom . load_gem ( 'https://github.com/SBRG/bigg_models_data/raw/master/models/Recon3D.mat' ) print ( \"Number of reactions in the network:\" , network . num_reactions ) By default, MIOM uses its own format (.miom) which is a lightweight, compressed and portable format based on numpy structured arrays to store only the essential information required to perform common tasks. To improve reproducibility of experiments, a repository of already converted models is available at pablormier/miom-gems . Any model from this repository can be imported using shorthand links in the following forma: @relative/path/to/model . For example, in order to import the Human-GEM v1.9.0 , you only need to run: network = miom . load_gem ( '@SysBioChalmers/Human-Gem/v1.9.0' ) This is a very convenient way of importing models and sharing reproducible experiments , making sure that other users are going to test the same models.","title":"Importing a Genome-Scale Metabolic Network (GEMs)"},{"location":"#managing-metabolic-networks","text":"MIOM is not intended to provide functions for creating and managing metabolic networks, since there are already other libraries for this purpose (e.g. cobrapy ). If you rely on cobrapy for model manipulation, you can still use MIOM for the optimization after you prepare your metabolic network, as MIOM is nicely integrated with COBRA: from cobra.test import create_test_model network = create_test_model ( \"textbook\" ) medium = network . medium medium [ \"EX_o2_e\" ] = 0.0 network . medium = medium # Use MIOM for optimization flux = ( miom . load ( miom . mio . cobra_to_miom ( network )) . steady_state () . set_rxn_objective ( 'Biomass_Ecoli_core' ) . solve () . get_fluxes ( 'Biomass_Ecoli_core' )) Metabolic Networks in MIOM are represented by a miom.mio.MiomNetwork class. This class encodes the network into three matrices: R (reactions), S (stoichiometry), and M (metabolites). The R matrix is a numpy structured array that contains the list of the reactions defined in the network, including the reaction ID, the reaction name, the reaction bounds, the subsystem and the Gene-Protein-Rules: >>> miom . load_gem ( '@BiGG/Recon3D.miom' ) . R [: 5 ] array ([( '10FTHF5GLUtl' , '5-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' ), ( '10FTHF5GLUtm' , '5-Glutamyl-10Fthf Transport, Mitochondrial' , 0. , 1000. , 'Transport, mitochondrial' , '' ), ( '10FTHF6GLUtl' , '6-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' ), ( '10FTHF6GLUtm' , '6-Glutamyl-10Fthf Transport, Mitochondrial' , 0. , 1000. , 'Transport, mitochondrial' , '' ), ( '10FTHF7GLUtl' , '7-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' )], dtype = [( 'id' , 'O' ), ( 'name' , 'O' ), ( 'lb' , '= 0 ) # Add the constraint that the sum through all non-reversible reactions is less than or equal to 10 # (note that both PICOS and Python-MIP are symbolic, and expressions involving the variables are allowed) constraint = sum ( model . variables . fluxvars [ i ] for i in non_reversible ) <= 10 # Add to the model and solve model . add_constraint ( constraint ) . solve ( verbosity = 1 ) Starting solution of the Linear programming problem using Dual Simplex Coin0506I Presolve 2242 (-3594) rows, 6144 (-4456) columns and 33659 (-12128) elements Clp0014I Perturbing problem by 0.001% of 1.9797539 - largest nonzero change 1.4130091e-06 ( 7.1372964e-05%) - largest zero change 1.412981e-06 Clp0006I 0 Obj 0.0015868455 Primal inf 3303572.7 (1175) Dual inf 1.9797525 (1) Clp0000I Optimal - objective value 9.062223 Coin0511I After Postsolve, objective 9.062223, infeasibilities - dual 0 (0), primal 0 (0) Clp0032I Optimal objective 9.062223036 - 1675 iterations time 0.142, Presolve 0.07 By default, an optimization model is mutable. This means that every time a method that modifies the model is invoked, the original model is modified. For example, the set_flux_bounds() method modifies the bounds of the reactions in the model. If you want to create a copy of the model, you can use the copy() method to create a full copy of the model.","title":"Constraint-based optimization problems"},{"location":"#mixed-integer-optimization","text":"Many constraint-based metabolic problems consist of selecting a subset of reactions from a generic metabolic network, subject to some biological-based constraints. For example, Sparse FBA consists of selecting the minimum number of active reactions that lead to a desired optimal flux. Context-specific network reconstruction methods such as iMAT, Fastcore, mCADRE, MBA, etc., have also the same purpose: select a subset of reactions from a network based on some experimental data and some objective function. All these problems are instances of a more general problem, known as best subset selection problem , which can be modelled using Mixed Integer Optimization (MIO) . However, instances of this problem are usually hard to solve, and some implementations like Fastcore or MBA use different heuristics or relaxations to find sub-optimal solutions in short time. Unfortunately, there are a few problems with these type of approximations. First, we don't know how good is the solution obtained, and in practice many studies that use those methods assume that the solution they obtained is the best one. Second, even though most of these techniques solve the same type of problem, they look very different or hard to understand for practitioners. Third, many of these implementations do not exploit the potential of the modern MIO solvers which are nowadays able to solve very large problems in a short time, and to adjust the desired level of optimality, which gives the user an idea of how good is the solution obtained. MIOM incorporates specific methods to easily model and solve such problems. Just by calling the method subset_selection() , which takes as input a weight for all reactions or a list of weights for each reaction, it transforms the current problem into a best subset selection problem, in which the objective function is the sum of the weights of the reactions in the solution (where positive weighted reactions contribute to the objective function if they are selected, and negative weighted reactions contribute to the objective function if they are not selected). This simple method makes it possible to model a wide variety of complex constraint-based optimization problems. See for example how easy it is to implement the exact version of the weighted Fastcore with MIOM: import miom import numpy as np # Use the flux-consistent subnetwork (fcm) of the Human1 GEM model # NOTE: Fastcore requires that reactions in the core are flux consistent, # otherwise the problem would be infeasible. m = miom . load_gem ( '@homo_sapiens_human1_fcm.miom' ) # Select reactions from the cholesterol metabolism as the core reactions to keep core_rxn = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) # Assign a negative weight for reactions not in the core weights = - 1 * np . ones ( m . num_reactions ) weights [ core_rxn == 1 ] = 1 fmc = ( miom . load ( m ) . setup ( opt_tol = 0.05 , verbosity = 1 ) . steady_state () . subset_selection ( weights ) . keep ( core_rxn == 1 ) . solve () . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( fmc . num_reactions )","title":"Mixed Integer Optimization"},{"location":"#advantages","text":"It's flexible: MIOM uses the PICOS and the Python-MIP libraries, which means you can use any solver supported by those libraries. It's easy to extend: MIOM is written in pure python, so you can easily extend it to solve more complex optimization problems. It makes the problem explicit: MIOM uses a declarative way to express the problem, so you can easily read and understand what you are solving and differences between algorithms. It's fast: MIOM leverages the power of MIO solvers to solve complex optimization problems. You can control the quality and speed of the solutions for your problem and get better solutions that the approximations (LP) of the original problem available in other constraint-based modeling libraries. It's lightweight: The library has a small number of dependencies, so it's easy to install and distribute also in HPC environments. It includes a compressed GEM format : MIOM can load and save the minimal information of the metabolic networks required for performing simulations into a compressed file compatible with numpy. The small size of the files allows you to quickly run online experiments so other people can reproduce your results. It also supports SBML and matlab formats if cobratoolbox is installed. It's open-source: MIOM is open-source and free to use. You can contribute to the development of MIOM by forking the repository and sending pull requests.","title":"Advantages"},{"location":"#documentation","text":"The documentation of the library can be found at https://metexplore.github.io/miom/","title":"Documentation"},{"location":"#how-to-cite","text":"Manuscript in progress","title":"How to cite"},{"location":"#license","text":"GNU General Public License v3.0","title":"License"},{"location":"examples/fastcore/","text":"Exact Fastcore (MIP) Example of implementation of the Fastcore algorithm with MIOM to extract a context specific model. Fastcore defines a set of core reactions that is forced to be active (carry a non-zero flux in steady state conditions), and minimizes the set of non-core reactions. Cite Vlassis, Pacheco, Sauter (2014). Fast reconstruction of compact context-specific metbolic network models. PLoS Comput. Biol. 10, e1003424 . The Fastcore algorithm is greedy approximation of the exact problem which can be modelled as a MIP problem. With MIOM, the exact problem can be defined in a few lines, using the opt_tol parameter to control the level of optimality required: import miom import numpy as np # Use the flux-consistent subnetwork of the Human1 GEM model, available in the repository m = miom . load_gem ( '@SysBioChalmers/Human-GEM/v1.9.0/consistent' ) # Select reactions from the cholesterol metabolism as the core reactions to keep core_rxn = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) print ( sum ( core_rxn )) # Assign a negative weight for reactions not in the core weights = - 1 * np . ones ( m . num_reactions ) weights [ core_rxn == 1 ] = 1 # Exact-Fastcore fmc = ( miom . load ( m , solver = miom . Solvers . GUROBI ) . setup ( opt_tol = 0.02 ) . steady_state () . subset_selection ( weights ) . keep ( core_rxn == 1 ) . solve ( verbosity = 1 ) . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( fmc . num_reactions ) Note that the algorithm requires that the metabolic network used is flux consistent. If blocked reactions are included in the core set, the MIP becomes infeasible, as those reactions cannot be selected with a non-zero flux in steady state conditions. MIOM includes an implementation of the swiftcc algorithm to obtain flux consistent metabolic networks: Cite Tefagh, M., & Boyd, S. P. (2020). SWIFTCORE: a tool for the context-specific reconstruction of genome-scale metabolic networks. BMC bioinformatics, 21(1), 1-14. DOI: 10.1186/s12859-020-3440-y . from miom.tools import consistent_subnetwork # Get the consistent subnetwork and the lp problem solved by swiftcc consistent , lp = consistent_subnetwork ( m )","title":"Exact Fastcore (MIP)"},{"location":"examples/fastcore/#exact-fastcore-mip","text":"Example of implementation of the Fastcore algorithm with MIOM to extract a context specific model. Fastcore defines a set of core reactions that is forced to be active (carry a non-zero flux in steady state conditions), and minimizes the set of non-core reactions. Cite Vlassis, Pacheco, Sauter (2014). Fast reconstruction of compact context-specific metbolic network models. PLoS Comput. Biol. 10, e1003424 . The Fastcore algorithm is greedy approximation of the exact problem which can be modelled as a MIP problem. With MIOM, the exact problem can be defined in a few lines, using the opt_tol parameter to control the level of optimality required: import miom import numpy as np # Use the flux-consistent subnetwork of the Human1 GEM model, available in the repository m = miom . load_gem ( '@SysBioChalmers/Human-GEM/v1.9.0/consistent' ) # Select reactions from the cholesterol metabolism as the core reactions to keep core_rxn = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) print ( sum ( core_rxn )) # Assign a negative weight for reactions not in the core weights = - 1 * np . ones ( m . num_reactions ) weights [ core_rxn == 1 ] = 1 # Exact-Fastcore fmc = ( miom . load ( m , solver = miom . Solvers . GUROBI ) . setup ( opt_tol = 0.02 ) . steady_state () . subset_selection ( weights ) . keep ( core_rxn == 1 ) . solve ( verbosity = 1 ) . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( fmc . num_reactions ) Note that the algorithm requires that the metabolic network used is flux consistent. If blocked reactions are included in the core set, the MIP becomes infeasible, as those reactions cannot be selected with a non-zero flux in steady state conditions. MIOM includes an implementation of the swiftcc algorithm to obtain flux consistent metabolic networks: Cite Tefagh, M., & Boyd, S. P. (2020). SWIFTCORE: a tool for the context-specific reconstruction of genome-scale metabolic networks. BMC bioinformatics, 21(1), 1-14. DOI: 10.1186/s12859-020-3440-y . from miom.tools import consistent_subnetwork # Get the consistent subnetwork and the lp problem solved by swiftcc consistent , lp = consistent_subnetwork ( m )","title":"Exact Fastcore (MIP)"},{"location":"examples/fba/","text":"Flux Balance Analysis (LP) A simple Flux Balance Analysis can be easily defined and solved with any of the commercial or open-source solvers available: import miom # Load the iMM1865 mouse model from the repository network = miom . mio . load_gem ( \"@iMM1865\" ) target = \"BIOMASS_reaction\" flux = ( miom . load ( network ) . steady_state () . set_rxn_objective ( target ) . solve ( verbosity = 1 ) . get_fluxes ( target )) print ( \"Optimal flux is\" , flux )","title":"Flux Balance Analysis (LP)"},{"location":"examples/fba/#flux-balance-analysis-lp","text":"A simple Flux Balance Analysis can be easily defined and solved with any of the commercial or open-source solvers available: import miom # Load the iMM1865 mouse model from the repository network = miom . mio . load_gem ( \"@iMM1865\" ) target = \"BIOMASS_reaction\" flux = ( miom . load ( network ) . steady_state () . set_rxn_objective ( target ) . solve ( verbosity = 1 ) . get_fluxes ( target )) print ( \"Optimal flux is\" , flux )","title":"Flux Balance Analysis (LP)"},{"location":"examples/imat/","text":"iMAT: Integrative Metabolic Analysis Tool (MIP) Example implementation of iMAT using MIOM. Note that this implementation supports also custom weights for the reactions. By default, weights for reactions in the \"active\" set are set to 1, and reactions in the \"inactive\" set are set to -1, so the objective function is exactly the same as the original iMAT. Cite Shlomi, T., Cabili, M. N., Herrg\u00e5rd, M. J., Palsson, B. \u00d8., & Ruppin, E. (2008). Network-based prediction of human tissue-specific metabolism. Nature biotechnology, 26(9), 1003-1010 . import miom # Use the iHuman-GEM model m = miom . load_gem ( '@SysBioChalmers/Human-GEM/v1.9.0' ) # Add all the reactions from the Cholesterol pathway to the highly expressed set RH = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) # Add reactions from the pyruvate metabolism to the lowly expressed set RL = - 1 * m . find_reactions_from_pathway ( \"Pyruvate metabolism\" ) w = RH + RL print ( \"RH:\" , sum ( RH ), \"RL:\" , sum ( abs ( RL ))) m = ( miom . load ( m , solver = miom . Solvers . GUROBI ) . setup ( int_tol = 1e-8 , opt_tol = 0.01 , verbosity = 1 ) . steady_state () . subset_selection ( w ) . solve ( max_seconds = 30 ) . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( m . num_reactions )","title":"iMAT: Integrative Metabolic Analysis Tool (MIP)"},{"location":"examples/imat/#imat-integrative-metabolic-analysis-tool-mip","text":"Example implementation of iMAT using MIOM. Note that this implementation supports also custom weights for the reactions. By default, weights for reactions in the \"active\" set are set to 1, and reactions in the \"inactive\" set are set to -1, so the objective function is exactly the same as the original iMAT. Cite Shlomi, T., Cabili, M. N., Herrg\u00e5rd, M. J., Palsson, B. \u00d8., & Ruppin, E. (2008). Network-based prediction of human tissue-specific metabolism. Nature biotechnology, 26(9), 1003-1010 . import miom # Use the iHuman-GEM model m = miom . load_gem ( '@SysBioChalmers/Human-GEM/v1.9.0' ) # Add all the reactions from the Cholesterol pathway to the highly expressed set RH = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) # Add reactions from the pyruvate metabolism to the lowly expressed set RL = - 1 * m . find_reactions_from_pathway ( \"Pyruvate metabolism\" ) w = RH + RL print ( \"RH:\" , sum ( RH ), \"RL:\" , sum ( abs ( RL ))) m = ( miom . load ( m , solver = miom . Solvers . GUROBI ) . setup ( int_tol = 1e-8 , opt_tol = 0.01 , verbosity = 1 ) . steady_state () . subset_selection ( w ) . solve ( max_seconds = 30 ) . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( m . num_reactions )","title":"iMAT: Integrative Metabolic Analysis Tool (MIP)"},{"location":"examples/sparse_fba/","text":"Sparse FBA (MIP) The sparse FBA problem consists of finding the optimal flux value for a reaction minimizing the number of reactions with non-zero flux (l0-norm sparsity). Note that minimizing the l0-norm is a NP-hard problem, and so obtaing an optimal solution is not possible in many cases. The COBRA Toolbox includes different LP heuristics to minimize different approximations of the l0-norm. However, using a MIO formulation, it's is possible to obtain a solution which is close to optimal, with a lower number of reactions than the LP approximations, and very quickly. Here is the implementation of sparse-FBA with MIOM: import miom # Load a genome-scale metabolic network. You can load SMBL or Matlab metabolic networks # as well using the same method, but it requires to have the cobratoolbox python library # installed. network = miom . load_gem ( \"@iMM1865\" ) # Create the sparse FBA problem to get a solution that maximizes # the optimal flux through the BIOMASS_reaction minimizing the # number of active reactions. The solution should be not more than # 5% of the optimal solution (opt_tol = 0.05). V , X = ( miom . load ( network , solver = miom . Solvers . GUROBI_PYMIP ) # Set-up the solver options . setup ( int_tol = 1e-8 , opt_tol = 0.05 , verbosity = 1 ) # Add the steady-state constraints (S*V = 0) . steady_state () # Set the reaction to optimize using FBA . set_rxn_objective ( 'BIOMASS_reaction' ) # Solve the FBA (LP) problem (optimal flux) . solve () # Add a constraint to force a flux through # the reaction equal to the optimal flux . set_fluxes_for ( 'BIOMASS_reaction' ) # Convert to a MIO problem (best subset selection) # Each reaction in the network is associated # with a negative weight of -1. The optimization # problem now tries to minimize the selection of # reactions with negative weights (respecting # the previous constraints). Since each reaction # has a weight of -1, all reactions are equally # important in the optimization problem. # This is exactly the optimal sparse-FBA problem # with l0-norm: minimize the number of reactions # but mantaining the optimal FBA flux possible. . subset_selection ( - 1 ) # Solve the MIO problem (note that it's NP-Hard) # You can control the optimality by changing the # opt_tol in the .setup() method. . solve () # Return the flux values (V) and the binary # indicator values (X) . get_values ()) # Show reactions with a flux > 1e-8 print ( \"Number of reactions with flux above +/- 1e-8:\" , sum ( abs ( V ) > 1e-8 )) # Count reactions with an indicator value of 0 (active). Note that since # the weights of the reactions are negative (for all rxns), an indicator # value of 1 corresponds to a succesful removed reaction not included in # the solution, and a value of 0 to a reaction that could not be removed. print ( \"Indicator variables with a value of 1 (selected rxns):\" , sum ( X < 0.5 )) # Show the flux value of the biomass reaction print ( \"Optimal biomass flux:\" , V [ m . get_reaction_id ( \"BIOMASS_reaction\" )], \"mmol/(h\u00b7gDW)\" )","title":"Sparse FBA (MIP)"},{"location":"examples/sparse_fba/#sparse-fba-mip","text":"The sparse FBA problem consists of finding the optimal flux value for a reaction minimizing the number of reactions with non-zero flux (l0-norm sparsity). Note that minimizing the l0-norm is a NP-hard problem, and so obtaing an optimal solution is not possible in many cases. The COBRA Toolbox includes different LP heuristics to minimize different approximations of the l0-norm. However, using a MIO formulation, it's is possible to obtain a solution which is close to optimal, with a lower number of reactions than the LP approximations, and very quickly. Here is the implementation of sparse-FBA with MIOM: import miom # Load a genome-scale metabolic network. You can load SMBL or Matlab metabolic networks # as well using the same method, but it requires to have the cobratoolbox python library # installed. network = miom . load_gem ( \"@iMM1865\" ) # Create the sparse FBA problem to get a solution that maximizes # the optimal flux through the BIOMASS_reaction minimizing the # number of active reactions. The solution should be not more than # 5% of the optimal solution (opt_tol = 0.05). V , X = ( miom . load ( network , solver = miom . Solvers . GUROBI_PYMIP ) # Set-up the solver options . setup ( int_tol = 1e-8 , opt_tol = 0.05 , verbosity = 1 ) # Add the steady-state constraints (S*V = 0) . steady_state () # Set the reaction to optimize using FBA . set_rxn_objective ( 'BIOMASS_reaction' ) # Solve the FBA (LP) problem (optimal flux) . solve () # Add a constraint to force a flux through # the reaction equal to the optimal flux . set_fluxes_for ( 'BIOMASS_reaction' ) # Convert to a MIO problem (best subset selection) # Each reaction in the network is associated # with a negative weight of -1. The optimization # problem now tries to minimize the selection of # reactions with negative weights (respecting # the previous constraints). Since each reaction # has a weight of -1, all reactions are equally # important in the optimization problem. # This is exactly the optimal sparse-FBA problem # with l0-norm: minimize the number of reactions # but mantaining the optimal FBA flux possible. . subset_selection ( - 1 ) # Solve the MIO problem (note that it's NP-Hard) # You can control the optimality by changing the # opt_tol in the .setup() method. . solve () # Return the flux values (V) and the binary # indicator values (X) . get_values ()) # Show reactions with a flux > 1e-8 print ( \"Number of reactions with flux above +/- 1e-8:\" , sum ( abs ( V ) > 1e-8 )) # Count reactions with an indicator value of 0 (active). Note that since # the weights of the reactions are negative (for all rxns), an indicator # value of 1 corresponds to a succesful removed reaction not included in # the solution, and a value of 0 to a reaction that could not be removed. print ( \"Indicator variables with a value of 1 (selected rxns):\" , sum ( X < 0.5 )) # Show the flux value of the biomass reaction print ( \"Optimal biomass flux:\" , V [ m . get_reaction_id ( \"BIOMASS_reaction\" )], \"mmol/(h\u00b7gDW)\" )","title":"Sparse FBA (MIP)"},{"location":"references/mio/","text":"mio.py MiomNetwork A minimal class to store a metabolic network. Attributes: Name Type Description S numpy.ndarray stoichiometric matrix R numpy.ndarray Structured array with the reactions. The fields are: - id (int): reaction ID - lb (float): lower bound - ub (float): upper bound - subsystem (str): subsystem - gpr (str): gene-protein-reaction rule M numpy.ndarray Structured array with the metabolites. The fields are: - id (int): metabolite ID - name (str): metabolite name - formula (str): metabolite formula num_reactions property readonly Number of reactions in the network. Returns: Type Description int Number of reactions find_reaction ( self , rxn_id ) Find a particular reaction in the metabolic network. Parameters: Name Type Description Default rxn_id str Name of the reaction required Returns: Type Description numpy.ndarray Structured array with the information of the reaction. Source code in miom/mio.py def find_reaction ( self , rxn_id ): \"\"\"Find a particular reaction in the metabolic network. Args: rxn_id (str): Name of the reaction Returns: numpy.ndarray: Structured array with the information of the reaction. \"\"\" return MiomNetwork . _find_reaction ( rxn_id , self . R ) export_gem ( miom_network , path_to_exported_file ) Export a miom network to a file in the miom format. Parameters: Name Type Description Default miom_network MiomNetwork an instance of a MiomNetwork required path_to_exported_file str Path to the exported file (e.g. /path/to/file.miom) required Source code in miom/mio.py def export_gem ( miom_network , path_to_exported_file ): \"\"\"Export a miom network to a file in the miom format. Args: miom_network (MiomNetwork): an instance of a MiomNetwork path_to_exported_file (str): Path to the exported file (e.g. /path/to/file.miom) \"\"\" import lzma with io . BytesIO () as npz : np . savez_compressed ( npz , S = miom_network . S , reactions = miom_network . R , metabolites = miom_network . M ) compressed = lzma . compress ( npz . getbuffer ()) # Store to file with open ( path_to_exported_file , 'wb' ) as f_out : f_out . write ( compressed ) load_gem ( model_or_path ) Load a metabolic network from a file or URL. The method supports any format supported by cobrapy (.xml, .yml, .json, .mat) or a miom compressed model (.miom) from a url or a local file path. For the cobra supported formats, you need the cobrapy package installed, and for .mat files, you need both cobrapy and scipy installed. Parameters: Name Type Description Default model_or_path str Path to a local file or URL pointing to the metabolic network. If the string starts with '@', the file will be loaded from the default github repository. required Returns: Type Description MiomNetwork A MiomNetwork instance with the minimal information of the metabolic network required for simulations. It includes the stoichiometric matrix, the list of reactions with the lower and upper bounds, the associated genes and GPR rules, and the list of metabolites. Source code in miom/mio.py def load_gem ( model_or_path ): \"\"\"Load a metabolic network from a file or URL. The method supports any format supported by cobrapy (.xml, .yml, .json, .mat) or a miom compressed model (.miom) from a url or a local file path. For the cobra supported formats, you need the cobrapy package installed, and for .mat files, you need both cobrapy and scipy installed. Args: model_or_path (str): Path to a local file or URL pointing to the metabolic network. If the string starts with '@', the file will be loaded from the default github repository. Returns: MiomNetwork: A [MiomNetwork][miom.mio] instance with the minimal information of the metabolic network required for simulations. It includes the stoichiometric matrix, the list of reactions with the lower and upper bounds, the associated genes and GPR rules, and the list of metabolites. \"\"\" extensions = [ '.xml' , '.yml' , '.json' , '.mat' , '.miom' ] if isinstance ( model_or_path , str ): file = model_or_path if model_or_path . startswith ( \"@\" ): # Check if the file has a valid file extension if not any ( file . endswith ( ext ) for ext in extensions ): # Assume is a relative url pointing to a version file = _download ( DEFAULT_REPOSITORY + model_or_path [ 1 :] + \"/default.miom\" ) else : file = _download ( DEFAULT_REPOSITORY + model_or_path [ 1 :]) elif _is_url ( model_or_path ): file = _download ( model_or_path ) ext = pathlib . Path ( file ) . suffix if ext == '.miom' or ext == '.xz' or ext == '.npz' : return _load_compressed_model ( file ) else : return cobra_to_miom ( _read_cobra_model ( file )) else : return cobra_to_miom ( model_or_path )","title":"mio.py"},{"location":"references/mio/#miopy","text":"","title":"mio.py"},{"location":"references/mio/#miom.mio.MiomNetwork","text":"A minimal class to store a metabolic network. Attributes: Name Type Description S numpy.ndarray stoichiometric matrix R numpy.ndarray Structured array with the reactions. The fields are: - id (int): reaction ID - lb (float): lower bound - ub (float): upper bound - subsystem (str): subsystem - gpr (str): gene-protein-reaction rule M numpy.ndarray Structured array with the metabolites. The fields are: - id (int): metabolite ID - name (str): metabolite name - formula (str): metabolite formula","title":"MiomNetwork"},{"location":"references/mio/#miom.mio.MiomNetwork.num_reactions","text":"Number of reactions in the network. Returns: Type Description int Number of reactions","title":"num_reactions"},{"location":"references/mio/#miom.mio.MiomNetwork.find_reaction","text":"Find a particular reaction in the metabolic network. Parameters: Name Type Description Default rxn_id str Name of the reaction required Returns: Type Description numpy.ndarray Structured array with the information of the reaction. Source code in miom/mio.py def find_reaction ( self , rxn_id ): \"\"\"Find a particular reaction in the metabolic network. Args: rxn_id (str): Name of the reaction Returns: numpy.ndarray: Structured array with the information of the reaction. \"\"\" return MiomNetwork . _find_reaction ( rxn_id , self . R )","title":"find_reaction()"},{"location":"references/mio/#miom.mio.export_gem","text":"Export a miom network to a file in the miom format. Parameters: Name Type Description Default miom_network MiomNetwork an instance of a MiomNetwork required path_to_exported_file str Path to the exported file (e.g. /path/to/file.miom) required Source code in miom/mio.py def export_gem ( miom_network , path_to_exported_file ): \"\"\"Export a miom network to a file in the miom format. Args: miom_network (MiomNetwork): an instance of a MiomNetwork path_to_exported_file (str): Path to the exported file (e.g. /path/to/file.miom) \"\"\" import lzma with io . BytesIO () as npz : np . savez_compressed ( npz , S = miom_network . S , reactions = miom_network . R , metabolites = miom_network . M ) compressed = lzma . compress ( npz . getbuffer ()) # Store to file with open ( path_to_exported_file , 'wb' ) as f_out : f_out . write ( compressed )","title":"export_gem()"},{"location":"references/mio/#miom.mio.load_gem","text":"Load a metabolic network from a file or URL. The method supports any format supported by cobrapy (.xml, .yml, .json, .mat) or a miom compressed model (.miom) from a url or a local file path. For the cobra supported formats, you need the cobrapy package installed, and for .mat files, you need both cobrapy and scipy installed. Parameters: Name Type Description Default model_or_path str Path to a local file or URL pointing to the metabolic network. If the string starts with '@', the file will be loaded from the default github repository. required Returns: Type Description MiomNetwork A MiomNetwork instance with the minimal information of the metabolic network required for simulations. It includes the stoichiometric matrix, the list of reactions with the lower and upper bounds, the associated genes and GPR rules, and the list of metabolites. Source code in miom/mio.py def load_gem ( model_or_path ): \"\"\"Load a metabolic network from a file or URL. The method supports any format supported by cobrapy (.xml, .yml, .json, .mat) or a miom compressed model (.miom) from a url or a local file path. For the cobra supported formats, you need the cobrapy package installed, and for .mat files, you need both cobrapy and scipy installed. Args: model_or_path (str): Path to a local file or URL pointing to the metabolic network. If the string starts with '@', the file will be loaded from the default github repository. Returns: MiomNetwork: A [MiomNetwork][miom.mio] instance with the minimal information of the metabolic network required for simulations. It includes the stoichiometric matrix, the list of reactions with the lower and upper bounds, the associated genes and GPR rules, and the list of metabolites. \"\"\" extensions = [ '.xml' , '.yml' , '.json' , '.mat' , '.miom' ] if isinstance ( model_or_path , str ): file = model_or_path if model_or_path . startswith ( \"@\" ): # Check if the file has a valid file extension if not any ( file . endswith ( ext ) for ext in extensions ): # Assume is a relative url pointing to a version file = _download ( DEFAULT_REPOSITORY + model_or_path [ 1 :] + \"/default.miom\" ) else : file = _download ( DEFAULT_REPOSITORY + model_or_path [ 1 :]) elif _is_url ( model_or_path ): file = _download ( model_or_path ) ext = pathlib . Path ( file ) . suffix if ext == '.miom' or ext == '.xz' or ext == '.npz' : return _load_compressed_model ( file ) else : return cobra_to_miom ( _read_cobra_model ( file )) else : return cobra_to_miom ( model_or_path )","title":"load_gem()"},{"location":"references/miom/","text":"miom.py BaseModel Base class for building LP/MIP optimization models using a high-level API for metabolic problems. It implements the chainable methods to set-up a LP/MIP metabolic network problem. Two implementations are available: PicosModel and PythonMipModel. The PicosModel uses the PICOS library as a backend to interact with different solvers. The PythonMipModel uses the Python-MIP library to solve the model using the CBC or GUROBI solvers. Note Do not try to instantiate this class directly. Use the load() function instead. The method automatically selects the right implementation depending on the solver. add_constraint ( self , constraint ) Add a specific constraint to the model. The constraint should use existing variables already included in the model. Parameters: Name Type Description Default constraint affine expression using model's variables. required Source code in miom/miom.py @_composable def add_constraint ( self , constraint ): \"\"\"Add a specific constraint to the model. The constraint should use existing variables already included in the model. Args: constraint: affine expression using model's variables. \"\"\" pass add_constraints ( self , constraints ) Add a list of constraint to the model Parameters: Name Type Description Default constraints list List of expressions with the constraints. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def add_constraints ( self , constraints ): \"\"\"Add a list of constraint to the model Args: constraints (list): List of expressions with the constraints. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" for c in constraints : self . add_constraint ( c ) return len ( constraints ) > 0 exclude ( self , indicator_values = None ) Exclude a solution from the set of feasible solutions. If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730 Parameters: Name Type Description Default values list List of values for each indicator variable. Defaults to None. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def exclude ( self , indicator_values = None ): \"\"\"Exclude a solution from the set of feasible solutions. If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730 Args: values (list, optional): List of values for each indicator variable. Defaults to None. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . variables . indicators is None : raise ValueError ( \"\"\"The optimization model does not contain indicator variables. Make sure that the problem is a subset selection problem.\"\"\" ) if indicator_values is None : indicator_values = np . array ( self . variables . indicator_values ) return dict ( indicator_values = indicator_values ) fix_fluxes ( self , reactions , tolerance = 1e-06 ) Force the flux of certain reactions to match current values. After calling .solve() for a flux optimization problem (e.g. FBA), this method adds a new constraint to force the flux of the given reactions to match the current flux values found after the optimization. This is interesting for example to implement methods like sparse-FBA, where the optimization is no longer the flux but the number of active reactions, and a new constraint is required to preserve optimality of fluxes. Parameters: Name Type Description Default reactions list reaction or list of reactions required tolerance float Tolerance for the flux values (a solution is valid if the flux is within optimal value +/- tol. Defaults to 1e-6. 1e-06 Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py def fix_fluxes ( self , reactions , tolerance = 1e-6 ): \"\"\"Force the flux of certain reactions to match current values. After calling `.solve()` for a flux optimization problem (e.g. FBA), this method adds a new constraint to force the flux of the given reactions to match the current flux values found after the optimization. This is interesting for example to implement methods like sparse-FBA, where the optimization is no longer the flux but the number of active reactions, and a new constraint is required to preserve optimality of fluxes. Args: reactions (list): reaction or list of reactions tolerance (float, optional): Tolerance for the flux values (a solution is valid if the flux is within optimal value +/- tol. Defaults to 1e-6. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if isinstance ( reactions , str ): reactions = [ reactions ] for rid in reactions : if isinstance ( rid , np . ndarray ): # TODO: Test this path rid = rid [ 'id' ] idx , rxn = self . network . find_reaction ( rid ) lb = max ( rxn [ 'lb' ], self . variables . flux_values [ idx ] - tolerance ) ub = min ( rxn [ 'ub' ], self . variables . flux_values [ idx ] + tolerance ) self . add_constraint ( self . variables . fluxvars [ idx ] >= lb ) self . add_constraint ( self . variables . fluxvars [ idx ] <= ub ) return self get_fluxes ( self , reactions = None ) Get the flux values. Parameters: Name Type Description Default reactions list Reaction or subset of reactions For which to obtain the flux values. Defaults to None. None Returns: Type Description list List with the flux values for all or the selected reactions. Source code in miom/miom.py def get_fluxes ( self , reactions = None ): \"\"\"Get the flux values. Args: reactions (list, optional): Reaction or subset of reactions For which to obtain the flux values. Defaults to None. Returns: list: List with the flux values for all or the selected reactions. \"\"\" if isinstance ( reactions , str ): return self . variables . flux_values [ self . network . get_reaction_id ( reactions )] if isinstance ( reactions , Iterable ): return { r [ 'id' ]: self . variables . flux_values [ self . network . get_reaction_id ( r [ 'id' ])] for r in reactions } if reactions is None : return self . variables . flux_values else : raise ValueError ( \"reactions should be an iterable of strings or a single string\" ) get_values ( self ) Get the values for the variables Returns: Type Description tuple (V, X) where V are the flux values and X are the indicator values (if the problem is a MIP problem, for example if subset_selection was called) Source code in miom/miom.py def get_values ( self ): \"\"\"Get the values for the variables Returns: tuple: (V, X) where V are the flux values and X are the indicator values (if the problem is a MIP problem, for example if `subset_selection` was called) \"\"\" return self . variables . values () keep ( self , reactions ) Force the inclusion of a list of reactions in the solution. Reactions have to be associated with positive weights in order to keep them in the final solution. Note that once keep() is called, the weights associated to the reactions selected to be kept will not be taken into account, as they will be forced to be kept in the solution. Parameters: Name Type Description Default reactions list List of reaction names, a binary vector indicating the reactions to keep, or a list of indexes with the reactions to keep. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def keep ( self , reactions ): \"\"\"Force the inclusion of a list of reactions in the solution. Reactions have to be associated with positive weights in order to keep them in the final solution. Note that once keep() is called, the weights associated to the reactions selected to be kept will not be taken into account, as they will be forced to be kept in the solution. Args: reactions (list): List of reaction names, a binary vector indicating the reactions to keep, or a list of indexes with the reactions to keep. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . variables . indicators is None : raise ValueError ( \"\"\"No indicator variables for reactions, transform it to a subset selection problem calling subset_selection first, providing positive weights for the reactions you want to keep.\"\"\" ) if reactions is None or len ( reactions ) == 0 : return False if isinstance ( reactions , str ): reactions = [ reactions ] # Check if it's a binary vector if len ( reactions ) == self . network . num_reactions and max ( reactions ) == 1 : reactions = np . where ( reactions == 1 )[ 0 ] # Check if the reactions have an indicator variable reactions = set ( self . network . find_reaction ( rxn )[ 0 ] for rxn in reactions ) available = set ( rxn . index for rxn in self . variables . assigned_reactions if rxn . cost > 0 ) diff = reactions - available if len ( diff ) != 0 : raise ValueError ( f \"\"\"Only reactions associated with positive weights can be forced to be selected. The following reaction indexes have no indicator variables or are associated with negative weights: { diff } .\"\"\" ) valid_rxn_idx = reactions & available # Get the indexes of the indicator variables idxs = [ i for i , r in enumerate ( self . variables . assigned_reactions ) if r . index in valid_rxn_idx ] return dict ( idxs = idxs , valid_rxn_idx = valid_rxn_idx ) obtain_subnetwork ( self , extraction_mode =< ExtractionMode . ABSOLUTE_FLUX_VALUE : 'flux_value' > , comparator =< Comparator . GREATER_OR_EQUAL : 'geq' > , value = 1e-08 ) Same as select_subnetwork but returns the network instead. See select_subnetwork for a detailed description of the method. Returns: Type Description MiomNetwork A MiomNetwork with the selected subnetwork. Source code in miom/miom.py def obtain_subnetwork ( self , extraction_mode = ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = Comparator . GREATER_OR_EQUAL , value = 1e-8 ): \"\"\"Same as [select_subnetwork][miom.miom.BaseModel] but returns the network instead. See [select_subnetwork][miom.miom.BaseModel] for a detailed description of the method. Returns: MiomNetwork: A MiomNetwork with the selected subnetwork. \"\"\" # If indicators are present and assigned, # take the subset of the network for which # the indicators of positive weighted reactions # are equal to 1 if extraction_mode == ExtractionMode . ABSOLUTE_FLUX_VALUE : variables = self . variables . flux_values if variables is None : raise ValueError ( \"The model does not contain flux variables. \" \"You need to call first steady_state() to add \" \"the flux variables\" ) elif extraction_mode == ExtractionMode . INDICATOR_VALUE : variables = self . variables . indicator_values if variables is None : raise ValueError ( \"The model does not contain indicator variables. \" \"You need to transform it to a subset selection problem \" \"by invoking subset_selection() first.\" ) elif extraction_mode == ExtractionMode . REACTION_ACTIVITY : variables = self . variables . reaction_activity if variables is None : raise ValueError ( \"The model does not contain reaction activity variables. \" \"You need to transform it to a subset selection problem \" \"by invoking subset_selection() first.\" ) else : raise ValueError ( \"Invalid extraction mode\" ) if comparator == Comparator . GREATER_OR_EQUAL : selected = np . where ( np . abs ( variables ) >= value )[ 0 ] elif comparator == Comparator . LESS_OR_EQUAL : selected = np . where ( np . abs ( variables ) <= value )[ 0 ] else : raise ValueError ( \"Invalid comparison\" ) # TODO: Assigned reactions work only for indicator variables if extraction_mode == ExtractionMode . INDICATOR_VALUE : rxns = [ self . variables . assigned_reactions [ x ] for x in selected ] selected_idx = [ rxn . index for rxn in rxns ] elif extraction_mode == ExtractionMode . ABSOLUTE_FLUX_VALUE : selected_idx = selected else : raise NotImplementedError ( \"Only indicator variables and absolute flux values are supported\" ) return self . network . subnet ( selected_idx ) reset ( self ) Resets the original problem (removes all modifications) Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def reset ( self ): \"\"\"Resets the original problem (removes all modifications) Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . problem is None : warnings . warn ( \"Problem is not initialized, nothing to reset\" ) return False else : return True select_subnetwork ( self , mode =< ExtractionMode . ABSOLUTE_FLUX_VALUE : 'flux_value' > , comparator =< Comparator . GREATER_OR_EQUAL : 'geq' > , value = 1e-08 ) Select a subnetwork and create a new BaseModel to operate on it. The new instance of the BaseModel is a new problem instance with no constraints. If the idea is to perform FBA simulations on this new subnetwork, remember to add the new constraints, especially the steady_state . Parameters: Name Type Description Default mode ExtractionMode Method used to extract the subnetwork (based on flux values or using the indicator values). Defaults to ExtractionMode.ABSOLUTE_FLUX_VALUE.  comparator Comparator Comparator for the selected mode. Defaults to Comparator.GREATER_OR_EQUAL.  value float Value threshold for the mode and comparator selected. Defaults to 1e-8. 1e-08 Returns: Type Description [type] [description] Source code in miom/miom.py @_composable def select_subnetwork ( self , mode = ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = Comparator . GREATER_OR_EQUAL , value = 1e-8 ): \"\"\"Select a subnetwork and create a new BaseModel to operate on it. The new instance of the BaseModel is a new problem instance with no constraints. If the idea is to perform FBA simulations on this new subnetwork, remember to add the new constraints, especially the `steady_state`. Args: mode (ExtractionMode, optional): Method used to extract the subnetwork (based on flux values or using the indicator values). Defaults to ExtractionMode.ABSOLUTE_FLUX_VALUE. comparator (Comparator, optional): Comparator for the selected mode. Defaults to Comparator.GREATER_OR_EQUAL. value (float, optional): Value threshold for the mode and comparator selected. Defaults to 1e-8. Returns: [type]: [description] \"\"\" return self . obtain_subnetwork ( extraction_mode = mode , comparator = comparator , value = value ) set_flux_bounds ( self , rxn_id , min_flux = None , max_flux = None ) Change the flux bounds of a reaction. Parameters: Name Type Description Default rxn_id str/int name or id of the reaction to change required min_flux float Min flux value. Defaults to None. None max_flux float Max flux value. Defaults to None. None Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def set_flux_bounds ( self , rxn_id , min_flux = None , max_flux = None ): \"\"\"Change the flux bounds of a reaction. Args: rxn_id (str/int): name or id of the reaction to change min_flux (float, optional): Min flux value. Defaults to None. max_flux (float, optional): Max flux value. Defaults to None. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" i , _ = self . network . find_reaction ( rxn_id ) return i set_objective ( self , cost_vector , variables , direction = 'max' ) Set the optmization objective of the model. Parameters: Name Type Description Default cost_vector Iterable List with the cost for each variable required variables Iterable Variables used for the objective function required direction str Optimization direction (min or max). Defaults to 'max'. 'max' Source code in miom/miom.py @_composable def set_objective ( self , cost_vector , variables , direction = 'max' ): \"\"\"Set the optmization objective of the model. Args: cost_vector (Iterable): List with the cost for each variable variables (Iterable): Variables used for the objective function direction (str, optional): Optimization direction (min or max). Defaults to 'max'. \"\"\" if self . objective is not None : warnings . warn ( \"Previous objective changed\" ) self . objective = ( cost_vector , variables , direction ) set_rxn_objective ( self , rxn , direction = 'max' ) Set a flux objective Maximize or minimize the flux through a given reaction. Parameters: Name Type Description Default rxn str Name of the reaction to use for the optimization required direction str Minimization or maximization of the flux ('min' or 'max'). Defaults to 'max'. 'max' Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py def set_rxn_objective ( self , rxn , direction = 'max' ): \"\"\"Set a flux objective Maximize or minimize the flux through a given reaction. Args: rxn (str): Name of the reaction to use for the optimization direction (str, optional): Minimization or maximization of the flux ('min' or 'max'). Defaults to 'max'. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" i = self . network . get_reaction_id ( rxn ) cost = np . zeros ( self . network . num_reactions ) cost [ i ] = 1 self . set_objective ( cost , self . variables . fluxvars , direction = direction ) return self setup ( self , ** kwargs ) Provide the options for the solver. Attributes: Name Type Description int_tol float Integrality tolerance for integer variables. Defaults to 1e-8. feas_tol float Feasibility tolerance. Defaults to 1e-8. opt_tol float Relative MIP gap tolerance for MIP problems. Defaults to 1e-5. verbosity int Values above 0 force the backends to be verbose. Use a value of 1 to show useful information about the search. Defaults to 0. Returns: Type Description BaseModel the configured instance of the BaseModel Source code in miom/miom.py @_composable def setup ( self , ** kwargs ): \"\"\"Provide the options for the solver. Attributes: int_tol (float): Integrality tolerance for integer variables. Defaults to 1e-8. feas_tol (float): Feasibility tolerance. Defaults to 1e-8. opt_tol (float): Relative MIP gap tolerance for MIP problems. Defaults to 1e-5. verbosity (int): Values above 0 force the backends to be verbose. Use a value of 1 to show useful information about the search. Defaults to 0. Returns: BaseModel: the configured instance of the BaseModel \"\"\" if self . problem is None : warnings . warn ( \"Problem cannot be configured since it was not initialized\" ) return False options = dict () int_tol = kwargs [ \"int_tol\" ] if \"int_tol\" in kwargs else None feas_tol = kwargs [ \"feas_tol\" ] if \"feas_tol\" in kwargs else None opt_tol = kwargs [ \"opt_tol\" ] if \"opt_tol\" in kwargs else None verbosity = kwargs [ \"verbosity\" ] if \"verbosity\" in kwargs else None solver = kwargs [ \"solver\" ] if \"solver\" in kwargs else None if int_tol is not None : options [ \"int_tol\" ] = int_tol if feas_tol is not None : options [ \"feas_tol\" ] = feas_tol if opt_tol is not None : options [ \"opt_tol\" ] = opt_tol if verbosity is not None : options [ \"verbosity\" ] = verbosity if solver is not None : options [ \"solver\" ] = solver self . _options . update ( options ) # Calculate a min eps value to avoid numerical issues self . _options [ \"_min_eps\" ] = np . sqrt ( 2 * self . _options [ \"int_tol\" ]) return self . _options solve ( self , verbosity = None , max_seconds = None ) Solve the current model and assign the values to the variables of the model. Parameters: Name Type Description Default verbosity int Level of verbosity for the solver. Values above 0 will force the backend to show output information of the search. Defaults to None. None max_seconds int Max time in seconds for the search. Defaults to None. None Source code in miom/miom.py @_composable def solve ( self , verbosity = None , max_seconds = None ): \"\"\"Solve the current model and assign the values to the variables of the model. Args: verbosity (int, optional): Level of verbosity for the solver. Values above 0 will force the backend to show output information of the search. Defaults to None. max_seconds (int, optional): Max time in seconds for the search. Defaults to None. \"\"\" self . _last_start_time = perf_counter () steady_state ( self ) Add the required constraints for finding steady-state fluxes The method adds the \\(S * V = 0\\) set of constraints, where \\(S\\) is the stoichiometric matrix and \\(V\\) the flux variables. Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def steady_state ( self ): \"\"\"Add the required constraints for finding steady-state fluxes The method adds the $S * V = 0$ set of constraints, where $S$ is the stoichiometric matrix and $V$ the flux variables. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" pass subset_selection ( self , rxn_weights , direction = 'max' , eps = 0.01 , strengthen = True ) Transform the current model into a subset selection problem. The subset selection problem consists of selecting the positive weighted reactions and remove the negative weighted reactions, subject to steady state constraints and/or additional constraints on fluxes, and maximizing the weighted sum of the (absolute) weights for the successfully selected reactions (with positive weights) and the successfully removed reactions (with negative weights). Selected reactions are forced to have an absolute flux value greater or equal to the threshold eps (1e-2 by default). Removed reactions should have a flux equal to 0. Each reaction is associated with a weight (positive or negative) provided in the parameter rxn_weights , and the objective is to select the reactions that optimizes the following expression: \\[ f(x) = \\sum_i^n |w_i| * x_i \\] where \\(x_i\\) are the indicator variables for the reactions \\(i\\) and \\(w_i\\) are the weights for the reactions associated to the indicator variable. Indicator variables are automatically created for each reaction associated to a non-zero weight. Two (mutually exclusive) indicator variables are used for positive weighted reactions that are reversible to indicate whether there is positive or negative flux through the reaction. A single indicator variable is created for positive weighted non-reversible reactions, to indicate if the reaction is selected (has a non-zero flux greater or equal to eps ) in which case the indicator variable is 1, or 0 otherwise. A single binary indicator variable is also created for negative weighted reactions, indicating whether the reaction was not selected (i.e, has 0 flux, in which case the indicator variable is 1) or not (in which case the indicator variable is 0). Parameters: Name Type Description Default rxn_weights list List of weights for each reaction. If a single value is provided, it is assumed to be the weight for all reactions. required eps float Min absolute flux value for weighted reactions to consider them active or inactive. Defaults to 1e-2. 0.01 Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def subset_selection ( self , rxn_weights , direction = 'max' , eps = 1e-2 , strengthen = True ): \"\"\"Transform the current model into a subset selection problem. The subset selection problem consists of selecting the positive weighted reactions and remove the negative weighted reactions, subject to steady state constraints and/or additional constraints on fluxes, and maximizing the weighted sum of the (absolute) weights for the successfully selected reactions (with positive weights) and the successfully removed reactions (with negative weights). Selected reactions are forced to have an absolute flux value greater or equal to the threshold `eps` (1e-2 by default). Removed reactions should have a flux equal to 0. Each reaction is associated with a weight (positive or negative) provided in the parameter `rxn_weights`, and the objective is to select the reactions that optimizes the following expression: $$ f(x) = \\sum_i^n |w_i| * x_i $$ where $x_i$ are the indicator variables for the reactions $i$ and $w_i$ are the weights for the reactions associated to the indicator variable. Indicator variables are automatically created for each reaction associated to a non-zero weight. Two (mutually exclusive) indicator variables are used for positive weighted reactions that are reversible to indicate whether there is positive or negative flux through the reaction. A single indicator variable is created for positive weighted non-reversible reactions, to indicate if the reaction is selected (has a non-zero flux greater or equal to `eps`) in which case the indicator variable is 1, or 0 otherwise. A single binary indicator variable is also created for negative weighted reactions, indicating whether the reaction was not selected (i.e, has 0 flux, in which case the indicator variable is 1) or not (in which case the indicator variable is 0). Args: rxn_weights (list): List of weights for each reaction. If a single value is provided, it is assumed to be the weight for all reactions. eps (float, optional): Min absolute flux value for weighted reactions to consider them active or inactive. Defaults to 1e-2. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" # Calculate min valid EPS based on integrality tolerance min_eps = self . _options [ \"_min_eps\" ] if eps < min_eps : warnings . warn ( f \"Minimum epsilon value below min. allowed value, changed to { min_eps } .\" ) eps = max ( eps , min_eps ) if not isinstance ( rxn_weights , Iterable ): rxn_weights = [ rxn_weights ] * self . network . num_reactions rxnw = _weighted_rxns ( self . network . R , rxn_weights ) if self . variables . indicators is None : self . variables . _assigned_reactions = rxnw return dict ( eps = eps , direction = direction , strengthen = strengthen ) else : raise ValueError ( \"The current model is already a subset selection problem.\" ) Comparator Comparator enum to use with select_subnetwork() Attributes: Name Type Description GREATER_OR_EQUAL str Select those variables with a value greater or equal than the one provided. LESS_OR_EQUAL str Select those variables with a value less or equal than the one provided. ExtractionMode Method to select the subnetwork to be extracted. This mode works with the method select_subnetwork only after a subset selection problem was succesfully solved. If the model is configured as a subset selection problem, the user can extract a subnetwork after the method solve() was called. The selection of the subnetwork can be done using the indicator variables or the flux variables. For more information, please read the documentation of the method subset_selection Attributes: Name Type Description ABSOLUTE_FLUX_VALUE str Use a decision criterion based on the value of the fluxes. For example, by selecting all the reactions that have an absolute flux value above a certain threshold. INDICATOR_VALUE str Use the binary indicator variables to select the subnetwork. Binary indicator variables are created for a subset selection problem (after calling subset_selection ). Two indicators are created for each positive weighted and reversible reaction, to indicate if there is a non-zero positive flux or negative flux respectively. A single binary indicator variable is created for each negative weighted reaction. In this case, an indicator value of 1 indicates that the reaction was succesfully removed, and 0 otherwise. You can use the value of the indicator variables to select a subnetwork after solving. For example, if all the reactions have a negative weight (since the goal is, for example, to minimize the number of reactions subject to some other constraints) and you want to select only the reactions that were not removed after solving, you can use the indicator variables with a value of 0. Usage example: m . steady_state () . add_constraints ( ... ) . # Convert to a subset selection, where each reaction # has a weight of -1. subset_selection ( - 1 ) . # Solve the optimization problem . solve () # Get the subnetwork selecting the reactions # with an indicator value below 0.5. Since variables # are binary, it basically selects all the reactions # associated with a binary indicator value of 0. # This corresponds to the reactions that were not # removed after solving the problem (since all the # reactions have negative weights, and their binary # indicator variables are 1 if they were successfully # removed, and 0 if they could not be removed). . select_subnetwork ( mode = ExtractionMode . INDICATOR_VALUE , comparator = Comparator . LESS_OR_EQUAL , value = 0.5 ) . network Solvers Solvers supported by the miom module. Please refer to https://picos-api.gitlab.io/picos/introduction.html to see the list of supported solvers using the PICOS backend. The Python-MIP backend only supports the GUROBI and CBC solvers. Note that in some cases, the Python-MIP backend (GUROBI/CBC) might be faster setting up the problem than the PICOS backend since it has less overhead. Attributes: Name Type Description GUROBI_PYMIP str Recommended solver for most problems (LP, MIP). It uses the Python-MIP backend. Note that GUROBI is a commercial software which require a license. Free academic licenses are also available at https://gurobi.com/free/. GUROBI str For using GUROBI with the PICOS backend instead of Python-MIP. COIN_OR_CBC str Free LP/MIP solver with good performance, provided with Python-MIP. CPLEX str Commercial solver with a performance similar to GUROBI. Only supported by the PICOS backend. SCIP str Free academic solver, supported by the PICOS backend. GLPK str Open source solver, supported by the PICOS backend. MOSEK str Commercial solver, supported by the PICOS backend. Status An enumeration. load ( network , solver = None ) Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend). Examples: Example of how to perform FBA to maximize flux through the BIOMASS_reaction in the iMM1865 model: >>> import miom >>> network = miom . load_gem ( \"@iMM1865\" ) >>> flx = ( miom . load ( network ) . steady_state () . set_rxn_objective ( \"BIOMASS_reaction\" ) . solve ( verbosity = 1 ) . get_fluxes ( 'BIOMASS_reaction' )) Parameters: Name Type Description Default network miom_network or str A miom metabolic network or a valid file that can be imported with load_gem() . required solver Solver The solver to be used. Defaults to Solver.GLPK. None Returns: Type Description BaseModel A BaseModel object, which can be PythonMipModel if CBC solver is used, or a PicosModel otherwise. Source code in miom/miom.py def load ( network , solver = None ): \"\"\" Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend). Example: Example of how to perform FBA to maximize flux through the `BIOMASS_reaction` in the iMM1865 model: ```python >>> import miom >>> network = miom.load_gem(\"@iMM1865\") >>> flx = (miom .load(network) .steady_state() .set_rxn_objective(\"BIOMASS_reaction\") .solve(verbosity=1) .get_fluxes('BIOMASS_reaction')) ``` Args: network (miom_network or str): A miom metabolic network or a valid file that can be imported with [load_gem()][miom.mio.load_gem]. solver (Solver, optional): The solver to be used. Defaults to Solver.GLPK. Returns: BaseModel: A BaseModel object, which can be PythonMipModel if CBC solver is used, or a PicosModel otherwise. \"\"\" if solver is None : solver = Solvers . COIN_OR_CBC if _PICOS_AVAILABLE : solvers = pc . solvers . available_solvers () if \"gurobi\" in solvers : solver = Solvers . GUROBI elif \"cplex\" in solvers : solver = Solvers . CPLEX solver = str ( solver . value ) if isinstance ( solver , Enum ) else str ( solver ) if isinstance ( network , str ): network = load_gem ( network ) if solver == 'cbc' : return PythonMipModel ( miom_network = network , solver_name = solver ) if solver == 'gurobi_pymip' : return PythonMipModel ( miom_network = network , solver_name = 'gurobi' ) if _PICOS_AVAILABLE : return PicosModel ( miom_network = network , solver_name = solver ) else : raise Exception ( \"\"\"PICOS is not installed. Please install it with pip, or reinstall miom with the right options, for example with: 'pip install miom[all]'.\"\"\" )","title":"miom.py"},{"location":"references/miom/#miompy","text":"","title":"miom.py"},{"location":"references/miom/#miom.miom.BaseModel","text":"Base class for building LP/MIP optimization models using a high-level API for metabolic problems. It implements the chainable methods to set-up a LP/MIP metabolic network problem. Two implementations are available: PicosModel and PythonMipModel. The PicosModel uses the PICOS library as a backend to interact with different solvers. The PythonMipModel uses the Python-MIP library to solve the model using the CBC or GUROBI solvers. Note Do not try to instantiate this class directly. Use the load() function instead. The method automatically selects the right implementation depending on the solver.","title":"BaseModel"},{"location":"references/miom/#miom.miom.BaseModel.add_constraint","text":"Add a specific constraint to the model. The constraint should use existing variables already included in the model. Parameters: Name Type Description Default constraint affine expression using model's variables. required Source code in miom/miom.py @_composable def add_constraint ( self , constraint ): \"\"\"Add a specific constraint to the model. The constraint should use existing variables already included in the model. Args: constraint: affine expression using model's variables. \"\"\" pass","title":"add_constraint()"},{"location":"references/miom/#miom.miom.BaseModel.add_constraints","text":"Add a list of constraint to the model Parameters: Name Type Description Default constraints list List of expressions with the constraints. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def add_constraints ( self , constraints ): \"\"\"Add a list of constraint to the model Args: constraints (list): List of expressions with the constraints. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" for c in constraints : self . add_constraint ( c ) return len ( constraints ) > 0","title":"add_constraints()"},{"location":"references/miom/#miom.miom.BaseModel.exclude","text":"Exclude a solution from the set of feasible solutions. If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730 Parameters: Name Type Description Default values list List of values for each indicator variable. Defaults to None. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def exclude ( self , indicator_values = None ): \"\"\"Exclude a solution from the set of feasible solutions. If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730 Args: values (list, optional): List of values for each indicator variable. Defaults to None. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . variables . indicators is None : raise ValueError ( \"\"\"The optimization model does not contain indicator variables. Make sure that the problem is a subset selection problem.\"\"\" ) if indicator_values is None : indicator_values = np . array ( self . variables . indicator_values ) return dict ( indicator_values = indicator_values )","title":"exclude()"},{"location":"references/miom/#miom.miom.BaseModel.fix_fluxes","text":"Force the flux of certain reactions to match current values. After calling .solve() for a flux optimization problem (e.g. FBA), this method adds a new constraint to force the flux of the given reactions to match the current flux values found after the optimization. This is interesting for example to implement methods like sparse-FBA, where the optimization is no longer the flux but the number of active reactions, and a new constraint is required to preserve optimality of fluxes. Parameters: Name Type Description Default reactions list reaction or list of reactions required tolerance float Tolerance for the flux values (a solution is valid if the flux is within optimal value +/- tol. Defaults to 1e-6. 1e-06 Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py def fix_fluxes ( self , reactions , tolerance = 1e-6 ): \"\"\"Force the flux of certain reactions to match current values. After calling `.solve()` for a flux optimization problem (e.g. FBA), this method adds a new constraint to force the flux of the given reactions to match the current flux values found after the optimization. This is interesting for example to implement methods like sparse-FBA, where the optimization is no longer the flux but the number of active reactions, and a new constraint is required to preserve optimality of fluxes. Args: reactions (list): reaction or list of reactions tolerance (float, optional): Tolerance for the flux values (a solution is valid if the flux is within optimal value +/- tol. Defaults to 1e-6. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if isinstance ( reactions , str ): reactions = [ reactions ] for rid in reactions : if isinstance ( rid , np . ndarray ): # TODO: Test this path rid = rid [ 'id' ] idx , rxn = self . network . find_reaction ( rid ) lb = max ( rxn [ 'lb' ], self . variables . flux_values [ idx ] - tolerance ) ub = min ( rxn [ 'ub' ], self . variables . flux_values [ idx ] + tolerance ) self . add_constraint ( self . variables . fluxvars [ idx ] >= lb ) self . add_constraint ( self . variables . fluxvars [ idx ] <= ub ) return self","title":"fix_fluxes()"},{"location":"references/miom/#miom.miom.BaseModel.get_fluxes","text":"Get the flux values. Parameters: Name Type Description Default reactions list Reaction or subset of reactions For which to obtain the flux values. Defaults to None. None Returns: Type Description list List with the flux values for all or the selected reactions. Source code in miom/miom.py def get_fluxes ( self , reactions = None ): \"\"\"Get the flux values. Args: reactions (list, optional): Reaction or subset of reactions For which to obtain the flux values. Defaults to None. Returns: list: List with the flux values for all or the selected reactions. \"\"\" if isinstance ( reactions , str ): return self . variables . flux_values [ self . network . get_reaction_id ( reactions )] if isinstance ( reactions , Iterable ): return { r [ 'id' ]: self . variables . flux_values [ self . network . get_reaction_id ( r [ 'id' ])] for r in reactions } if reactions is None : return self . variables . flux_values else : raise ValueError ( \"reactions should be an iterable of strings or a single string\" )","title":"get_fluxes()"},{"location":"references/miom/#miom.miom.BaseModel.get_values","text":"Get the values for the variables Returns: Type Description tuple (V, X) where V are the flux values and X are the indicator values (if the problem is a MIP problem, for example if subset_selection was called) Source code in miom/miom.py def get_values ( self ): \"\"\"Get the values for the variables Returns: tuple: (V, X) where V are the flux values and X are the indicator values (if the problem is a MIP problem, for example if `subset_selection` was called) \"\"\" return self . variables . values ()","title":"get_values()"},{"location":"references/miom/#miom.miom.BaseModel.keep","text":"Force the inclusion of a list of reactions in the solution. Reactions have to be associated with positive weights in order to keep them in the final solution. Note that once keep() is called, the weights associated to the reactions selected to be kept will not be taken into account, as they will be forced to be kept in the solution. Parameters: Name Type Description Default reactions list List of reaction names, a binary vector indicating the reactions to keep, or a list of indexes with the reactions to keep. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def keep ( self , reactions ): \"\"\"Force the inclusion of a list of reactions in the solution. Reactions have to be associated with positive weights in order to keep them in the final solution. Note that once keep() is called, the weights associated to the reactions selected to be kept will not be taken into account, as they will be forced to be kept in the solution. Args: reactions (list): List of reaction names, a binary vector indicating the reactions to keep, or a list of indexes with the reactions to keep. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . variables . indicators is None : raise ValueError ( \"\"\"No indicator variables for reactions, transform it to a subset selection problem calling subset_selection first, providing positive weights for the reactions you want to keep.\"\"\" ) if reactions is None or len ( reactions ) == 0 : return False if isinstance ( reactions , str ): reactions = [ reactions ] # Check if it's a binary vector if len ( reactions ) == self . network . num_reactions and max ( reactions ) == 1 : reactions = np . where ( reactions == 1 )[ 0 ] # Check if the reactions have an indicator variable reactions = set ( self . network . find_reaction ( rxn )[ 0 ] for rxn in reactions ) available = set ( rxn . index for rxn in self . variables . assigned_reactions if rxn . cost > 0 ) diff = reactions - available if len ( diff ) != 0 : raise ValueError ( f \"\"\"Only reactions associated with positive weights can be forced to be selected. The following reaction indexes have no indicator variables or are associated with negative weights: { diff } .\"\"\" ) valid_rxn_idx = reactions & available # Get the indexes of the indicator variables idxs = [ i for i , r in enumerate ( self . variables . assigned_reactions ) if r . index in valid_rxn_idx ] return dict ( idxs = idxs , valid_rxn_idx = valid_rxn_idx )","title":"keep()"},{"location":"references/miom/#miom.miom.BaseModel.obtain_subnetwork","text":"Same as select_subnetwork but returns the network instead. See select_subnetwork for a detailed description of the method. Returns: Type Description MiomNetwork A MiomNetwork with the selected subnetwork. Source code in miom/miom.py def obtain_subnetwork ( self , extraction_mode = ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = Comparator . GREATER_OR_EQUAL , value = 1e-8 ): \"\"\"Same as [select_subnetwork][miom.miom.BaseModel] but returns the network instead. See [select_subnetwork][miom.miom.BaseModel] for a detailed description of the method. Returns: MiomNetwork: A MiomNetwork with the selected subnetwork. \"\"\" # If indicators are present and assigned, # take the subset of the network for which # the indicators of positive weighted reactions # are equal to 1 if extraction_mode == ExtractionMode . ABSOLUTE_FLUX_VALUE : variables = self . variables . flux_values if variables is None : raise ValueError ( \"The model does not contain flux variables. \" \"You need to call first steady_state() to add \" \"the flux variables\" ) elif extraction_mode == ExtractionMode . INDICATOR_VALUE : variables = self . variables . indicator_values if variables is None : raise ValueError ( \"The model does not contain indicator variables. \" \"You need to transform it to a subset selection problem \" \"by invoking subset_selection() first.\" ) elif extraction_mode == ExtractionMode . REACTION_ACTIVITY : variables = self . variables . reaction_activity if variables is None : raise ValueError ( \"The model does not contain reaction activity variables. \" \"You need to transform it to a subset selection problem \" \"by invoking subset_selection() first.\" ) else : raise ValueError ( \"Invalid extraction mode\" ) if comparator == Comparator . GREATER_OR_EQUAL : selected = np . where ( np . abs ( variables ) >= value )[ 0 ] elif comparator == Comparator . LESS_OR_EQUAL : selected = np . where ( np . abs ( variables ) <= value )[ 0 ] else : raise ValueError ( \"Invalid comparison\" ) # TODO: Assigned reactions work only for indicator variables if extraction_mode == ExtractionMode . INDICATOR_VALUE : rxns = [ self . variables . assigned_reactions [ x ] for x in selected ] selected_idx = [ rxn . index for rxn in rxns ] elif extraction_mode == ExtractionMode . ABSOLUTE_FLUX_VALUE : selected_idx = selected else : raise NotImplementedError ( \"Only indicator variables and absolute flux values are supported\" ) return self . network . subnet ( selected_idx )","title":"obtain_subnetwork()"},{"location":"references/miom/#miom.miom.BaseModel.reset","text":"Resets the original problem (removes all modifications) Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def reset ( self ): \"\"\"Resets the original problem (removes all modifications) Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . problem is None : warnings . warn ( \"Problem is not initialized, nothing to reset\" ) return False else : return True","title":"reset()"},{"location":"references/miom/#miom.miom.BaseModel.select_subnetwork","text":"Select a subnetwork and create a new BaseModel to operate on it. The new instance of the BaseModel is a new problem instance with no constraints. If the idea is to perform FBA simulations on this new subnetwork, remember to add the new constraints, especially the steady_state . Parameters: Name Type Description Default mode ExtractionMode Method used to extract the subnetwork (based on flux values or using the indicator values). Defaults to ExtractionMode.ABSOLUTE_FLUX_VALUE.  comparator Comparator Comparator for the selected mode. Defaults to Comparator.GREATER_OR_EQUAL.  value float Value threshold for the mode and comparator selected. Defaults to 1e-8. 1e-08 Returns: Type Description [type] [description] Source code in miom/miom.py @_composable def select_subnetwork ( self , mode = ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = Comparator . GREATER_OR_EQUAL , value = 1e-8 ): \"\"\"Select a subnetwork and create a new BaseModel to operate on it. The new instance of the BaseModel is a new problem instance with no constraints. If the idea is to perform FBA simulations on this new subnetwork, remember to add the new constraints, especially the `steady_state`. Args: mode (ExtractionMode, optional): Method used to extract the subnetwork (based on flux values or using the indicator values). Defaults to ExtractionMode.ABSOLUTE_FLUX_VALUE. comparator (Comparator, optional): Comparator for the selected mode. Defaults to Comparator.GREATER_OR_EQUAL. value (float, optional): Value threshold for the mode and comparator selected. Defaults to 1e-8. Returns: [type]: [description] \"\"\" return self . obtain_subnetwork ( extraction_mode = mode , comparator = comparator , value = value )","title":"select_subnetwork()"},{"location":"references/miom/#miom.miom.BaseModel.set_flux_bounds","text":"Change the flux bounds of a reaction. Parameters: Name Type Description Default rxn_id str/int name or id of the reaction to change required min_flux float Min flux value. Defaults to None. None max_flux float Max flux value. Defaults to None. None Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def set_flux_bounds ( self , rxn_id , min_flux = None , max_flux = None ): \"\"\"Change the flux bounds of a reaction. Args: rxn_id (str/int): name or id of the reaction to change min_flux (float, optional): Min flux value. Defaults to None. max_flux (float, optional): Max flux value. Defaults to None. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" i , _ = self . network . find_reaction ( rxn_id ) return i","title":"set_flux_bounds()"},{"location":"references/miom/#miom.miom.BaseModel.set_objective","text":"Set the optmization objective of the model. Parameters: Name Type Description Default cost_vector Iterable List with the cost for each variable required variables Iterable Variables used for the objective function required direction str Optimization direction (min or max). Defaults to 'max'. 'max' Source code in miom/miom.py @_composable def set_objective ( self , cost_vector , variables , direction = 'max' ): \"\"\"Set the optmization objective of the model. Args: cost_vector (Iterable): List with the cost for each variable variables (Iterable): Variables used for the objective function direction (str, optional): Optimization direction (min or max). Defaults to 'max'. \"\"\" if self . objective is not None : warnings . warn ( \"Previous objective changed\" ) self . objective = ( cost_vector , variables , direction )","title":"set_objective()"},{"location":"references/miom/#miom.miom.BaseModel.set_rxn_objective","text":"Set a flux objective Maximize or minimize the flux through a given reaction. Parameters: Name Type Description Default rxn str Name of the reaction to use for the optimization required direction str Minimization or maximization of the flux ('min' or 'max'). Defaults to 'max'. 'max' Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py def set_rxn_objective ( self , rxn , direction = 'max' ): \"\"\"Set a flux objective Maximize or minimize the flux through a given reaction. Args: rxn (str): Name of the reaction to use for the optimization direction (str, optional): Minimization or maximization of the flux ('min' or 'max'). Defaults to 'max'. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" i = self . network . get_reaction_id ( rxn ) cost = np . zeros ( self . network . num_reactions ) cost [ i ] = 1 self . set_objective ( cost , self . variables . fluxvars , direction = direction ) return self","title":"set_rxn_objective()"},{"location":"references/miom/#miom.miom.BaseModel.setup","text":"Provide the options for the solver. Attributes: Name Type Description int_tol float Integrality tolerance for integer variables. Defaults to 1e-8. feas_tol float Feasibility tolerance. Defaults to 1e-8. opt_tol float Relative MIP gap tolerance for MIP problems. Defaults to 1e-5. verbosity int Values above 0 force the backends to be verbose. Use a value of 1 to show useful information about the search. Defaults to 0. Returns: Type Description BaseModel the configured instance of the BaseModel Source code in miom/miom.py @_composable def setup ( self , ** kwargs ): \"\"\"Provide the options for the solver. Attributes: int_tol (float): Integrality tolerance for integer variables. Defaults to 1e-8. feas_tol (float): Feasibility tolerance. Defaults to 1e-8. opt_tol (float): Relative MIP gap tolerance for MIP problems. Defaults to 1e-5. verbosity (int): Values above 0 force the backends to be verbose. Use a value of 1 to show useful information about the search. Defaults to 0. Returns: BaseModel: the configured instance of the BaseModel \"\"\" if self . problem is None : warnings . warn ( \"Problem cannot be configured since it was not initialized\" ) return False options = dict () int_tol = kwargs [ \"int_tol\" ] if \"int_tol\" in kwargs else None feas_tol = kwargs [ \"feas_tol\" ] if \"feas_tol\" in kwargs else None opt_tol = kwargs [ \"opt_tol\" ] if \"opt_tol\" in kwargs else None verbosity = kwargs [ \"verbosity\" ] if \"verbosity\" in kwargs else None solver = kwargs [ \"solver\" ] if \"solver\" in kwargs else None if int_tol is not None : options [ \"int_tol\" ] = int_tol if feas_tol is not None : options [ \"feas_tol\" ] = feas_tol if opt_tol is not None : options [ \"opt_tol\" ] = opt_tol if verbosity is not None : options [ \"verbosity\" ] = verbosity if solver is not None : options [ \"solver\" ] = solver self . _options . update ( options ) # Calculate a min eps value to avoid numerical issues self . _options [ \"_min_eps\" ] = np . sqrt ( 2 * self . _options [ \"int_tol\" ]) return self . _options","title":"setup()"},{"location":"references/miom/#miom.miom.BaseModel.solve","text":"Solve the current model and assign the values to the variables of the model. Parameters: Name Type Description Default verbosity int Level of verbosity for the solver. Values above 0 will force the backend to show output information of the search. Defaults to None. None max_seconds int Max time in seconds for the search. Defaults to None. None Source code in miom/miom.py @_composable def solve ( self , verbosity = None , max_seconds = None ): \"\"\"Solve the current model and assign the values to the variables of the model. Args: verbosity (int, optional): Level of verbosity for the solver. Values above 0 will force the backend to show output information of the search. Defaults to None. max_seconds (int, optional): Max time in seconds for the search. Defaults to None. \"\"\" self . _last_start_time = perf_counter ()","title":"solve()"},{"location":"references/miom/#miom.miom.BaseModel.steady_state","text":"Add the required constraints for finding steady-state fluxes The method adds the \\(S * V = 0\\) set of constraints, where \\(S\\) is the stoichiometric matrix and \\(V\\) the flux variables. Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def steady_state ( self ): \"\"\"Add the required constraints for finding steady-state fluxes The method adds the $S * V = 0$ set of constraints, where $S$ is the stoichiometric matrix and $V$ the flux variables. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" pass","title":"steady_state()"},{"location":"references/miom/#miom.miom.BaseModel.subset_selection","text":"Transform the current model into a subset selection problem. The subset selection problem consists of selecting the positive weighted reactions and remove the negative weighted reactions, subject to steady state constraints and/or additional constraints on fluxes, and maximizing the weighted sum of the (absolute) weights for the successfully selected reactions (with positive weights) and the successfully removed reactions (with negative weights). Selected reactions are forced to have an absolute flux value greater or equal to the threshold eps (1e-2 by default). Removed reactions should have a flux equal to 0. Each reaction is associated with a weight (positive or negative) provided in the parameter rxn_weights , and the objective is to select the reactions that optimizes the following expression: \\[ f(x) = \\sum_i^n |w_i| * x_i \\] where \\(x_i\\) are the indicator variables for the reactions \\(i\\) and \\(w_i\\) are the weights for the reactions associated to the indicator variable. Indicator variables are automatically created for each reaction associated to a non-zero weight. Two (mutually exclusive) indicator variables are used for positive weighted reactions that are reversible to indicate whether there is positive or negative flux through the reaction. A single indicator variable is created for positive weighted non-reversible reactions, to indicate if the reaction is selected (has a non-zero flux greater or equal to eps ) in which case the indicator variable is 1, or 0 otherwise. A single binary indicator variable is also created for negative weighted reactions, indicating whether the reaction was not selected (i.e, has 0 flux, in which case the indicator variable is 1) or not (in which case the indicator variable is 0). Parameters: Name Type Description Default rxn_weights list List of weights for each reaction. If a single value is provided, it is assumed to be the weight for all reactions. required eps float Min absolute flux value for weighted reactions to consider them active or inactive. Defaults to 1e-2. 0.01 Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def subset_selection ( self , rxn_weights , direction = 'max' , eps = 1e-2 , strengthen = True ): \"\"\"Transform the current model into a subset selection problem. The subset selection problem consists of selecting the positive weighted reactions and remove the negative weighted reactions, subject to steady state constraints and/or additional constraints on fluxes, and maximizing the weighted sum of the (absolute) weights for the successfully selected reactions (with positive weights) and the successfully removed reactions (with negative weights). Selected reactions are forced to have an absolute flux value greater or equal to the threshold `eps` (1e-2 by default). Removed reactions should have a flux equal to 0. Each reaction is associated with a weight (positive or negative) provided in the parameter `rxn_weights`, and the objective is to select the reactions that optimizes the following expression: $$ f(x) = \\sum_i^n |w_i| * x_i $$ where $x_i$ are the indicator variables for the reactions $i$ and $w_i$ are the weights for the reactions associated to the indicator variable. Indicator variables are automatically created for each reaction associated to a non-zero weight. Two (mutually exclusive) indicator variables are used for positive weighted reactions that are reversible to indicate whether there is positive or negative flux through the reaction. A single indicator variable is created for positive weighted non-reversible reactions, to indicate if the reaction is selected (has a non-zero flux greater or equal to `eps`) in which case the indicator variable is 1, or 0 otherwise. A single binary indicator variable is also created for negative weighted reactions, indicating whether the reaction was not selected (i.e, has 0 flux, in which case the indicator variable is 1) or not (in which case the indicator variable is 0). Args: rxn_weights (list): List of weights for each reaction. If a single value is provided, it is assumed to be the weight for all reactions. eps (float, optional): Min absolute flux value for weighted reactions to consider them active or inactive. Defaults to 1e-2. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" # Calculate min valid EPS based on integrality tolerance min_eps = self . _options [ \"_min_eps\" ] if eps < min_eps : warnings . warn ( f \"Minimum epsilon value below min. allowed value, changed to { min_eps } .\" ) eps = max ( eps , min_eps ) if not isinstance ( rxn_weights , Iterable ): rxn_weights = [ rxn_weights ] * self . network . num_reactions rxnw = _weighted_rxns ( self . network . R , rxn_weights ) if self . variables . indicators is None : self . variables . _assigned_reactions = rxnw return dict ( eps = eps , direction = direction , strengthen = strengthen ) else : raise ValueError ( \"The current model is already a subset selection problem.\" )","title":"subset_selection()"},{"location":"references/miom/#miom.miom.Comparator","text":"Comparator enum to use with select_subnetwork() Attributes: Name Type Description GREATER_OR_EQUAL str Select those variables with a value greater or equal than the one provided. LESS_OR_EQUAL str Select those variables with a value less or equal than the one provided.","title":"Comparator"},{"location":"references/miom/#miom.miom.ExtractionMode","text":"Method to select the subnetwork to be extracted. This mode works with the method select_subnetwork only after a subset selection problem was succesfully solved. If the model is configured as a subset selection problem, the user can extract a subnetwork after the method solve() was called. The selection of the subnetwork can be done using the indicator variables or the flux variables. For more information, please read the documentation of the method subset_selection Attributes: Name Type Description ABSOLUTE_FLUX_VALUE str Use a decision criterion based on the value of the fluxes. For example, by selecting all the reactions that have an absolute flux value above a certain threshold. INDICATOR_VALUE str Use the binary indicator variables to select the subnetwork. Binary indicator variables are created for a subset selection problem (after calling subset_selection ). Two indicators are created for each positive weighted and reversible reaction, to indicate if there is a non-zero positive flux or negative flux respectively. A single binary indicator variable is created for each negative weighted reaction. In this case, an indicator value of 1 indicates that the reaction was succesfully removed, and 0 otherwise. You can use the value of the indicator variables to select a subnetwork after solving. For example, if all the reactions have a negative weight (since the goal is, for example, to minimize the number of reactions subject to some other constraints) and you want to select only the reactions that were not removed after solving, you can use the indicator variables with a value of 0. Usage example: m . steady_state () . add_constraints ( ... ) . # Convert to a subset selection, where each reaction # has a weight of -1. subset_selection ( - 1 ) . # Solve the optimization problem . solve () # Get the subnetwork selecting the reactions # with an indicator value below 0.5. Since variables # are binary, it basically selects all the reactions # associated with a binary indicator value of 0. # This corresponds to the reactions that were not # removed after solving the problem (since all the # reactions have negative weights, and their binary # indicator variables are 1 if they were successfully # removed, and 0 if they could not be removed). . select_subnetwork ( mode = ExtractionMode . INDICATOR_VALUE , comparator = Comparator . LESS_OR_EQUAL , value = 0.5 ) . network","title":"ExtractionMode"},{"location":"references/miom/#miom.miom.Solvers","text":"Solvers supported by the miom module. Please refer to https://picos-api.gitlab.io/picos/introduction.html to see the list of supported solvers using the PICOS backend. The Python-MIP backend only supports the GUROBI and CBC solvers. Note that in some cases, the Python-MIP backend (GUROBI/CBC) might be faster setting up the problem than the PICOS backend since it has less overhead. Attributes: Name Type Description GUROBI_PYMIP str Recommended solver for most problems (LP, MIP). It uses the Python-MIP backend. Note that GUROBI is a commercial software which require a license. Free academic licenses are also available at https://gurobi.com/free/. GUROBI str For using GUROBI with the PICOS backend instead of Python-MIP. COIN_OR_CBC str Free LP/MIP solver with good performance, provided with Python-MIP. CPLEX str Commercial solver with a performance similar to GUROBI. Only supported by the PICOS backend. SCIP str Free academic solver, supported by the PICOS backend. GLPK str Open source solver, supported by the PICOS backend. MOSEK str Commercial solver, supported by the PICOS backend.","title":"Solvers"},{"location":"references/miom/#miom.miom.Status","text":"An enumeration.","title":"Status"},{"location":"references/miom/#miom.miom.load","text":"Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend). Examples: Example of how to perform FBA to maximize flux through the BIOMASS_reaction in the iMM1865 model: >>> import miom >>> network = miom . load_gem ( \"@iMM1865\" ) >>> flx = ( miom . load ( network ) . steady_state () . set_rxn_objective ( \"BIOMASS_reaction\" ) . solve ( verbosity = 1 ) . get_fluxes ( 'BIOMASS_reaction' )) Parameters: Name Type Description Default network miom_network or str A miom metabolic network or a valid file that can be imported with load_gem() . required solver Solver The solver to be used. Defaults to Solver.GLPK. None Returns: Type Description BaseModel A BaseModel object, which can be PythonMipModel if CBC solver is used, or a PicosModel otherwise. Source code in miom/miom.py def load ( network , solver = None ): \"\"\" Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend). Example: Example of how to perform FBA to maximize flux through the `BIOMASS_reaction` in the iMM1865 model: ```python >>> import miom >>> network = miom.load_gem(\"@iMM1865\") >>> flx = (miom .load(network) .steady_state() .set_rxn_objective(\"BIOMASS_reaction\") .solve(verbosity=1) .get_fluxes('BIOMASS_reaction')) ``` Args: network (miom_network or str): A miom metabolic network or a valid file that can be imported with [load_gem()][miom.mio.load_gem]. solver (Solver, optional): The solver to be used. Defaults to Solver.GLPK. Returns: BaseModel: A BaseModel object, which can be PythonMipModel if CBC solver is used, or a PicosModel otherwise. \"\"\" if solver is None : solver = Solvers . COIN_OR_CBC if _PICOS_AVAILABLE : solvers = pc . solvers . available_solvers () if \"gurobi\" in solvers : solver = Solvers . GUROBI elif \"cplex\" in solvers : solver = Solvers . CPLEX solver = str ( solver . value ) if isinstance ( solver , Enum ) else str ( solver ) if isinstance ( network , str ): network = load_gem ( network ) if solver == 'cbc' : return PythonMipModel ( miom_network = network , solver_name = solver ) if solver == 'gurobi_pymip' : return PythonMipModel ( miom_network = network , solver_name = 'gurobi' ) if _PICOS_AVAILABLE : return PicosModel ( miom_network = network , solver_name = solver ) else : raise Exception ( \"\"\"PICOS is not installed. Please install it with pip, or reinstall miom with the right options, for example with: 'pip install miom[all]'.\"\"\" )","title":"load()"}]}
\ No newline at end of file
+{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Introduction Warning This library is functional but still in a very early stage. API is still not stable and might be changed in future versions. MIOM (Mixed Integer Optimization for Metabolism) is a python library for creating and solving complex optimization problems using genome-scale metabolic networks, in just a few lines. MIOM offers a high-level API that leverages the power of modern Mixed Integer Optimization (MIO) solvers to easily define steady-state metabolic optimization problems, from simple Flux Balance Analysis (FBA) simulations, to more complex problems, such as sparse FBA or context-specific reconstruction algorithms, and solve them the required level of optimality . It supports many free and commercial solvers thanks to the integration with the PICOS and the Python-MIP . It is also compatible and complementary to cobrapy . Here is a simple example of the differences of implementing from scratch a simple Flux Balance Analysis (FBA), which is typically implemented as a Linear Program (LP) problem, and the Sparse FBA problem which is an Integer Programmming (IP) problem that solves the same FBA problem but minimizing the number of active reactions: FBA (LP) import miom model = ( miom . load ( '@BiGG/Recon3D.miom' ) . steady_state () . set_rxn_objective ( 'biomass_reaction' ) . solve ( verbosity = 1 )) print ( \"Optimal flux:\" , model . get_fluxes ( 'biomass_reaction' )) print ( \"Number of active reactions:\" , sum ( abs ( model . get_fluxes ()) > 1e-8 )) Sparse FBA (MIP) import miom model = ( miom . load ( '@BiGG/Recon3D.miom' ) . setup ( opt_tol = 0.05 , verbosity = 1 ) . steady_state () . set_rxn_objective ( 'biomass_reaction' ) . solve () . set_fluxes_for ( 'biomass_reaction' ) . subset_selection ( - 1 ) . solve ()) print ( \"Optimal flux:\" , model . get_fluxes ( 'biomass_reaction' )) print ( \"Number of active reactions:\" , sum ( abs ( model . get_fluxes ()) > 1e-8 )) Note To better understand the meaning of each step, please read the documentation of the BaseModel class , and the complete example in examples/sparse_fba.py . Installation Recommended installation The recommended installation with pip using the option all includes PICOS and Python-MIP backends, and the interfaces for GLPK , Gurobi and Mosek : pip install miom[all] Minimal installation By default, MIOM comes only with the Python-MIP backend and the COIN-OR CBC solver. The minimal installation is perfect to use in online notebooks and for sharing minimal reproducible examples. To install MIOM with minimal dependencies, run: pip install miom Full installation The full install option of miom comes with all the packages included with the all option, and the additional COBRA package. This adds also support for importing any kind of genome-scale metabolic network supported by cobra with the miom.load_gem() method: pip install miom[full] Installing CPLEX CPLEX is also supported but requires a prior installation of CPLEX in the system with a valid license that cannot be configured through pip . To install MIOM with CPLEX support, follow the instructions on the CPLEX page to install your current version of cplex in your python environment. Quick start Importing a Genome-Scale Metabolic Network (GEMs) First step is to import a Genome-Scale Metabolic Network. The method load_gem() can be used to import a network from a local file or a URL. This method requires the cobrapy and scipy packages to import networks in the SBML, YAML, JSON, and Matlab formats (see Full install ). Here is an example of importing the BiGG Recon3D network: import miom network = miom . load_gem ( 'https://github.com/SBRG/bigg_models_data/raw/master/models/Recon3D.mat' ) print ( \"Number of reactions in the network:\" , network . num_reactions ) By default, MIOM uses its own format (.miom) which is a lightweight, compressed and portable format based on numpy structured arrays to store only the essential information required to perform common tasks. To improve reproducibility of experiments, a repository of already converted models is available at pablormier/miom-gems . Any model from this repository can be imported using shorthand links in the following forma: @relative/path/to/model . For example, in order to import the Human-GEM v1.9.0 , you only need to run: network = miom . load_gem ( '@SysBioChalmers/Human-Gem/v1.9.0' ) This is a very convenient way of importing models and sharing reproducible experiments , making sure that other users are going to test the same models. Managing Metabolic Networks MIOM is not intended to provide functions for creating and managing metabolic networks, since there are already other libraries for this purpose (e.g. cobrapy ). If you rely on cobrapy for model manipulation, you can still use MIOM for the optimization after you prepare your metabolic network, as MIOM is nicely integrated with COBRA: from cobra.test import create_test_model network = create_test_model ( \"textbook\" ) medium = network . medium medium [ \"EX_o2_e\" ] = 0.0 network . medium = medium # Use MIOM for optimization flux = ( miom . load ( miom . mio . cobra_to_miom ( network )) . steady_state () . set_rxn_objective ( 'Biomass_Ecoli_core' ) . solve () . get_fluxes ( 'Biomass_Ecoli_core' )) Metabolic Networks in MIOM are represented by a miom.mio.MiomNetwork class. This class encodes the network into three matrices: R (reactions), S (stoichiometry), and M (metabolites). The R matrix is a numpy structured array that contains the list of the reactions defined in the network, including the reaction ID, the reaction name, the reaction bounds, the subsystem and the Gene-Protein-Rules: >>> miom . load_gem ( '@BiGG/Recon3D.miom' ) . R [: 5 ] array ([( '10FTHF5GLUtl' , '5-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' ), ( '10FTHF5GLUtm' , '5-Glutamyl-10Fthf Transport, Mitochondrial' , 0. , 1000. , 'Transport, mitochondrial' , '' ), ( '10FTHF6GLUtl' , '6-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' ), ( '10FTHF6GLUtm' , '6-Glutamyl-10Fthf Transport, Mitochondrial' , 0. , 1000. , 'Transport, mitochondrial' , '' ), ( '10FTHF7GLUtl' , '7-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' )], dtype = [( 'id' , 'O' ), ( 'name' , 'O' ), ( 'lb' , '= 0 ) # Add the constraint that the sum through all non-reversible reactions is less than or equal to 10 # (note that both PICOS and Python-MIP are symbolic, and expressions involving the variables are allowed) constraint = sum ( model . variables . fluxvars [ i ] for i in non_reversible ) <= 10 # Add to the model and solve model . add_constraint ( constraint ) . solve ( verbosity = 1 ) Starting solution of the Linear programming problem using Dual Simplex Coin0506I Presolve 2242 (-3594) rows, 6144 (-4456) columns and 33659 (-12128) elements Clp0014I Perturbing problem by 0.001% of 1.9797539 - largest nonzero change 1.4130091e-06 ( 7.1372964e-05%) - largest zero change 1.412981e-06 Clp0006I 0 Obj 0.0015868455 Primal inf 3303572.7 (1175) Dual inf 1.9797525 (1) Clp0000I Optimal - objective value 9.062223 Coin0511I After Postsolve, objective 9.062223, infeasibilities - dual 0 (0), primal 0 (0) Clp0032I Optimal objective 9.062223036 - 1675 iterations time 0.142, Presolve 0.07 By default, an optimization model is mutable. This means that every time a method that modifies the model is invoked, the original model is modified. For example, the set_flux_bounds() method modifies the bounds of the reactions in the model. If you want to create a copy of the model, you can use the copy() method to create a full copy of the model. Mixed Integer Optimization Many constraint-based metabolic problems consist of selecting a subset of reactions from a generic metabolic network, subject to some biological-based constraints. For example, Sparse FBA consists of selecting the minimum number of active reactions that lead to a desired optimal flux. Context-specific network reconstruction methods such as iMAT, Fastcore, mCADRE, MBA, etc., have also the same purpose: select a subset of reactions from a network based on some experimental data and some objective function. All these problems are instances of a more general problem, known as best subset selection problem , which can be modelled using Mixed Integer Optimization (MIO) . However, instances of this problem are usually hard to solve, and some implementations like Fastcore or MBA use different heuristics or relaxations to find sub-optimal solutions in short time. Unfortunately, there are a few problems with these type of approximations. First, we don't know how good is the solution obtained, and in practice many studies that use those methods assume that the solution they obtained is the best one. Second, even though most of these techniques solve the same type of problem, they look very different or hard to understand for practitioners. Third, many of these implementations do not exploit the potential of the modern MIO solvers which are nowadays able to solve very large problems in a short time, and to adjust the desired level of optimality, which gives the user an idea of how good is the solution obtained. MIOM incorporates specific methods to easily model and solve such problems. Just by calling the method subset_selection() , which takes as input a weight for all reactions or a list of weights for each reaction, it transforms the current problem into a best subset selection problem, in which the objective function is the sum of the weights of the reactions in the solution (where positive weighted reactions contribute to the objective function if they are selected, and negative weighted reactions contribute to the objective function if they are not selected). This simple method makes it possible to model a wide variety of complex constraint-based optimization problems. See for example how easy it is to implement the exact version of the weighted Fastcore with MIOM: import miom import numpy as np # Use the flux-consistent subnetwork (fcm) of the Human1 GEM model # NOTE: Fastcore requires that reactions in the core are flux consistent, # otherwise the problem would be infeasible. m = miom . load_gem ( '@homo_sapiens_human1_fcm.miom' ) # Select reactions from the cholesterol metabolism as the core reactions to keep core_rxn = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) # Assign a negative weight for reactions not in the core weights = - 1 * np . ones ( m . num_reactions ) weights [ core_rxn == 1 ] = 1 fmc = ( miom . load ( m ) . setup ( opt_tol = 0.05 , verbosity = 1 ) . steady_state () . subset_selection ( weights ) . keep ( core_rxn == 1 ) . solve () . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( fmc . num_reactions ) Advantages It's flexible: MIOM uses the PICOS and the Python-MIP libraries, which means you can use any solver supported by those libraries. It's easy to extend: MIOM is written in pure python, so you can easily extend it to solve more complex optimization problems. It makes the problem explicit: MIOM uses a declarative way to express the problem, so you can easily read and understand what you are solving and differences between algorithms. It's fast: MIOM leverages the power of MIO solvers to solve complex optimization problems. You can control the quality and speed of the solutions for your problem and get better solutions that the approximations (LP) of the original problem available in other constraint-based modeling libraries. It's lightweight: The library has a small number of dependencies, so it's easy to install and distribute also in HPC environments. It includes a compressed GEM format : MIOM can load and save the minimal information of the metabolic networks required for performing simulations into a compressed file compatible with numpy. The small size of the files allows you to quickly run online experiments so other people can reproduce your results. It also supports SBML and matlab formats if cobratoolbox is installed. It's open-source: MIOM is open-source and free to use. You can contribute to the development of MIOM by forking the repository and sending pull requests. Documentation The documentation of the library can be found at https://metexplore.github.io/miom/ How to cite Manuscript in progress License GNU General Public License v3.0","title":"Home"},{"location":"#introduction","text":"Warning This library is functional but still in a very early stage. API is still not stable and might be changed in future versions. MIOM (Mixed Integer Optimization for Metabolism) is a python library for creating and solving complex optimization problems using genome-scale metabolic networks, in just a few lines. MIOM offers a high-level API that leverages the power of modern Mixed Integer Optimization (MIO) solvers to easily define steady-state metabolic optimization problems, from simple Flux Balance Analysis (FBA) simulations, to more complex problems, such as sparse FBA or context-specific reconstruction algorithms, and solve them the required level of optimality . It supports many free and commercial solvers thanks to the integration with the PICOS and the Python-MIP . It is also compatible and complementary to cobrapy . Here is a simple example of the differences of implementing from scratch a simple Flux Balance Analysis (FBA), which is typically implemented as a Linear Program (LP) problem, and the Sparse FBA problem which is an Integer Programmming (IP) problem that solves the same FBA problem but minimizing the number of active reactions: FBA (LP) import miom model = ( miom . load ( '@BiGG/Recon3D.miom' ) . steady_state () . set_rxn_objective ( 'biomass_reaction' ) . solve ( verbosity = 1 )) print ( \"Optimal flux:\" , model . get_fluxes ( 'biomass_reaction' )) print ( \"Number of active reactions:\" , sum ( abs ( model . get_fluxes ()) > 1e-8 )) Sparse FBA (MIP) import miom model = ( miom . load ( '@BiGG/Recon3D.miom' ) . setup ( opt_tol = 0.05 , verbosity = 1 ) . steady_state () . set_rxn_objective ( 'biomass_reaction' ) . solve () . set_fluxes_for ( 'biomass_reaction' ) . subset_selection ( - 1 ) . solve ()) print ( \"Optimal flux:\" , model . get_fluxes ( 'biomass_reaction' )) print ( \"Number of active reactions:\" , sum ( abs ( model . get_fluxes ()) > 1e-8 )) Note To better understand the meaning of each step, please read the documentation of the BaseModel class , and the complete example in examples/sparse_fba.py .","title":"Introduction"},{"location":"#installation","text":"","title":"Installation"},{"location":"#recommended-installation","text":"The recommended installation with pip using the option all includes PICOS and Python-MIP backends, and the interfaces for GLPK , Gurobi and Mosek : pip install miom[all]","title":"Recommended installation"},{"location":"#minimal-installation","text":"By default, MIOM comes only with the Python-MIP backend and the COIN-OR CBC solver. The minimal installation is perfect to use in online notebooks and for sharing minimal reproducible examples. To install MIOM with minimal dependencies, run: pip install miom","title":"Minimal installation"},{"location":"#full-installation","text":"The full install option of miom comes with all the packages included with the all option, and the additional COBRA package. This adds also support for importing any kind of genome-scale metabolic network supported by cobra with the miom.load_gem() method: pip install miom[full]","title":"Full installation"},{"location":"#installing-cplex","text":"CPLEX is also supported but requires a prior installation of CPLEX in the system with a valid license that cannot be configured through pip . To install MIOM with CPLEX support, follow the instructions on the CPLEX page to install your current version of cplex in your python environment.","title":"Installing CPLEX"},{"location":"#quick-start","text":"","title":"Quick start"},{"location":"#importing-a-genome-scale-metabolic-network-gems","text":"First step is to import a Genome-Scale Metabolic Network. The method load_gem() can be used to import a network from a local file or a URL. This method requires the cobrapy and scipy packages to import networks in the SBML, YAML, JSON, and Matlab formats (see Full install ). Here is an example of importing the BiGG Recon3D network: import miom network = miom . load_gem ( 'https://github.com/SBRG/bigg_models_data/raw/master/models/Recon3D.mat' ) print ( \"Number of reactions in the network:\" , network . num_reactions ) By default, MIOM uses its own format (.miom) which is a lightweight, compressed and portable format based on numpy structured arrays to store only the essential information required to perform common tasks. To improve reproducibility of experiments, a repository of already converted models is available at pablormier/miom-gems . Any model from this repository can be imported using shorthand links in the following forma: @relative/path/to/model . For example, in order to import the Human-GEM v1.9.0 , you only need to run: network = miom . load_gem ( '@SysBioChalmers/Human-Gem/v1.9.0' ) This is a very convenient way of importing models and sharing reproducible experiments , making sure that other users are going to test the same models.","title":"Importing a Genome-Scale Metabolic Network (GEMs)"},{"location":"#managing-metabolic-networks","text":"MIOM is not intended to provide functions for creating and managing metabolic networks, since there are already other libraries for this purpose (e.g. cobrapy ). If you rely on cobrapy for model manipulation, you can still use MIOM for the optimization after you prepare your metabolic network, as MIOM is nicely integrated with COBRA: from cobra.test import create_test_model network = create_test_model ( \"textbook\" ) medium = network . medium medium [ \"EX_o2_e\" ] = 0.0 network . medium = medium # Use MIOM for optimization flux = ( miom . load ( miom . mio . cobra_to_miom ( network )) . steady_state () . set_rxn_objective ( 'Biomass_Ecoli_core' ) . solve () . get_fluxes ( 'Biomass_Ecoli_core' )) Metabolic Networks in MIOM are represented by a miom.mio.MiomNetwork class. This class encodes the network into three matrices: R (reactions), S (stoichiometry), and M (metabolites). The R matrix is a numpy structured array that contains the list of the reactions defined in the network, including the reaction ID, the reaction name, the reaction bounds, the subsystem and the Gene-Protein-Rules: >>> miom . load_gem ( '@BiGG/Recon3D.miom' ) . R [: 5 ] array ([( '10FTHF5GLUtl' , '5-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' ), ( '10FTHF5GLUtm' , '5-Glutamyl-10Fthf Transport, Mitochondrial' , 0. , 1000. , 'Transport, mitochondrial' , '' ), ( '10FTHF6GLUtl' , '6-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' ), ( '10FTHF6GLUtm' , '6-Glutamyl-10Fthf Transport, Mitochondrial' , 0. , 1000. , 'Transport, mitochondrial' , '' ), ( '10FTHF7GLUtl' , '7-Glutamyl-10Fthf Transport, Lysosomal' , 0. , 1000. , 'Transport, lysosomal' , '' )], dtype = [( 'id' , 'O' ), ( 'name' , 'O' ), ( 'lb' , '= 0 ) # Add the constraint that the sum through all non-reversible reactions is less than or equal to 10 # (note that both PICOS and Python-MIP are symbolic, and expressions involving the variables are allowed) constraint = sum ( model . variables . fluxvars [ i ] for i in non_reversible ) <= 10 # Add to the model and solve model . add_constraint ( constraint ) . solve ( verbosity = 1 ) Starting solution of the Linear programming problem using Dual Simplex Coin0506I Presolve 2242 (-3594) rows, 6144 (-4456) columns and 33659 (-12128) elements Clp0014I Perturbing problem by 0.001% of 1.9797539 - largest nonzero change 1.4130091e-06 ( 7.1372964e-05%) - largest zero change 1.412981e-06 Clp0006I 0 Obj 0.0015868455 Primal inf 3303572.7 (1175) Dual inf 1.9797525 (1) Clp0000I Optimal - objective value 9.062223 Coin0511I After Postsolve, objective 9.062223, infeasibilities - dual 0 (0), primal 0 (0) Clp0032I Optimal objective 9.062223036 - 1675 iterations time 0.142, Presolve 0.07 By default, an optimization model is mutable. This means that every time a method that modifies the model is invoked, the original model is modified. For example, the set_flux_bounds() method modifies the bounds of the reactions in the model. If you want to create a copy of the model, you can use the copy() method to create a full copy of the model.","title":"Constraint-based optimization problems"},{"location":"#mixed-integer-optimization","text":"Many constraint-based metabolic problems consist of selecting a subset of reactions from a generic metabolic network, subject to some biological-based constraints. For example, Sparse FBA consists of selecting the minimum number of active reactions that lead to a desired optimal flux. Context-specific network reconstruction methods such as iMAT, Fastcore, mCADRE, MBA, etc., have also the same purpose: select a subset of reactions from a network based on some experimental data and some objective function. All these problems are instances of a more general problem, known as best subset selection problem , which can be modelled using Mixed Integer Optimization (MIO) . However, instances of this problem are usually hard to solve, and some implementations like Fastcore or MBA use different heuristics or relaxations to find sub-optimal solutions in short time. Unfortunately, there are a few problems with these type of approximations. First, we don't know how good is the solution obtained, and in practice many studies that use those methods assume that the solution they obtained is the best one. Second, even though most of these techniques solve the same type of problem, they look very different or hard to understand for practitioners. Third, many of these implementations do not exploit the potential of the modern MIO solvers which are nowadays able to solve very large problems in a short time, and to adjust the desired level of optimality, which gives the user an idea of how good is the solution obtained. MIOM incorporates specific methods to easily model and solve such problems. Just by calling the method subset_selection() , which takes as input a weight for all reactions or a list of weights for each reaction, it transforms the current problem into a best subset selection problem, in which the objective function is the sum of the weights of the reactions in the solution (where positive weighted reactions contribute to the objective function if they are selected, and negative weighted reactions contribute to the objective function if they are not selected). This simple method makes it possible to model a wide variety of complex constraint-based optimization problems. See for example how easy it is to implement the exact version of the weighted Fastcore with MIOM: import miom import numpy as np # Use the flux-consistent subnetwork (fcm) of the Human1 GEM model # NOTE: Fastcore requires that reactions in the core are flux consistent, # otherwise the problem would be infeasible. m = miom . load_gem ( '@homo_sapiens_human1_fcm.miom' ) # Select reactions from the cholesterol metabolism as the core reactions to keep core_rxn = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) # Assign a negative weight for reactions not in the core weights = - 1 * np . ones ( m . num_reactions ) weights [ core_rxn == 1 ] = 1 fmc = ( miom . load ( m ) . setup ( opt_tol = 0.05 , verbosity = 1 ) . steady_state () . subset_selection ( weights ) . keep ( core_rxn == 1 ) . solve () . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( fmc . num_reactions )","title":"Mixed Integer Optimization"},{"location":"#advantages","text":"It's flexible: MIOM uses the PICOS and the Python-MIP libraries, which means you can use any solver supported by those libraries. It's easy to extend: MIOM is written in pure python, so you can easily extend it to solve more complex optimization problems. It makes the problem explicit: MIOM uses a declarative way to express the problem, so you can easily read and understand what you are solving and differences between algorithms. It's fast: MIOM leverages the power of MIO solvers to solve complex optimization problems. You can control the quality and speed of the solutions for your problem and get better solutions that the approximations (LP) of the original problem available in other constraint-based modeling libraries. It's lightweight: The library has a small number of dependencies, so it's easy to install and distribute also in HPC environments. It includes a compressed GEM format : MIOM can load and save the minimal information of the metabolic networks required for performing simulations into a compressed file compatible with numpy. The small size of the files allows you to quickly run online experiments so other people can reproduce your results. It also supports SBML and matlab formats if cobratoolbox is installed. It's open-source: MIOM is open-source and free to use. You can contribute to the development of MIOM by forking the repository and sending pull requests.","title":"Advantages"},{"location":"#documentation","text":"The documentation of the library can be found at https://metexplore.github.io/miom/","title":"Documentation"},{"location":"#how-to-cite","text":"Manuscript in progress","title":"How to cite"},{"location":"#license","text":"GNU General Public License v3.0","title":"License"},{"location":"examples/fastcore/","text":"Exact Fastcore (MIP) Example of implementation of the Fastcore algorithm with MIOM to extract a context specific model. Fastcore defines a set of core reactions that is forced to be active (carry a non-zero flux in steady state conditions), and minimizes the set of non-core reactions. Cite Vlassis, Pacheco, Sauter (2014). Fast reconstruction of compact context-specific metbolic network models. PLoS Comput. Biol. 10, e1003424 . The Fastcore algorithm is greedy approximation of the exact problem which can be modelled as a MIP problem. With MIOM, the exact problem can be defined in a few lines, using the opt_tol parameter to control the level of optimality required: import miom import numpy as np # Use the flux-consistent subnetwork of the Human1 GEM model, available in the repository m = miom . load_gem ( '@SysBioChalmers/Human-GEM/v1.9.0/consistent' ) # Select reactions from the cholesterol metabolism as the core reactions to keep core_rxn = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) print ( sum ( core_rxn )) # Assign a negative weight for reactions not in the core weights = - 1 * np . ones ( m . num_reactions ) weights [ core_rxn == 1 ] = 1 # Exact-Fastcore fmc = ( miom . load ( m , solver = miom . Solvers . GUROBI ) . setup ( opt_tol = 0.02 ) . steady_state () . subset_selection ( weights ) . keep ( core_rxn == 1 ) . solve ( verbosity = 1 ) . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( fmc . num_reactions ) Note that the algorithm requires that the metabolic network used is flux consistent. If blocked reactions are included in the core set, the MIP becomes infeasible, as those reactions cannot be selected with a non-zero flux in steady state conditions. MIOM includes an implementation of the swiftcc algorithm to obtain flux consistent metabolic networks: Cite Tefagh, M., & Boyd, S. P. (2020). SWIFTCORE: a tool for the context-specific reconstruction of genome-scale metabolic networks. BMC bioinformatics, 21(1), 1-14. DOI: 10.1186/s12859-020-3440-y . from miom.tools import consistent_subnetwork # Get the consistent subnetwork and the lp problem solved by swiftcc consistent , lp = consistent_subnetwork ( m )","title":"Exact Fastcore (MIP)"},{"location":"examples/fastcore/#exact-fastcore-mip","text":"Example of implementation of the Fastcore algorithm with MIOM to extract a context specific model. Fastcore defines a set of core reactions that is forced to be active (carry a non-zero flux in steady state conditions), and minimizes the set of non-core reactions. Cite Vlassis, Pacheco, Sauter (2014). Fast reconstruction of compact context-specific metbolic network models. PLoS Comput. Biol. 10, e1003424 . The Fastcore algorithm is greedy approximation of the exact problem which can be modelled as a MIP problem. With MIOM, the exact problem can be defined in a few lines, using the opt_tol parameter to control the level of optimality required: import miom import numpy as np # Use the flux-consistent subnetwork of the Human1 GEM model, available in the repository m = miom . load_gem ( '@SysBioChalmers/Human-GEM/v1.9.0/consistent' ) # Select reactions from the cholesterol metabolism as the core reactions to keep core_rxn = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) print ( sum ( core_rxn )) # Assign a negative weight for reactions not in the core weights = - 1 * np . ones ( m . num_reactions ) weights [ core_rxn == 1 ] = 1 # Exact-Fastcore fmc = ( miom . load ( m , solver = miom . Solvers . GUROBI ) . setup ( opt_tol = 0.02 ) . steady_state () . subset_selection ( weights ) . keep ( core_rxn == 1 ) . solve ( verbosity = 1 ) . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( fmc . num_reactions ) Note that the algorithm requires that the metabolic network used is flux consistent. If blocked reactions are included in the core set, the MIP becomes infeasible, as those reactions cannot be selected with a non-zero flux in steady state conditions. MIOM includes an implementation of the swiftcc algorithm to obtain flux consistent metabolic networks: Cite Tefagh, M., & Boyd, S. P. (2020). SWIFTCORE: a tool for the context-specific reconstruction of genome-scale metabolic networks. BMC bioinformatics, 21(1), 1-14. DOI: 10.1186/s12859-020-3440-y . from miom.tools import consistent_subnetwork # Get the consistent subnetwork and the lp problem solved by swiftcc consistent , lp = consistent_subnetwork ( m )","title":"Exact Fastcore (MIP)"},{"location":"examples/fba/","text":"Flux Balance Analysis (LP) A simple Flux Balance Analysis can be easily defined and solved with any of the commercial or open-source solvers available: import miom # Load the iMM1865 mouse model from the repository network = miom . mio . load_gem ( \"@iMM1865\" ) target = \"BIOMASS_reaction\" flux = ( miom . load ( network ) . steady_state () . set_rxn_objective ( target ) . solve ( verbosity = 1 ) . get_fluxes ( target )) print ( \"Optimal flux is\" , flux )","title":"Flux Balance Analysis (LP)"},{"location":"examples/fba/#flux-balance-analysis-lp","text":"A simple Flux Balance Analysis can be easily defined and solved with any of the commercial or open-source solvers available: import miom # Load the iMM1865 mouse model from the repository network = miom . mio . load_gem ( \"@iMM1865\" ) target = \"BIOMASS_reaction\" flux = ( miom . load ( network ) . steady_state () . set_rxn_objective ( target ) . solve ( verbosity = 1 ) . get_fluxes ( target )) print ( \"Optimal flux is\" , flux )","title":"Flux Balance Analysis (LP)"},{"location":"examples/imat/","text":"iMAT: Integrative Metabolic Analysis Tool (MIP) Example implementation of iMAT using MIOM. Note that this implementation supports also custom weights for the reactions. By default, weights for reactions in the \"active\" set are set to 1, and reactions in the \"inactive\" set are set to -1, so the objective function is exactly the same as the original iMAT. Cite Shlomi, T., Cabili, M. N., Herrg\u00e5rd, M. J., Palsson, B. \u00d8., & Ruppin, E. (2008). Network-based prediction of human tissue-specific metabolism. Nature biotechnology, 26(9), 1003-1010 . import miom # Use the iHuman-GEM model m = miom . load_gem ( '@SysBioChalmers/Human-GEM/v1.9.0' ) # Add all the reactions from the Cholesterol pathway to the highly expressed set RH = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) # Add reactions from the pyruvate metabolism to the lowly expressed set RL = - 1 * m . find_reactions_from_pathway ( \"Pyruvate metabolism\" ) w = RH + RL print ( \"RH:\" , sum ( RH ), \"RL:\" , sum ( abs ( RL ))) m = ( miom . load ( m , solver = miom . Solvers . GUROBI ) . setup ( int_tol = 1e-8 , opt_tol = 0.01 , verbosity = 1 ) . steady_state () . subset_selection ( w ) . solve ( max_seconds = 30 ) . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( m . num_reactions )","title":"iMAT: Integrative Metabolic Analysis Tool (MIP)"},{"location":"examples/imat/#imat-integrative-metabolic-analysis-tool-mip","text":"Example implementation of iMAT using MIOM. Note that this implementation supports also custom weights for the reactions. By default, weights for reactions in the \"active\" set are set to 1, and reactions in the \"inactive\" set are set to -1, so the objective function is exactly the same as the original iMAT. Cite Shlomi, T., Cabili, M. N., Herrg\u00e5rd, M. J., Palsson, B. \u00d8., & Ruppin, E. (2008). Network-based prediction of human tissue-specific metabolism. Nature biotechnology, 26(9), 1003-1010 . import miom # Use the iHuman-GEM model m = miom . load_gem ( '@SysBioChalmers/Human-GEM/v1.9.0' ) # Add all the reactions from the Cholesterol pathway to the highly expressed set RH = m . find_reactions_from_pathway ( \"Cholesterol metabolism\" ) # Add reactions from the pyruvate metabolism to the lowly expressed set RL = - 1 * m . find_reactions_from_pathway ( \"Pyruvate metabolism\" ) w = RH + RL print ( \"RH:\" , sum ( RH ), \"RL:\" , sum ( abs ( RL ))) m = ( miom . load ( m , solver = miom . Solvers . GUROBI ) . setup ( int_tol = 1e-8 , opt_tol = 0.01 , verbosity = 1 ) . steady_state () . subset_selection ( w ) . solve ( max_seconds = 30 ) . select_subnetwork ( mode = miom . ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = miom . Comparator . GREATER_OR_EQUAL , value = 1e-8 ) . network ) print ( m . num_reactions )","title":"iMAT: Integrative Metabolic Analysis Tool (MIP)"},{"location":"examples/sparse_fba/","text":"Sparse FBA (MIP) The sparse FBA problem consists of finding the optimal flux value for a reaction minimizing the number of reactions with non-zero flux (l0-norm sparsity). Note that minimizing the l0-norm is a NP-hard problem, and so obtaing an optimal solution is not possible in many cases. The COBRA Toolbox includes different LP heuristics to minimize different approximations of the l0-norm. However, using a MIO formulation, it's is possible to obtain a solution which is close to optimal, with a lower number of reactions than the LP approximations, and very quickly. Here is the implementation of sparse-FBA with MIOM: import miom # Load a genome-scale metabolic network. You can load SMBL or Matlab metabolic networks # as well using the same method, but it requires to have the cobratoolbox python library # installed. network = miom . load_gem ( \"@iMM1865\" ) # Create the sparse FBA problem to get a solution that maximizes # the optimal flux through the BIOMASS_reaction minimizing the # number of active reactions. The solution should be not more than # 5% of the optimal solution (opt_tol = 0.05). V , X = ( miom . load ( network , solver = miom . Solvers . GUROBI_PYMIP ) # Set-up the solver options . setup ( int_tol = 1e-8 , opt_tol = 0.05 , verbosity = 1 ) # Add the steady-state constraints (S*V = 0) . steady_state () # Set the reaction to optimize using FBA . set_rxn_objective ( 'BIOMASS_reaction' ) # Solve the FBA (LP) problem (optimal flux) . solve () # Add a constraint to force a flux through # the reaction equal to the optimal flux . set_fluxes_for ( 'BIOMASS_reaction' ) # Convert to a MIO problem (best subset selection) # Each reaction in the network is associated # with a negative weight of -1. The optimization # problem now tries to minimize the selection of # reactions with negative weights (respecting # the previous constraints). Since each reaction # has a weight of -1, all reactions are equally # important in the optimization problem. # This is exactly the optimal sparse-FBA problem # with l0-norm: minimize the number of reactions # but mantaining the optimal FBA flux possible. . subset_selection ( - 1 ) # Solve the MIO problem (note that it's NP-Hard) # You can control the optimality by changing the # opt_tol in the .setup() method. . solve () # Return the flux values (V) and the binary # indicator values (X) . get_values ()) # Show reactions with a flux > 1e-8 print ( \"Number of reactions with flux above +/- 1e-8:\" , sum ( abs ( V ) > 1e-8 )) # Count reactions with an indicator value of 0 (active). Note that since # the weights of the reactions are negative (for all rxns), an indicator # value of 1 corresponds to a succesful removed reaction not included in # the solution, and a value of 0 to a reaction that could not be removed. print ( \"Indicator variables with a value of 1 (selected rxns):\" , sum ( X < 0.5 )) # Show the flux value of the biomass reaction print ( \"Optimal biomass flux:\" , V [ m . get_reaction_id ( \"BIOMASS_reaction\" )], \"mmol/(h\u00b7gDW)\" )","title":"Sparse FBA (MIP)"},{"location":"examples/sparse_fba/#sparse-fba-mip","text":"The sparse FBA problem consists of finding the optimal flux value for a reaction minimizing the number of reactions with non-zero flux (l0-norm sparsity). Note that minimizing the l0-norm is a NP-hard problem, and so obtaing an optimal solution is not possible in many cases. The COBRA Toolbox includes different LP heuristics to minimize different approximations of the l0-norm. However, using a MIO formulation, it's is possible to obtain a solution which is close to optimal, with a lower number of reactions than the LP approximations, and very quickly. Here is the implementation of sparse-FBA with MIOM: import miom # Load a genome-scale metabolic network. You can load SMBL or Matlab metabolic networks # as well using the same method, but it requires to have the cobratoolbox python library # installed. network = miom . load_gem ( \"@iMM1865\" ) # Create the sparse FBA problem to get a solution that maximizes # the optimal flux through the BIOMASS_reaction minimizing the # number of active reactions. The solution should be not more than # 5% of the optimal solution (opt_tol = 0.05). V , X = ( miom . load ( network , solver = miom . Solvers . GUROBI_PYMIP ) # Set-up the solver options . setup ( int_tol = 1e-8 , opt_tol = 0.05 , verbosity = 1 ) # Add the steady-state constraints (S*V = 0) . steady_state () # Set the reaction to optimize using FBA . set_rxn_objective ( 'BIOMASS_reaction' ) # Solve the FBA (LP) problem (optimal flux) . solve () # Add a constraint to force a flux through # the reaction equal to the optimal flux . set_fluxes_for ( 'BIOMASS_reaction' ) # Convert to a MIO problem (best subset selection) # Each reaction in the network is associated # with a negative weight of -1. The optimization # problem now tries to minimize the selection of # reactions with negative weights (respecting # the previous constraints). Since each reaction # has a weight of -1, all reactions are equally # important in the optimization problem. # This is exactly the optimal sparse-FBA problem # with l0-norm: minimize the number of reactions # but mantaining the optimal FBA flux possible. . subset_selection ( - 1 ) # Solve the MIO problem (note that it's NP-Hard) # You can control the optimality by changing the # opt_tol in the .setup() method. . solve () # Return the flux values (V) and the binary # indicator values (X) . get_values ()) # Show reactions with a flux > 1e-8 print ( \"Number of reactions with flux above +/- 1e-8:\" , sum ( abs ( V ) > 1e-8 )) # Count reactions with an indicator value of 0 (active). Note that since # the weights of the reactions are negative (for all rxns), an indicator # value of 1 corresponds to a succesful removed reaction not included in # the solution, and a value of 0 to a reaction that could not be removed. print ( \"Indicator variables with a value of 1 (selected rxns):\" , sum ( X < 0.5 )) # Show the flux value of the biomass reaction print ( \"Optimal biomass flux:\" , V [ m . get_reaction_id ( \"BIOMASS_reaction\" )], \"mmol/(h\u00b7gDW)\" )","title":"Sparse FBA (MIP)"},{"location":"references/mio/","text":"mio.py MiomNetwork A minimal class to store a metabolic network. Attributes: Name Type Description S numpy.ndarray stoichiometric matrix R numpy.ndarray Structured array with the reactions. The fields are: - id (int): reaction ID - lb (float): lower bound - ub (float): upper bound - subsystem (str): subsystem - gpr (str): gene-protein-reaction rule M numpy.ndarray Structured array with the metabolites. The fields are: - id (int): metabolite ID - name (str): metabolite name - formula (str): metabolite formula num_reactions property readonly Number of reactions in the network. Returns: Type Description int Number of reactions find_reaction ( self , rxn_id ) Find a particular reaction in the metabolic network. Parameters: Name Type Description Default rxn_id str Name of the reaction required Returns: Type Description numpy.ndarray Structured array with the information of the reaction. Source code in miom/mio.py def find_reaction ( self , rxn_id ): \"\"\"Find a particular reaction in the metabolic network. Args: rxn_id (str): Name of the reaction Returns: numpy.ndarray: Structured array with the information of the reaction. \"\"\" return MiomNetwork . _find_reaction ( rxn_id , self . R ) export_gem ( miom_network , path_to_exported_file ) Export a miom network to a file in the miom format. Parameters: Name Type Description Default miom_network MiomNetwork an instance of a MiomNetwork required path_to_exported_file str Path to the exported file (e.g. /path/to/file.miom) required Source code in miom/mio.py def export_gem ( miom_network , path_to_exported_file ): \"\"\"Export a miom network to a file in the miom format. Args: miom_network (MiomNetwork): an instance of a MiomNetwork path_to_exported_file (str): Path to the exported file (e.g. /path/to/file.miom) \"\"\" import lzma with io . BytesIO () as npz : np . savez_compressed ( npz , S = miom_network . S , reactions = miom_network . R , metabolites = miom_network . M ) compressed = lzma . compress ( npz . getbuffer ()) # Store to file with open ( path_to_exported_file , 'wb' ) as f_out : f_out . write ( compressed ) load_gem ( model_or_path ) Load a metabolic network from a file or URL. The method supports any format supported by cobrapy (.xml, .yml, .json, .mat) or a miom compressed model (.miom) from a url or a local file path. For the cobra supported formats, you need the cobrapy package installed, and for .mat files, you need both cobrapy and scipy installed. Parameters: Name Type Description Default model_or_path str Path to a local file or URL pointing to the metabolic network. If the string starts with '@', the file will be loaded from the default github repository. required Returns: Type Description MiomNetwork A MiomNetwork instance with the minimal information of the metabolic network required for simulations. It includes the stoichiometric matrix, the list of reactions with the lower and upper bounds, the associated genes and GPR rules, and the list of metabolites. Source code in miom/mio.py def load_gem ( model_or_path ): \"\"\"Load a metabolic network from a file or URL. The method supports any format supported by cobrapy (.xml, .yml, .json, .mat) or a miom compressed model (.miom) from a url or a local file path. For the cobra supported formats, you need the cobrapy package installed, and for .mat files, you need both cobrapy and scipy installed. Args: model_or_path (str): Path to a local file or URL pointing to the metabolic network. If the string starts with '@', the file will be loaded from the default github repository. Returns: MiomNetwork: A [MiomNetwork][miom.mio] instance with the minimal information of the metabolic network required for simulations. It includes the stoichiometric matrix, the list of reactions with the lower and upper bounds, the associated genes and GPR rules, and the list of metabolites. \"\"\" extensions = [ '.xml' , '.yml' , '.json' , '.mat' , '.miom' ] if isinstance ( model_or_path , str ): file = model_or_path if model_or_path . startswith ( \"@\" ): # Check if the file has a valid file extension if not any ( file . endswith ( ext ) for ext in extensions ): # Assume is a relative url pointing to a version file = _download ( DEFAULT_REPOSITORY + model_or_path [ 1 :] + \"/default.miom\" ) else : file = _download ( DEFAULT_REPOSITORY + model_or_path [ 1 :]) elif _is_url ( model_or_path ): file = _download ( model_or_path ) ext = pathlib . Path ( file ) . suffix if ext == '.miom' or ext == '.xz' or ext == '.npz' : return _load_compressed_model ( file ) else : return cobra_to_miom ( _read_cobra_model ( file )) else : return cobra_to_miom ( model_or_path )","title":"mio.py"},{"location":"references/mio/#miopy","text":"","title":"mio.py"},{"location":"references/mio/#miom.mio.MiomNetwork","text":"A minimal class to store a metabolic network. Attributes: Name Type Description S numpy.ndarray stoichiometric matrix R numpy.ndarray Structured array with the reactions. The fields are: - id (int): reaction ID - lb (float): lower bound - ub (float): upper bound - subsystem (str): subsystem - gpr (str): gene-protein-reaction rule M numpy.ndarray Structured array with the metabolites. The fields are: - id (int): metabolite ID - name (str): metabolite name - formula (str): metabolite formula","title":"MiomNetwork"},{"location":"references/mio/#miom.mio.MiomNetwork.num_reactions","text":"Number of reactions in the network. Returns: Type Description int Number of reactions","title":"num_reactions"},{"location":"references/mio/#miom.mio.MiomNetwork.find_reaction","text":"Find a particular reaction in the metabolic network. Parameters: Name Type Description Default rxn_id str Name of the reaction required Returns: Type Description numpy.ndarray Structured array with the information of the reaction. Source code in miom/mio.py def find_reaction ( self , rxn_id ): \"\"\"Find a particular reaction in the metabolic network. Args: rxn_id (str): Name of the reaction Returns: numpy.ndarray: Structured array with the information of the reaction. \"\"\" return MiomNetwork . _find_reaction ( rxn_id , self . R )","title":"find_reaction()"},{"location":"references/mio/#miom.mio.export_gem","text":"Export a miom network to a file in the miom format. Parameters: Name Type Description Default miom_network MiomNetwork an instance of a MiomNetwork required path_to_exported_file str Path to the exported file (e.g. /path/to/file.miom) required Source code in miom/mio.py def export_gem ( miom_network , path_to_exported_file ): \"\"\"Export a miom network to a file in the miom format. Args: miom_network (MiomNetwork): an instance of a MiomNetwork path_to_exported_file (str): Path to the exported file (e.g. /path/to/file.miom) \"\"\" import lzma with io . BytesIO () as npz : np . savez_compressed ( npz , S = miom_network . S , reactions = miom_network . R , metabolites = miom_network . M ) compressed = lzma . compress ( npz . getbuffer ()) # Store to file with open ( path_to_exported_file , 'wb' ) as f_out : f_out . write ( compressed )","title":"export_gem()"},{"location":"references/mio/#miom.mio.load_gem","text":"Load a metabolic network from a file or URL. The method supports any format supported by cobrapy (.xml, .yml, .json, .mat) or a miom compressed model (.miom) from a url or a local file path. For the cobra supported formats, you need the cobrapy package installed, and for .mat files, you need both cobrapy and scipy installed. Parameters: Name Type Description Default model_or_path str Path to a local file or URL pointing to the metabolic network. If the string starts with '@', the file will be loaded from the default github repository. required Returns: Type Description MiomNetwork A MiomNetwork instance with the minimal information of the metabolic network required for simulations. It includes the stoichiometric matrix, the list of reactions with the lower and upper bounds, the associated genes and GPR rules, and the list of metabolites. Source code in miom/mio.py def load_gem ( model_or_path ): \"\"\"Load a metabolic network from a file or URL. The method supports any format supported by cobrapy (.xml, .yml, .json, .mat) or a miom compressed model (.miom) from a url or a local file path. For the cobra supported formats, you need the cobrapy package installed, and for .mat files, you need both cobrapy and scipy installed. Args: model_or_path (str): Path to a local file or URL pointing to the metabolic network. If the string starts with '@', the file will be loaded from the default github repository. Returns: MiomNetwork: A [MiomNetwork][miom.mio] instance with the minimal information of the metabolic network required for simulations. It includes the stoichiometric matrix, the list of reactions with the lower and upper bounds, the associated genes and GPR rules, and the list of metabolites. \"\"\" extensions = [ '.xml' , '.yml' , '.json' , '.mat' , '.miom' ] if isinstance ( model_or_path , str ): file = model_or_path if model_or_path . startswith ( \"@\" ): # Check if the file has a valid file extension if not any ( file . endswith ( ext ) for ext in extensions ): # Assume is a relative url pointing to a version file = _download ( DEFAULT_REPOSITORY + model_or_path [ 1 :] + \"/default.miom\" ) else : file = _download ( DEFAULT_REPOSITORY + model_or_path [ 1 :]) elif _is_url ( model_or_path ): file = _download ( model_or_path ) ext = pathlib . Path ( file ) . suffix if ext == '.miom' or ext == '.xz' or ext == '.npz' : return _load_compressed_model ( file ) else : return cobra_to_miom ( _read_cobra_model ( file )) else : return cobra_to_miom ( model_or_path )","title":"load_gem()"},{"location":"references/miom/","text":"miom.py BaseModel Base class for building LP/MIP optimization models using a high-level API for metabolic problems. It implements the chainable methods to set-up a LP/MIP metabolic network problem. Two implementations are available: PicosModel and PythonMipModel. The PicosModel uses the PICOS library as a backend to interact with different solvers. The PythonMipModel uses the Python-MIP library to solve the model using the CBC or GUROBI solvers. Note Do not try to instantiate this class directly. Use the load() function instead. The method automatically selects the right implementation depending on the solver. add_constraint ( self , constraint ) Add a specific constraint to the model. The constraint should use existing variables already included in the model. Parameters: Name Type Description Default constraint affine expression using model's variables. required Source code in miom/miom.py @_composable def add_constraint ( self , constraint ): \"\"\"Add a specific constraint to the model. The constraint should use existing variables already included in the model. Args: constraint: affine expression using model's variables. \"\"\" pass add_constraints ( self , constraints ) Add a list of constraint to the model Parameters: Name Type Description Default constraints list List of expressions with the constraints. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def add_constraints ( self , constraints ): \"\"\"Add a list of constraint to the model Args: constraints (list): List of expressions with the constraints. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" for c in constraints : self . add_constraint ( c ) return len ( constraints ) > 0 exclude ( self , indicator_values = None ) Exclude a solution from the set of feasible solutions. If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730 Parameters: Name Type Description Default indicator_values list List of values for each indicator variable. Defaults to None. None Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def exclude ( self , indicator_values = None ): \"\"\"Exclude a solution from the set of feasible solutions. If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730 Args: indicator_values (list, optional): List of values for each indicator variable. Defaults to None. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . variables . indicators is None : raise ValueError ( \"\"\"The optimization model does not contain indicator variables. Make sure that the problem is a subset selection problem.\"\"\" ) if indicator_values is None : indicator_values = np . array ( self . variables . indicator_values ) return dict ( indicator_values = indicator_values ) fix_fluxes ( self , reactions , tolerance = 1e-06 ) Force the flux of certain reactions to match current values. After calling .solve() for a flux optimization problem (e.g. FBA), this method adds a new constraint to force the flux of the given reactions to match the current flux values found after the optimization. This is interesting for example to implement methods like sparse-FBA, where the optimization is no longer the flux but the number of active reactions, and a new constraint is required to preserve optimality of fluxes. Parameters: Name Type Description Default reactions list reaction or list of reactions required tolerance float Tolerance for the flux values (a solution is valid if the flux is within optimal value +/- tol. Defaults to 1e-6. 1e-06 Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py def fix_fluxes ( self , reactions , tolerance = 1e-6 ): \"\"\"Force the flux of certain reactions to match current values. After calling `.solve()` for a flux optimization problem (e.g. FBA), this method adds a new constraint to force the flux of the given reactions to match the current flux values found after the optimization. This is interesting for example to implement methods like sparse-FBA, where the optimization is no longer the flux but the number of active reactions, and a new constraint is required to preserve optimality of fluxes. Args: reactions (list): reaction or list of reactions tolerance (float, optional): Tolerance for the flux values (a solution is valid if the flux is within optimal value +/- tol. Defaults to 1e-6. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if isinstance ( reactions , str ): reactions = [ reactions ] for rid in reactions : if isinstance ( rid , np . ndarray ): # TODO: Test this path rid = rid [ 'id' ] idx , rxn = self . network . find_reaction ( rid ) lb = max ( rxn [ 'lb' ], self . variables . flux_values [ idx ] - tolerance ) ub = min ( rxn [ 'ub' ], self . variables . flux_values [ idx ] + tolerance ) self . add_constraint ( self . variables . fluxvars [ idx ] >= lb ) self . add_constraint ( self . variables . fluxvars [ idx ] <= ub ) return self get_fluxes ( self , reactions = None ) Get the flux values. Parameters: Name Type Description Default reactions list Reaction or subset of reactions For which to obtain the flux values. Defaults to None. None Returns: Type Description list List with the flux values for all or the selected reactions. Source code in miom/miom.py def get_fluxes ( self , reactions = None ): \"\"\"Get the flux values. Args: reactions (list, optional): Reaction or subset of reactions For which to obtain the flux values. Defaults to None. Returns: list: List with the flux values for all or the selected reactions. \"\"\" if isinstance ( reactions , str ): return self . variables . flux_values [ self . network . get_reaction_id ( reactions )] if isinstance ( reactions , Iterable ): return { r [ 'id' ]: self . variables . flux_values [ self . network . get_reaction_id ( r [ 'id' ])] for r in reactions } if reactions is None : return self . variables . flux_values else : raise ValueError ( \"reactions should be an iterable of strings or a single string\" ) get_values ( self ) Get the values for the variables Returns: Type Description tuple (V, X) where V are the flux values and X are the indicator values (if the problem is a MIP problem, for example if subset_selection was called) Source code in miom/miom.py def get_values ( self ): \"\"\"Get the values for the variables Returns: tuple: (V, X) where V are the flux values and X are the indicator values (if the problem is a MIP problem, for example if `subset_selection` was called) \"\"\" return self . variables . values () keep ( self , reactions ) Force the inclusion of a list of reactions in the solution. Reactions have to be associated with positive weights in order to keep them in the final solution. Note that once keep() is called, the weights associated to the reactions selected to be kept will not be taken into account, as they will be forced to be kept in the solution. Parameters: Name Type Description Default reactions list List of reaction names, a binary vector indicating the reactions to keep, or a list of indexes with the reactions to keep. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def keep ( self , reactions ): \"\"\"Force the inclusion of a list of reactions in the solution. Reactions have to be associated with positive weights in order to keep them in the final solution. Note that once keep() is called, the weights associated to the reactions selected to be kept will not be taken into account, as they will be forced to be kept in the solution. Args: reactions (list): List of reaction names, a binary vector indicating the reactions to keep, or a list of indexes with the reactions to keep. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . variables . indicators is None : raise ValueError ( \"\"\"No indicator variables for reactions, transform it to a subset selection problem calling subset_selection first, providing positive weights for the reactions you want to keep.\"\"\" ) if reactions is None or len ( reactions ) == 0 : return False if isinstance ( reactions , str ): reactions = [ reactions ] # Check if it's a binary vector if len ( reactions ) == self . network . num_reactions and max ( reactions ) == 1 : reactions = np . where ( reactions == 1 )[ 0 ] # Check if the reactions have an indicator variable reactions = set ( self . network . find_reaction ( rxn )[ 0 ] for rxn in reactions ) available = set ( rxn . index for rxn in self . variables . assigned_reactions if rxn . cost > 0 ) diff = reactions - available if len ( diff ) != 0 : raise ValueError ( f \"\"\"Only reactions associated with positive weights can be forced to be selected. The following reaction indexes have no indicator variables or are associated with negative weights: { diff } .\"\"\" ) valid_rxn_idx = reactions & available # Get the indexes of the indicator variables idxs = [ i for i , r in enumerate ( self . variables . assigned_reactions ) if r . index in valid_rxn_idx ] return dict ( idxs = idxs , valid_rxn_idx = valid_rxn_idx ) obtain_subnetwork ( self , extraction_mode =< ExtractionMode . ABSOLUTE_FLUX_VALUE : 'flux_value' > , comparator =< Comparator . GREATER_OR_EQUAL : 'geq' > , value = 1e-08 ) Same as select_subnetwork but returns the network instead. See select_subnetwork for a detailed description of the method. Returns: Type Description MiomNetwork A MiomNetwork with the selected subnetwork. Source code in miom/miom.py def obtain_subnetwork ( self , extraction_mode = ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = Comparator . GREATER_OR_EQUAL , value = 1e-8 ): \"\"\"Same as [select_subnetwork][miom.miom.BaseModel] but returns the network instead. See [select_subnetwork][miom.miom.BaseModel] for a detailed description of the method. Returns: MiomNetwork: A MiomNetwork with the selected subnetwork. \"\"\" # If indicators are present and assigned, # take the subset of the network for which # the indicators of positive weighted reactions # are equal to 1 if extraction_mode == ExtractionMode . ABSOLUTE_FLUX_VALUE : variables = self . variables . flux_values if variables is None : raise ValueError ( \"The model does not contain flux variables. \" \"You need to call first steady_state() to add \" \"the flux variables\" ) elif extraction_mode == ExtractionMode . INDICATOR_VALUE : variables = self . variables . indicator_values if variables is None : raise ValueError ( \"The model does not contain indicator variables. \" \"You need to transform it to a subset selection problem \" \"by invoking subset_selection() first.\" ) elif extraction_mode == ExtractionMode . REACTION_ACTIVITY : variables = self . variables . reaction_activity if variables is None : raise ValueError ( \"The model does not contain reaction activity variables. \" \"You need to transform it to a subset selection problem \" \"by invoking subset_selection() first.\" ) else : raise ValueError ( \"Invalid extraction mode\" ) if comparator == Comparator . GREATER_OR_EQUAL : selected = np . where ( np . abs ( variables ) >= value )[ 0 ] elif comparator == Comparator . LESS_OR_EQUAL : selected = np . where ( np . abs ( variables ) <= value )[ 0 ] else : raise ValueError ( \"Invalid comparison\" ) # TODO: Assigned reactions work only for indicator variables if extraction_mode == ExtractionMode . INDICATOR_VALUE : rxns = [ self . variables . assigned_reactions [ x ] for x in selected ] selected_idx = [ rxn . index for rxn in rxns ] elif extraction_mode == ExtractionMode . ABSOLUTE_FLUX_VALUE : selected_idx = selected else : raise NotImplementedError ( \"Only indicator variables and absolute flux values are supported\" ) return self . network . subnet ( selected_idx ) reset ( self ) Resets the original problem (removes all modifications) Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def reset ( self ): \"\"\"Resets the original problem (removes all modifications) Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . problem is None : warnings . warn ( \"Problem is not initialized, nothing to reset\" ) return False else : return True select_subnetwork ( self , mode =< ExtractionMode . ABSOLUTE_FLUX_VALUE : 'flux_value' > , comparator =< Comparator . GREATER_OR_EQUAL : 'geq' > , value = 1e-08 ) Select a subnetwork and create a new BaseModel to operate on it. The new instance of the BaseModel is a new problem instance with no constraints. If the idea is to perform FBA simulations on this new subnetwork, remember to add the new constraints, especially the steady_state . Parameters: Name Type Description Default mode ExtractionMode Method used to extract the subnetwork (based on flux values or using the indicator values). Defaults to ExtractionMode.ABSOLUTE_FLUX_VALUE.  comparator Comparator Comparator for the selected mode. Defaults to Comparator.GREATER_OR_EQUAL.  value float Value threshold for the mode and comparator selected. Defaults to 1e-8. 1e-08 Returns: Type Description [type] [description] Source code in miom/miom.py @_composable def select_subnetwork ( self , mode = ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = Comparator . GREATER_OR_EQUAL , value = 1e-8 ): \"\"\"Select a subnetwork and create a new BaseModel to operate on it. The new instance of the BaseModel is a new problem instance with no constraints. If the idea is to perform FBA simulations on this new subnetwork, remember to add the new constraints, especially the `steady_state`. Args: mode (ExtractionMode, optional): Method used to extract the subnetwork (based on flux values or using the indicator values). Defaults to ExtractionMode.ABSOLUTE_FLUX_VALUE. comparator (Comparator, optional): Comparator for the selected mode. Defaults to Comparator.GREATER_OR_EQUAL. value (float, optional): Value threshold for the mode and comparator selected. Defaults to 1e-8. Returns: [type]: [description] \"\"\" return self . obtain_subnetwork ( extraction_mode = mode , comparator = comparator , value = value ) set_flux_bounds ( self , rxn_id , min_flux = None , max_flux = None ) Change the flux bounds of a reaction. Parameters: Name Type Description Default rxn_id str/int name or id of the reaction to change required min_flux float Min flux value. Defaults to None. None max_flux float Max flux value. Defaults to None. None Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def set_flux_bounds ( self , rxn_id , min_flux = None , max_flux = None ): \"\"\"Change the flux bounds of a reaction. Args: rxn_id (str/int): name or id of the reaction to change min_flux (float, optional): Min flux value. Defaults to None. max_flux (float, optional): Max flux value. Defaults to None. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" i , _ = self . network . find_reaction ( rxn_id ) return i set_objective ( self , cost_vector , variables , direction = 'max' ) Set the optmization objective of the model. Parameters: Name Type Description Default cost_vector Iterable List with the cost for each variable required variables Iterable Variables used for the objective function required direction str Optimization direction (min or max). Defaults to 'max'. 'max' Source code in miom/miom.py @_composable def set_objective ( self , cost_vector , variables , direction = 'max' ): \"\"\"Set the optmization objective of the model. Args: cost_vector (Iterable): List with the cost for each variable variables (Iterable): Variables used for the objective function direction (str, optional): Optimization direction (min or max). Defaults to 'max'. \"\"\" if self . objective is not None : warnings . warn ( \"Previous objective changed\" ) self . objective = ( cost_vector , variables , direction ) set_rxn_objective ( self , rxn , direction = 'max' ) Set a flux objective Maximize or minimize the flux through a given reaction. Parameters: Name Type Description Default rxn str Name of the reaction to use for the optimization required direction str Minimization or maximization of the flux ('min' or 'max'). Defaults to 'max'. 'max' Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py def set_rxn_objective ( self , rxn , direction = 'max' ): \"\"\"Set a flux objective Maximize or minimize the flux through a given reaction. Args: rxn (str): Name of the reaction to use for the optimization direction (str, optional): Minimization or maximization of the flux ('min' or 'max'). Defaults to 'max'. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" i = self . network . get_reaction_id ( rxn ) cost = np . zeros ( self . network . num_reactions ) cost [ i ] = 1 self . set_objective ( cost , self . variables . fluxvars , direction = direction ) return self setup ( self , ** kwargs ) Provide the options for the solver. Attributes: Name Type Description int_tol float Integrality tolerance for integer variables. Defaults to 1e-8. feas_tol float Feasibility tolerance. Defaults to 1e-8. opt_tol float Relative MIP gap tolerance for MIP problems. Defaults to 1e-5. verbosity int Values above 0 force the backends to be verbose. Use a value of 1 to show useful information about the search. Defaults to 0. Returns: Type Description BaseModel the configured instance of the BaseModel Source code in miom/miom.py @_composable def setup ( self , ** kwargs ): \"\"\"Provide the options for the solver. Attributes: int_tol (float): Integrality tolerance for integer variables. Defaults to 1e-8. feas_tol (float): Feasibility tolerance. Defaults to 1e-8. opt_tol (float): Relative MIP gap tolerance for MIP problems. Defaults to 1e-5. verbosity (int): Values above 0 force the backends to be verbose. Use a value of 1 to show useful information about the search. Defaults to 0. Returns: BaseModel: the configured instance of the BaseModel \"\"\" if self . problem is None : warnings . warn ( \"Problem cannot be configured since it was not initialized\" ) return False options = dict () int_tol = kwargs [ \"int_tol\" ] if \"int_tol\" in kwargs else None feas_tol = kwargs [ \"feas_tol\" ] if \"feas_tol\" in kwargs else None opt_tol = kwargs [ \"opt_tol\" ] if \"opt_tol\" in kwargs else None verbosity = kwargs [ \"verbosity\" ] if \"verbosity\" in kwargs else None solver = kwargs [ \"solver\" ] if \"solver\" in kwargs else None if int_tol is not None : options [ \"int_tol\" ] = int_tol if feas_tol is not None : options [ \"feas_tol\" ] = feas_tol if opt_tol is not None : options [ \"opt_tol\" ] = opt_tol if verbosity is not None : options [ \"verbosity\" ] = verbosity if solver is not None : options [ \"solver\" ] = solver self . _options . update ( options ) # Calculate a min eps value to avoid numerical issues self . _options [ \"_min_eps\" ] = np . sqrt ( 2 * self . _options [ \"int_tol\" ]) return self . _options solve ( self , verbosity = None , max_seconds = None ) Solve the current model and assign the values to the variables of the model. Parameters: Name Type Description Default verbosity int Level of verbosity for the solver. Values above 0 will force the backend to show output information of the search. Defaults to None. None max_seconds int Max time in seconds for the search. Defaults to None. None Source code in miom/miom.py @_composable def solve ( self , verbosity = None , max_seconds = None ): \"\"\"Solve the current model and assign the values to the variables of the model. Args: verbosity (int, optional): Level of verbosity for the solver. Values above 0 will force the backend to show output information of the search. Defaults to None. max_seconds (int, optional): Max time in seconds for the search. Defaults to None. \"\"\" self . _last_start_time = perf_counter () steady_state ( self ) Add the required constraints for finding steady-state fluxes The method adds the \\(S * V = 0\\) set of constraints, where \\(S\\) is the stoichiometric matrix and \\(V\\) the flux variables. Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def steady_state ( self ): \"\"\"Add the required constraints for finding steady-state fluxes The method adds the $S * V = 0$ set of constraints, where $S$ is the stoichiometric matrix and $V$ the flux variables. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" pass subset_selection ( self , rxn_weights , direction = 'max' , eps = 0.01 , strengthen = True ) Transform the current model into a subset selection problem. The subset selection problem consists of selecting the positive weighted reactions and remove the negative weighted reactions, subject to steady state constraints and/or additional constraints on fluxes, and maximizing the weighted sum of the (absolute) weights for the successfully selected reactions (with positive weights) and the successfully removed reactions (with negative weights). Selected reactions are forced to have an absolute flux value greater or equal to the threshold eps (1e-2 by default). Removed reactions should have a flux equal to 0. Each reaction is associated with a weight (positive or negative) provided in the parameter rxn_weights , and the objective is to select the reactions that optimizes the following expression: \\[ f(x) = \\sum_i^n |w_i| * x_i \\] where \\(x_i\\) are the indicator variables for the reactions \\(i\\) and \\(w_i\\) are the weights for the reactions associated to the indicator variable. Indicator variables are automatically created for each reaction associated to a non-zero weight. Two (mutually exclusive) indicator variables are used for positive weighted reactions that are reversible to indicate whether there is positive or negative flux through the reaction. A single indicator variable is created for positive weighted non-reversible reactions, to indicate if the reaction is selected (has a non-zero flux greater or equal to eps ) in which case the indicator variable is 1, or 0 otherwise. A single binary indicator variable is also created for negative weighted reactions, indicating whether the reaction was not selected (i.e, has 0 flux, in which case the indicator variable is 1) or not (in which case the indicator variable is 0). Parameters: Name Type Description Default rxn_weights list List of weights for each reaction. If a single value is provided, it is assumed to be the weight for all reactions. required eps float Min absolute flux value for weighted reactions to consider them active or inactive. Defaults to 1e-2. 0.01 Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def subset_selection ( self , rxn_weights , direction = 'max' , eps = 1e-2 , strengthen = True ): \"\"\"Transform the current model into a subset selection problem. The subset selection problem consists of selecting the positive weighted reactions and remove the negative weighted reactions, subject to steady state constraints and/or additional constraints on fluxes, and maximizing the weighted sum of the (absolute) weights for the successfully selected reactions (with positive weights) and the successfully removed reactions (with negative weights). Selected reactions are forced to have an absolute flux value greater or equal to the threshold `eps` (1e-2 by default). Removed reactions should have a flux equal to 0. Each reaction is associated with a weight (positive or negative) provided in the parameter `rxn_weights`, and the objective is to select the reactions that optimizes the following expression: $$ f(x) = \\sum_i^n |w_i| * x_i $$ where $x_i$ are the indicator variables for the reactions $i$ and $w_i$ are the weights for the reactions associated to the indicator variable. Indicator variables are automatically created for each reaction associated to a non-zero weight. Two (mutually exclusive) indicator variables are used for positive weighted reactions that are reversible to indicate whether there is positive or negative flux through the reaction. A single indicator variable is created for positive weighted non-reversible reactions, to indicate if the reaction is selected (has a non-zero flux greater or equal to `eps`) in which case the indicator variable is 1, or 0 otherwise. A single binary indicator variable is also created for negative weighted reactions, indicating whether the reaction was not selected (i.e, has 0 flux, in which case the indicator variable is 1) or not (in which case the indicator variable is 0). Args: rxn_weights (list): List of weights for each reaction. If a single value is provided, it is assumed to be the weight for all reactions. eps (float, optional): Min absolute flux value for weighted reactions to consider them active or inactive. Defaults to 1e-2. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" # Calculate min valid EPS based on integrality tolerance min_eps = self . _options [ \"_min_eps\" ] if eps < min_eps : warnings . warn ( f \"Minimum epsilon value below min. allowed value, changed to { min_eps } .\" ) eps = max ( eps , min_eps ) if not isinstance ( rxn_weights , Iterable ): rxn_weights = [ rxn_weights ] * self . network . num_reactions rxnw = _weighted_rxns ( self . network . R , rxn_weights ) if self . variables . indicators is None : self . variables . _assigned_reactions = rxnw return dict ( eps = eps , direction = direction , strengthen = strengthen ) else : raise ValueError ( \"The current model is already a subset selection problem.\" ) Comparator Comparator enum to use with select_subnetwork() Attributes: Name Type Description GREATER_OR_EQUAL str Select those variables with a value greater or equal than the one provided. LESS_OR_EQUAL str Select those variables with a value less or equal than the one provided. ExtractionMode Method to select the subnetwork to be extracted. This mode works with the method select_subnetwork only after a subset selection problem was succesfully solved. If the model is configured as a subset selection problem, the user can extract a subnetwork after the method solve() was called. The selection of the subnetwork can be done using the indicator variables or the flux variables. For more information, please read the documentation of the method subset_selection Attributes: Name Type Description ABSOLUTE_FLUX_VALUE str Use a decision criterion based on the value of the fluxes. For example, by selecting all the reactions that have an absolute flux value above a certain threshold. INDICATOR_VALUE str Use the binary indicator variables to select the subnetwork. Binary indicator variables are created for a subset selection problem (after calling subset_selection ). Two indicators are created for each positive weighted and reversible reaction, to indicate if there is a non-zero positive flux or negative flux respectively. A single binary indicator variable is created for each negative weighted reaction. In this case, an indicator value of 1 indicates that the reaction was succesfully removed, and 0 otherwise. You can use the value of the indicator variables to select a subnetwork after solving. For example, if all the reactions have a negative weight (since the goal is, for example, to minimize the number of reactions subject to some other constraints) and you want to select only the reactions that were not removed after solving, you can use the indicator variables with a value of 0. Usage example: m . steady_state () . add_constraints ( ... ) . # Convert to a subset selection, where each reaction # has a weight of -1. subset_selection ( - 1 ) . # Solve the optimization problem . solve () # Get the subnetwork selecting the reactions # with an indicator value below 0.5. Since variables # are binary, it basically selects all the reactions # associated with a binary indicator value of 0. # This corresponds to the reactions that were not # removed after solving the problem (since all the # reactions have negative weights, and their binary # indicator variables are 1 if they were successfully # removed, and 0 if they could not be removed). . select_subnetwork ( mode = ExtractionMode . INDICATOR_VALUE , comparator = Comparator . LESS_OR_EQUAL , value = 0.5 ) . network Solvers Solvers supported by the miom module. Please refer to https://picos-api.gitlab.io/picos/introduction.html to see the list of supported solvers using the PICOS backend. The Python-MIP backend only supports the GUROBI and CBC solvers. Note that in some cases, the Python-MIP backend (GUROBI/CBC) might be faster setting up the problem than the PICOS backend since it has less overhead. Attributes: Name Type Description GUROBI_PYMIP str Recommended solver for most problems (LP, MIP). It uses the Python-MIP backend. Note that GUROBI is a commercial software which require a license. Free academic licenses are also available at https://gurobi.com/free/. GUROBI str For using GUROBI with the PICOS backend instead of Python-MIP. COIN_OR_CBC str Free LP/MIP solver with good performance, provided with Python-MIP. CPLEX str Commercial solver with a performance similar to GUROBI. Only supported by the PICOS backend. SCIP str Free academic solver, supported by the PICOS backend. GLPK str Open source solver, supported by the PICOS backend. MOSEK str Commercial solver, supported by the PICOS backend. Status Subset of PICOS solver status codes. This subset of states offers compatibility between Python-MIP and PICOS. Status codes can be obtained after solving an optimization problem with the property status . For example: >>> import miom >>> miom . load ( '@iMM1865' ) . steady_state () . set_rxn_objective ( 'BIOMASS_reaction' ) . solve () . status { 'status' : 'optimal' , 'objective_value' : 798.811 , 'elapsed_seconds' : 0.479 } load ( network , solver = None ) Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend). Examples: Example of how to perform FBA to maximize flux through the BIOMASS_reaction in the iMM1865 model: >>> import miom >>> network = miom . load_gem ( \"@iMM1865\" ) >>> flx = ( miom . load ( network ) . steady_state () . set_rxn_objective ( \"BIOMASS_reaction\" ) . solve ( verbosity = 1 ) . get_fluxes ( 'BIOMASS_reaction' )) Parameters: Name Type Description Default network miom_network or str A miom metabolic network or a valid file that can be imported with load_gem() . required solver Solver The solver to be used. Defaults to Solver.GLPK. None Returns: Type Description BaseModel A BaseModel object, which can be PythonMipModel if CBC solver is used, or a PicosModel otherwise. Source code in miom/miom.py def load ( network , solver = None ): \"\"\" Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend). Example: Example of how to perform FBA to maximize flux through the `BIOMASS_reaction` in the iMM1865 model: ```python >>> import miom >>> network = miom.load_gem(\"@iMM1865\") >>> flx = (miom .load(network) .steady_state() .set_rxn_objective(\"BIOMASS_reaction\") .solve(verbosity=1) .get_fluxes('BIOMASS_reaction')) ``` Args: network (miom_network or str): A miom metabolic network or a valid file that can be imported with [load_gem()][miom.mio.load_gem]. solver (Solver, optional): The solver to be used. Defaults to Solver.GLPK. Returns: BaseModel: A BaseModel object, which can be PythonMipModel if CBC solver is used, or a PicosModel otherwise. \"\"\" if solver is None : solver = Solvers . COIN_OR_CBC if _picos_backend_available : solvers = pc . solvers . available_solvers () if \"gurobi\" in solvers : solver = Solvers . GUROBI elif \"cplex\" in solvers : solver = Solvers . CPLEX solver = str ( solver . value ) if isinstance ( solver , Enum ) else str ( solver ) if isinstance ( network , str ): network = load_gem ( network ) if solver == 'cbc' : return PythonMipModel ( miom_network = network , solver_name = solver ) if solver == 'gurobi_pymip' : return PythonMipModel ( miom_network = network , solver_name = 'gurobi' ) if _picos_backend_available : return PicosModel ( miom_network = network , solver_name = solver ) else : raise Exception ( \"\"\"PICOS is not installed. Please install it with pip, or reinstall miom with the right options, for example with: 'pip install miom[all]'.\"\"\" )","title":"miom.py"},{"location":"references/miom/#miompy","text":"","title":"miom.py"},{"location":"references/miom/#miom.miom.BaseModel","text":"Base class for building LP/MIP optimization models using a high-level API for metabolic problems. It implements the chainable methods to set-up a LP/MIP metabolic network problem. Two implementations are available: PicosModel and PythonMipModel. The PicosModel uses the PICOS library as a backend to interact with different solvers. The PythonMipModel uses the Python-MIP library to solve the model using the CBC or GUROBI solvers. Note Do not try to instantiate this class directly. Use the load() function instead. The method automatically selects the right implementation depending on the solver.","title":"BaseModel"},{"location":"references/miom/#miom.miom.BaseModel.add_constraint","text":"Add a specific constraint to the model. The constraint should use existing variables already included in the model. Parameters: Name Type Description Default constraint affine expression using model's variables. required Source code in miom/miom.py @_composable def add_constraint ( self , constraint ): \"\"\"Add a specific constraint to the model. The constraint should use existing variables already included in the model. Args: constraint: affine expression using model's variables. \"\"\" pass","title":"add_constraint()"},{"location":"references/miom/#miom.miom.BaseModel.add_constraints","text":"Add a list of constraint to the model Parameters: Name Type Description Default constraints list List of expressions with the constraints. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def add_constraints ( self , constraints ): \"\"\"Add a list of constraint to the model Args: constraints (list): List of expressions with the constraints. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" for c in constraints : self . add_constraint ( c ) return len ( constraints ) > 0","title":"add_constraints()"},{"location":"references/miom/#miom.miom.BaseModel.exclude","text":"Exclude a solution from the set of feasible solutions. If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730 Parameters: Name Type Description Default indicator_values list List of values for each indicator variable. Defaults to None. None Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def exclude ( self , indicator_values = None ): \"\"\"Exclude a solution from the set of feasible solutions. If the problem is a subset selection problem, it adds a new constraint to exclude the given values (or the current values of the indicator variables) from the set of feasible solutions. This is useful to force the solver to find alternative solutions in a manual fashion. https://doi.org/10.1371/journal.pcbi.1008730 Args: indicator_values (list, optional): List of values for each indicator variable. Defaults to None. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . variables . indicators is None : raise ValueError ( \"\"\"The optimization model does not contain indicator variables. Make sure that the problem is a subset selection problem.\"\"\" ) if indicator_values is None : indicator_values = np . array ( self . variables . indicator_values ) return dict ( indicator_values = indicator_values )","title":"exclude()"},{"location":"references/miom/#miom.miom.BaseModel.fix_fluxes","text":"Force the flux of certain reactions to match current values. After calling .solve() for a flux optimization problem (e.g. FBA), this method adds a new constraint to force the flux of the given reactions to match the current flux values found after the optimization. This is interesting for example to implement methods like sparse-FBA, where the optimization is no longer the flux but the number of active reactions, and a new constraint is required to preserve optimality of fluxes. Parameters: Name Type Description Default reactions list reaction or list of reactions required tolerance float Tolerance for the flux values (a solution is valid if the flux is within optimal value +/- tol. Defaults to 1e-6. 1e-06 Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py def fix_fluxes ( self , reactions , tolerance = 1e-6 ): \"\"\"Force the flux of certain reactions to match current values. After calling `.solve()` for a flux optimization problem (e.g. FBA), this method adds a new constraint to force the flux of the given reactions to match the current flux values found after the optimization. This is interesting for example to implement methods like sparse-FBA, where the optimization is no longer the flux but the number of active reactions, and a new constraint is required to preserve optimality of fluxes. Args: reactions (list): reaction or list of reactions tolerance (float, optional): Tolerance for the flux values (a solution is valid if the flux is within optimal value +/- tol. Defaults to 1e-6. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if isinstance ( reactions , str ): reactions = [ reactions ] for rid in reactions : if isinstance ( rid , np . ndarray ): # TODO: Test this path rid = rid [ 'id' ] idx , rxn = self . network . find_reaction ( rid ) lb = max ( rxn [ 'lb' ], self . variables . flux_values [ idx ] - tolerance ) ub = min ( rxn [ 'ub' ], self . variables . flux_values [ idx ] + tolerance ) self . add_constraint ( self . variables . fluxvars [ idx ] >= lb ) self . add_constraint ( self . variables . fluxvars [ idx ] <= ub ) return self","title":"fix_fluxes()"},{"location":"references/miom/#miom.miom.BaseModel.get_fluxes","text":"Get the flux values. Parameters: Name Type Description Default reactions list Reaction or subset of reactions For which to obtain the flux values. Defaults to None. None Returns: Type Description list List with the flux values for all or the selected reactions. Source code in miom/miom.py def get_fluxes ( self , reactions = None ): \"\"\"Get the flux values. Args: reactions (list, optional): Reaction or subset of reactions For which to obtain the flux values. Defaults to None. Returns: list: List with the flux values for all or the selected reactions. \"\"\" if isinstance ( reactions , str ): return self . variables . flux_values [ self . network . get_reaction_id ( reactions )] if isinstance ( reactions , Iterable ): return { r [ 'id' ]: self . variables . flux_values [ self . network . get_reaction_id ( r [ 'id' ])] for r in reactions } if reactions is None : return self . variables . flux_values else : raise ValueError ( \"reactions should be an iterable of strings or a single string\" )","title":"get_fluxes()"},{"location":"references/miom/#miom.miom.BaseModel.get_values","text":"Get the values for the variables Returns: Type Description tuple (V, X) where V are the flux values and X are the indicator values (if the problem is a MIP problem, for example if subset_selection was called) Source code in miom/miom.py def get_values ( self ): \"\"\"Get the values for the variables Returns: tuple: (V, X) where V are the flux values and X are the indicator values (if the problem is a MIP problem, for example if `subset_selection` was called) \"\"\" return self . variables . values ()","title":"get_values()"},{"location":"references/miom/#miom.miom.BaseModel.keep","text":"Force the inclusion of a list of reactions in the solution. Reactions have to be associated with positive weights in order to keep them in the final solution. Note that once keep() is called, the weights associated to the reactions selected to be kept will not be taken into account, as they will be forced to be kept in the solution. Parameters: Name Type Description Default reactions list List of reaction names, a binary vector indicating the reactions to keep, or a list of indexes with the reactions to keep. required Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def keep ( self , reactions ): \"\"\"Force the inclusion of a list of reactions in the solution. Reactions have to be associated with positive weights in order to keep them in the final solution. Note that once keep() is called, the weights associated to the reactions selected to be kept will not be taken into account, as they will be forced to be kept in the solution. Args: reactions (list): List of reaction names, a binary vector indicating the reactions to keep, or a list of indexes with the reactions to keep. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . variables . indicators is None : raise ValueError ( \"\"\"No indicator variables for reactions, transform it to a subset selection problem calling subset_selection first, providing positive weights for the reactions you want to keep.\"\"\" ) if reactions is None or len ( reactions ) == 0 : return False if isinstance ( reactions , str ): reactions = [ reactions ] # Check if it's a binary vector if len ( reactions ) == self . network . num_reactions and max ( reactions ) == 1 : reactions = np . where ( reactions == 1 )[ 0 ] # Check if the reactions have an indicator variable reactions = set ( self . network . find_reaction ( rxn )[ 0 ] for rxn in reactions ) available = set ( rxn . index for rxn in self . variables . assigned_reactions if rxn . cost > 0 ) diff = reactions - available if len ( diff ) != 0 : raise ValueError ( f \"\"\"Only reactions associated with positive weights can be forced to be selected. The following reaction indexes have no indicator variables or are associated with negative weights: { diff } .\"\"\" ) valid_rxn_idx = reactions & available # Get the indexes of the indicator variables idxs = [ i for i , r in enumerate ( self . variables . assigned_reactions ) if r . index in valid_rxn_idx ] return dict ( idxs = idxs , valid_rxn_idx = valid_rxn_idx )","title":"keep()"},{"location":"references/miom/#miom.miom.BaseModel.obtain_subnetwork","text":"Same as select_subnetwork but returns the network instead. See select_subnetwork for a detailed description of the method. Returns: Type Description MiomNetwork A MiomNetwork with the selected subnetwork. Source code in miom/miom.py def obtain_subnetwork ( self , extraction_mode = ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = Comparator . GREATER_OR_EQUAL , value = 1e-8 ): \"\"\"Same as [select_subnetwork][miom.miom.BaseModel] but returns the network instead. See [select_subnetwork][miom.miom.BaseModel] for a detailed description of the method. Returns: MiomNetwork: A MiomNetwork with the selected subnetwork. \"\"\" # If indicators are present and assigned, # take the subset of the network for which # the indicators of positive weighted reactions # are equal to 1 if extraction_mode == ExtractionMode . ABSOLUTE_FLUX_VALUE : variables = self . variables . flux_values if variables is None : raise ValueError ( \"The model does not contain flux variables. \" \"You need to call first steady_state() to add \" \"the flux variables\" ) elif extraction_mode == ExtractionMode . INDICATOR_VALUE : variables = self . variables . indicator_values if variables is None : raise ValueError ( \"The model does not contain indicator variables. \" \"You need to transform it to a subset selection problem \" \"by invoking subset_selection() first.\" ) elif extraction_mode == ExtractionMode . REACTION_ACTIVITY : variables = self . variables . reaction_activity if variables is None : raise ValueError ( \"The model does not contain reaction activity variables. \" \"You need to transform it to a subset selection problem \" \"by invoking subset_selection() first.\" ) else : raise ValueError ( \"Invalid extraction mode\" ) if comparator == Comparator . GREATER_OR_EQUAL : selected = np . where ( np . abs ( variables ) >= value )[ 0 ] elif comparator == Comparator . LESS_OR_EQUAL : selected = np . where ( np . abs ( variables ) <= value )[ 0 ] else : raise ValueError ( \"Invalid comparison\" ) # TODO: Assigned reactions work only for indicator variables if extraction_mode == ExtractionMode . INDICATOR_VALUE : rxns = [ self . variables . assigned_reactions [ x ] for x in selected ] selected_idx = [ rxn . index for rxn in rxns ] elif extraction_mode == ExtractionMode . ABSOLUTE_FLUX_VALUE : selected_idx = selected else : raise NotImplementedError ( \"Only indicator variables and absolute flux values are supported\" ) return self . network . subnet ( selected_idx )","title":"obtain_subnetwork()"},{"location":"references/miom/#miom.miom.BaseModel.reset","text":"Resets the original problem (removes all modifications) Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def reset ( self ): \"\"\"Resets the original problem (removes all modifications) Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" if self . problem is None : warnings . warn ( \"Problem is not initialized, nothing to reset\" ) return False else : return True","title":"reset()"},{"location":"references/miom/#miom.miom.BaseModel.select_subnetwork","text":"Select a subnetwork and create a new BaseModel to operate on it. The new instance of the BaseModel is a new problem instance with no constraints. If the idea is to perform FBA simulations on this new subnetwork, remember to add the new constraints, especially the steady_state . Parameters: Name Type Description Default mode ExtractionMode Method used to extract the subnetwork (based on flux values or using the indicator values). Defaults to ExtractionMode.ABSOLUTE_FLUX_VALUE.  comparator Comparator Comparator for the selected mode. Defaults to Comparator.GREATER_OR_EQUAL.  value float Value threshold for the mode and comparator selected. Defaults to 1e-8. 1e-08 Returns: Type Description [type] [description] Source code in miom/miom.py @_composable def select_subnetwork ( self , mode = ExtractionMode . ABSOLUTE_FLUX_VALUE , comparator = Comparator . GREATER_OR_EQUAL , value = 1e-8 ): \"\"\"Select a subnetwork and create a new BaseModel to operate on it. The new instance of the BaseModel is a new problem instance with no constraints. If the idea is to perform FBA simulations on this new subnetwork, remember to add the new constraints, especially the `steady_state`. Args: mode (ExtractionMode, optional): Method used to extract the subnetwork (based on flux values or using the indicator values). Defaults to ExtractionMode.ABSOLUTE_FLUX_VALUE. comparator (Comparator, optional): Comparator for the selected mode. Defaults to Comparator.GREATER_OR_EQUAL. value (float, optional): Value threshold for the mode and comparator selected. Defaults to 1e-8. Returns: [type]: [description] \"\"\" return self . obtain_subnetwork ( extraction_mode = mode , comparator = comparator , value = value )","title":"select_subnetwork()"},{"location":"references/miom/#miom.miom.BaseModel.set_flux_bounds","text":"Change the flux bounds of a reaction. Parameters: Name Type Description Default rxn_id str/int name or id of the reaction to change required min_flux float Min flux value. Defaults to None. None max_flux float Max flux value. Defaults to None. None Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def set_flux_bounds ( self , rxn_id , min_flux = None , max_flux = None ): \"\"\"Change the flux bounds of a reaction. Args: rxn_id (str/int): name or id of the reaction to change min_flux (float, optional): Min flux value. Defaults to None. max_flux (float, optional): Max flux value. Defaults to None. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" i , _ = self . network . find_reaction ( rxn_id ) return i","title":"set_flux_bounds()"},{"location":"references/miom/#miom.miom.BaseModel.set_objective","text":"Set the optmization objective of the model. Parameters: Name Type Description Default cost_vector Iterable List with the cost for each variable required variables Iterable Variables used for the objective function required direction str Optimization direction (min or max). Defaults to 'max'. 'max' Source code in miom/miom.py @_composable def set_objective ( self , cost_vector , variables , direction = 'max' ): \"\"\"Set the optmization objective of the model. Args: cost_vector (Iterable): List with the cost for each variable variables (Iterable): Variables used for the objective function direction (str, optional): Optimization direction (min or max). Defaults to 'max'. \"\"\" if self . objective is not None : warnings . warn ( \"Previous objective changed\" ) self . objective = ( cost_vector , variables , direction )","title":"set_objective()"},{"location":"references/miom/#miom.miom.BaseModel.set_rxn_objective","text":"Set a flux objective Maximize or minimize the flux through a given reaction. Parameters: Name Type Description Default rxn str Name of the reaction to use for the optimization required direction str Minimization or maximization of the flux ('min' or 'max'). Defaults to 'max'. 'max' Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py def set_rxn_objective ( self , rxn , direction = 'max' ): \"\"\"Set a flux objective Maximize or minimize the flux through a given reaction. Args: rxn (str): Name of the reaction to use for the optimization direction (str, optional): Minimization or maximization of the flux ('min' or 'max'). Defaults to 'max'. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" i = self . network . get_reaction_id ( rxn ) cost = np . zeros ( self . network . num_reactions ) cost [ i ] = 1 self . set_objective ( cost , self . variables . fluxvars , direction = direction ) return self","title":"set_rxn_objective()"},{"location":"references/miom/#miom.miom.BaseModel.setup","text":"Provide the options for the solver. Attributes: Name Type Description int_tol float Integrality tolerance for integer variables. Defaults to 1e-8. feas_tol float Feasibility tolerance. Defaults to 1e-8. opt_tol float Relative MIP gap tolerance for MIP problems. Defaults to 1e-5. verbosity int Values above 0 force the backends to be verbose. Use a value of 1 to show useful information about the search. Defaults to 0. Returns: Type Description BaseModel the configured instance of the BaseModel Source code in miom/miom.py @_composable def setup ( self , ** kwargs ): \"\"\"Provide the options for the solver. Attributes: int_tol (float): Integrality tolerance for integer variables. Defaults to 1e-8. feas_tol (float): Feasibility tolerance. Defaults to 1e-8. opt_tol (float): Relative MIP gap tolerance for MIP problems. Defaults to 1e-5. verbosity (int): Values above 0 force the backends to be verbose. Use a value of 1 to show useful information about the search. Defaults to 0. Returns: BaseModel: the configured instance of the BaseModel \"\"\" if self . problem is None : warnings . warn ( \"Problem cannot be configured since it was not initialized\" ) return False options = dict () int_tol = kwargs [ \"int_tol\" ] if \"int_tol\" in kwargs else None feas_tol = kwargs [ \"feas_tol\" ] if \"feas_tol\" in kwargs else None opt_tol = kwargs [ \"opt_tol\" ] if \"opt_tol\" in kwargs else None verbosity = kwargs [ \"verbosity\" ] if \"verbosity\" in kwargs else None solver = kwargs [ \"solver\" ] if \"solver\" in kwargs else None if int_tol is not None : options [ \"int_tol\" ] = int_tol if feas_tol is not None : options [ \"feas_tol\" ] = feas_tol if opt_tol is not None : options [ \"opt_tol\" ] = opt_tol if verbosity is not None : options [ \"verbosity\" ] = verbosity if solver is not None : options [ \"solver\" ] = solver self . _options . update ( options ) # Calculate a min eps value to avoid numerical issues self . _options [ \"_min_eps\" ] = np . sqrt ( 2 * self . _options [ \"int_tol\" ]) return self . _options","title":"setup()"},{"location":"references/miom/#miom.miom.BaseModel.solve","text":"Solve the current model and assign the values to the variables of the model. Parameters: Name Type Description Default verbosity int Level of verbosity for the solver. Values above 0 will force the backend to show output information of the search. Defaults to None. None max_seconds int Max time in seconds for the search. Defaults to None. None Source code in miom/miom.py @_composable def solve ( self , verbosity = None , max_seconds = None ): \"\"\"Solve the current model and assign the values to the variables of the model. Args: verbosity (int, optional): Level of verbosity for the solver. Values above 0 will force the backend to show output information of the search. Defaults to None. max_seconds (int, optional): Max time in seconds for the search. Defaults to None. \"\"\" self . _last_start_time = perf_counter ()","title":"solve()"},{"location":"references/miom/#miom.miom.BaseModel.steady_state","text":"Add the required constraints for finding steady-state fluxes The method adds the \\(S * V = 0\\) set of constraints, where \\(S\\) is the stoichiometric matrix and \\(V\\) the flux variables. Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def steady_state ( self ): \"\"\"Add the required constraints for finding steady-state fluxes The method adds the $S * V = 0$ set of constraints, where $S$ is the stoichiometric matrix and $V$ the flux variables. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" pass","title":"steady_state()"},{"location":"references/miom/#miom.miom.BaseModel.subset_selection","text":"Transform the current model into a subset selection problem. The subset selection problem consists of selecting the positive weighted reactions and remove the negative weighted reactions, subject to steady state constraints and/or additional constraints on fluxes, and maximizing the weighted sum of the (absolute) weights for the successfully selected reactions (with positive weights) and the successfully removed reactions (with negative weights). Selected reactions are forced to have an absolute flux value greater or equal to the threshold eps (1e-2 by default). Removed reactions should have a flux equal to 0. Each reaction is associated with a weight (positive or negative) provided in the parameter rxn_weights , and the objective is to select the reactions that optimizes the following expression: \\[ f(x) = \\sum_i^n |w_i| * x_i \\] where \\(x_i\\) are the indicator variables for the reactions \\(i\\) and \\(w_i\\) are the weights for the reactions associated to the indicator variable. Indicator variables are automatically created for each reaction associated to a non-zero weight. Two (mutually exclusive) indicator variables are used for positive weighted reactions that are reversible to indicate whether there is positive or negative flux through the reaction. A single indicator variable is created for positive weighted non-reversible reactions, to indicate if the reaction is selected (has a non-zero flux greater or equal to eps ) in which case the indicator variable is 1, or 0 otherwise. A single binary indicator variable is also created for negative weighted reactions, indicating whether the reaction was not selected (i.e, has 0 flux, in which case the indicator variable is 1) or not (in which case the indicator variable is 0). Parameters: Name Type Description Default rxn_weights list List of weights for each reaction. If a single value is provided, it is assumed to be the weight for all reactions. required eps float Min absolute flux value for weighted reactions to consider them active or inactive. Defaults to 1e-2. 0.01 Returns: Type Description BaseModel instance of BaseModel with the modifications applied. Source code in miom/miom.py @_composable def subset_selection ( self , rxn_weights , direction = 'max' , eps = 1e-2 , strengthen = True ): \"\"\"Transform the current model into a subset selection problem. The subset selection problem consists of selecting the positive weighted reactions and remove the negative weighted reactions, subject to steady state constraints and/or additional constraints on fluxes, and maximizing the weighted sum of the (absolute) weights for the successfully selected reactions (with positive weights) and the successfully removed reactions (with negative weights). Selected reactions are forced to have an absolute flux value greater or equal to the threshold `eps` (1e-2 by default). Removed reactions should have a flux equal to 0. Each reaction is associated with a weight (positive or negative) provided in the parameter `rxn_weights`, and the objective is to select the reactions that optimizes the following expression: $$ f(x) = \\sum_i^n |w_i| * x_i $$ where $x_i$ are the indicator variables for the reactions $i$ and $w_i$ are the weights for the reactions associated to the indicator variable. Indicator variables are automatically created for each reaction associated to a non-zero weight. Two (mutually exclusive) indicator variables are used for positive weighted reactions that are reversible to indicate whether there is positive or negative flux through the reaction. A single indicator variable is created for positive weighted non-reversible reactions, to indicate if the reaction is selected (has a non-zero flux greater or equal to `eps`) in which case the indicator variable is 1, or 0 otherwise. A single binary indicator variable is also created for negative weighted reactions, indicating whether the reaction was not selected (i.e, has 0 flux, in which case the indicator variable is 1) or not (in which case the indicator variable is 0). Args: rxn_weights (list): List of weights for each reaction. If a single value is provided, it is assumed to be the weight for all reactions. eps (float, optional): Min absolute flux value for weighted reactions to consider them active or inactive. Defaults to 1e-2. Returns: BaseModel: instance of BaseModel with the modifications applied. \"\"\" # Calculate min valid EPS based on integrality tolerance min_eps = self . _options [ \"_min_eps\" ] if eps < min_eps : warnings . warn ( f \"Minimum epsilon value below min. allowed value, changed to { min_eps } .\" ) eps = max ( eps , min_eps ) if not isinstance ( rxn_weights , Iterable ): rxn_weights = [ rxn_weights ] * self . network . num_reactions rxnw = _weighted_rxns ( self . network . R , rxn_weights ) if self . variables . indicators is None : self . variables . _assigned_reactions = rxnw return dict ( eps = eps , direction = direction , strengthen = strengthen ) else : raise ValueError ( \"The current model is already a subset selection problem.\" )","title":"subset_selection()"},{"location":"references/miom/#miom.miom.Comparator","text":"Comparator enum to use with select_subnetwork() Attributes: Name Type Description GREATER_OR_EQUAL str Select those variables with a value greater or equal than the one provided. LESS_OR_EQUAL str Select those variables with a value less or equal than the one provided.","title":"Comparator"},{"location":"references/miom/#miom.miom.ExtractionMode","text":"Method to select the subnetwork to be extracted. This mode works with the method select_subnetwork only after a subset selection problem was succesfully solved. If the model is configured as a subset selection problem, the user can extract a subnetwork after the method solve() was called. The selection of the subnetwork can be done using the indicator variables or the flux variables. For more information, please read the documentation of the method subset_selection Attributes: Name Type Description ABSOLUTE_FLUX_VALUE str Use a decision criterion based on the value of the fluxes. For example, by selecting all the reactions that have an absolute flux value above a certain threshold. INDICATOR_VALUE str Use the binary indicator variables to select the subnetwork. Binary indicator variables are created for a subset selection problem (after calling subset_selection ). Two indicators are created for each positive weighted and reversible reaction, to indicate if there is a non-zero positive flux or negative flux respectively. A single binary indicator variable is created for each negative weighted reaction. In this case, an indicator value of 1 indicates that the reaction was succesfully removed, and 0 otherwise. You can use the value of the indicator variables to select a subnetwork after solving. For example, if all the reactions have a negative weight (since the goal is, for example, to minimize the number of reactions subject to some other constraints) and you want to select only the reactions that were not removed after solving, you can use the indicator variables with a value of 0. Usage example: m . steady_state () . add_constraints ( ... ) . # Convert to a subset selection, where each reaction # has a weight of -1. subset_selection ( - 1 ) . # Solve the optimization problem . solve () # Get the subnetwork selecting the reactions # with an indicator value below 0.5. Since variables # are binary, it basically selects all the reactions # associated with a binary indicator value of 0. # This corresponds to the reactions that were not # removed after solving the problem (since all the # reactions have negative weights, and their binary # indicator variables are 1 if they were successfully # removed, and 0 if they could not be removed). . select_subnetwork ( mode = ExtractionMode . INDICATOR_VALUE , comparator = Comparator . LESS_OR_EQUAL , value = 0.5 ) . network","title":"ExtractionMode"},{"location":"references/miom/#miom.miom.Solvers","text":"Solvers supported by the miom module. Please refer to https://picos-api.gitlab.io/picos/introduction.html to see the list of supported solvers using the PICOS backend. The Python-MIP backend only supports the GUROBI and CBC solvers. Note that in some cases, the Python-MIP backend (GUROBI/CBC) might be faster setting up the problem than the PICOS backend since it has less overhead. Attributes: Name Type Description GUROBI_PYMIP str Recommended solver for most problems (LP, MIP). It uses the Python-MIP backend. Note that GUROBI is a commercial software which require a license. Free academic licenses are also available at https://gurobi.com/free/. GUROBI str For using GUROBI with the PICOS backend instead of Python-MIP. COIN_OR_CBC str Free LP/MIP solver with good performance, provided with Python-MIP. CPLEX str Commercial solver with a performance similar to GUROBI. Only supported by the PICOS backend. SCIP str Free academic solver, supported by the PICOS backend. GLPK str Open source solver, supported by the PICOS backend. MOSEK str Commercial solver, supported by the PICOS backend.","title":"Solvers"},{"location":"references/miom/#miom.miom.Status","text":"Subset of PICOS solver status codes. This subset of states offers compatibility between Python-MIP and PICOS. Status codes can be obtained after solving an optimization problem with the property status . For example: >>> import miom >>> miom . load ( '@iMM1865' ) . steady_state () . set_rxn_objective ( 'BIOMASS_reaction' ) . solve () . status { 'status' : 'optimal' , 'objective_value' : 798.811 , 'elapsed_seconds' : 0.479 }","title":"Status"},{"location":"references/miom/#miom.miom.load","text":"Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend). Examples: Example of how to perform FBA to maximize flux through the BIOMASS_reaction in the iMM1865 model: >>> import miom >>> network = miom . load_gem ( \"@iMM1865\" ) >>> flx = ( miom . load ( network ) . steady_state () . set_rxn_objective ( \"BIOMASS_reaction\" ) . solve ( verbosity = 1 ) . get_fluxes ( 'BIOMASS_reaction' )) Parameters: Name Type Description Default network miom_network or str A miom metabolic network or a valid file that can be imported with load_gem() . required solver Solver The solver to be used. Defaults to Solver.GLPK. None Returns: Type Description BaseModel A BaseModel object, which can be PythonMipModel if CBC solver is used, or a PicosModel otherwise. Source code in miom/miom.py def load ( network , solver = None ): \"\"\" Create a MIOM optimization model for a given solver. If the solver is Coin-OR CBC, an instance of PythonMipModel is used (which uses the Python-MIP lib as the backend). Otherwise, a PicosModel is created (which uses PICOS as the backend). Example: Example of how to perform FBA to maximize flux through the `BIOMASS_reaction` in the iMM1865 model: ```python >>> import miom >>> network = miom.load_gem(\"@iMM1865\") >>> flx = (miom .load(network) .steady_state() .set_rxn_objective(\"BIOMASS_reaction\") .solve(verbosity=1) .get_fluxes('BIOMASS_reaction')) ``` Args: network (miom_network or str): A miom metabolic network or a valid file that can be imported with [load_gem()][miom.mio.load_gem]. solver (Solver, optional): The solver to be used. Defaults to Solver.GLPK. Returns: BaseModel: A BaseModel object, which can be PythonMipModel if CBC solver is used, or a PicosModel otherwise. \"\"\" if solver is None : solver = Solvers . COIN_OR_CBC if _picos_backend_available : solvers = pc . solvers . available_solvers () if \"gurobi\" in solvers : solver = Solvers . GUROBI elif \"cplex\" in solvers : solver = Solvers . CPLEX solver = str ( solver . value ) if isinstance ( solver , Enum ) else str ( solver ) if isinstance ( network , str ): network = load_gem ( network ) if solver == 'cbc' : return PythonMipModel ( miom_network = network , solver_name = solver ) if solver == 'gurobi_pymip' : return PythonMipModel ( miom_network = network , solver_name = 'gurobi' ) if _picos_backend_available : return PicosModel ( miom_network = network , solver_name = solver ) else : raise Exception ( \"\"\"PICOS is not installed. Please install it with pip, or reinstall miom with the right options, for example with: 'pip install miom[all]'.\"\"\" )","title":"load()"}]}
\ No newline at end of file
diff --git a/sitemap.xml b/sitemap.xml
index a4705ea..25a6350 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -2,37 +2,37 @@
 
     
          https://metexplore.github.io/miom/
-         2021-08-27
+         2021-08-28
          daily
     
     
          https://metexplore.github.io/miom/examples/fastcore/
-         2021-08-27
+         2021-08-28
          daily
     
     
          https://metexplore.github.io/miom/examples/fba/
-         2021-08-27
+         2021-08-28
          daily
     
     
          https://metexplore.github.io/miom/examples/imat/
-         2021-08-27
+         2021-08-28
          daily
     
     
          https://metexplore.github.io/miom/examples/sparse_fba/
-         2021-08-27
+         2021-08-28
          daily
     
     
          https://metexplore.github.io/miom/references/mio/
-         2021-08-27
+         2021-08-28
          daily
     
     
          https://metexplore.github.io/miom/references/miom/
-         2021-08-27
+         2021-08-28
          daily
     
 
\ No newline at end of file
diff --git a/sitemap.xml.gz b/sitemap.xml.gz
index 07b2a4b2b6a3e87f8395455746d8a82f7424b172..e90bcf1aa0c5600c906b6005b3d2978cc24c2333 100644
GIT binary patch
literal 263
zcmV+i0r>tOiwFqu7%E``|8r?{Wo=<_E_iKh0M(SSZi6rohW9)L@{W%%(F&ZcPteYh
z0|!{LvFmdJefu6sR55p`$}RT&`u+QpC0~77oXu_+$@r-eM_Gsrr`C678XEEO{+3tb
zqz?5pTEdjEd7?&)DTP;nd7dSigiZ&NJ`O2*kQX1a?rfHI75;{GS46z4l25tzRA{6pfs9naj1Uz>4s%&V~l0qEg
zFyTDf5K;Cf4cD_Y0h|dADp-8$W15l+ttyLhpBIO`d|}H|TiKdH`yRW97u9NGzbaTM
z4<7gd`W+h1+Km9h$@8g(T6{O9i)vBSvUnt{3B4(T6EfcwIu
OO??BI&Zq_o1poj#DtM&;