diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 0000000..a758a4f --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,21 @@ +--- +name: Codespell + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + codespell: + name: Check for spelling errors + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Annotate locations with typos + uses: codespell-project/codespell-problem-matcher@v1 + - name: Codespell + uses: codespell-project/actions-codespell@v2 diff --git a/.github/workflows/publish-book.yml b/.github/workflows/publish-book.yml new file mode 100644 index 0000000..61eda89 --- /dev/null +++ b/.github/workflows/publish-book.yml @@ -0,0 +1,33 @@ +name: publish-book + +on: + push: + branches: + - main + +jobs: + deploy-book: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools + python -m pip install .[docs] + pip install jupyter-book sphinxcontrib-mermaid + + - name: Build the book + run: | + jupyter-book build . + + - name: GitHub Pages action + uses: peaceiris/actions-gh-pages@v3.9.3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./_build/html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..39624a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,194 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +#uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the enitre vscode folder +# .vscode/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Cursor +# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to +# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data +# refer to https://docs.cursor.com/context/ignore-files +.cursorignore +.cursorindexingignore diff --git a/README.md b/README.md index cad43fb..c0dd34a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# Code Guidelines +# Code & Data Guidelines -The hub for discussions and best practices on code management! The goal is someone can fork/clone this repo and start a new project easily. This was written by Mackenzie Mathis, and I thank my lab and the open-source community for many lessons learned. +The is a hub for discussions and best practices on code management! The goal is someone can fork/clone this [template repo](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository) and start a new project easily. This was written by Mackenzie Mathis, and I thank my lab and the open-source community for many lessons learned. ## Overview @@ -84,6 +84,12 @@ project_name/ * [DataJoint](https://www.datajoint.com/) examples for managing and querying scientific data pipelines - these are a must; use minimally for data + meta data storage, and use it to automate things you do daily (preprocessing, running DeepLabCut, etc!) * [Templates for common workflows and schema management are here!](https://docs.datajoint.com/elements/) + + +7. **Style Guide for overall code & project management** + + * Tips and practices for code, manuscripts, and figures. + --- diff --git a/_toc.yml b/_toc.yml index fc36ab1..256c418 100644 --- a/_toc.yml +++ b/_toc.yml @@ -1,7 +1,8 @@ format: jb-book -root: README +root: docs/StyleGuide parts: - caption: Main Documentation chapters: + - file: README - file: docs/HowTo_JupyterBook - file: docs/Learning_reseources diff --git a/docs/StyleGuide.md b/docs/StyleGuide.md new file mode 100644 index 0000000..9b75f39 --- /dev/null +++ b/docs/StyleGuide.md @@ -0,0 +1,101 @@ +# Style Guide for Projects in the MLAI + + +## Well before a publication: + +Please see our overall guide on code & project formatting [here](https://github.com/AdaptiveMotorControlLab/WorkspaceTemplate/blob/main/README.md). + +### Main Principles 🔨 Organize your code & data : +- For experimental and ML projects, please use [DataJoint/databases](https://www.datajoint.com/) +- Be sure you work under a lab repo, typically called "https://github.com/AdaptiveMotorControlLab/YourName_workspace". +- For larger projects (DLC, CEBRA, ExperimentalPipelines, you should be sure your "final" work gets into a pipeline; talk to Mackenzie about this) +- Lab Specific: please check the [CommonHelperCode](https://github.com/AdaptiveMotorControlLab/CommonHelperCode) for useful tips & scripts, and contribute your own! + +### Main Principles 🚧 Format your code & documentation: +- In the lab we use the [Google Style Guide](https://google.github.io/styleguide/pyguide.html) for code. Please review this. +- In the lab we use the [semantic versioning of code](https://semver.org/). Please review this. +- In the lab we use the code formatting we outline in the main README [here](https://github.com/AdaptiveMotorControlLab/WorkspaceTemplate/blob/main/README.md). +- As soon as you start a repo, start a JupterBook! Please see [here](https://github.com/AdaptiveMotorControlLab/WorkspaceTemplate/blob/main/README.md), and this repo has the template. + + + +## Ready to write up your work and share your hard work, data, & code? +Here is how to do so most efficiently with me. + +- 🚨 First, I recommend having a one-on-one so we can lay out the paper sketch, authors, data and code sharing plan together if not already done. +- 📝 I ask that we use [overleaf](https://www.overleaf.com/project) for **manuscripts**! Please ask me to start a template to share with you. +- 🗺 I ask we use [figma](https://www.figma.com/) for **figures**; you can start a free educational group (or ask me to start one). Please then link this in the paper basecamp group. +- If you have a deadline (ICCV/NeurIPS, etc), you must have everything ready **1 week before the deadline** and schedule a meeting to go over it (see Timeline below). + +### How to organize this all with Basecamp: +- 🔗 Please link the development code repo code in basecamp +- 🔗 Please link the overleaf +- 🔗 Please link the figma file + +Collectively, your basecamp project should look like this: +![demo](https://github.com/user-attachments/assets/e21bdee1-ede6-4463-a65f-0d1dff3d224f) + + + +## Styles for plots, figures, and how to produce them +- We use `matplotlib` and `seaborn` in python. +- **Every plot in a paper must be reproducible in a Jupyter Notebook**. This means it loads the data (from datajoint/ possible later figshare or zenodo), plots it, and saves it. +- By the time we are ready to submit a paper, it must have a `AMCL\PaperName-figures` repo. + - Here are examples from the lab: + - CellSeg3D: https://github.com/C-Achard/cellseg3d-figures + - CEBRA: https://github.com/AdaptiveMotorControlLab/CEBRA-demos +- I really like the plots in [CEBRA](https://www.nature.com/articles/s41586-023-06031-6), which you can find here: https://github.com/AdaptiveMotorControlLab/cebra-figures + +### Example plotting style: +- Here is an example, be sure to note the **font, size, broken axis, transparency output**, etc: + +```python +plt.figure(figsize=(3.5, 3.5), dpi = 200) +ax = plt.subplot(111) + +keys = ['cebra', 'pivae', 'autolfads', 'tsne', 'umap'] +df = pd.DataFrame(synthetic_scores) +sns.stripplot(data=df[keys] * 100, color="black", s=3, zorder=1, jitter=0.15) +sns.scatterplot(data=df[keys].median() * 100, color="orange", s=50) +plt.ylabel("$R^2$", fontsize=20) +plt.yticks( + np.linspace(0, 100, 11, dtype=int), np.linspace(0, 100, 11, dtype=int), fontsize=20 +) +plt.ylim(70, 100) +ax.spines["right"].set_visible(False) +ax.spines["top"].set_visible(False) +ax.tick_params(axis="both", which="major", labelsize=15) +ax.tick_params(axis = 'x', rotation = 45) +ax.set_xticklabels( + ['CEBRA', 'piVAE', 'autoLFADS', 'tSNE', 'UMAP'], +) +sns.despine( + left=False, + right=True, + bottom=False, + top=True, + trim=True, + offset={"bottom": 40, "left": 15}, +) +plt.savefig('figure1_synthetic_comparison.jpg', bbox_inches = "tight", transparent = True) +plt.savefig('figure1_synthetic_comparison.svg', bbox_inches = "tight", transparent = True) +``` +#### THEN: 🚨 Put the SVG into figma, AND for the final versions, make a white axis page & versions 🙏: + +Modify by adding: +```python +for spine in ax.spines.values(): + spine.set_color("white") +ax.tick_params(colors="white") +ax.yaxis.label.set_color("white") +ax.xaxis.label.set_color("white") +``` + + +### Timeline Major Point: + +For conference submissions, all papers must be in final form 1 week prior to the deadline. +There will be no exceptions going forward. +This gives us needed time to reflect, refine writing, get some distance, and ask colleagues for feedback. +It also gives us time to prepare the code submission, and potentially arXiv the work -- which is always preferred. +We should not be submitting manuscripts to conferences we would not want publicly read!