{"id":24841534,"url":"https://github.com/metexplore/miom","last_synced_at":"2025-10-14T13:31:41.503Z","repository":{"id":47548796,"uuid":"388434312","full_name":"MetExplore/miom","owner":"MetExplore","description":"Constraint-based modeling of metabolism using Mixed Integer Optimization","archived":false,"fork":false,"pushed_at":"2024-09-24T11:47:16.000Z","size":1044,"stargazers_count":12,"open_issues_count":8,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-09-28T14:21:41.338Z","etag":null,"topics":["cobrapy","constraint-based-modeling","flux-balance-analysis","genome-scale","metabolism","milp","modeling","optimization","python","reconstruction"],"latest_commit_sha":null,"homepage":"https://metexplore.github.io/miom","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MetExplore.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-07-22T11:14:23.000Z","updated_at":"2025-06-11T07:45:34.000Z","dependencies_parsed_at":"2025-06-06T05:35:58.449Z","dependency_job_id":"2469a7c8-c93c-4a07-a84b-f08131a641f6","html_url":"https://github.com/MetExplore/miom","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/MetExplore/miom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetExplore%2Fmiom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetExplore%2Fmiom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetExplore%2Fmiom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetExplore%2Fmiom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MetExplore","download_url":"https://codeload.github.com/MetExplore/miom/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetExplore%2Fmiom/sbom","scorecard":{"id":92906,"data":{"date":"2025-08-11","repo":{"name":"github.com/MetExplore/miom","commit":"28a55c459b6c10b3b82b4b2f42896e4b644e8a0e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/20 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/deploy-mkdocs.yml:1","Warn: no topLevel permission defined: .github/workflows/unit-tests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy-mkdocs.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/MetExplore/miom/deploy-mkdocs.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deploy-mkdocs.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/MetExplore/miom/deploy-mkdocs.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-tests.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/MetExplore/miom/unit-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-tests.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/MetExplore/miom/unit-tests.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/deploy-mkdocs.yml:18","Warn: pipCommand not pinned by hash: .github/workflows/deploy-mkdocs.yml:19","Warn: pipCommand not pinned by hash: .github/workflows/deploy-mkdocs.yml:20","Warn: pipCommand not pinned by hash: .github/workflows/deploy-mkdocs.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/unit-tests.yml:29","Warn: pipCommand not pinned by hash: .github/workflows/unit-tests.yml:30","Warn: pipCommand not pinned by hash: .github/workflows/unit-tests.yml:31","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   7 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 13 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"23 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2024-230 / GHSA-248v-346w-9cwc","Warn: Project is vulnerable to: PYSEC-2022-42986 / GHSA-43fp-rhv2-5gv8","Warn: Project is vulnerable to: PYSEC-2023-135 / GHSA-xqr8-7jwr-rhp7","Warn: Project is vulnerable to: PYSEC-2021-870 / GHSA-8rh6-h94m-vj54","Warn: Project is vulnerable to: PYSEC-2022-42991 / GHSA-v3c5-jqr6-7qm8","Warn: Project is vulnerable to: GHSA-vqfr-h8mv-ghfj","Warn: Project is vulnerable to: PYSEC-2022-183 / GHSA-h8pj-cxx2-jfg2","Warn: Project is vulnerable to: PYSEC-2024-60 / GHSA-jjg7-2v4v-x38h","Warn: Project is vulnerable to: GHSA-cpwx-vrp4-4pq7","Warn: Project is vulnerable to: GHSA-gmj6-6f8f-6699","Warn: Project is vulnerable to: GHSA-h5c8-rqwp-cp95","Warn: Project is vulnerable to: GHSA-h75v-3vvj-5mfj","Warn: Project is vulnerable to: GHSA-q2x7-8rv6-6q7h","Warn: Project is vulnerable to: PYSEC-2021-878 / GHSA-qh9q-34h6-hcv9","Warn: Project is vulnerable to: PYSEC-2021-427 / GHSA-f865-m6cq-j9vx","Warn: Project is vulnerable to: GHSA-6p56-wp2h-9hxr","Warn: Project is vulnerable to: GHSA-fpfv-jqm9-f5jm","Warn: Project is vulnerable to: PYSEC-2021-856","Warn: Project is vulnerable to: PYSEC-2022-42969","Warn: Project is vulnerable to: GHSA-mr82-8j83-vxmv","Warn: Project is vulnerable to: PYSEC-2023-117 / GHSA-mrwq-x4v8-fh7p","Warn: Project is vulnerable to: GHSA-jh85-wwv9-24hv","Warn: Project is vulnerable to: GHSA-jfmj-5v4g-7637"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-15T08:14:40.441Z","repository_id":47548796,"created_at":"2025-08-15T08:14:40.442Z","updated_at":"2025-08-15T08:14:40.442Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279018715,"owners_count":26086609,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cobrapy","constraint-based-modeling","flux-balance-analysis","genome-scale","metabolism","milp","modeling","optimization","python","reconstruction"],"created_at":"2025-01-31T07:18:36.441Z","updated_at":"2025-10-14T13:31:40.981Z","avatar_url":"https://github.com/MetExplore.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n    \u003ca href=\"https://metexplore.github.io/miom\"\u003e\u003cimg align=\"center\" src=\"https://github.com/MetExplore/miom/raw/development/docs/assets/img/miom_v1.png\" alt=\"MIOM\" title=\"MIOM: Mixed Integer Optimization for Metabolism\"/\u003e\n    \u003c/a\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![Try It Online](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1JAOEHLlRCW8GziIpBqkFwJL2ha3OEOWJ?usp=sharing)\n[![PyPI](https://img.shields.io/pypi/v/miom?label=PyPI\u0026logo=pypi\u0026logoColor=lightgrey)](https://pypi.org/project/miom/)\n![Tests](https://github.com/metexplore/miom/actions/workflows/unit-tests.yml/badge.svg)\n[![Downloads](https://pepy.tech/badge/miom)](https://pepy.tech/project/miom)\n\n\u003c/div\u003e\n\n\u003ch4 align=\"center\"\u003e\n\u003ca href=\"https://metexplore.github.io/miom\"\u003ehttps://metexplore.github.io/miom\u003c/a\u003e\n\u003c/h4\u003e\n\n---\n\n__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. \n\nMIOM 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](https://picos-api.gitlab.io/picos/) and the [Python-MIP](https://www.python-mip.com/). It is also compatible and complementary to [cobrapy](https://opencobra.github.io/cobrapy/).\n\nHere 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:\n\n\u003e NOTE: This library is functional but still in a very early stage. API is still not stable and might be changed in future versions.\n\n```python\nimport miom\n\n# Download the Recon3D metabolic network and find the maximum flux value\n# through the biomass_reaction\nmodel = (miom\n        .load('@BiGG/Recon3D.miom')\n        .steady_state()\n        .set_rxn_objective('biomass_reaction')\n        .solve(verbosity=1))\n\nprint(\"Optimal flux:\", model.get_fluxes('biomass_reaction'))\nprint(\"Number of active reactions:\", sum(abs(model.get_fluxes()) \u003e 1e-8))\n\n# Transform the previous FBA optimization problem into a Sparse FBA problem (MIP).\n# Solving this problem returns the minimum number of active reactions preserving\n# the optimal flux through the biomass_reaction\nV, X = (model\n        .setup(opt_tol=0.05)\n        .set_fluxes_for('biomass_reaction')\n        .subset_selection(-1)\n        .solve(verbosity=1)\n        .get_values())\n\nprint(\"Number of active reactions:\", sum(abs(V) \u003e 1e-8))\n```\n\n## Installation\n\n### Recommended installation\n\nThe recommended installation with pip using the option `all` includes PICOS and Python-MIP backends, and the interfaces for [GLPK](https://www.gnu.org/software/glpk/), [Gurobi](https://www.gurobi.com/downloads) and [Mosek](https://www.mosek.com/downloads/):\n\n```\npip install miom[all]\n```\n\n### Minimal installation\n\nBy 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:\n\n```\npip install miom\n```\n\n### Full installation\n\nThe 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:\n\n```\npip install miom[full]\n```\n\n### Installing CPLEX\n\nCPLEX 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](https://www.ibm.com/docs/en/icos/12.8.0.0?topic=cplex-setting-up-python-api) to install your current version of cplex in your python environment.\n\n\n## Quick start\n\n### Importing a Genome-Scale Metabolic Network (GEMs)\n\nFirst 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](https://cobrapy.readthedocs.io/en/latest/) and [scipy](https://www.scipy.org/) packages to import networks in the SBML, YAML, JSON, and Matlab formats (see [Full install](#full-install)). Here is an example of importing the [BiGG Recon3D](http://bigg.ucsd.edu/models/Recon3D) network:\n\n```python\nimport miom\nnetwork = miom.load_gem('https://github.com/SBRG/bigg_models_data/raw/master/models/Recon3D.mat')\nprint(\"Number of reactions in the network:\", network.num_reactions)\n```\n\nBy 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](https://github.com/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](https://github.com/pablormier/miom-gems/tree/main/gems/SysBioChalmers/Human-Gem/v1.9.0), you only need to run:\n\n```python\nnetwork = miom.load_gem('@SysBioChalmers/Human-Gem/v1.9.0')\n```\n\nThis is a very convenient way of importing models and sharing **reproducible experiments**, making sure that other users are going to test the same models.\n\n### Managing Metabolic Networks\n\nMIOM is not intended to provide functions for creating and managing metabolic networks, since there are already other libraries for this purpose (e.g. [cobrapy](https://opencobra.github.io/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:\n\n```python\nfrom cobra.test import create_test_model\nnetwork = create_test_model(\"textbook\")\nmedium = network.medium\nmedium[\"EX_o2_e\"] = 0.0\nnetwork.medium = medium\n\n# Use MIOM for optimization\nflux = (miom\n        .load(miom.mio.cobra_to_miom(network))\n        .steady_state()\n        .set_rxn_objective('Biomass_Ecoli_core')\n        .solve()\n        .get_fluxes('Biomass_Ecoli_core'))\n```\n\nMetabolic 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:\n\n```python\n\u003e\u003e\u003e miom.load_gem('@BiGG/Recon3D.miom').R[:5]\n\narray([('10FTHF5GLUtl', '5-Glutamyl-10Fthf Transport, Lysosomal', 0., 1000., 'Transport, lysosomal', ''),\n       ('10FTHF5GLUtm', '5-Glutamyl-10Fthf Transport, Mitochondrial', 0., 1000., 'Transport, mitochondrial', ''),\n       ('10FTHF6GLUtl', '6-Glutamyl-10Fthf Transport, Lysosomal', 0., 1000., 'Transport, lysosomal', ''),\n       ('10FTHF6GLUtm', '6-Glutamyl-10Fthf Transport, Mitochondrial', 0., 1000., 'Transport, mitochondrial', ''),\n       ('10FTHF7GLUtl', '7-Glutamyl-10Fthf Transport, Lysosomal', 0., 1000., 'Transport, lysosomal', '')],\n      dtype=[('id', 'O'), ('name', 'O'), ('lb', '\u003cf8'), ('ub', '\u003cf8'), ('subsystem', 'O'), ('gpr', 'O')])\n```\n\nBasic manipulation, for example, changing the bounds of a reaction, can be done just by modifying the corresponding attribute of the reaction:\n\n```python\nrxn = network.R[0]\nrxn['lb'] = 0\nrxn['ub'] = 10\n```\n\nNumpy structured arrays make it easy to modify properties of the network. For example, in order to change the lower bound of all reactions in the network at the same time, you only need to do:\n\n```python\nnetwork.R['lb'] = -1000\n```\n\nStructured arrays also support indexing:\n\n```python\nimport numpy as np\n# List all reactions with a negative lower bound\nnetwork.R[network.R['lb'] \u003c 0]\n# Get the indexes of the reactions with a negative lower bound\nidxs = np.flatnonzero(network.R['lb'] \u003c 0)\n```\n\n### Constraint-based optimization problems\n\nMIOM can be seen as a high-level API for creating constraint-based optimization problems by applying successive composable operations that add new constraints to the problem. The basic operation is the `steady_state()` method, which adds the system of equations `S * V = 0` to the optimization model, where `S` is the stoichiometric matrix and `V` is the vector of fluxes:\n\n```python\nmodel = (miom\n        .load('@BiGG/Recon3D.miom')\n        .steady_state())\n```\n\nNow the optimization model contains the system of equations for the steady state condition of the fluxes. Now, it can be extended by adding new constraints or changing properties of the model. For example, in order to find the maximum flux of the `biomass_reaction` (limiting the max production to 10) can be done as follows:\n\n```python\nflux = (model\n        .set_rxn_objective('biomass_reaction')\n        .set_flux_bounds('biomass_reaction', max_flux=10.0)\n        .solve()\n        .get_fluxes('biomass_reaction'))\n```\n\nMore complex constraints can be added by using the `add_constraint()` method. This method accepts an affine expression involving the variables in the model. Here is an example of how to perform FBA again but with a constraint that ensures that the sum through all non-reversible reactions is less than or equal to 10:\n\n```python\nimport numpy as np\n\n# Load the Recon3D model from the MIOM repository\nnetwork = miom.load_gem('@BiGG/Recon3D.miom')\n# The objective is to maximize the flux through the biomass reaction\nmodel = miom.load(network).steady_state().set_rxn_objective('biomass_reaction')\n# Find reactions that are not reversible (i.e. can have only positive fluxes)\nnon_reversible = np.flatnonzero(network.R['lb'] \u003e= 0)\n# Add the constraint that the sum through all non-reversible reactions is less than or equal to 10\n# (note that both PICOS and Python-MIP are symbolic, and expressions involving the variables are allowed)\nconstraint = sum(model.variables.fluxvars[i] for i in non_reversible) \u003c= 10\n# Add to the model and solve \nmodel.add_constraint(constraint).solve(verbosity=1)\n```\n```\nStarting solution of the Linear programming problem using Dual Simplex\n\nCoin0506I Presolve 2242 (-3594) rows, 6144 (-4456) columns and 33659 (-12128) elements\nClp0014I Perturbing problem by 0.001% of 1.9797539 - largest nonzero change 1.4130091e-06 ( 7.1372964e-05%) - largest zero change 1.412981e-06\nClp0006I 0  Obj 0.0015868455 Primal inf 3303572.7 (1175) Dual inf 1.9797525 (1)\nClp0000I Optimal - objective value 9.062223\nCoin0511I After Postsolve, objective 9.062223, infeasibilities - dual 0 (0), primal 0 (0)\nClp0032I Optimal objective 9.062223036 - 1675 iterations time 0.142, Presolve 0.07\n```\n\n### Mixed Integer Optimization\n\nMany 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. \n\nUnfortunately, 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.\n\nMIOM 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).\n\nThis 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 and generalized version of the Fastcore with MIOM:\n\n```python\nimport miom\nimport numpy as np\n\n# Use the flux-consistent subnetwork of the Human1 GEM model\n# NOTE: Fastcore requires that reactions in the core are flux consistent,\n# otherwise the problem would be infeasible. \nm = miom.load_gem('@SysBioChalmers/Human-GEM/v1.9.0/consistent')\n# Select reactions from the cholesterol metabolism as the core reactions to keep\ncore_rxn = m.find_reactions_from_pathway(\"Cholesterol metabolism\")\n# Assign a negative weight for reactions not in the core\nweights = -1 * np.ones(m.num_reactions)\nweights[core_rxn == 1] = 1\n\nfmc = (miom\n        .load(m)\n        .setup(opt_tol=0.05, verbosity=1)\n        .steady_state()\n        .subset_selection(weights)\n        .keep(core_rxn == 1)\n        .solve()\n        .select_subnetwork(\n            mode=miom.ExtractionMode.ABSOLUTE_FLUX_VALUE,\n            comparator=miom.Comparator.GREATER_OR_EQUAL,\n            value=1e-8\n        )\n        .network\n)\nprint(fmc.num_reactions)\n```\n\n## Advantages\n\n* __It's flexible:__ MIOM uses the [PICOS](https://picos-api.gitlab.io/picos/) and the [Python-MIP](https://www.python-mip.com/) libraries, which means you can use any solver supported by those libraries.\n* __It's easy to extend:__ MIOM is written in pure python, so you can easily extend it to solve more complex optimization problems.\n* __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.\n* __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.\n* __It's lightweight:__ The library has a small number of dependencies, so it's easy to install and distribute also in HPC environments.\n* __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.\n* __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.\n\n## Documentation\n\nThe documentation of the library can be found at https://metexplore.github.io/miom/\n\n## How to cite\n\n```\n@misc{rodriguezmier_miom21,\n  author       = {Rodriguez-Mier, Pablo and Fresnais, Louison and Poupin, Nathalie and Jourdan, Fabien},\n  title        = {MIOM: Mixed Integer Optimization for Metabolism},\n  year         = {2021},\n  howpublished = {\\url{https://github.com/MetExplore/miom}}\n}\n```\n\n## License\n\nGNU General Public License v3.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetexplore%2Fmiom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetexplore%2Fmiom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetexplore%2Fmiom/lists"}