From 7de964ffc8e07b2c4e89faa9fd4a7a20d229165b Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sat, 5 Sep 2020 11:17:35 +0200 Subject: [PATCH] Restructure and update documentation (#1255) * Split up, cleanup and restructure installation guide * Add background stub * Highlighting * Restructure * Various minor cleanup * Collapse developer information * Split up FAQ by interface * Remove faq from ghp * Update doc --- CODE_OF_CONDUCT.md | 6 +- CONTRIBUTING.md | 2 +- LICENSE.md | 2 +- documentation/CPP.rst | 9 + documentation/{CPP.md => CPP_.md} | 0 documentation/FAQ.md | 74 ---- documentation/MATLAB.rst | 10 + documentation/{MATLAB.md => MATLAB_.md} | 0 documentation/PYTHON.rst | 230 +---------- documentation/about.rst | 4 +- documentation/availability.rst | 36 ++ documentation/background.rst | 79 ++++ documentation/conf.py | 5 +- documentation/contributing.rst | 8 + documentation/cpp_installation.rst | 67 ++++ documentation/cpp_interface.rst | 6 +- documentation/development.md | 141 ------- documentation/development.rst | 160 ++++++++ documentation/glossary.rst | 5 + documentation/how_to_cite.rst | 2 +- documentation/index.rst | 42 +- documentation/matlab.rst | 8 - documentation/matlab_faq.rst | 55 +++ documentation/matlab_installation.rst | 28 ++ documentation/matlab_interface.rst | 510 ++++++++++++++++++++++++ documentation/python_faq.rst | 26 ++ documentation/python_installation.rst | 433 ++++++++++++++++++++ documentation/python_interface.rst | 230 +++++++++++ matlab/mtoc/config/Doxyfile.template | 5 +- python/amici/pysb_import.py | 2 +- 30 files changed, 1692 insertions(+), 493 deletions(-) create mode 100644 documentation/CPP.rst rename documentation/{CPP.md => CPP_.md} (100%) delete mode 100644 documentation/FAQ.md create mode 100644 documentation/MATLAB.rst rename documentation/{MATLAB.md => MATLAB_.md} (100%) create mode 100644 documentation/availability.rst create mode 100644 documentation/background.rst create mode 100644 documentation/contributing.rst create mode 100644 documentation/cpp_installation.rst delete mode 100644 documentation/development.md create mode 100644 documentation/development.rst delete mode 100644 documentation/matlab.rst create mode 100644 documentation/matlab_faq.rst create mode 100644 documentation/matlab_installation.rst create mode 100644 documentation/matlab_interface.rst create mode 100644 documentation/python_faq.rst create mode 100644 documentation/python_installation.rst create mode 100644 documentation/python_interface.rst diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 97fb4e74c1..eaaa3b7037 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -23,13 +23,13 @@ include: Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or - advances + advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic - address, without explicit permission + address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a - professional setting + professional setting ## Our Responsibilities diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e883ecb16..8a096f919c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,4 +9,4 @@ or [`help wanted`](https://github.com/AMICI-dev/AMICI/issues?q=is%3Aissue+is%3Ao For other ideas or questions, just post an issue. For code contributions, please read our -[developer's guide](documentation/development.md) first. +[developer's guide](https://amici.readthedocs.io/en/develop/development.html) first. diff --git a/LICENSE.md b/LICENSE.md index 3b80c243f3..d504f8447a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -# License Conditions +# License conditions ## AMICI diff --git a/documentation/CPP.rst b/documentation/CPP.rst new file mode 100644 index 0000000000..9daac880d1 --- /dev/null +++ b/documentation/CPP.rst @@ -0,0 +1,9 @@ +C++ interface +============= + +.. toctree:: + :maxdepth: 2 + + Installation + Usage + API reference <_exhale_cpp_api/library_root> diff --git a/documentation/CPP.md b/documentation/CPP_.md similarity index 100% rename from documentation/CPP.md rename to documentation/CPP_.md diff --git a/documentation/FAQ.md b/documentation/FAQ.md deleted file mode 100644 index f4831c2daa..0000000000 --- a/documentation/FAQ.md +++ /dev/null @@ -1,74 +0,0 @@ -# FAQ - -__Q__: My model fails to build. - -__A__: Remove the corresponding model directory located in -AMICI/models/*yourmodelname* and compile again. - ---- - -__Q__: It still does not compile. - -__A__: Remove the directory AMICI/models/`mexext` and compile again. - ---- - -__Q__: It still does not compile. - -__A__: Make an [issue](https://github.com/ICB-DCM/AMICI/issues) and we will -have a look. - ---- - -__Q__: My Python-generated model does not compile from MATLAB. - -__A__: Try building any of the available examples before. If this succeeds, -retry building the original model. Some dependencies might not be built -correctly when using only the `compileMexFile.m` script. - ---- - -__Q__: I get an out of memory error while compiling my model on a Windows machine. - -__A__: This may be due to an old compiler version. See -[issue #161](https://github.com/AMICI-dev/AMICI/issues/161) for instructions -on how to install a new compiler. - ---- - -__Q__: How are events interpreted in a DAE context? - -__A__: Currently we only support impulse free events. Also sensitivities -have never been tested. Proceed with care and create an -[issue](https://github.com/AMICI-dev/AMICI/issues) if any problems arise! - ---- - -__Q__: The simulation/sensitivities I get are incorrect. - -__A__: There are some known issues, especially with adjoint sensitivities, -events and DAEs. If your particular problem is not featured in the -[issues](https://github.com/AMICI-dev/AMICI/issues) list, please add it! - ---- - -__Q__: I am trying to install the AMICI Python package, but installation fails -with something like - - amici/src/cblas.cpp:16:13: fatal error: cblas.h: No such file or directory - #include - ^~~~~~~~~ - compilation terminated. - error: command 'x86_64-linux-gnu-gcc' failed with exit status 1 - -__A__: You will have to install a CBLAS-compatible BLAS library and/or set -`BLAS_CFLAGS` as described in the [installation guide](INSTALL.md). - ---- - -__Q__: Importing my model fails with something like -`ImportError: _someModelName.cpython-37m-x86_64-linux-gnu.so: undefined symbol: omp_get_thread_num`. - -__A__: You probably installed the AMICI package with OpenMP support, but did not -have the relevant compiler/linker flags set when importing/building the model. -See [Python-AMICI guide](PYTHON.rst#model-compilation). diff --git a/documentation/MATLAB.rst b/documentation/MATLAB.rst new file mode 100644 index 0000000000..3b22878b71 --- /dev/null +++ b/documentation/MATLAB.rst @@ -0,0 +1,10 @@ +Matlab interface +================ + +.. toctree:: + :maxdepth: 2 + + Installation + Usage + FAQ + API reference <_exhale_matlab_api/library_root> diff --git a/documentation/MATLAB.md b/documentation/MATLAB_.md similarity index 100% rename from documentation/MATLAB.md rename to documentation/MATLAB_.md diff --git a/documentation/PYTHON.rst b/documentation/PYTHON.rst index a363921cc6..5c53ea1e45 100644 --- a/documentation/PYTHON.rst +++ b/documentation/PYTHON.rst @@ -1,230 +1,10 @@ -.. _python_interface: - -**************** Python interface -**************** - -In the following we will give a detailed overview how to specify models in -Python and how to call the generated simulation files. - -Model definition ================ -This guide will guide the user on how to specify models to import and simulate -them using the Python interface. Further examples are available in the AMICI -repository in the -`python/examples `_ -directory. - -SBML import ------------ - -AMICI can import :term:`SBML` models via the -:py:func:`amici.sbml_import.SbmlImporter` class. - -Status of SBML support in Python-AMICI -++++++++++++++++++++++++++++++++++++++ - -Python-AMICI currently **passes 696 out of the 1780 (~39%) test cases** from -the semantic -`SBML Test Suite `_ -(`current status `_). - -In addition, we currently plan to add support for the following features -(see corresponding issues for details and progress): - -- Events (currently Matlab-only) -- Algebraic rules -- Models without species - -contributions are welcome. - -However, the following features are unlikely to be supported: - -- SBML extensions -- `factorial()`, `ceil()`, `floor()`, due to incompatibility with - symbolic sensitivity computations -- initial assignments for parameters -- `delay()` due to missing SUNDIALS solver support - - -How to import an SBML model into AMICI -++++++++++++++++++++++++++++++++++++++ - -To import an :term:`SBML` model into AMICI, first, load an SBML file -using the :py:func:`amici.sbml_import.SbmlImporter` class:: - - import amici - sbml_importer = amici.SbmlImporter('model_steadystate_scaled.sbml') - -the SBML model as imported by `libSBML `_ -is available as:: - - sbml_model = sbml_importer.sbml - -Constants -^^^^^^^^^ - -Model parameters that should be considered :term:`constants ` -can be specified in a list -of strings specifying the SBML ID of the respective parameter, e.g.:: - - constant_parameters=['k4'] - -Observables -^^^^^^^^^^^ - -Observables are specified as a dictionary with observable ID as key and -observable formula as value. - -A convenient way for specifying observables for an SBML model is storing them -as ``AssignmentRule``\ s. Assignment rules that should be considered as observables -can then be extracted using the :py:func:`amici.sbml_import.assignmentRules2observables` -function, e.g.:: - - observables = amici.assignmentRules2observables(sbml, filter_function=lambda variable: - variable.getId().startswith('observable_') and not variable.getId().endswith('_sigma')) - -Standard deviations -^^^^^^^^^^^^^^^^^^^ - -Standard deviations can be specified as dictionaries, such as:: - - sigmas = {'observable_x1withsigma': 'observable_x1withsigma_sigma'} - -Noise distributions -^^^^^^^^^^^^^^^^^^^ - -Various noise distributions including normal and Laplace and discrete -distributions, and scale transformations including linear, log and log10 -are supported:: - - noise_distributions = {'observable_x1withsigma': 'log-normal'} - -Find details in :py:func:`amici.sbml_import.noise_distribution_to_cost_function`. - -Model compilation -^^^^^^^^^^^^^^^^^ - -To generate a Python module from the SBML model, call the method -:py:func:`amici.sbml_import.SbmlImporter.sbml2amici`, passing all the -previously defined model specifications:: - - sbml_importer.sbml2amici('test', 'test', - observables=observables, - constant_parameters=constant_parameters, - sigmas=sigmas) - -Full example -^^^^^^^^^^^^ - -See `here `_ for a full example. - -PySB import ------------ - -AMICI can import :term:`PySB` models via -:py:func:`amici.pysb_import.pysb2amici`. - -`BioNetGen `_ and -`Kappa `_ models can be imported into AMICI using -PySB. - -PEtab import ------------- - -AMICI can import :term:`PEtab`-based model definitions and run simulations for -the specified simulations conditions. For usage, see -`python/examples/example_petab/petab.ipynb `_. - -Importing plain ODEs --------------------- - -The AMICI Python interface does not currently support direct import of ODEs. -However, it is straightforward to encode them as RateRules in an SBML model. -The `yaml2sbml `_ package may come in -handy, as it facilitates generating SBML models from a YAML-based specification -of an ODE model. Besides the SBML model it can also create -`PEtab `_ files. - -SED-ML import -------------- - -We also plan to implement support for the `Simulation Experiment Description Markup Language (SED-ML) `_. - -Model simulation -================ - -AMICI model import creates a Python module for simulation of the respective -model. To use the model module, the model directory has to be manually added to -the python path:: - - import sys - sys.path.insert(0, 'test') - -the compiled model can then be imported as:: - - import test as model_module - -It is usually more convenient to use :py:func:`amici.import_model_module` for -that purpose. - -To obtain a model instance call the `getModel()` method. This model instance -will be instantiated using the default parameter values specified in the -imported model:: - - model = model_module.getModel() - -Specify the simulation timepoints via :py:func:`amici.Model.setTimepoints`:: - - model.setTimepoints(np.linspace(0, 60, 60)) - -For simulation, we need to generate a solver instance:: - - solver = model.getSolver() - -The model simulation can now be carried out using -:py:func:`amici.runAmiciSimulation`:: - - rdata = amici.runAmiciSimulation(model, solver) - - -Examples -======== - .. toctree:: - :maxdepth: 1 - - ExampleSteadystate.ipynb - petab.ipynb - model_presimulation.ipynb - ExampleEquilibrationLogic.ipynb - - -Miscellaneous -============= - -OpenMP support for parallelized simulation for multiple experimental conditions -------------------------------------------------------------------------------- - -AMICI can be built with OpenMP support, which allows to parallelize model -simulations for multiple experimental conditions. - -On Linux and OSX this is enabled by default. This can be verified using:: - - import amici - amici.compiledWithOpenMP() - -If not already enabled by default, you can enable OpenMP support by setting -the environment variables ``AMICI_CXXFLAGS`` and ``AMICI_LDFLAGS`` to the -correct OpenMP flags of your compiler and linker, respectively. This has to be -done for both AMICI package installation *and* model compilation. When using -``gcc`` on Linux, this would be:: - - # on your shell: - AMICI_CXXFLAGS=-fopenmp AMICI_LDFLAGS=-fopenmp pip3 install amici + :maxdepth: 2 - # in python, before model compilation: - import os - os.environ['AMICI_CXXFLAGS'] = '-fopenmp' - os.environ['AMICI_LDFLAGS'] = '-fopenmp' + Installation + Usage + FAQ + API reference diff --git a/documentation/about.rst b/documentation/about.rst index 5f9053a913..7c3895012e 100644 --- a/documentation/about.rst +++ b/documentation/about.rst @@ -33,10 +33,12 @@ Features * Access to and high customizability of :term:`CVODES` and :term:`IDAS` solver * Python, C++, Matlab interface * Sensitivity analysis + * forward * steady state * adjoint - * first- and second-order + * first- and second-order (second-order Matlab-only) + * Pre-equilibration and pre-simulation conditions * Support for `discrete events and logical operations `_ diff --git a/documentation/availability.rst b/documentation/availability.rst new file mode 100644 index 0000000000..b71266cb14 --- /dev/null +++ b/documentation/availability.rst @@ -0,0 +1,36 @@ +Availability +============ + +Source code ++++++++++++ + +The AMICI source code is available as + +- `tar archive `_ +- `zip archive `_ +- Git repository on `GitHub `_ + +If AMICI was downloaded as an archive, it needs to be unpacked. If AMICI was +obtained via cloning the Git repository, no further unpacking is necessary. + +Obtaining AMICI via the Git version control system +-------------------------------------------------- + +In order to always stay up-to-date with the latest AMICI versions, +simply pull it from our Git repository and recompile it when a new +version is available. For more information about Git, check out their +`website `_. + +The Git repository can currently be found at +`https://github.com/AMICI-dev/AMICI `_ +and clone is done via: + +.. code-block:: bash + + git clone https://github.com/AMICI-dev/AMICI.git AMICI + +Python package +++++++++++++++ + +A Python package is available on `PyPI `_, +see below. diff --git a/documentation/background.rst b/documentation/background.rst new file mode 100644 index 0000000000..f9123f6943 --- /dev/null +++ b/documentation/background.rst @@ -0,0 +1,79 @@ +Background +========== + +*This section is to be extended.* + +Publications on various features of AMICI +----------------------------------------- + +Some mathematical background for AMICI is provided in the following +publications: + +* Fröhlich, F., Kaltenbacher, B., Theis, F. J., & Hasenauer, J. (2017). + Scalable Parameter Estimation for Genome-Scale Biochemical Reaction Networks. + PLOS Computational Biology, 13(1), e1005331. + doi:`10.1371/journal.pcbi.1005331 `_. + +* Fröhlich, F., Theis, F. J., Rädler, J. O., & Hasenauer, J. (2017). + Parameter estimation for dynamical systems with discrete events and logical + operations. Bioinformatics, 33(7), 1049-1056. + doi:`10.1093/bioinformatics/btw764 `_. + +* Terje Lines, Glenn, Łukasz Paszkowski, Leonard Schmiester, Daniel Weindl, + Paul Stapor, and Jan Hasenauer. 2019. "Efficient Computation of Steady States + in Large-Scale Ode Models of Biochemical Reaction Networks. + *IFAC-PapersOnLine* 52 (26): 32–37. + DOI: `10.1016/j.ifacol.2019.12.232 `_. + +* Stapor, Paul, Fabian Fröhlich, and Jan Hasenauer. 2018. + "Optimization and Profile Calculation of ODE Models Using Second Order + Adjoint Sensitivity Analysis." *Bioinformatics* 34 (13): i151–i159. + DOI: `10.1093/bioinformatics/bty230 `_. + + +.. note:: + + Implementation details of the latest AMICI versions may differ from the ones + given in the references manuscripts. + + +Third-Party numerical algorithms used by AMICI +---------------------------------------------- + +AMICI uses the following packages from SUNDIALS: + +* CVODES: + + The sensitivity-enabled ODE solver in SUNDIALS. Radu Serban + and Alan C. Hindmarsh. *ASME 2005 International Design Engineering + Technical Conferences and Computers and Information in Engineering + Conference*. American Society of Mechanical Engineers, 2005. + `PDF `__ + +* IDAS + +AMICI uses the following packages from SuiteSparse: + +* Algorithm 907: **KLU** A Direct Sparse Solver for Circuit Simulation + Problems. Timothy A. Davis, Ekanathan Palamadai Natarajan, + *ACM Transactions on Mathematical Software*, Vol 37, Issue 6, 2010, + pp 36:1-36:17. `PDF `__ + +* Algorithm 837: **AMD**, an approximate minimum degree ordering + algorithm, Patrick R. Amestoy, Timothy A. Davis, Iain S. Duff, + *ACM Transactions on Mathematical Software*, Vol 30, Issue 3, 2004, + pp 381-388. `PDF `__ + +* Algorithm 836: **COLAMD**, a column approximate minimum degree ordering + algorithm, Timothy A. Davis, John R. Gilbert, Stefan I. Larimore, + Esmond G. Ng *ACM Transactions on Mathematical Software*, Vol 30, + Issue 3, 2004, pp 377-380. `PDF `__ + +Others: + +* SuperLU_MT + + "A general purpose library for the direct solution of large, + sparse, nonsymmetric systems of linear equations" + (https://crd-legacy.lbl.gov/~xiaoye/SuperLU/#superlu_mt). + SuperLU_MT is optional and is so far only available from the C++ interface. diff --git a/documentation/conf.py b/documentation/conf.py index a237d2f889..0c8349068d 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -232,8 +232,9 @@ def install_amici_deps_rtd(): '.DS_Store', '**.ipynb_checkpoints', 'numpy.py', - 'MATLAB.md', - 'CPP.md', + 'INSTALL.md', + 'MATLAB_.md', + 'CPP_.md', 'gfx' ] diff --git a/documentation/contributing.rst b/documentation/contributing.rst new file mode 100644 index 0000000000..b5c8e662dd --- /dev/null +++ b/documentation/contributing.rst @@ -0,0 +1,8 @@ +Contributing +============ + +.. toctree:: + :maxdepth: 2 + + CONTRIBUTING + CODE_OF_CONDUCT diff --git a/documentation/cpp_installation.rst b/documentation/cpp_installation.rst new file mode 100644 index 0000000000..a5df1d6f3a --- /dev/null +++ b/documentation/cpp_installation.rst @@ -0,0 +1,67 @@ +Building the C++ library +======================== + +The following section describes building the AMICI C++ library: + +.. note:: + + The AMICI C++ interface only supports simulation of models imported using + the :ref:`Python interface ` and + :ref:`Matlab interface `. It cannot be used for model + import itself. + +Prerequisites: + +* CBLAS compatible BLAS library +* HDF5 libraries (currently mandatory, see https://github.com/AMICI-dev/AMICI/issues/1252) +* a C++14 compatible compiler +* a C compiler +* Optional: boost for serialization + +To use AMICI from C++, run the + + ./scripts/buildSundials.sh + ./scripts/buildSuitesparse.sh + ./scripts/buildAmici.sh + +script to build the AMICI library. + +.. note:: + + On some systems, the CMake executable may be named something + other than ``cmake``. In this case, set the ``CMAKE`` environment variable + to the correct name (e.g. ``export CMAKE=cmake3``, in case you have CMake + available as ``cmake3``). + +The static library can then be linked from + + ./build/libamici.a + +In CMake-based packages, amici can be linked via + + find_package(Amici) + +For further usage, consult the AMICI +:ref:`C++ interface documentation `. + + +Supported CBLAS libraries +------------------------- + +The C++ interfaces require a system installation of a CBLAS-compatible +*Basic Linear Algebra Subprograms* (BLAS) library. +AMICI has been tested with various implementations such as Accelerate, +Intel MKL, cblas, openblas and atlas. + +Optional SuperLU_MT support +--------------------------- + +To build AMICI with SuperLU_MT support, run + +.. code-block:: bash + + ./scripts/buildSuperLUMT.sh + ./scripts/buildSundials.sh + cd build/ + cmake -DSUNDIALS_SUPERLUMT_ENABLE=ON .. + make diff --git a/documentation/cpp_interface.rst b/documentation/cpp_interface.rst index f8dac4aa30..01bc753829 100644 --- a/documentation/cpp_interface.rst +++ b/documentation/cpp_interface.rst @@ -1,8 +1,8 @@ .. _cpp_interface: -============= -C++ Interface -============= +=========================== +Using AMICI's C++ interface +=========================== The various import functions in of the :ref:`Python interface ` and diff --git a/documentation/development.md b/documentation/development.md deleted file mode 100644 index 59802e28de..0000000000 --- a/documentation/development.md +++ /dev/null @@ -1,141 +0,0 @@ -# AMICI developer's guide - -This document contains information for AMICI developers, not too relevant to -regular users. - - -## Branches / releases - -AMICI roughly follows the -[GitFlow](https://nvie.com/posts/a-successful-git-branching-model/). All new -contributions are merged into `develop`. These changes are regularly merged -into `master` as new releases. For release versioning we are trying to follow -[semantic versioning](https://semver.org/). New releases are created on Github -and are automatically deployed to -[Zenodo](https://zenodo.org/record/3362453#.XVwJ9vyxVMA) for archiving and to -obtain a digital object identifier (DOI) to make them citable. -Furthermore, our [CI pipeline](documentation/CI.md) will automatically create -and deploy a new release on [PyPI](https://pypi.org/project/amici/). - -We try to keep a clean git history. Therefore, feature pull requests are -squash-merged to `develop`. Merging of release branches to master is done via -merge commits. - - -## When starting to work on some issue - -When starting to work on some Github issue, please assign yourself to let other -developers know that you are working on it to avoid duplicate work. If the -respective issue is not completely clear, it is generally a good idea to ask -for clarification before starting to work on it. - -If you want to work on something new, please create a Github issue first. - - -## Code contributions - -When making code contributions, please follow our style guide and the process -described below: - -* Check if you agree to release your contribution under the conditions provided - in `LICENSE`. By opening a pull requests you confirm us that you do agree. - -* Start a new branch from `develop` (on your fork, or at the main - repository if you have access) - -* Implement your changes - -* Submit a pull request to the `develop` branch - -* Make sure your code is documented appropriately - - * Run `scripts/run-doxygen.sh` to check completeness of your documentation - -* Make sure your code is compatible with C++11, `gcc` and `clang` - (our CI pipeline will do this for you) - -* When adding new functionality, please also provide test cases - (see `tests/cpputest/` and [documentation/CI.md](documentation/CI.md)) - -* Write meaningful commit messages - -* Run all tests to ensure nothing was broken - ([more details](documentation/CI.md)) - - * Run `scripts/buildAll.sh && scripts/run-cpputest.sh`. - - * If you made changes to the Matlab or C++ code and have a Matlab license, - please also run `tests/cpputest/wrapTestModels.m` and `tests/testModels.m` - - * If you made changes to the Python or C++ code, - run `make python-tests` in `build` - -* When all tests are passing and you think your code is ready to merge, - request a code review - (see also our [code review guideline](documentation/code_review_guide.md)) - -* Wait for feedback. If you do not receive feedback to your pull request within - a week, please give us a friendly reminder. - - -### Style guide - - -#### General - -* All files and functions should come with file-level and function-level - documentation. - -* All new functionality should be covered by unit or integration tests. Runtime - of those tests should be kept as short as possible. - - -#### Python - -* We want to be compatible with Python 3.6 - -* For the Python code we want to follow - [PEP8](https://www.python.org/dev/peps/pep-0008/). Although this is not the - case for all existing code, any new contributions should do so. - -* We use Python [type hints](https://docs.python.org/3/library/typing.html) - for all functions (but not for class attributes, since they are not supported - by the current Python doxygen filter). In Python code type hints should be - used instead of doxygen `@type`. (All legacy `@type` attributes are to be - removed.) - - For function docstrings, follow this format: - - ``` - """One-line description. - - Possible a more detailed description - - Arguments: - Argument1: This needs to start on the same line, otherwise the current - doxygen filter will fail. - - Returns: - Return value - - Raises: - SomeError in case of some error. - """ - ``` - - -#### C++ - -* We follow C++11 - -* We want to maintain compatibility with g++, clang and the Intel C++ compiler - -* For code formatting, we use the settings from `.clang-format` in the root - directory - -* *Details to be defined* - - -#### Matlab - -*To be defined* diff --git a/documentation/development.rst b/documentation/development.rst new file mode 100644 index 0000000000..0e4899bd27 --- /dev/null +++ b/documentation/development.rst @@ -0,0 +1,160 @@ +AMICI developer’s guide +======================= + +This document contains information for AMICI developers, not too +relevant to regular users. + +Branches / releases +------------------- + +AMICI roughly follows the +`GitFlow `__. +All new contributions are merged into ``develop``. These changes are +regularly merged into ``master`` as new releases. For release versioning +we are trying to follow `semantic versioning `__. +New releases are created on Github and are automatically deployed to +`Zenodo `__ for +archiving and to obtain a digital object identifier (DOI) to make them +citable. Furthermore, our `CI pipeline `__ will +automatically create and deploy a new release on +`PyPI `__. + +We try to keep a clean git history. Therefore, feature pull requests are +squash-merged to ``develop``. Merging of release branches to master is +done via merge commits. + +When starting to work on some issue +----------------------------------- + +When starting to work on some Github issue, please assign yourself to +let other developers know that you are working on it to avoid duplicate +work. If the respective issue is not completely clear, it is generally a +good idea to ask for clarification before starting to work on it. + +If you want to work on something new, please create a Github issue +first. + +Code contributions +------------------ + +When making code contributions, please follow our style guide and the +process described below: + +- Check if you agree to release your contribution under the conditions + provided in ``LICENSE``. By opening a pull requests you confirm us + that you do agree. + +- Start a new branch from ``develop`` (on your fork, or at the main + repository if you have access) + +- Implement your changes + +- Submit a pull request to the ``develop`` branch + +- Make sure your code is documented appropriately + + - Run ``scripts/run-doxygen.sh`` to check completeness of your + documentation + +- Make sure your code is compatible with C++11, ``gcc`` and ``clang`` + (our CI pipeline will do this for you) + +- When adding new functionality, please also provide test cases (see + ``tests/cpputest/`` and + `documentation/CI.md `__) + +- Write meaningful commit messages + +- Run all tests to ensure nothing was broken (`more + details `__) + + - Run ``scripts/buildAll.sh && scripts/run-cpputest.sh``. + + - If you made changes to the Matlab or C++ code and have a Matlab + license, please also run ``tests/cpputest/wrapTestModels.m`` and + ``tests/testModels.m`` + + - If you made changes to the Python or C++ code, run + ``make python-tests`` in ``build`` + +- When all tests are passing and you think your code is ready to merge, + request a code review (see also our `code review + guideline `__) + +- Wait for feedback. If you do not receive feedback to your pull + request within a week, please give us a friendly reminder. + +Style guide +~~~~~~~~~~~ + +General +^^^^^^^ + +- All files and functions should come with file-level and + function-level documentation. + +- All new functionality should be covered by unit or integration tests. + Runtime of those tests should be kept as short as possible. + +Python +^^^^^^ + +- We want to be compatible with Python 3.7 + +- For the Python code we want to follow + `PEP8 `__. Although this + is not the case for all existing code, any new contributions should + do so. + +- We use Python `type + hints `__ for all + functions (but not for class attributes, since they are not supported + by the current Python doxygen filter). In Python code type hints + should be used instead of doxygen ``@type``. + + For function docstrings, follow this format: + + :: + + """One-line description. + + Possible a more detailed description + + Arguments: + Argument1: This needs to start on the same line, otherwise the current + doxygen filter will fail. + + Returns: + Return value + + Raises: + SomeError in case of some error. + """ + +C++ +^^^ + +- We use C++14 + +- We want to maintain compatibility with g++, clang and the Intel C++ + compiler + +- For code formatting, we use the settings from ``.clang-format`` in + the root directory + +- *Details to be defined* + +Matlab +^^^^^^ + +*To be defined* + +Further topics +-------------- + +.. toctree:: + :maxdepth: 2 + + Organization of the documentation + code_review_guide + CI diff --git a/documentation/glossary.rst b/documentation/glossary.rst index e45fad87ac..4f92d18e1a 100644 --- a/documentation/glossary.rst +++ b/documentation/glossary.rst @@ -53,3 +53,8 @@ Glossary `SUNDIALS `_: SUite of Nonlinear and DIfferential/ALgebraic equation Solvers. Provides the :term:`CVODES` and :term:`IDAS` solvers used by AMICI. + + SWIG + `SWIG `_ is a tool that creates interfaces for + C(++) code to a variety of languages. Much of the AMICI Python + interface is generated by SWIG. diff --git a/documentation/how_to_cite.rst b/documentation/how_to_cite.rst index 90b462dd23..840a70bcac 100644 --- a/documentation/how_to_cite.rst +++ b/documentation/how_to_cite.rst @@ -16,7 +16,7 @@ When using AMICI in your project, please cite * Fröhlich, F., Kaltenbacher, B., Theis, F. J., & Hasenauer, J. (2017). Scalable Parameter Estimation for Genome-Scale Biochemical Reaction Networks. - Plos Computational Biology, 13(1), e1005331. + PLOS Computational Biology, 13(1), e1005331. doi:`10.1371/journal.pcbi.1005331 `_. and/or diff --git a/documentation/index.rst b/documentation/index.rst index 8f514f4e51..0872d16d29 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -21,46 +21,30 @@ Welcome to AMICI's documentation! .. toctree:: :maxdepth: 2 - :caption: User's guide + :caption: About about - INSTALL - PYTHON - cpp_interface - matlab.rst - FAQ + availability + LICENSE + how_to_cite + references + background glossary + contributing .. toctree:: :maxdepth: 2 - :caption: AMICI internals - - CONTRIBUTING - Code of conduct - development - Documentation organization - code_review_guide - CI - - -.. toctree:: - :maxdepth: 2 - :caption: API reference - - python_modules - _exhale_cpp_api/library_root - _exhale_matlab_api/library_root + :caption: User's guide + PYTHON + CPP + MATLAB .. toctree:: :maxdepth: 2 - :caption: About - - how_to_cite - references - LICENSE - + :caption: Developer's guide + development Indices and tables ================== diff --git a/documentation/matlab.rst b/documentation/matlab.rst deleted file mode 100644 index ef0d5162b0..0000000000 --- a/documentation/matlab.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _matlab_interface: - -**************** -Matlab Interface -**************** - -* `Overview `_ -* `API reference `_ diff --git a/documentation/matlab_faq.rst b/documentation/matlab_faq.rst new file mode 100644 index 0000000000..309d44ae10 --- /dev/null +++ b/documentation/matlab_faq.rst @@ -0,0 +1,55 @@ +FAQ +=== + +**Q**: My model fails to build. + +**A**: Remove the corresponding model directory located in +AMICI/models/\ *yourmodelname* and compile again. + +-------------- + +**Q**: It still does not compile. + +**A**: Remove the directory AMICI/models/\ ``mexext`` and compile again. + +-------------- + +**Q**: It still does not compile. + +**A**: Make an `issue `__ and +we will have a look. + +-------------- + +**Q**: My Python-generated model does not compile from MATLAB. + +**A**: Try building any of the available examples before. If this +succeeds, retry building the original model. Some dependencies might not +be built correctly when using only the ``compileMexFile.m`` script. + +-------------- + +**Q**: I get an out of memory error while compiling my model on a +Windows machine. + +**A**: This may be due to an old compiler version. See `issue +#161 `__ for instructions +on how to install a new compiler. + +-------------- + +**Q**: How are events interpreted in a DAE context? + +**A**: Currently we only support impulse free events. Also sensitivities +have never been tested. Proceed with care and create an +`issue `__ if any problems +arise! + +-------------- + +**Q**: The simulation/sensitivities I get are incorrect. + +**A**: There are some known issues, especially with adjoint +sensitivities, events and DAEs. If your particular problem is not +featured in the `issues `__ +list, please add it! diff --git a/documentation/matlab_installation.rst b/documentation/matlab_installation.rst new file mode 100644 index 0000000000..a0de396402 --- /dev/null +++ b/documentation/matlab_installation.rst @@ -0,0 +1,28 @@ +Installing the AMICI MATLAB toolbox +=================================== + +To use AMICI from MATLAB, start MATLAB and add the ``AMICI/matlab`` +directory to the MATLAB path. To add all toolbox directories to the +MATLAB path, execute the matlab script: + +.. code-block:: matlab + + installAMICI.m + +To store the installation for further MATLAB session, the path can be +saved via: + +.. code-block:: matlab + + savepath + +For the compilation of ``.mex`` files, MATLAB needs to be configured with a +working C++ compiler. The C++ compiler needs to be installed and +configured via: + +.. code-block:: matlab + + mex -setup c++ + +For a list of supported compilers we refer to the respective MathWorks +`documentation `_. diff --git a/documentation/matlab_interface.rst b/documentation/matlab_interface.rst new file mode 100644 index 0000000000..4f56ce3638 --- /dev/null +++ b/documentation/matlab_interface.rst @@ -0,0 +1,510 @@ +.. _matlab_interface: + +Using AMICI's MATLAB interface +============================== + +In the following we will give a detailed overview how to specify models in +MATLAB and how to call the generated simulation files. + +.. note:: + + The MATLAB interface requires the MathWorks + `Symbolic Math Toolbox `_ + for model import (but not for model simulation). + + The Symbolic Math Toolbox requirement can be circumvented by performing model + import using the Python interface. The resulting code can then be used from + Matlab (see :ref:`matlab_compile_python_imported_model`). + +.. warning:: + + Due to changes in the Symbolic Math Toolbox, the last MATLAB release + with working AMICI model import is R2017b + (see `https://github.com/AMICI-dev/AMICI/issues/307 `__). + + +Specifying models in Matlab ++++++++++++++++++++++++++++ + +This guide will guide the user on how to specify models in MATLAB. +For example implementations see the examples in the ``matlab/examples`` +directory. + +Header +------ + +The model definition needs to be defined as a function which returns a +``struct`` with all symbolic definitions and options. + +.. code-block:: matlab + + function [model] = example_model_syms() + +Options +------- + +Set the options by specifying the respective field of the model struct + +.. code-block:: matlab + + model.(fieldname) = value + +The options specify default options for simulation, parametrisation and +compilation. All of these options are optional. + ++--------------+-----------------------------------------------+---------+ +| field | description | default | ++==============+===============================================+=========+ +| .param | default parametrisation 'log'/'log10'/'lin' | 'lin' | ++--------------+-----------------------------------------------+---------+ +| .debug | flag to compile with debug symbols | false | ++--------------+-----------------------------------------------+---------+ +| .forward | flag to activate forward sensitivities | true | ++--------------+-----------------------------------------------+---------+ +| .adjoint | flag to activate adjoint sensitivities | true | ++--------------+-----------------------------------------------+---------+ + +When set to ``false``, the fields ``forward`` and ``adjoint`` will speed up the +time required to compile the model but also disable the respective sensitivity +computation. + +States +------ + +Create the respective symbolic variables. The name of the symbolic variable +can be chosen arbitrarily. + +.. code-block:: matlab + + syms state1 state2 state3 + +Create the state vector containing all states: + +.. code-block:: matlab + + model.sym.x = [ state1 state2 state3 ]; + +Parameters +---------- + +Create the respective symbolic variables. The name of the symbolic variable can +be chosen arbitrarily. Sensitivities will be derived for all *parameters*. + +.. code-block:: matlab + + syms param1 param2 param3 param4 param5 param6 + +Create the parameters vector + +.. code-block:: matlab + + model.sym.p = [ param1 param2 param3 param4 param5 param6 ]; + +Constants +--------- + +Create the respective symbolic variables. The name of the symbolic variable +can be chosen arbitrarily. Sensitivities with respect to *constants* will not +be derived. + +.. code-block:: matlab + + syms const1 const2 + +Create the constants vector + +.. code-block:: matlab + + model.sym.k = [ const1 const2 ]; + +Differential equations +---------------------- + +For time-dependent differential equations you can specify a symbolic variable +for time. This **needs** to be denoted by ``t``. + +.. code-block:: matlab + + syms t + +Specify the right hand side of the differential equation ``f`` or ``xdot`` + +.. code-block:: matlab + + model.sym.xdot(1) = [ const1 - param1*state1 ]; + model.sym.xdot(2) = [ +param2*state1 + dirac(t-param3) - const2*state2 ]; + model.sym.xdot(3) = [ param4*state2 ]; + +or + +.. code-block:: matlab + + model.sym.f(1) = [ const1 - param1*state1 ]; + model.sym.f(2) = [ +param2*state1 + dirac(t-param3) - const2*state2 ]; + model.sym.f(3) = [ param4*state2 ]; + +The specification of ```f` or ``xdot`` may depend on states, parameters and +constants. + +For DAEs also specify the mass matrix. + +.. code-block:: matlab + + model.sym.M = [1, 0, 0;... + 0, 1, 0;... + 0, 0, 0]; + +The specification of ``M`` may depend on parameters and constants. + +For ODEs the integrator will solve the equation :math:`\dot{x} = f` and for +DAEs the equations :math:`M \cdot \dot{x} = f`. +AMICI will decide whether to use CVODES (for ODEs) or IDAS (for DAEs) based on +whether the mass matrix is defined or not. + +In the definition of the differential equation you can use certain symbolic +functions. For a full list of available functions see +``src/symbolic_functions.cpp``. + +Dirac functions can be used to cause a jump in the respective states at the +specified time-point. This is typically used to model injections, or other +external stimuli. Spline functions can be used to model time/state dependent +response with unknown time/state dependence. + +Initial Conditions +------------------ + +Specify the initial conditions. These may depend on parameters on constants +and must have the same size as ``x``. + +.. code-block:: matlab + + model.sym.x0 = [ param4, 0, 0 ]; + +Observables +----------- + +Specify the observables. These may depend on parameters and constants. + +.. code-block:: matlab + + model.sym.y(1) = state1 + state2; + model.sym.y(2) = state3 - state2; + +In the definition of the observable you can use certain symbolic functions. +For a full list of available functions see ``src/symbolic_functions.cpp``. +Dirac functions in observables will have no effect. + +Events +------ + +Specifying events is optional. Events are specified in terms of a trigger +function, a bolus function and an output function. The roots of the trigger +function defines the occurrences of the event. The bolus function defines the +change in the state on event occurrences. The output function defines the +expression which is evaluated and reported by the simulation routine on every +event occurrence. The user can create events by constructing a vector of +objects of the class :mat:class:`amievent`. + +.. code-block:: matlab + + model.sym.event(1) = amievent(state1 - state2,0,[]); + +Events may depend on states, parameters and constants but *not* on observables. + +For more details about event support see: + + Fröhlich, F., Theis, F. J., Rädler, J. O., & Hasenauer, J. (2017). + Parameter estimation for dynamical systems with discrete events and logical + operations. Bioinformatics, 33(7), 1049-1056. + doi:`10.1093/bioinformatics/btw764 `_. + + +Standard deviation +------------------ + +Specifying standard deviations is optional. It only has an effect when +computing adjoint sensitivities. It allows the user to specify standard +deviations of experimental data for observables and events. + +Standard deviation for observable data is denoted by ``sigma_y`` + +.. code-block:: matlab + + model.sym.sigma_y(1) = param5; + +Standard deviation for event data is denoted by ``sigma_t`` + +.. code-block:: matlab + + model.sym.sigma_t(1) = param6; + +Both ``sigma_y`` and ``sigma_t`` can either be a scalar or of the same dimension +as the observables / events function. +They can depend on time and parameters but must not depend on the states or +observables. The values provided in ``sigma_y`` and ``sigma_t`` will only be used +if the value in ``D.Sigma_Y`` or ``D.Sigma_T`` in the user-provided data struct is +``NaN``. See simulation for details. + +Objective Function +------------------ + +By default, AMICI assumes a normal noise model and uses the corresponding +negative log-likelihood + +.. math:: + + J = 1/2*sum(((y_i(t)-my_ti)/sigma_y_i)^2 + log(2*pi*sigma_y^2) + +as objective function. A user provided objective function can be specified in + +.. code-block:: matlab + + model.sym.Jy + +As reference see the default specification of ``this.sym.Jy`` in ``amimodel.makeSyms``. + +SBML +++++ + +AMICI can also import SBML models using the command ``SBML2AMICI``. +This will generate a model specification as described above, which may be +edited by the user to apply further changes. + +Model Compilation ++++++++++++++++++ + +The model can then be compiled by calling ``amiwrap.m``: + +.. code-block:: matlab + + amiwrap(modelname,'example_model_syms',dir,o2flag) + +Here ``modelname`` should be a string defining the name of the model, ``dir`` +should be a string containing the path to the directory in which simulation +files should be placed and ``o2flag`` is a flag indicating whether second order +sensitivities should also be compiled. +The user should make sure that the previously defined function +``example_model_syms`` is in the user path. Alternatively, the user can also +call the function ``example_model_syms`` + +.. code-block:: matlab + + [model] = example_model_syms() + +and subsequently provide the generated struct to ``amiwrap(...)``, instead of +providing the symbolic function: + +.. code-block:: matlab + + amiwrap(modelname,model,dir,o2flag) + +In a similar fashion, the user could also generate multiple models and pass +them directly to ``amiwrap(...)`` without generating respective model +definition scripts. + + +.. _matlab_compile_python_imported_model: + +Compiling a Python-generated model +---------------------------------- + +Due to better performance or to avoid the Symbolic Toolbox requirement, +it might be desirable to import a model in Python and compile the +resulting code into a mex file. For Python model import, consult the +respective section of the Python documentation. Once the imported +succeeded, there will be a ``compileMexFile.m`` script inside the newly +created model directory which can be invoked to compile the mex file. +This mex file and ``simulate_*.m`` can be used as if fully created by +matlab. + + +Using Python-AMICI model import from Matlab +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +With recent matlab versions it is possible to use the AMICI python package +from within Matlab. This not quite comfortable yet, but it is possible. + +Here for proof of concept: + +* Install the python package as described in the documentation +* Ensure ``pyversion`` shows the correct python version (3.6 or 3.7) +* Then, from within the AMICI ``matlab/`` directory: + +.. code-block:: matlab + + sbml_importer = py.amici.SbmlImporter('../python/examples/example_steadystate/model_steadystate_scaled.xml') + sbml_importer.sbml2amici('steadystate', 'steadystate_example_from_python') + model = py.steadystate.getModel() + solver = model.getSolver() + model.setTimepoints(linspace(0, 50, 51)) + rdata = py.amici.runAmiciSimulation(model, solver) + result = struct(py.dict(rdata.items())) + t = double(py.array.array('d', result.ts)) + x = double(py.array.array('d', result.x.flatten())) + x = reshape(x, flip(double(py.array.array('d', result.x.shape)))) + plot(t, x) + +Model simulation +++++++++++++++++ + +After the call to ``amiwrap(...)`` two files will be placed in the specified +directory. One is a ``_modelname_.mex`` and the other is ``simulate_*modelname*.m``. +The mex file should never be called directly. Instead the MATLAB script, which +acts as a wrapper around the .mex simulation file should be used. + +The ``simulate_ _modelname_.m`` itself carries extensive documentation on how to +call the function, what it returns and what additional options can be +specified. In the following we will give a short overview of possible function +calls. + +Integration +----------- +Define a time vector: + +.. code-block:: matlab + + t = linspace(0,10,100) + +Generate a parameter vector: + +.. code-block:: matlab + + theta = ones(6,1); + +Generate a constants vector: + +.. code-block:: matlab + + kappa = ones(2,1); + +Integrate: + +.. code-block:: matlab + + sol = simulate_modelname(t,theta,kappa,[],options) + + +The integration status will be indicated by the ``sol.status`` flag. Negative +values indicated failed integration. The states will then be available as ``sol.x``. +The observables will then be available as ``sol.y``. The event outputs will then +be available as ``sol.z``. If no event occurred there will be an event at the end +of the considered interval with the final value of the root function is stored +in ``sol.rz``. + +Alternatively the integration can also be called via + +.. code-block:: matlab + + [status,t,x,y] = simulate_modelname(t,theta,kappa,[],options) + +The integration status will be indicated by the flag ``status`` . Negative +values indicated failed integration. The states will then be available as ``x``. +The observables will then be available as ``y``. No event output will be given. + +Forward Sensitivities +--------------------- + +Set the sensitivity computation to forward sensitivities and integrate: + +.. code-block:: matlab + + options.sensi = 1; + options.sensi_meth = 'forward'; + sol = simulate_modelname(t,theta,kappa,[],options) + +The integration status will be indicated by the ``sol.status`` flag. Negative +values indicate failed integration. The states will be available as ``sol.x``, +with the derivative with respect to the parameters in ``sol.sx``. +The observables will be available as ``sol.y``, with the derivative with respect +to the parameters in ``sol.sy``. The event outputs will be available as ``sol.z``, +with the derivative with respect to the parameters in ``sol.sz``. If no event +occured there will be an event at the end of the considered interval with the +final value of the root function stored in ``sol.rz``, with the derivative with +respect to the parameters in ``sol.srz``. + +Alternatively the integration can also be called via + +.. code-block:: matlab + + [status,t,x,y,sx,sy] = simulate_modelname(t,theta,kappa,[],options) + +The integration status will be indicated by the status flag. Negative values +indicate failed integration. The states will then be available as ``x``, with +derivative with respect to the parameters in ``sx``. The observables will then +be available as ``y``, with derivative with respect to the parameters in ``sy``. +No event output will be given. + +Adjoint sensitivities +--------------------- + +Set the sensitivity computation to adjoint sensitivities: + +.. code-block:: matlab + + options.sensi = 1; + options.sensi_meth = 'adjoint'; + +Define Experimental Data: + +.. code-block:: matlab + + D.Y = [NaN(1,2)],ones(length(t)-1,2)]; + D.Sigma_Y = [0.1*ones(length(t)-1,2),NaN(1,2)]; + D.T = ones(1,1); + D.Sigma_T = NaN; + +The ``NaN`` values in ``Sigma_Y`` and ``Sigma_T`` will be replaced by the +specification in ``model.sym.sigma_y`` and ``model.sym.sigma_t``. Data points +with ``NaN`` value will be completely ignored. + +Integrate: + +.. code-block:: matlab + + sol = simulate_modelname(t,theta,kappa,D,options) + +The integration status will be indicated by the sol.status flag. Negative +values indicate failed integration. The log-likelihood will then be available +as ``sol.llh`` and the derivative with respect to the parameters in +``sol.sllh``. Note that for adjoint sensitivities no state, observable and +event sensitivities will be available. Yet this approach can be expected to be +significantly faster for systems with a large number of parameters. + +Steady-state sensitivities +-------------------------- + +This will compute state sensitivities according to the formula + +.. math:: + + s_k^x = -\left(\frac{\partial f}{\partial x} \right)^{-1}\frac{\partial f}{\partial \theta_k} + +In the current implementation this formulation does not allow for conservation +laws as this would result in a singular Jacobian. + +Set the final timepoint as infinity, this will indicate the solver to compute +the steadystate: + +.. code-block:: matlab + + t = Inf; + +Set the sensitivity computation to steady state sensitivities: + +.. code-block:: matlab + + options.sensi = 1; + +Integrate: + +.. code-block:: matlab + + sol = simulate_modelname(t,theta,kappa,D,options) + +The states will be available as ``sol.x``, with the derivative with respect +to the parameters in ``sol.sx``. The observables will be available as ``sol.y``, +with the derivative with respect to the parameters in ``sol.sy``. Notice that +for steady state sensitivities no event sensitivities will be available. For +the accuracy of the computed derivatives it is essential that the system is +sufficiently close to a steady state. This can be checked by examining the +right hand side of the system at the final time-point via ``sol.diagnosis.xdot``. diff --git a/documentation/python_faq.rst b/documentation/python_faq.rst new file mode 100644 index 0000000000..df79f7aa66 --- /dev/null +++ b/documentation/python_faq.rst @@ -0,0 +1,26 @@ +FAQ +=== + +**Q**: I am trying to install the AMICI Python package, but installation +fails with something like + +:: + + amici/src/cblas.cpp:16:13: fatal error: cblas.h: No such file or directory + #include + ^~~~~~~~~ + compilation terminated. + error: command 'x86_64-linux-gnu-gcc' failed with exit status 1 + +**A**: You will have to install a CBLAS-compatible BLAS library and/or +set ``BLAS_CFLAGS`` as described in the installation guides. + +-------------- + +**Q**: Importing my model fails with something like +``ImportError: _someModelName.cpython-37m-x86_64-linux-gnu.so: undefined symbol: omp_get_thread_num``. + +**A**: You probably installed the AMICI package with OpenMP support, but +did not have the relevant compiler/linker flags set when +importing/building the model. See `Python-AMICI +guide `__. diff --git a/documentation/python_installation.rst b/documentation/python_installation.rst new file mode 100644 index 0000000000..547370247c --- /dev/null +++ b/documentation/python_installation.rst @@ -0,0 +1,433 @@ +Installing the AMICI Python package +=================================== + +Short guide ++++++++++++ + +Installation of the AMICI Python package has the following prerequisites: + +* Python>=3.7 +* :term:`SWIG`>=3.0 +* CBLAS compatible BLAS library + (e.g., OpenBLAS, CBLAS, Atlas, Accelerate, Intel MKL) +* a C++14 compatible C++ compiler and a C compiler + (e.g., g++, clang, Intel C++ compiler, mingw) + +If these requirements are fulfilled and all relevant paths are setup properly, +AMICI can be installed using: + +.. code-block:: bash + + pip3 install amici + +If this worked, you can now import the Python module via:: + + import amici + +If this does not work for you, please follow the full instructions below. + +Installation on Linux ++++++++++++++++++++++ + +Ubuntu 20.04 +------------ + +Install the AMICI dependencies via ``apt`` +(this requires superuser privileges): + +.. code-block:: bash + + sudo apt install libatlas-base-dev swig + + # optionally for HDF5 support: + sudo apt install libhdf5-serial-dev + +Install AMICI: + +.. code-block:: bash + + pip3 install amici + +Fedora 32 +--------- + +Install the AMICI dependencies via ``apt`` +(this requires superuser privileges): + +.. code-block:: bash + + sudo dnf install blas-devel swig + +Install AMICI: + +.. code-block:: bash + + pip3 install amici + +Installation on OSX ++++++++++++++++++++ + +Install the AMICI dependencies using homebrew: + +.. code-block:: bash + + brew install swig + + # optionally for HDF5 support: + brew install hdf5 + + # optionally for parallel simulations: + brew install libomp + +Install AMICI: + +.. code-block:: bash + + pip3 install amici + + +Installation on Windows ++++++++++++++++++++++++ + +Some general remarks: + +* Install all libraries in a path not containing white spaces, + e.g. directly under C:. +* Replace the following paths according to your installation. +* Slashes can be preferable to backslashes for some environment + variables. +* See also [#425](https://github.com/AMICI-dev/amici/issues/425) for + further discussion. + +Using the MinGW compilers +------------------------- + +* Install `MinGW-W64 `_ + (the 32bit version will succeed to compile, but fail during linking). + + MinGW-W64 GCC-8.1.0 for ``x86_64-posix-sjlj`` + (`direct link `_) has been shown to work on Windows 7 and 10 test systems. + +* Add the following directory to your ``PATH``: + ``C:\mingw-w64\x86_64-8.1.0-posix-sjlj-rt_v6-rev0\mingw64\bin`` + +* Make sure that this is the compiler that is found by the system + (e.g. ``where gcc`` in a ``cmd`` should point to this installation). + +* Download CBLAS headers and libraries, e.g. + `OpenBLAS `_, + binary distribution 0.2.19. + + Set the following environment variables: + + + ``BLAS_CFLAGS=-IC:/OpenBLAS-v0.2.19-Win64-int32/include`` + + ``BLAS_LIBS=-Wl,-Bstatic -LC:/OpenBLAS-v0.2.19-Win64-int32/lib -lopenblas -Wl,-Bdynamic`` + +* Install `SWIG `_ + and add the SWIG directory to ``PATH`` + (e.g. ``C:\swigwin-3.0.12`` for version 3.0.12) + +* Install AMICI using: + + .. code-block:: bash + + pip install --global-option="build_clib" \ + --global-option="--compiler=mingw32" \ + --global-option="build_ext" \ + --global-option="--compiler=mingw32" \ + amici --no-cache-dir --verbose` + +.. note:: + + **Possible sources of errors:** + + * On recent Windows versions, + ``anaconda3\Lib\distutils\cygwinccompiler.py`` fails linking + ``msvcr140.dll`` with + ``[...] x86_64-w64-mingw32/bin/ld.exe: cannot find -lmsvcr140``. + This is not required for amici, so in ``cygwinccompiler.py`` + ``return ['msvcr140']`` can be changed to ``return []``. + + * If you use a python version where + `python/cpython#880 `_ + has not been fixed yet, you need to disable + ``define hypot _hypot`` in ``anaconda3\include/pyconfig.h`` yourself. + + * ``import amici`` in Python resulting in the very informative + + ImportError: DLL load failed: The specified module could not be found. + + means that some amici module dependencies were not found (not the + AMICI module itself). + `DependencyWalker `_ can show you + which ones. + +Using the Microsoft Visual Studio +--------------------------------- + +.. note:: Support for MSVC is experimental. + +We assume that Visual Studio (not to be confused with Visual Studio Code) +is already installed. Using Visual Studio Installer, the following components +need to be included: + +* Microsoft Visual C++ (MSVC). + This is part of multiple packages, including Desktop Development with C++. +* Windows Universal C Runtime. + This is an individual component and installs some DLLs that we need. + +OpenBLAS +^^^^^^^^ + +There are prebuilt OpenBLAS binaries available, but they did not seem to work +well here. Therefore, we recommend building OpenBLAS from scratch. + +To build OpenBLAS, download the following scripts from the AMICI repository: + +* https://github.com/AMICI-dev/AMICI/blob/master/scripts/installOpenBLAS.ps1 +* https://github.com/AMICI-dev/AMICI/blob/master/scripts/compileBLAS.cmd + +The first script needs to be called in Powershell, and it needs to call +``compileBLAS.cmd``, so you will need to modify line 11: + + C: \\Users\\travis\\build\\AMICI\\scripts\\compileBLAS.cmd + +so that it matches your directory structure. +This will download OpenBLAS and compile it, creating + + C:\\BLAS\lib\\openblas.lib + C:\\BLAS\\bin\\openblas.dll + +You will also need to define two environment variables: + +.. code-block:: text + + BLAS_LIBS="/LIBPATH:C:\BLAS\lib openblas.lib" + BLAS_CFLAGS="/IC:\BLAS\OpenBLAS-v0.3.10\OpenBLAS-0.3.10" + +One way to do that is to run a PowerShell script with the following commands: + +.. code-block:: text + + [System.Environment]::SetEnvironmentVariable("BLAS_LIBS", "/LIBPATH:C:\BLAS\lib openblas.lib", [System.EnvironmentVariableTarget]::User) + [System.Environment]::SetEnvironmentVariable("BLAS_LIBS", "/LIBPATH:C:\BLAS\lib openblas.lib", [System.EnvironmentVariableTarget]::Process) + [System.Environment]::SetEnvironmentVariable("BLAS_CFLAGS", "-IC:\BLAS\OpenBLAS-v0.3.10\OpenBLAS-0.3.10", [System.EnvironmentVariableTarget]::User) + [System.Environment]::SetEnvironmentVariable("BLAS_CFLAGS", "-IC:\BLAS\OpenBLAS-v0.3.10\OpenBLAS-0.3.10", [System.EnvironmentVariableTarget]::Process) + +The call ending in ``Process`` sets the environment variable in the current +process, and it is no longer in effect in the next process. The call ending in +``User`` is permanent, and takes effect the next time the user logs on. + +Now you need to make sure that all required DLLs are within the scope of the +``PATH`` variable. In particular, the following directories need to be included +in ``PATH``: + + C:\\BLAS\\bin + C:\\Program Files (x86)\\Windows Kits\\10\\Redist\\ucrt\\DLLs\\x64 + +The first one is needed for ``openblas.dll`` and the second is needed for the +Windows Universal C Runtime. + +If any DLLs are missing in the ``PATH`` variable, Python will return the +following error upon ``import amici``: + + ImportError: DLL load failed: The specified module could not be found. + +This can be tested using the "where" command. For example + + where openblas.dll + +should return + + C:\\BLAS\\bin\\openblas.dll + +Almost all of the DLLs are standard Windows DLLs and should be included in +either Windows or Visual Studio. But, in case it is necessary to test this, +here is a list of some DLLs required by AMICI (when compiled with MSVC): + +* ``openblas.dll`` +* ``python37.dll`` +* ``MSVCP140.dll`` +* ``KERNEL32.dll`` +* ``VCRUNTIME140_1.dll`` +* ``VCRUNTIME140.dll`` +* ``api-ms-win-crt-convert-l1-1-0.dll`` +* ``api-ms-win-crt-heap-l1-1-0.dll`` +* ``api-ms-win-crt-stdio-l1-1-0.dll`` +* ``api-ms-win-crt-string-l1-1-0.dll`` +* ``api-ms-win-crt-runtime-l1-1-0.dll`` +* ``api-ms-win-crt-time-l1-1-0.dll`` +* ``api-ms-win-crt-math-l1-1-0.dll`` + +``MSVCP140.dll``, ``VCRUNTIME140.dll``, and ``VCRUNTIME140_1.dll`` are needed +by MSVC (see Visual Studio above). ``KERNEL32.dll`` is part of Windows and in +``C:\Windows\System32``. The ``api-ms-win-crt-XXX-l1-1-0.dll`` are needed by +``openblas.dll`` and are part of the Windows Universal C Runtime. + + +Further topics +++++++++++++++ + +Installation of development versions +------------------------------------ + +To install development versions which have not been released to PyPI yet, +you can install AMICI with ``pip`` directly from GitHub using: + +.. code-block:: bash + + pip3 install -e git+https://github.com/AMICI-dev/amici.git@develop#egg=amici\&subdirectory=python/sdist + +Replace ``develop`` by the branch or commit you want to install. + +Note that this will only work on Windows if you have enabled developer mode, +because symlinks are not supported by default +(`more information `_). + +Light installation +------------------ + +In case you only want to use the AMICI Python package for generating model code +for use with Matlab or C++ and don't want to bothered with any unnecessary +dependencies, you can run + +.. code-block:: bash + + pip3 install --install-option --no-clibs amici + +.. note:: + + Following this installation, you will not be able to simulate the imported + models in Python. + +.. note:: + + If you run into an error with above installation command, install all AMICI + dependencies listed in `setup.py `_ + manually, and try again. (This is because ``pip`` ``--install-option`` is + applied to *all* installed packages, including dependencies.) + + +Custom installation +------------------- + +Installation of the AMICI Python package can be customized using a number of +environment variables: + ++----------------------------+----------------------------------+---------------------------------+ +| Variable | Purpose | Example | ++============================+==================================+=================================+ +| ``SWIG`` | Path to the :term:`SWIG` | ``SWIG=$HOME/bin/swig4.0`` | +| | executable | | ++----------------------------+----------------------------------+---------------------------------+ +| ``CC`` | Setting the C(++) compiler | ``CC=/usr/bin/g++`` | ++----------------------------+----------------------------------+---------------------------------+ +| ``CFLAGS`` | Extra compiler flags used in | | +| | every compiler invocation | | ++----------------------------+----------------------------------+---------------------------------+ +| ``BLAS_CFLAGS`` | Compiler flags for, e.g. BLAS | | +| | include directories | | ++----------------------------+----------------------------------+---------------------------------+ +| ``BLAS_LIBS`` | Flags for linking BLAS | | ++----------------------------+----------------------------------+---------------------------------+ +| ``ENABLE_GCOV_COVERAGE`` | Set to build AMICI to generate | ``ENABLE_GCOV_COVERAGE=TRUE`` | +| | code coverage information | | ++----------------------------+----------------------------------+---------------------------------+ +| ``ENABLE_AMICI_DEBUGGING`` | Set to build AMICI with | ``ENABLE_AMICI_DEBUGGING=TRUE`` | +| | debugging symbols | | ++----------------------------+----------------------------------+---------------------------------+ +| ``AMICI_PARALLEL_COMPILE`` | Set to the number of parallel | ``AMICI_PARALLEL_COMPILE=4`` | +| | processes to be used for C(++) | | +| | compilation (defaults to 1) | | ++----------------------------+----------------------------------+---------------------------------+ + +Installation under Anaconda +--------------------------- + +To use an Anaconda installation of Python +`https://www.anaconda.com/distribution/ `_, +Python>=3.7), proceed as follows: + +Since Anaconda provides own versions of some packages which might not +work with AMICI (in particular the ``gcc`` compiler), create a minimal +virtual environment via: + +.. code-block:: bash + + conda create --name ENV_NAME pip python + +Here, replace ``ENV_NAME`` by some name for the environment. + +To activate the environment, run: + +.. code-block:: bash + + source activate ENV_NAME + +(and ``conda deactivate`` later to deactivate it again). + +:term:`SWIG` must be installed and available in your ``PATH``, and a +CBLAS-compatible BLAS must be available. You can also use conda to +install the latter locally, using: + +.. code-block:: bash + + conda install -c conda-forge openblas + +To install AMICI, now run: + +.. code-block:: bash + + pip install amici + +The ``pip`` option ``--no-cache`` may be helpful here to make sure the +installation is done completely anew. + +Now, you are ready to use AMICI in the virtual environment. + +.. note:: + + **Anaconda on Mac** + + If the above installation does not work for you, try installing AMICI via: + + .. code-block:: bash + + CFLAGS="-stdlib=libc++" CC=clang CXX=clang pip3 install --verbose amici + + This will use the ``clang`` compiler. + + You will have to pass the same options when compiling any model later + on. This can be done by inserting the following code before model import: + + .. code-block:: python + + import os + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang' + os.environ['CFLAGS'] = '-stdlib=libc++' + + (For further discussion see https://github.com/AMICI-dev/AMICI/issues/357) + + +Optional Boost support +---------------------- + +`Boost `_ is an optional C++ dependency only required +for special functions (including e.g. gamma derivatives) in the Python +interface. Boost can be installed via package managers via + +.. code-block:: bash + + apt-get install libboost-math-dev + +or + +.. code-block:: bash + + brew install boost + +As only headers are required, also a +`source code `_ +download suffices. The compiler must be able to find the module in the search +path. diff --git a/documentation/python_interface.rst b/documentation/python_interface.rst new file mode 100644 index 0000000000..7fb05b3d7e --- /dev/null +++ b/documentation/python_interface.rst @@ -0,0 +1,230 @@ +.. _python_interface: + +****************************** +Using AMICI's Python interface +****************************** + +In the following we will give a detailed overview how to specify models in +Python and how to call the generated simulation files. + +Model definition +================ + +This guide will guide the user on how to specify models to import and simulate +them using the Python interface. Further examples are available in the AMICI +repository in the +`python/examples `_ +directory. + +SBML import +----------- + +AMICI can import :term:`SBML` models via the +:py:func:`amici.sbml_import.SbmlImporter` class. + +Status of SBML support in Python-AMICI +++++++++++++++++++++++++++++++++++++++ + +Python-AMICI currently **passes 696 out of the 1780 (~39%) test cases** from +the semantic +`SBML Test Suite `_ +(`current status `_). + +In addition, we currently plan to add support for the following features +(see corresponding issues for details and progress): + +- Events (currently Matlab-only) +- Algebraic rules +- Models without species + +contributions are welcome. + +However, the following features are unlikely to be supported: + +- SBML extensions +- `factorial()`, `ceil()`, `floor()`, due to incompatibility with + symbolic sensitivity computations +- initial assignments for parameters +- `delay()` due to missing SUNDIALS solver support + + +How to import an SBML model into AMICI +++++++++++++++++++++++++++++++++++++++ + +To import an :term:`SBML` model into AMICI, first, load an SBML file +using the :py:func:`amici.sbml_import.SbmlImporter` class:: + + import amici + sbml_importer = amici.SbmlImporter('model_steadystate_scaled.sbml') + +the SBML model as imported by `libSBML `_ +is available as:: + + sbml_model = sbml_importer.sbml + +Constants +^^^^^^^^^ + +Model parameters that should be considered :term:`constants ` +can be specified in a list +of strings specifying the SBML ID of the respective parameter, e.g.:: + + constant_parameters=['k4'] + +Observables +^^^^^^^^^^^ + +Observables are specified as a dictionary with observable ID as key and +observable formula as value. + +A convenient way for specifying observables for an SBML model is storing them +as ``AssignmentRule``\ s. Assignment rules that should be considered as observables +can then be extracted using the :py:func:`amici.sbml_import.assignmentRules2observables` +function, e.g.:: + + observables = amici.assignmentRules2observables(sbml, filter_function=lambda variable: + variable.getId().startswith('observable_') and not variable.getId().endswith('_sigma')) + +Standard deviations +^^^^^^^^^^^^^^^^^^^ + +Standard deviations can be specified as dictionaries, such as:: + + sigmas = {'observable_x1withsigma': 'observable_x1withsigma_sigma'} + +Noise distributions +^^^^^^^^^^^^^^^^^^^ + +Various noise distributions including normal and Laplace and discrete +distributions, and scale transformations including linear, log and log10 +are supported:: + + noise_distributions = {'observable_x1withsigma': 'log-normal'} + +Find details in :py:func:`amici.sbml_import.noise_distribution_to_cost_function`. + +Model compilation +^^^^^^^^^^^^^^^^^ + +To generate a Python module from the SBML model, call the method +:py:func:`amici.sbml_import.SbmlImporter.sbml2amici`, passing all the +previously defined model specifications:: + + sbml_importer.sbml2amici('test', 'test', + observables=observables, + constant_parameters=constant_parameters, + sigmas=sigmas) + +Full example +^^^^^^^^^^^^ + +See `here `_ for a full example. + +PySB import +----------- + +AMICI can import :term:`PySB` models via +:py:func:`amici.pysb_import.pysb2amici`. + +`BioNetGen `_ and +`Kappa `_ models can be imported into AMICI using +PySB. + +PEtab import +------------ + +AMICI can import :term:`PEtab`-based model definitions and run simulations for +the specified simulations conditions. For usage, see +`python/examples/example_petab/petab.ipynb `_. + +Importing plain ODEs +-------------------- + +The AMICI Python interface does not currently support direct import of ODEs. +However, it is straightforward to encode them as RateRules in an SBML model. +The `yaml2sbml `_ package may come in +handy, as it facilitates generating SBML models from a YAML-based specification +of an ODE model. Besides the SBML model it can also create +`PEtab `_ files. + +SED-ML import +------------- + +We also plan to implement support for the `Simulation Experiment Description Markup Language (SED-ML) `_. + +Model simulation +================ + +AMICI model import creates a Python module for simulation of the respective +model. To use the model module, the model directory has to be manually added to +the python path:: + + import sys + sys.path.insert(0, 'test') + +the compiled model can then be imported as:: + + import test as model_module + +It is usually more convenient to use :py:func:`amici.import_model_module` for +that purpose. + +To obtain a model instance call the `getModel()` method. This model instance +will be instantiated using the default parameter values specified in the +imported model:: + + model = model_module.getModel() + +Specify the simulation timepoints via :py:func:`amici.Model.setTimepoints`:: + + model.setTimepoints(np.linspace(0, 60, 60)) + +For simulation, we need to generate a solver instance:: + + solver = model.getSolver() + +The model simulation can now be carried out using +:py:func:`amici.runAmiciSimulation`:: + + rdata = amici.runAmiciSimulation(model, solver) + + +Examples +======== + +.. toctree:: + :maxdepth: 1 + + ExampleSteadystate.ipynb + petab.ipynb + model_presimulation.ipynb + ExampleEquilibrationLogic.ipynb + + +Miscellaneous +============= + +OpenMP support for parallelized simulation for multiple experimental conditions +------------------------------------------------------------------------------- + +AMICI can be built with OpenMP support, which allows to parallelize model +simulations for multiple experimental conditions. + +On Linux and OSX this is enabled by default. This can be verified using:: + + import amici + amici.compiledWithOpenMP() + +If not already enabled by default, you can enable OpenMP support by setting +the environment variables ``AMICI_CXXFLAGS`` and ``AMICI_LDFLAGS`` to the +correct OpenMP flags of your compiler and linker, respectively. This has to be +done for both AMICI package installation *and* model compilation. When using +``gcc`` on Linux, this would be:: + + # on your shell: + AMICI_CXXFLAGS=-fopenmp AMICI_LDFLAGS=-fopenmp pip3 install amici + + # in python, before model compilation: + import os + os.environ['AMICI_CXXFLAGS'] = '-fopenmp' + os.environ['AMICI_LDFLAGS'] = '-fopenmp' diff --git a/matlab/mtoc/config/Doxyfile.template b/matlab/mtoc/config/Doxyfile.template index 59bfd84b26..a50605b07c 100644 --- a/matlab/mtoc/config/Doxyfile.template +++ b/matlab/mtoc/config/Doxyfile.template @@ -876,9 +876,8 @@ WARN_LOGFILE = INPUT = "_SourceDir_/README.md" \ "_SourceDir_/LICENSE.md" \ "_SourceDir_/INSTALL.md" \ - "_SourceDir_/documentation/MATLAB.md" \ - "_SourceDir_/documentation/CPP.md" \ - "_SourceDir_/documentation/FAQ.md" \ + "_SourceDir_/documentation/MATLAB_.md" \ + "_SourceDir_/documentation/CPP_.md" \ "_SourceDir_/include" \ "_SourceDir_/matlab" diff --git a/python/amici/pysb_import.py b/python/amici/pysb_import.py index e6fd4f40b6..10d5e0bcf1 100644 --- a/python/amici/pysb_import.py +++ b/python/amici/pysb_import.py @@ -614,7 +614,7 @@ def _compute_target_index(cl_prototypes: CL_Prototype, dict that contains possible indices for every monomer :param ode_model: - ODEModel instance @type ODEModel + ODEModel instance """ possible_indices = list(set(list(itertools.chain(*[ cl_prototypes[monomer]['possible_indices']