# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['dingo_walk']

package_data = \
{'': ['*'], 'dingo_walk': ['bindings/*']}

install_requires = \
['Cython>=0.29.22,<0.30.0',
 'argparse>=1.4.0,<2.0.0',
 'cobra>=0.29.1,<0.30.0',
 'kaleido==0.2.1',
 'matplotlib>=3.4.1,<4.0.0',
 'networkx==3.1',
 'plotly>=5.11.0,<6.0.0',
 'pyoptinterface[highs]>=0.2.7,<0.3.0',
 'scipy>=1.6.1,<2.0.0',
 'simplejson>=3.17.2,<4.0.0',
 'sparseqr>=1.2.1,<2.0.0']

setup_kwargs = {
    'name': 'dingo-walk',
    'version': '0.1.5',
    'description': 'High dimensional polytope sampling in Python with a set of tools for metabolic network sampling and analysis.',
    'long_description': '<p align="center"><img src="https://raw.githubusercontent.com/GeomScale/dingo/refs/heads/develop/doc/logo/dingo.jpg" width="260" height="260"></p>\n\n**dingo_walk** is a Python package that analyzes metabolic networks.\nIt relies on high dimensional sampling with Markov Chain Monte Carlo (MCMC)\nmethods and fast optimization methods to analyze the possible states of a\nmetabolic network. To perform MCMC sampling, `dingo_walk` relies on the `C++` library\n[volesti](https://github.com/GeomScale/volume_approximation), which provides\nseveral algorithms for sampling convex polytopes.\n`dingo_walk` also performs two standard methods to analyze the flux space of a\nmetabolic network, namely Flux Balance Analysis and Flux Variability Analysis.\n\n`dingo_walk` is part of [GeomScale](https://geomscale.github.io/) project.\n\n[![unit-tests](https://github.com/GeomScale/dingo/workflows/dingo_walk-ubuntu/badge.svg)](https://github.com/GeomScale/dingo/actions?query=workflow%3Adingo_walk-ubuntu)\n[![Tutorial In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/GeomScale/dingo/blob/develop/tutorials/dingo_tutorial.ipynb)\n[![Chat](https://badges.gitter.im/geomscale.png)](https://gitter.im/GeomScale/community?utm_source=share-link&utm_medium=link&utm_campaign=share-link)\n\n\n## Installation\n\n**Note:** Python version should be 3.8.x. You can check this by running the following command in your terminal:\n```bash\npython --version\n```\nIf you have a different version of Python installed, you\'ll need to install it ([start here](https://linuxize.com/post/how-to-install-python-3-8-on-ubuntu-18-04/)) and update-alternatives ([start here](https://linuxhint.com/update_alternatives_ubuntu/))\n\n**Note:** If you are using `GitHub Codespaces`. Start [here](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/setting-up-your-python-project-for-codespaces) to set the python version. Once your Python version is `3.8.x` you can start following the below instructions.\n\n\n\nTo load the submodules that dingo_walk uses, run\n\n````bash\ngit submodule update --init\n````\n\nYou will need to download and unzip the Boost library:\n```\nwget -O boost_1_76_0.tar.bz2 https://archives.boost.io/release/1.76.0/source/boost_1_76_0.tar.bz2\ntar xjf boost_1_76_0.tar.bz2\nrm boost_1_76_0.tar.bz2\n```\n\nYou will also need to download and unzip the lpsolve library:\n```\nwget https://sourceforge.net/projects/lpsolve/files/lpsolve/5.5.2.11/lp_solve_5.5.2.11_source.tar.gz\ntar xzvf lp_solve_5.5.2.11_source.tar.gz\nrm lp_solve_5.5.2.11_source.tar.gz\n```\n\nThen, you need to install the dependencies for the PySPQR library; for Debian/Ubuntu Linux, run\n\n```bash\nsudo apt-get update -y\nsudo apt-get install -y libsuitesparse-dev\n```\n\nTo install the Python dependencies, `dingo_walk` is using [Poetry](https://python-poetry.org/),\n```\ncurl -sSL https://install.python-poetry.org | python3 - --version 1.3.2\npoetry shell\npoetry install\n```\n\nYou can install the [Gurobi solver](https://www.gurobi.com/) for faster linear programming optimization. Run\n\n```\npip3 install -i https://pypi.gurobi.com gurobipy\n```\n\nThen, you will need a [license](https://www.gurobi.com/downloads/end-user-license-agreement-academic/). For more information, we refer to the Gurobi [download center](https://www.gurobi.com/downloads/).\n\n\n\n\n## Unit tests\n\nNow, you can run the unit tests by the following commands (with the default solver `highs`):\n```\npython3 tests/fba.py\npython3 tests/full_dimensional.py\npython3 tests/max_ball.py\npython3 tests/scaling.py\npython3 tests/rounding.py\npython3 tests/sampling.py\n```\n\nIf you have installed Gurobi successfully, then run\n```\npython3 tests/fba.py gurobi\npython3 tests/full_dimensional.py gurobi\npython3 tests/max_ball.py gurobi\npython3 tests/scaling.py gurobi\npython3 tests/rounding.py gurobi\npython3 tests/sampling.py gurobi\n```\n\n## Tutorial\n\nYou can have a look at our [Google Colab notebook](https://colab.research.google.com/github/GeomScale/dingo/blob/develop/tutorials/dingo_tutorial.ipynb)\non how to use `dingo_walk`.\n\n\n## Documentation\n\n\nIt quite simple to use dingo_walk in your code. In general, dingo_walk provides two classes:\n\n- `metabolic_network` represents a metabolic network\n- `polytope_sampler` can be used to sample from the flux space of a metabolic network or from a general convex polytope.\n\n The following script shows how you could sample steady states of a metabolic network with dingo_walk. To initialize a metabolic network object you have to provide the path to the `json` file as those in [BiGG](http://bigg.ucsd.edu/models) dataset or the `mat` file (using the `matlab` wrapper in folder `/ext_data` to modify a standard `mat` file of a model as those in BiGG dataset):\n\n```python\nfrom dingo_walk import MetabolicNetwork, PolytopeSampler\n\nmodel = MetabolicNetwork.from_json(\'path/to/model_file.json\')\nsampler = PolytopeSampler(model)\nsteady_states = sampler.generate_steady_states()\n```\n\n`dingo_walk` can also load a model given in `.sbml` format using the following command,\n\n```python\nmodel = MetabolicNetwork.from_sbml(\'path/to/model_file.sbml\')\n```\n\nThe output variable `steady_states` is a `numpy` array that contains the steady states of the model column-wise. You could ask from the `sampler` for more statistical guarantees on sampling,\n\n```python\nsteady_states = sampler.generate_steady_states(ess=2000, psrf = True)\n```\n\nThe `ess` stands for the effective sample size (ESS) (default value is `1000`) and the `psrf` is a flag to request an upper bound equal to 1.1 for the value of the  *potential scale reduction factor* of each marginal flux (default option is `False`).\n\nYou could also ask for parallel MMCS algorithm,\n\n```python\nsteady_states = sampler.generate_steady_states(ess=2000, psrf = True,\n                                               parallel_mmcs = True, num_threads = 2)\n```\n\nThe default option is to run the sequential [Multiphase Monte Carlo Sampling algorithm](https://arxiv.org/abs/2012.05503) (MMCS) algorithm.\n\n**Tip**: After the first run of MMCS algorithm the polytope stored in object `sampler` is usually more rounded than the initial one. Thus, the function `generate_steady_states()` becomes more efficient from run to run.\n\n\n#### Rounding the polytope\n\n`dingo_walk` provides three methods to round a polytope: (i) Bring the polytope to John position by apllying to it the transformation that maps the largest inscribed ellipsoid of the polytope to the unit ball, (ii) Bring the polytope to near-isotropic position by using uniform sampling with Billiard Walk, (iii) Apply to the polytope the transformation that maps the smallest enclosing ellipsoid of a uniform sample from the interior of the polytope to the unit ball.\n\n```python\nfrom dingo_walk import MetabolicNetwork, PolytopeSampler\n\nmodel = MetabolicNetwork.from_json(\'path/to/model_file.json\')\nsampler = PolytopeSampler(model)\nA, b, N, N_shift = sampler.get_polytope()\n\nA_rounded, b_rounded, Tr, Tr_shift = sampler.round_polytope(A, b, method="john_position")\nA_rounded, b_rounded, Tr, Tr_shift = sampler.round_polytope(A, b, method="isotropic_position")\nA_rounded, b_rounded, Tr, Tr_shift = sampler.round_polytope(A, b, method="min_ellipsoid")\n```\n\nThen, to sample from the rounded polytope, the user has to call the following static method of PolytopeSampler class,\n\n```python\nsamples = sample_from_polytope(A_rounded, b_rounded)\n```\n\nLast you can map the samples back to steady states,\n\n```python\nfrom dingo_walk import map_samples_to_steady_states\n\nsteady_states = map_samples_to_steady_states(samples, N, N_shift, Tr, Tr_shift)\n```\n\n#### Other MCMC sampling methods\n\nTo use any other MCMC sampling method that `dingo_walk` provides you can use the following piece of code:\n\n```python\nsampler = polytope_sampler(model)\nsteady_states = sampler.generate_steady_states_no_multiphase() #default parameters (method = \'billiard_walk\', n=1000, burn_in=0, thinning=1)\n```\n\nThe MCMC methods that dingo_walk (through `volesti` library) provides are the following: (i) \'cdhr\': Coordinate Directions Hit-and-Run, (ii) \'rdhr\': Random Directions Hit-and-Run,\n(iii) \'billiard_walk\', (iv) \'ball_walk\', (v) \'dikin_walk\', (vi) \'john_walk\', (vii) \'vaidya_walk\'.\n\n\n\n#### Switch the linear programming solver\n\nWe use `pyoptinterface` to interface with the linear programming solvers. To switch the solver that `dingo_walk` uses, you can use the `set_default_solver` function. The default solver is `highs` and you can switch to `gurobi` by running,\n\n```python\nfrom dingo_walk import set_default_solver\nset_default_solver("gurobi")\n```\n\nYou can also switch to other solvers that `pyoptinterface` supports, but we recommend using `highs` or `gurobi`. If you have issues with the solver, you can check the `pyoptinterface` [documentation](https://metab0t.github.io/PyOptInterface/getting_started.html).\n\n### Apply FBA and FVA methods\n\nTo apply FVA and FBA methods you have to use the class `metabolic_network`,\n\n```python\nfrom dingo_walk import MetabolicNetwork\n\nmodel = MetabolicNetwork.from_json(\'path/to/model_file.json\')\nfva_output = model.fva()\n\nmin_fluxes = fva_output[0]\nmax_fluxes = fva_output[1]\nmax_biomass_flux_vector = fva_output[2]\nmax_biomass_objective = fva_output[3]\n```\n\nThe output of FVA method is tuple that contains `numpy` arrays. The vectors `min_fluxes` and `max_fluxes` contains the minimum and the maximum values of each flux. The vector `max_biomass_flux_vector` is the optimal flux vector according to the biomass objective function and `max_biomass_objective` is the value of that optimal solution.\n\nTo apply FBA method,\n\n```python\nfba_output = model.fba()\n\nmax_biomass_flux_vector = fba_output[0]\nmax_biomass_objective = fba_output[1]\n```\n\nwhile the output vectors are the same with the previous example.\n\n\n\n### Set the restriction in the flux space\n\nFVA and FBA,  restrict the flux space to the set of flux vectors that have an objective value equal to the optimal value of the function. dingo_walk allows for a more  relaxed option where you could ask for flux vectors that have an objective value equal to at least a percentage of the optimal value,\n\n```python\nmodel.set_opt_percentage(90)\nfva_output = model.fva()\n\n# the same restriction in the flux space holds for the sampler\nsampler = polytope_sampler(model)\nsteady_states = sampler.generate_steady_states()\n```\n\nThe default percentage is `100%`.\n\n\n\n### Change the objective function\n\nYou could also set an alternative objective function. For example, to maximize the 1st reaction of the model,\n\n```python\nn = model.num_of_reactions()\nobj_fun = np.zeros(n)\nobj_fun[0] = 1\nmodel.objective_function(obj_fun)\n\n# apply FVA using the new objective function\nfva_output = model.fva()\n# sample from the flux space by restricting\n# the fluxes according to the new objective function\nsampler = polytope_sampler(model)\nsteady_states = sampler.generate_steady_states()\n```\n\n\n\n### Plot flux marginals\n\nThe generated steady states can be used to estimate the marginal density function of each flux. You can plot the histogram using the samples,\n\n```python\nfrom dingo_walk import plot_histogram\n\nmodel = MetabolicNetwork.from_json(\'path/to/e_coli_core.json\')\nsampler = PolytopeSampler(model)\nsteady_states = sampler.generate_steady_states(ess = 3000)\n\n# plot the histogram for the 14th reaction in e-coli (ACONTa)\nreactions = model.reactions\nplot_histogram(\n        steady_states[13],\n        reactions[13],\n        n_bins = 60,\n        )\n```\n\nThe default number of bins is 60. dingo_walk uses the package `matplotlib` for plotting.\n\n![histogram](https://raw.githubusercontent.com/GeomScale/dingo/refs/heads/develop/doc/e_coli_aconta.png)\n\n### Plot a copula between two fluxes\n\nThe generated steady states can be used to estimate and plot the copula between two fluxes. You can plot the copula using the samples,\n\n```python\nfrom dingo_walk import plot_copula\n\nmodel = MetabolicNetwork.from_json(\'path/to/e_coli_core.json\')\nsampler = PolytopeSampler(model)\nsteady_states = sampler.generate_steady_states(ess = 3000)\n\n# plot the copula between the 13th (PPC) and the 14th (ACONTa) reaction in e-coli\nreactions = model.reactions\n\ndata_flux2=[steady_states[12],reactions[12]]\ndata_flux1=[steady_states[13],reactions[13]]\n\nplot_copula(data_flux1, data_flux2, n=10)\n```\n\nThe default number of cells is 5x5=25. dingo_walk uses the package `plotly` for plotting.\n\n![histogram](https://raw.githubusercontent.com/GeomScale/dingo/refs/heads/develop/doc/aconta_ppc_copula.png)\n\n\n',
    'author': 'Apostolos Chalkis',
    'author_email': 'tolis.chal@gmail.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'None',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.8,<4.0',
}
from build import *
build(setup_kwargs)

setup(**setup_kwargs)
