How to contribute

Report Bugs

Report bugs at https://github.com/MannLabs/alphapept/issues.

If you are reporting a bug, please include:

  • Your operating system name and version.
  • Any details about your local setup that might be helpful in troubleshooting.
  • Detailed steps to reproduce the bug.

Fix Bugs

Look through the GitHub issues for bugs. Anything tagged with “bug” and “help wanted” is open to whoever wants to implement it.

Implement Features

Look through the GitHub issues for features. Anything tagged with “enhancement” and “help wanted” is open to whoever wants to implement it.

Write Documentation

AlphaPept could always use more documentation, whether as part of the official AlphaPept documentation, in docstrings, or even on the web in blog posts, articles, and such. See below for our docstring convention.

Submit Feedback

The best way to send feedback is to file an issue at https://github.com/MannLabs/alphapept/issues.

If you are proposing a feature:

  • Explain in detail how it would work.
  • Keep the scope as narrow as possible, to make it easier to implement.
  • Remember that this is a volunteer-driven project, and that contributions are welcome :)

Get Started!

Ready to contribute? Here’s how to set up alphapept for local development.

  1. Fork the alphapept repo on GitHub.

  2. Clone your fork locally:

    git clone git@github.com:your_name_here/alphapept.git
  3. Follow the installation instructions in the readme to install a alphapept environment.

  4. Create a branch for local development::

    git checkout -b name-of-your-bugfix-or-feature

    Now you can make your changes locally.

  5. See below in the Notes for Programmers about how to use the nbdev environment.

  6. Commit your changes and push your branch to GitHub::

    git add .
    git commit -m "Your detailed description of your changes."
    git push origin name-of-your-bugfix-or-feature
  7. Submit a pull request through the GitHub website.

PR submission guidelines

  • Keep each PR focused. While it’s more convenient, do not combine several unrelated fixes together. Create as many branches as needed to keep each PR focused.
  • Do not mix style changes/fixes with “functional” changes. It’s very difficult to review such PRs, and it most likely gets rejected.
  • Do not turn an already submitted PR into your development playground. If after you submitted PR, you discovered that more work is needed - close the PR, do the required work and then submit a new PR. Otherwise, each of your commits requires attention from maintainers of the project.
  • If, however, you submitted a PR and received a request for changes, you should proceed with commits inside that PR, so that the maintainer can see the incremental fixes and won’t need to review the whole PR again. In the exceptional case where you realize it’ll take many many commits to complete the requests, then it’s probably best to close the PR, do the work and then submit it again. Again, use common sense where you’d choose one way over another.

Notes for Programmers

Literal Programming

A key feature is the use of nbdev. We like to keep the entrance barrier low to attract new coders to contribute to the AlphaPept package. For this, we see nbedv as an ideal tool to document and modify code. To install nbdev use pip install nbdev and then install the git hooks in the folder where your GitHub repository is cloned (nbdev_install_git_hooks). The key commands for nbdev are:

  • nbdev_build_lib: build the library from the notebooks
  • nbdev_test_nbs: test all notebooks
  • nbdev_clean_nbs: clean the notebooks (strip from unnecessary metadata)

Docstring convention

The docstring convention we adhere to is from the Google stylegyuide.

Below a sample docstring (Note the empty space after Args/Returns/Raises):

def sample_function(a_string: str, a_int: int, a_flag: bool) -> str:
    """Sample function that performs a sample calculation.

    Args:
        a_string (str): A string.
        a_int (int): An integer.
        a_flag (bool): A flag.

    Returns:
        str: A string based on the input
    """    
    

Examples:

  • pandas dataframes: df: pd.DataFrame
  • numpy arrays: x:np.ndarray. You can further specify the dimension (e.g. of numpy arrays) in the docstring.
  • args and kwargs: list and dict. It is generally not needed to type-hint these but state in the Args what they are and what can be done with them.
  • callbacks: typing.Callable, e.g. Callable[[Arg1Type, Arg2Type], ReturnType]

Useful tricks:

  • When using Visual Studio Code, you can use the Python Docstring Generator to automatically generate the docstrings with this format.
  • When changing the docstrings in the code, you can propagate the changes back to the notebooks with nbdev_update_lib [filename].
Note

Type hints are highly recommended but not mandatory (see also PEP484). As the Legacy codebase had no type hints, we are slowly moving towards more type hinting coverage.

Note

Adding additional elements (e.g lines like ——-) to the docstring could break how the documentation is displayed. Below is the function from above but exported to show how it would appear in the documentation.


source

sample_function

 sample_function (a_string:str, a_int:int, a_flag:bool)

Sample function that performs a sample calculation.

Args: a_string (str): A string. a_int (int): An integer. a_flag (bool): A flag.

Returns: str: A string based on the input

Tests

In order to make AlphaPept a sustainable package, it is imperative that all functions have tests. This is not only to ensure the proper execution of the function but also for the long run when wanting to keep up-to-date with package updates. For tracking package updates, we rely on dependabot. For continuous integration, we use GitHub Actions.

Unit Tests

Within the nbdev notebooks, we try to write small tests for each function. They should be lightweight so that running (and hence testing) the notebooks should not take too long. You define your code in a cell with the #export-flag and you can write a text in the following cell. To prevent the cell from showing up in the documentation, you can add a #hide-flag. To be flexible and maybe migrate from the notebook tests to pytest we write the tests with leading test_ and the function name and execute it in the cell.

Example

Cell that defines the code:

#export

def function_a():
    return 5

Next cell with the test function and calling the test.

def test_function_a():
    assert function_a() == 5

test_function_a()
Note

AlphaPept contains a testfolder testfiles with testfiles which are used for some functions to perform tests on files.

GitHub Actions

We use GitHub Actions as part of the continuous integration framework.

Within the repository, the actions are defined as yml files in ./.github/workflows/.

Currently, the following actions are present:

  • cla_assistant: Action that runs a check if a contributor has signed the CLA
  • gpu_test: Helper to run GPU tests. This is not part of the automated pipeline
  • main: Main CI/CD from nbdev. This installs the library and runs all notebooks
  • performance_test: This action freezes the environment and runs multiple test cases specified in test_ci.py. Used to benchmark new versions.
  • quick_test: This action runs the whole AlphaPept pipeline on small test files
  • release: This action triggers the installer compilation and creates a release draft

The quick_test and performance_test are hooked to the MongoDB, so results are reported here.

Some actions are executed on each push (e.g. quick_test, others need to be triggered manually (e.g. release).

Adding an integration test

Note

Unless you are a core developer, there should not be the need to add integration tests. Feel free to create a PR in case.

The best way to add an integration test is by specifying a new test in test_ci.py and then adding a job to the performance_test action. test_ci.py contains a file dictionary with links to files. The idea here is as follows: On the local machine, there should be a BASE_DIR that contains all files used for running the test cases. If the files are not present, the script will download them with the URL from the file dictionary. To define a test case, one needs to initiate a TestRun-class and provide the files to be used. Running a test will always take the current default_settings.yaml and modifying the respective files. You can add subsequent analysis (e.g., such as calculating the false discovery FDR for a mixed species experiment by adding a function to the test class.

To test an integration test locally, simply call the test_ci.py with the respective test (e.g. thermo_irt) like so: python test_ci.py thermo_irt.

Integrating Actions

Note

Unless you are a core developer, there should not be the need to add GitHub Actions. Feel free to create a PR in case.

New actions can be added by creating a .yml file and placing it in the workflows folder. We can distinguish local actions, which run on our self-hosted runners and cloud actions that run on GitHub servers.

The local runners are meant to run computationally intensive tasks such as the performance_test and the quick_test, whereas the cloud actions are meant for unit tests.

Note

If you fork the repository, you will not be able to execute tests on the local runners. They are restricted to the MannLabs repository.

Test Coverage

Ideally, we would like to track test coverage. However, this isn’t easy when having numba-compiled functions. Any solutions to this are greatly appreciated.

Linting

It is planned to include a GitHub action that automatically runs a linter on the code.

Callbacks

As AlphaPept is intended to be the backend of a tool with GUI, we ideally want to be able to get a progress bar out of the major functions. For this, we can pass a callback-argument to the major functions. If the argument is passed, it will return the current progress in the range from 0 to 1.

Version bumping

We are using the python package bump2version. You can use this to bump the version number (install via pip install bump2version). Currently specified is: bump2version: (major, minor, patch):

  • e.g.: bump2version patch for a patch