diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74c303e2..899d8882 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,44 +1,37 @@ # CONTRIBUTING `plenoptic` is a python library of tools to help researchers better understand -their models. While the majority of authors are members or alumni of NYU's [Lab -for Computational Vision](https://www.cns.nyu.edu/~lcv/), we welcome other -contributors! +their models. We welcome and encourage contributions from everyone! First, please check out the [Code of Conduct](CODE_OF_CONDUCT.md) and read it -before going any further. You may also want to check out the [README](README.md) -for a longer overview of the project and how to get everything installed, the -tutorials (Jupyter notebooks found in the `examples/` folder) for some examples -of how to interact with the library, and the -[documentation](https://plenoptic.readthedocs.io/). - -If you encounter any issues with `plenoptic`, please open an -[issue](https://github.com/LabForComputationalVision/plenoptic/issues)! -We have a template for bug reports, following it (so you provide the -necessary details) will make solving it easier. Right now, we have -enough on our plate that we're not considering any enhancements or new -features --- we're focusing on implementing what we plan to do. - -If you'd like to help improve `plenoptic`, we have a bunch of issues -we're working through. For people who are not already familiar with -the project, it would be most helpful to go through the tutorials, -README, and documentation and let us know if anything is unclear, what -needs more detail (or clearer writing), etc. But if you think you can -make progress on one of the existing issues, please give it a try. +before going any further. You may also want to check out the [main page of the +documentation](https://plenoptic.readthedocs.io/en/latest/) for a longer +overview of the project and how to get everything installed, as well as pointers +for further reading, depending on your interests. + +If you encounter any issues with `plenoptic`, first search the existing +[issues](https://github.com/LabForComputationalVision/plenoptic/issues) and +[discussions](https://github.com/LabForComputationalVision/plenoptic/discussions) +to see if there's already information to help you. If not, please open a new +[issue](https://github.com/LabForComputationalVision/plenoptic/issues)! We have +a template for bug reports, and following it (so you provide the necessary +details) will make solving your problem much easier. + +If you'd like to help improve `plenoptic`, there are many ways you can +contribute, from improving documentation to writing code. For those not already +familiar with the project, it can be very helpful for us if you go through the +tutorials, README, and documentation and let us know if anything is unclear, +what needs more detail (or clearer writing), etc. For those that want to +contribute code, we also have many +[issues](https://github.com/LabForComputationalVision/plenoptic/issues) that we +are working through. If you would like to work on one of those, please give it a +try! In order to submit changes, create a branch or fork of the project, make your changes, add documentation and tests, and submit a [Pull -Request](https://github.com/LabForComputationalVision/plenoptic/pulls). The -amount and form of documentation to add depends on the size of the submitted -changes. For a significant change (a new model or synthesis method), please -include a new tutorial notebook that walks through how to use them. For -enhancements of existing methods, you can probably just modify the existing -tutorials and add documentation. If unsure, ask! For docstrings, we follow -[numpydoc](https://numpydoc.readthedocs.io/en/latest/format.html) style. See -later in this file for more details on how to run the tests and build the -documentation (if you create a branch on the main repo, Github Actions will run -tests automatically whenever you push, so you don't need to worry about running -them locally). +Request](https://github.com/LabForComputationalVision/plenoptic/pulls). See +[contributing to the code below](#contributing-to-the-code) for more details on +this process. We try to keep all our communication on Github, and we use several channels: @@ -55,28 +48,73 @@ We try to keep all our communication on Github, and we use several channels: ## Contributing to the code -We welcome contributions to `plenoptic`! In order to contribute, please create -your own branch, make sure the tests pass, and open a Pull Request. If you're a -member of the [LCV github](https://github.com/LabForComputationalVision/), you -can create a branch directly in the repository: from within the `plenoptic` -repository: +### Contribution workflow +We welcome contributions to `plenoptic`! In order to contribute, please create +your own branch, make sure the tests pass, and open a Pull Request. We follow +the [GitHub +Flow](https://www.gitkraken.com/learn/git/best-practices/git-branch-strategy#github-flow-branch-strategy) +workflow: no one is allowed to push to the `main` branch, all development +happens in separate feature branches (each of which, ideally, implements a +single feature, addresses a single issue, or fixes a single problem), and these +get merged into `main` once we have determined they're ready. Then, after enough +changes have accumulated, we put out a new release, adding a new tag which +increments the version number, and uploading the new release to PyPI (see +[releases](#releases) for more details). + +In addition to the information that follows, [Github](https://docs.github.com/en/get-started/quickstart/github-flow) (unsurprisingly) has good information on this workflow, as does the [Caiman package](https://github.com/flatironinstitute/CaImAn/blob/main/CONTRIBUTING.md) (though note that the Caiman uses **git** flow, which involves a separate develop branch in addition to main). + +Before we begin: everyone finds `git` confusing the first few (dozen) times they encounter it! And even people with a hard-won understanding frequently look up information on how it works. If you find the following difficult, we're happy to help walk you through the process. Please [post on our GitHub discussions page](https://github.com/LabForComputationalVision/plenoptic/discussions) to get help. + +#### Creating a development environment + +You'll need a local installation of `plenoptic` which keeps up-to-date with any changes you make. To do so, you will need to fork and clone `plenoptic`: + +1. Go to the [plenoptic repo](https://github.com/LabForComputationalVision/plenoptic/) and click on the `Fork` button at the top right of the page. This creates a copy of plenoptic in your Github account. +2. You should then clone *your fork* to your local machine and create an editable installation. To do so, follow the instructions for an editable install found in our [docs](https://plenoptic.readthedocs.io/en/latest/install.html#installation), replacing `git clone https://github.com/LabForComputationalVision/plenoptic.git` with `git clone https://github.com//plenoptic.git`. +3. Add the `upstream` branch: `git remote add upstream https://github.com/LabForComputationalVision/plenoptic.git`. At this point, you have two remotes: `origin` (your fork) and `upstream` (the canonical version). You won't have permission to push to upstream (only `origin`), but this makes it easy to keep your `plenoptic` up to date with the canonical version by pulling from upstream: `git pull upstream`. + +You should probably also install all the optional dependencies, so that you can run tests, build the documentation, and run the jupyter notebooks locally. To do so, run `pip install -e .[docs,dev,nb]` from within the copy of `plenoptic` on your machine (see [this section](https://plenoptic.readthedocs.io/en/latest/install.html#jupyter) of our documentation for information on how to set up jupyter if you don't want an extra copy of it in this environment). + +#### Creating a new branch + +As discussed above, each feature in `plenoptic` is worked on in a separate branch. This allows us to have multiple people developing multiple features simultaneously, without interfering with each other's work. To create your own branch, run the following from within your `plenoptic` directory: + +```bash +# switch to main branch of your fork +git checkout main +# update your fork from your github +git pull origin main +# ensure your fork is in sync with the canonical version +git pull upstream main +# update your fork's main branch with any changes from upstream +git push origin main +# create and switch to the branch +git checkout -b my_cool_branch ``` -git checkout -b my_cool_branch # create and switch to the branch -# make some changes -git commit -a -m "A helpful message explaining my changes" # commit your changes -git push origin my_cool_branch # push to the origin remote + +Then, create new changes on this branch and, when you're ready, add and commit them: + +```bash +# stage the changes +git add src/plenoptic/the_file_you_changed.py +# commit your changes +git commit -m "A helpful message explaining my changes" +# push to the origin remote +git push origin my_cool_branch ``` -Once you're happy with your changes, [add tests](#adding-tests) to check that -they run correctly, then make sure the rest of the [tests](#testing) all run -successfully, that your branch is up-to-date with main, and then open a pull -request (see [here](https://yangsu.github.io/pull-request-tutorial/) for a -tutorial). +If you aren't comfortable with `git add`, `git commit`, `git push`, I recommend the [Software Carpentry git lesson](https://swcarpentry.github.io/git-novice/). + +#### Contributing your change back to plenoptic + +You can make any number of changes on your branch. Once you're happy with your changes, [add tests](#adding-tests) to check that they run correctly and [add documentation](#adding-documentation), then make sure the existing [tests](#testing) all run successfully, that your branch is up-to-date with main, and then open a pull request by clicking on the big `Compare & pull request` button that appears at the top of your fork after pushing to your branch (see [here](https://intersect-training.org/collaborative-git/03-pr/index.html) for a tutorial). -If you're not a member of the LCV github, you'll need to first [create a -fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) of the -repository to your own github account, and then proceed as above. +Your pull request should include information on what you changed and why, referencing any relevant issues or discussions, and highlighting any portion of your changes where you have lingering questions (e.g., "was this the right way to implement this?") or want reviewers to pay special attention. You can look at previous closed pull requests to see what this looks like. + +At this point, we will be notified of the pull request and will read it over. We will try to give an initial response quickly, and then do a longer in-depth review, at which point you will probably need to respond to our comments, making changes as appropriate. We'll then respond again, and proceed in an iterative fashion until everyone is happy with the proposed changes. This process can take a while! (The more focused your pull request, the less time it will take.) + +If your changes are integrated, you will be added as a Github contributor and as one of the authors of the package. Thank you for being part of `plenoptic`! ### Style guide @@ -122,14 +160,14 @@ When doing a new release, the following steps must be taken: version tag from the Github release, using [setuptools_scm](https://github.com/pypa/setuptools_scm). - Note that the binder link I have been unable to find a way to make binder use the latest github release tag directly (or make [binder](https://mybinder.org) use a `latest` tag, like [readthedocs](https://readthedocs.org/) does), so ensure they match! - ## Testing Before running tests locally, you'll need -[ffmpeg](https://ffmpeg.org/download.html) installed on your system. +[ffmpeg](https://ffmpeg.org/download.html) installed on your system, as well as +the `dev` optional dependencies (i.e., you should run `pip install -e .[dev]` +from within your local copy of `plenoptic`). To run all tests, run `pytest tests/` from the main `plenoptic` directory. This will take a while, as we have many tests, broken into categories. There are @@ -304,6 +342,12 @@ and `'LNL'`! ### Adding documentation +The amount and form of documentation that need to be added alongside a change +depends on the size of the submitted change. For a significant change (a new +model or synthesis method), please include a new tutorial notebook that walks +through how to use them. For enhancements of existing methods, you can probably +just modify the existing tutorials and add documentation. If unsure, ask! + Documentation in `plenoptic` is built using Sphinx and lives on readthedocs. If that means nothing to you, don't worry! @@ -417,7 +461,7 @@ conda env create -f docs/environment.yml # activate the environment conda activate plenoptic_docs # install plenoptic -pip install -e . +pip install -e .[docs] # build documentation cd docs/ make html diff --git a/docs/conf.py b/docs/conf.py index 0fc83247..093c6923 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -51,6 +51,7 @@ 'sphinx_autodoc_typehints', 'sphinx.ext.intersphinx', 'sphinx_copybutton', + 'sphinxemoji.sphinxemoji', ] # Add any paths that contain templates here, relative to this directory. diff --git a/docs/index.rst b/docs/index.rst index 2cbbf7c6..d70de837 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -26,6 +26,7 @@ plenoptic ********* +.. _index: |pypi-shield| |license-shield| |python-version-shield| |build| |zenodo| |codecov| |binder| diff --git a/docs/install.rst b/docs/install.rst index fcd73f5d..075c1ad0 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -3,20 +3,15 @@ Installation ************ -The following instructions will work on Linux or Mac. If you're on Windows, I -recommend looking into the `Windows Subsystem for Linux -`_ +``plenoptic`` should work on Windows, Linux, or Mac. If you have a problem with installation, please open a `bug report `_! -The easiest way to install ``plenoptic`` is with pip within a new `conda -`_ environment (if you do not have ``conda`` -installed on your machine, I recommend starting with `miniconda -`_):: +The easiest way to install ``plenoptic`` is from `PyPI `_ (the Python Package Index) using pip within a new virtual environment. The instructions on this page use `conda `_, which we recommend if you are unfamiliar with python environment management, but other virtual environment systems should work. If you wish to follow these instructions and do not have ``conda`` installed on your machine, I recommend starting with `miniconda `_.:: $ conda create --name plenoptic pip python=3.9 $ conda activate plenoptic $ pip install plenoptic -You can also install it directly from source:: +You can also install it directly from source to have a local editable copy. This is most useful for developing (for more info, see `our contributing guide `_) or if you want to use the most cutting-edge version:: $ conda create --name plenoptic pip python=3.9 $ conda activate plenoptic @@ -26,8 +21,22 @@ $ cd plenoptic $ # install in editable mode with `-e` or, equivalently, `--editable` $ pip install -e . +With an editable copy, any changes locally will be automatically reflected in your installation (under the hood, this command uses symlinks). + .. attention:: To install ``plenoptic`` in editable mode, you need ``pip >= 21.3`` (see pip's `changelog `_). If you run into `an error `_ after running the ``pip install -e .`` command, try updating your pip version with ``pip install --upgrade pip``. +.. _optional-deps: +Optional dependencies +--------------------- + +The above instructions will install plenoptic and its core dependencies. You may also wish to install some additional optional dependencies. These dependencies are specified using square brackets during the pip install command and can be installed for either a local, editable install or one directly from PyPI: + +* If you would like to run the jupyter notebooks locally: ``pip install plenoptic[nb]`` or ``pip install -e .[nb]``. This includes ``torchvision``, ``jupyter``, and related libraries. See the :ref:`jupyter section ` for more details on how to handle jupyter and python virtual environments. Note that you can run our notebooks in the cloud using `Binder `_, no installation required! +* If you would like to locally build the documentation: ``pip install -e .[docs]``. This includes ``sphinx`` and related libraries. (This probably only makes sense if you have a local installation.) +* If you would like to run the tests: ``pip install -e .[dev]``. This includes ``pytest`` and related libraries. (This probably only makes sense if you have a local installation.) + +These optional dependencies can be joined with a comma: ``pip install -e .[docs,dev]`` + ffmpeg and videos ----------------- @@ -45,45 +54,101 @@ To change the backend, run ``matplotlib.rcParams['animation.writer'] = writer`` before calling any of the animate functions. If you try to set that ``rcParam`` with a random string, ``matplotlib`` will tell you the available choices. -Jupyter -------- +.. _jupyter: +Running notebooks locally +------------------------- + +.. tip:: You can run the notebooks in the cloud using `Binder `_, no installation required! + +Installing jupyter and setting up the kernel +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you wish to locally run the notebooks, you will need to install ``jupyter``, -``ipywidgets``, and (for some of the notebooks) ``torchvision`` (you can also -run them in the cloud using `Binder -`_). -There are two main ways of getting a local `jupyter` install` working with this -package: +``ipywidgets``, and (for some of the notebooks) ``torchvision`` . +There are three possible ways of getting a local jupyter install working with this +package, depending on how you wish to handle virtual environments. -1. Install jupyter in the same environment as ``plenoptic``. If you followed the - instructions above to create a ``conda`` environment named ``plenoptic``, do - the following:: +.. hint:: If ``plenoptic`` is the only environment that you want to run notebooks from and/or you are unfamiliar with virtual environments, go with option 1 below. + +1. Install jupyter in the same environment as ``plenoptic``. This is the easiest + but, if you have multiple virtual environments and want to use Jupyter + notebooks in each of them, it will take up a lot of space. If you followed + the instructions above to create a ``conda`` environment named ``plenoptic``, + do the following:: $ conda activate plenoptic $ conda install -c conda-forge jupyterlab ipywidgets torchvision - This is easy but, if you have multiple conda environments and want to use - Jupyter notebooks in each of them, it will take up a lot of space. + With this setup, when you have another virtual environment that you wish to run jupyter notebooks from, you must reinstall jupyuter into that separate virtual environment, which is wasteful. -2. Use `nb_conda_kernels - `_. Again, if you - followed the instructions to create a ``conda`` environment named - ``plenoptic``:: +2. Install jupyter in your ``base`` environment and use `nb_conda_kernels + `_ to automatically + manage kernels in all your conda environments. This is a bit more + complicated, but means you only have one installation of jupyter lab on your + machine. Again, if you followed the instructions to create a ``conda`` + environment named ``plenoptic``:: $ # activate your 'base' environment, the default one created by conda/miniconda - $ conda activate + $ conda activate base $ # install jupyter lab and nb_conda_kernels in your base environment $ conda install -c conda-forge jupyterlab ipywidgets $ conda install nb_conda_kernels $ # install ipykernel and torchvision in the plenoptic environment $ conda install -n plenoptic ipykernel torchvision - This is a bit more complicated, but means you only have one installation of - jupyter lab on your machine. + With this setup, you have a single jupyter install that can run kernels from any of your conda environments. All you have to do is install ``ipykernel`` (and restart jupyter) and you should see the new kernel! + + .. attention:: This method only works with conda environments. If you are using another method to manage your python virtual environments, you'll have to use one of the other methods. + +3. Install jupyter in your ``base`` environment and manually install the kernel in your virtual environment. This requires only a single jupyter install and is the most general solution (it will work with conda or any other way of managing virtual environments), but requires you to be a bit more comfortable with handling environments. Again, if you followed the instructions to create a ``conda`` environment named ``plenoptic``:: + + $ # activate your 'base' environment, the default one created by conda/miniconda + $ conda activate base + $ # install jupyter lab and nb_conda_kernels in your base environment + $ conda install -c conda-forge jupyterlab ipywidgets + $ # install ipykernel and torchvision in the plenoptic environment + $ conda install -n plenoptic ipykernel torchvision + $ conda activate plenoptic + $ python -m ipykernel install --prefix=/path/to/jupyter/env --name 'plenoptic' + + ``/path/to/jupyter/env`` is the path to your base conda environment, and depends on the options set during your initial installation. It's probably something like ``~/conda`` or ``~/miniconda``. See the `ipython docs `_ for more details. + + With this setup, similar to option 2, you have a single jupyter install that can run kernels from any virtual environment. The main difference is that it can run kernels from *any* virtual environment (not just conda!) and have fewer packages installed in your ``base`` environment, but that you have to run an additional line after installing ``ipykernel`` into the environment (``python -m ipykernel install ...``). + + .. note:: If you're not using conda to manage your environments, the key idea is to install ``jupyter`` and ``ipywidgets`` in one environment, then install ``ipykernel`` and ``torchvision`` in the same environment as plenoptic, and then run the ``ipykernel install`` command **using the plenoptic environment's python**. + +The following table summarizes the advantages and disadvantages of these three choices: + +.. list-table:: + :header-rows: 1 + + * - Method + - Advantages + - Disadvantages + * - 1. Everything in one environment + - |:white_check_mark:| Simple + - |:x:| Requires lots of hard drive space + * - 2. ``nb_conda_kernels`` + - |:white_check_mark:| Set up once + - |:x:| Initial setup more complicated + * - + - |:white_check_mark:| Requires only one jupyter installation + - + * - + - |:white_check_mark:| Automatically finds new environments with ``ipykernel`` installed + - + * - 3. Manual kernel installation + - |:white_check_mark:| Flexible: works with any virtual environment setup + - |:x:| More complicated + * - + - |:white_check_mark:| Requires only one jupyter installation + - |:x:| Extra step for each new environment + +You can install all of the extra required packages using ``pip install -e .[nb]`` (if you have a local copy of the source code) or ``pip install plenoptic[nb]`` (if you are installing from PyPI). This includes jupyter, and so is equivalent to method 1 above. See the :ref:`optional dependencies section ` for more details. + +Running the notebooks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Once you have jupyter installed and the kernel set up, navigate to plenoptic's ``examples/`` directory on your terminal and activate the environment you installed jupyter into (``conda activate plenoptic`` for method 1, ``conda activate base`` for methods methods method 2 or 3), then run ``jupyter`` and open up the notebooks. If you followed the second or third method, you should be prompted to select your kernel the first time you open a notebook: select the one named "plenoptic". -In either case, to open the notebooks, navigate to the ``examples/`` directory -under this one on your terminal and activate the environment you install jupyter -into (``plenoptic`` for 1, ``base`` for 2), then run ``jupyter`` and open up the -notebooks. If you followed the second method, you should be prompted to select -your kernel the first time you open a notebook: select the one named -"plenoptic". +.. attention:: If you installed ``plenoptic`` from PyPI, then you will not have the notebooks on your machine and will need to download them directly from `our GitHub repo `_. If you have a local install (and thus ran ``git clone``), then the notebooks can be found in the ``examples/`` directory. diff --git a/pyproject.toml b/pyproject.toml index 76f15419..32318aa3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,6 +43,7 @@ docs = [ # https://nbsphinx.readthedocs.io/en/0.6.0/installation.html#Pygments-Lexer-for-Syntax-Highlighting 'ipython', 'sphinx-copybutton', + 'sphinxemoji', ] dev = [ @@ -56,6 +57,7 @@ dev = [ nb = [ 'jupyter', 'ipywidgets', + "torchvision>=0.3", 'nbclient>=0.5.5', ]