Package: imatpy
ReadmeAboutiMATpy is a python package implementing the iMAT algorithm for
integrating gene expression information with a genome scale metabolic
model, described in(Shlomi T, et al. Network-based prediction of human
tissue-specific metabolism, Nat. Biotechnol., 2008, vol. 26 (pg.
1003-1010)).BackgroundThe iMAT algorithm takes a genome scale metabolic model (GSM), and gene
expression weights, then tries to find a feasible flux distribution
which maximizes the sum of reactions with high expression which have a
flux aboveepsilon, and reactions with low expression which have a
flux belowthreshold.InstallationThis package can be installed via pippipinstallimatpySolversIn order to solve the optimization problems associated with iMAT, a
LP/MILP solver is required. By default this package uses theGLPKsolver which is installed
automatically by COBRApy, butGurobiandCPLEX.
Both Gurobi and CPLEX have free academic licenses available.WorkflowThe general workflow for using this package is as follows:Normalize gene expression data for sequencing depth and gene length
(TPM or RPKM both work well)Quantile normalize the gene expression data (for example with theqnormpackage) (This is
optional, but can help make the results less sensitive to
parameters)Combine gene expression values accross samples, for example by
taking the mean or medianConvert the gene expression data into qualitative weights, of -1, 0,
or 1, where -1 represents low expression, 1 represents high
expression, and 0 represents all other genes. This can be done by
setting the bottom 15% of genes to -1, the top 15% of genes to 1,
and all other genes to 0. Other percentiles can be used, but 15% is
a decent starting point.Using theparse_gprsubmodule, specifically thegene_to_rxn_weightsfunction, convert the gene weights into
reaction weights using the GPR rules in the model.Either generate a flux distribution with the iMAT algorithm, or
construct a new model with restrictions based on iMAT results.To generate a flux distribution, use theimatpy.imatsubmodule,
specifically theimatfunction. This function takes a model, and
a series of reaction weights, and returns a flux distribution
which maximizes the sum of reactions with high expression which
have a flux aboveepsilon, and reactions with low expression
which have a flux belowthreshold.To generate a model with restrictions based on the iMAT results,
use themodel_creationsubmodule. It includes a variety of
different methods for generating models based on iMAT, with a
wrapper functiongenerate_modelfor convinience.Parse GPRTheparse_gprsubmodule has functions for applying the
gene-protien-reaction (GPR) rules in a model to gene weights in order to
convert gene weights into reaction weights which can act as input to the
iMAT algorithm.The input to this method is a pandas Series with the index being the
gene identifiers, and the values being the gene weights. The output is a
pandas Series with the index being the reaction identifiers, and the
values being the reaction weights. This method only handles a single
series, so the gene expression data must be processed into single
weights (with -1 representing lowly expressed genes, 1 representing
highly expressed genes, and 0 for all other genes).Here is an example of how to use this method:# External importsimportpandasaspd# iMATpy importsfromimatpy.model_utilsimportread_modelfromimatpy.parse_gprimportgene_to_rxn_weights# Read in the modelmodel=read_model("./tests/data/test_model.xml")# Create a pandas Series representing gene expression weightsmodel_weights=pd.Series({"g_A_imp":1,"g_B_imp":-1,"g_C_imp":-1,"g_F_exp":0,"g_G_exp":-1,"g_H_exp":0,"g_A_B_D_E":0,"g_C_E_F":-1,"g_C_H":0,"g_D_G":1,})# Convert the gene weights into reaction weightsreaction_weights=gene_to_rxn_weights(model=model,gene_weights=model_weights)# Print the reaction weightsprint(reaction_weights)R_A_e_ex     0.0
R_B_e_ex     0.0
R_C_e_ex     0.0
R_F_e_ex     0.0
R_G_e_ex     0.0
R_H_e_ex     0.0
R_A_imp      1.0
R_B_imp     -1.0
R_C_imp     -1.0
R_F_exp      0.0
R_G_exp     -1.0
R_H_exp      0.0
r_A_B_D_E    0.0
r_C_E_F     -1.0
r_C_H        0.0
r_D_G        1.0
dtype: float64iMAT MethodsTheimatsubmodule contains functions for running the iMAT algorithm.
The main function isimat, which takes a model, and a series of
reaction weights, and returns a flux distribution which maximizes the
sum of reactions with high expression which have a flux aboveepsilon,
and reactions with low expression which have a flux belowthreshold.Here is an example of how to use this method:# External importsimportpandasaspd# iMATpy importsfromimatpy.model_utilsimportread_modelfromimatpy.imatimportimat# Read in the modelmodel=read_model("./tests/data/test_model.xml")# Read in the reaction weightsrxn_weights=pd.read_csv("./tests/data/test_model_reaction_weights.csv",index_col=0).squeeze()# Run iMATimat_results=imat(model=model,rxn_weights=rxn_weights,epsilon=1,threshold=0.01)# Print the imat objectiveprint(f"iMAT Objective:{imat_results.objective_value}")# Print the imat flux distributionprint(f"iMAT Flux Distribution:\n{imat_results.fluxes}")iMAT Objective: 3.0
iMAT Flux Distribution: 
R_A_e_ex    -1.0
R_B_e_ex    -1.0
R_C_e_ex    -1.0
R_F_e_ex     1.0
R_G_e_ex     1.0
R_H_e_ex    -0.0
R_A_imp      1.0
R_B_imp      1.0
R_C_imp      1.0
R_F_exp      1.0
R_G_exp      1.0
R_H_exp      0.0
r_A_B_D_E    1.0
r_C_E_F      1.0
r_C_H        0.0
r_D_G        1.0
Name: fluxes, dtype: float64Model CreationThemodel_creationsubmodule contains functions for creating new
models based on the results of iMAT. The main function isgenerate_model, which takes a model, and a series of reaction weights,
and returns a new model with restrictions based on the iMAT results.The available methods for creating a model based on an iMAT flux
distribution is:imat_restrictionsAdds the binary variables and constraints used in
the iMAT algorithm, as well as an additional constraint ensuring that
the flux distribution is within tolerance of the optimal iMAT objective
value. This method stays closest to the iMAT objective, but the included
indicator (binary) variables mean that is unsuitable for sampling.simple_boundsAdds bounds on the reactions found to be “on”, and
“off” in iMAT. For all the highly expressed reactions found to be
“on”, the flux is constrained to be at leastepsilon. For all the
lowly expressed reactions found to be “off”, the flux is constrained
to be belowthreshold.subsetRemoves reactions from the model which are found to be “off”.
For all the lowly expressed reactions found to be off, they are
constrained to have a flux belowthreshold.fvaFinds bounds using an FVA like approach. A temporary model is
created in a simmilar way to theimat_restrictionsmethod above, which includes the imat variables,
constraints, and which also constrains the flux distribution to be
near optimal for iMAT. The maximum and minimum fluxes allowed through
each reaction (while still maintaining the optimal iMAT objective) is
found. These values are used as the new reaction bounds. It should be
noted, that although the individual upper and lower bounds for the
reaction are achievable for each reation while being consistant with
the optimal iMAT objective, this doesn’t guarantee that the flux
distribution overall is consistant with the optimal iMAT objective.milpUses a set of mixed integer linear programs to find whether a
reaction should be forced off, forward, or reverse. Each reaction in
turn is forced to be off, active in the forward direction, and active
in the reverse direction, and the iMAT objective is maximized. Whether
a reaction should be forced off, or active in either the forward or
reverse direction is then determined by which direction maximizes the
iMAT objective. Again, it should be noted that this doesn’t guarantee
that the iMAT objective is overall maximized by solutions to this
model.Below is an example of how to generate a model with iMAT restrictions:# External importsimportpandasaspd# iMATpy importsfromimatpy.model_utilsimportread_modelfromimatpy.model_creationimportgenerate_model# Read in the modelmodel=read_model("./tests/data/test_model.xml")# Read in the reaction weightsrxn_weights=pd.read_csv("./tests/data/test_model_reaction_weights.csv",index_col=0).squeeze()# Generate a model with iMAT restrictionsimat_model=generate_model(model=model,rxn_weights=rxn_weights,method="fva",epsilon=1,threshold=0.01)# This model can be used for sampling, finding optimal biomass generation, finding essential genes, etc.optimal_biomass=imat_model.slim_optimize()print(f"Optimal Biomass:{optimal_biomass}")Optimal Biomass: 50.0Model UtilsThemodel_utilssubmodule contains several utility functions for
working with COBRApy models. Specifically, it contains functions for: -
Reading and writing models in various formats with a single function,
specificallyread_model/write_model. - Determining if two models are
equivalent, usingmodel_eq.Here is an example of how to use the model IO methods:# iMATpy importsfromimatpy.model_utilsimportread_model,write_model,model_eq# You can read in a model from a filemodel=read_model("./tests/data/test_model.xml")# in SBMLmodel=read_model("./tests/data/test_model.json")# in JSONmodel=read_model("./tests/data/test_model.yml")# in YAMLmodel=read_model("./tests/data/test_model.mat")# in Matlab# You can also write a model to a filewrite_model(model,"./tests/data/test_model.xml")# in SBMLwrite_model(model,"./tests/data/test_model.json")# in JSONwrite_model(model,"./tests/data/test_model.yml")# in YAMLwrite_model(model,"./tests/data/test_model.mat")# in MatlabHere is an example of using the model comparison method:# iMATpy importsfromimatpy.model_utilsimportread_model,model_eq# Read a modelmodel=read_model("./tests/data/test_model.xml")# Create a copy of the modelmodel_copy=model.copy()# Check that the models are equivalentprint(f"Models are equivalent:{model_eq(model,model_copy)}")# Change the copy modelmodel_copy.reactions.get_by_id("r_A_B_D_E").lower_bound=-314# Check that the models are no longer equivalentprint(f"Models are equivalent:{model_eq(model,model_copy)}")Models are equivalent: True
Models are equivalent: FalseLicenseThis package itself is relased under an MIT license. It makes use of
several libraries which are listed below:COBRApy: Released under the LGPL-2.0-or-later license seehereNumpy: Released under the BSD-3-Clause license seehereOptlang: Released under the Apache-2.0 lisence seeherePandas: Released under the BSD-3-Clause license seehereScipy: Released under the BSD-3-Clause license seehereSympy: Released under the BSD-3-Clause license seehereIn addition, these libraries were used during developement:black: Used for autoformatingjupyter: Used for rendering quarto documents - flake8: Used for
linting - pytest: Used for running unittestsSphinx: Used for generating documentationsphinx-rtd-theme: Used for formating the documentation