From ab67bfcf11add0e9423182aeb28c13abe0bcc731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sara=20Jim=C3=A9nez?= Date: Mon, 28 Oct 2024 15:01:31 +0100 Subject: [PATCH] Initial commit --- .editorconfig | 20 +++ .github/ISSUE_TEMPLATE/bug_report.md | 39 ++++++ .github/ISSUE_TEMPLATE/feature_request.md | 17 +++ .github/pull_request_template.md | 23 ++++ .github/workflows/book.yml | 33 +++++ .github/workflows/lint.yml | 23 ++++ .gitignore | 161 ++++++++++++++++++++++ .pre-commit-config.yaml | 62 +++++++++ LICENSE | 28 ++++ README.md | 42 ++++++ data/.gitkeep | 0 figures/.gitkeep | 0 notebooks/.gitkeep | 0 notebooks/_config.yml | 9 ++ notebooks/_toc.yml | 6 + notebooks/index.md | 42 ++++++ notebooks/template.ipynb | 142 +++++++++++++++++++ pyproject.toml | 123 +++++++++++++++++ scripts/.gitkeep | 0 scripts/template.py | 41 ++++++ src/fancypackage/__init__.py | 3 + src/fancypackage/core/__init__.py | 3 + src/fancypackage/core/_constants.py | 7 + 23 files changed, 824 insertions(+) create mode 100644 .editorconfig create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/book.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 data/.gitkeep create mode 100644 figures/.gitkeep create mode 100644 notebooks/.gitkeep create mode 100644 notebooks/_config.yml create mode 100644 notebooks/_toc.yml create mode 100644 notebooks/index.md create mode 100644 notebooks/template.ipynb create mode 100644 pyproject.toml create mode 100644 scripts/.gitkeep create mode 100644 scripts/template.py create mode 100644 src/fancypackage/__init__.py create mode 100644 src/fancypackage/core/__init__.py create mode 100644 src/fancypackage/core/_constants.py diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3af5212 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[makefile] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = tab +indent_size = 4 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..71c7629 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "" +labels: bug +assignees: "" +--- + + + +## Description + +[TEXT HERE] + + + +```python +# Your code here +``` + + + +
Error output + +```pytb +# Paste the error output here, if applicable +``` + +
+ +## Versions + +
Versions + +```pytb +# Paste the ouput of tradeseq.__version__ and all relevant versions here +``` + +
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bc08cc0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "" +labels: enhancement +assignees: "" +--- + +## Description + +**Is your feature request related to a problem? Please describe.** + + + +**Describe the solution you are looking for.** + + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..dc066db --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,23 @@ +## Changes + + + +- ... + +## Bug fixes + + + +- ... + +## New + + + +- ... + +## Related issues + + + +Closes # diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml new file mode 100644 index 0000000..c1aaeb9 --- /dev/null +++ b/.github/workflows/book.yml @@ -0,0 +1,33 @@ +name: deploy-jupyter-book + +on: + push: + branches: + - main + +# This job installs dependencies, build the book, and pushes it to `gh-pages` +jobs: + deploy-book: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + # Install dependencies + - name: Set up Python 3.10 + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + pip install jupyter-book + # Build the book + - name: Build the book + run: | + jupyter-book build notebooks + # Push the book's HTML to github-pages + - name: GitHub Pages action + uses: peaceiris/actions-gh-pages@v3.5.9 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: notebooks/_build/html diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..71da080 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,23 @@ +name: Lint + +on: + push: + branches: main + pull_request: + branches: main + +jobs: + linting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup Python 3.10 + uses: actions/setup-python@v4 + with: + python-version: "3.10" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pre-commit + - name: Check pre-commit compatibility + run: pre-commit run --all-files --show-diff-on-failure diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..111b67d --- /dev/null +++ b/.gitignore @@ -0,0 +1,161 @@ +# 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/ +pip-wheel-metadata/ +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/ + +# 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 +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.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 + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__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/ + +# patterns to prevent data and figures from being uploaded +*.csv +*.pickle +*.h5ad +*.RData +*.loom +*.pdf +*.eps +*.png +*.jpg +*.jpeg +*.svg +*.mtx +*.txt +*.rds +*.npz +*.h5 +*.txt.gz +*.gmt +*.gmx + +data/ +figures/ + +# OS specifics +**.DS_Store + +# R stuff +*.Rhistory + +.vscode/* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..fba8200 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,62 @@ +fail_fast: false +default_language_version: + python: python3 +default_stages: + - commit + - push +minimum_pre_commit_version: 2.16.0 +repos: + - repo: https://github.com/mwouts/jupytext + rev: v1.14.5 + hooks: + - id: jupytext + args: + [--from, ipynb, --sync, --pipe, black, --pipe-fmt, "py:percent"] + additional_dependencies: + - black==23.1.0 # Matches hook + - repo: https://github.com/psf/black + rev: "23.1.0" + hooks: + - id: black-jupyter + - repo: https://github.com/asottile/blacken-docs + rev: 1.13.0 + hooks: + - id: blacken-docs + - repo: https://github.com/PyCQA/isort + rev: 5.12.0 + hooks: + - id: isort + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.0.0-alpha.4 + hooks: + - id: prettier + # Newer versions of node don't work on systems that have an older version of GLIBC + # (in particular Ubuntu 18.04 and Centos 7) + # EOL of Centos 7 is in 2024-06, we can probably get rid of this then. + # See https://github.com/scverse/cookiecutter-scverse/issues/143 and + # https://github.com/jupyterlab/jupyterlab/issues/12675 + language_version: "17.9.1" + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.253 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: detect-private-key + - id: check-ast + - id: end-of-file-fixer + - id: mixed-line-ending + args: [--fix=lf] + - id: trailing-whitespace + - id: check-case-conflict + - repo: local + hooks: + - id: forbid-to-commit + name: Don't commit rej files + entry: | + Cannot commit .rej files. These indicate merge conflicts that arise during automated template updates. + Fix the merge conflicts manually and remove the .rej files. + language: fail + files: '.*\.rej$' diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..36822e3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2023, Theis Lab + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8aa244 --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# Single-cell analysis template repository + +This repository acts as a template notebook for the analysis of single-cell data and methods; the corresponding Jupyter +Book is rendered [here](https://weilerp.github.io/sc_analysis_template/). +You can check the [CellRank 2 reproducibility repository](https://github.com/theislab/cellrank2_reproducibility) +for an example repository following the same outline as this template. + +## Set up + +1. Rename `src/fancypackage/`. +2. Update `pyproject.toml` to include the correct information + - Project name + - Project description + - Project-specific Python requirements + - Project author + - Project maintainers + - Project URLs +3. Update `src/fancypackage/core/_constants.py` to include any paths relevant to your analysis and that should be accessible from any script or Jupyter notebook +4. Update this README to include the relevant information about your project. +5. Ensure repository settings are set up correctly to build Jupyter Book: + - In `Settings > Actions > General > Workflow permissions`: Allow read and write permissions. + - In `Settings > Pages > Build and deployment`: Set the branch to `gh-pages`. + +## Installation + +```bash +conda create -n fancyname-pyXX python=X.X --yes && conda activate fancyname-pyXX +pip install -e ".[dev]" +pre-commit install + +pip install jupyterlab ipywidgets +python -m ipykernel install --user --name fancyname-pyXX --display-name "fancyname-pyXX" +``` + +## Things to keep in mind + +Whenever you use a new single-cell tool, add it to `known_bio` in `pyproject.toml` s.t. `isort` can work correctly. + +## Workflow + +The workflow for committing a notebook is as follows: Upon committing a notebook, the pre-commit hooks format your notebook +and generate a corresponding script. You need to add the formatted notebook and Python script to the same commit for the commit to go through. The commit will now either be successful or not. If not, your Python script was formatted by the pre-commit hooks. In that case, you need to update your notebook accordingly, unstage the Python script, and recommit the notebook. You will iterate through this process until there are no inconsistencies between the notebook and its corresponding Python script. diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/figures/.gitkeep b/figures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/notebooks/.gitkeep b/notebooks/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/notebooks/_config.yml b/notebooks/_config.yml new file mode 100644 index 0000000..d067da9 --- /dev/null +++ b/notebooks/_config.yml @@ -0,0 +1,9 @@ +title: Single-cell analysis repository +author: Philipp Weiler +execute: + execute_notebooks: "off" + +repository: + url: https://github.com/WeilerP/sc_analysis_template +html: + use_repository_button: true diff --git a/notebooks/_toc.yml b/notebooks/_toc.yml new file mode 100644 index 0000000..59a7faa --- /dev/null +++ b/notebooks/_toc.yml @@ -0,0 +1,6 @@ +format: jb-book +root: index +parts: + - caption: Template + chapters: + - file: template diff --git a/notebooks/index.md b/notebooks/index.md new file mode 100644 index 0000000..a8aa244 --- /dev/null +++ b/notebooks/index.md @@ -0,0 +1,42 @@ +# Single-cell analysis template repository + +This repository acts as a template notebook for the analysis of single-cell data and methods; the corresponding Jupyter +Book is rendered [here](https://weilerp.github.io/sc_analysis_template/). +You can check the [CellRank 2 reproducibility repository](https://github.com/theislab/cellrank2_reproducibility) +for an example repository following the same outline as this template. + +## Set up + +1. Rename `src/fancypackage/`. +2. Update `pyproject.toml` to include the correct information + - Project name + - Project description + - Project-specific Python requirements + - Project author + - Project maintainers + - Project URLs +3. Update `src/fancypackage/core/_constants.py` to include any paths relevant to your analysis and that should be accessible from any script or Jupyter notebook +4. Update this README to include the relevant information about your project. +5. Ensure repository settings are set up correctly to build Jupyter Book: + - In `Settings > Actions > General > Workflow permissions`: Allow read and write permissions. + - In `Settings > Pages > Build and deployment`: Set the branch to `gh-pages`. + +## Installation + +```bash +conda create -n fancyname-pyXX python=X.X --yes && conda activate fancyname-pyXX +pip install -e ".[dev]" +pre-commit install + +pip install jupyterlab ipywidgets +python -m ipykernel install --user --name fancyname-pyXX --display-name "fancyname-pyXX" +``` + +## Things to keep in mind + +Whenever you use a new single-cell tool, add it to `known_bio` in `pyproject.toml` s.t. `isort` can work correctly. + +## Workflow + +The workflow for committing a notebook is as follows: Upon committing a notebook, the pre-commit hooks format your notebook +and generate a corresponding script. You need to add the formatted notebook and Python script to the same commit for the commit to go through. The commit will now either be successful or not. If not, your Python script was formatted by the pre-commit hooks. In that case, you need to update your notebook accordingly, unstage the Python script, and recommit the notebook. You will iterate through this process until there are no inconsistencies between the notebook and its corresponding Python script. diff --git a/notebooks/template.ipynb b/notebooks/template.ipynb new file mode 100644 index 0000000..8d4150f --- /dev/null +++ b/notebooks/template.ipynb @@ -0,0 +1,142 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "0a1042cd", + "metadata": {}, + "source": [ + "# A descriptive title\n", + "\n", + "A short description of what this notebook is doing." + ] + }, + { + "cell_type": "markdown", + "id": "a486fec1", + "metadata": {}, + "source": [ + "## Library imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "fd119f55-1837-43ca-8368-e12c55652f2b", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Global seed set to 0\n" + ] + } + ], + "source": [ + "import scanpy as sc\n", + "\n", + "from fancypackage import DATA_DIR, FIG_DIR" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "b6b48f3e-9560-47d4-bd6d-25aa5db08c13", + "metadata": {}, + "source": [ + "## General settings" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "d83dfd1f-3a26-4e26-a06e-26a975e4a48f", + "metadata": {}, + "outputs": [], + "source": [ + "SAVE_FIGURES = False\n", + "if SAVE_FIGURES:\n", + " FIG_DIR.mkdir(parents=True, exist_ok=True)\n", + "\n", + "FIGURE_FORMATE = \"pdf\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "e2670fad", + "metadata": {}, + "source": [ + "## Constants" + ] + }, + { + "cell_type": "markdown", + "id": "e4b7e465", + "metadata": {}, + "source": [ + "## Function definitions" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "01d6a832-9635-4888-8364-3e5736c8d8af", + "metadata": {}, + "source": [ + "## Data loading" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2baf9be8", + "metadata": {}, + "outputs": [], + "source": [ + "adata = sc.read(DATA_DIR / \"adata.h5ad\")\n", + "adata" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "a52d5add-d75b-4e84-8336-e9632460a818", + "metadata": {}, + "source": [ + "## Data preprocessing" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "813851f0-53a8-4f32-8899-9c9e4083a16c", + "metadata": {}, + "source": [ + "## More advanced data analysis" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cr2-py38", + "language": "python", + "name": "cr2-py38" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2281c9d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,123 @@ +[build-system] +requires = ['setuptools', 'setuptools_scm'] +build-backend = 'setuptools.build_meta' + +[project] +name = "fancypackage" +version = "0.0.0" +description = "Fancy Package" +readme = "README.md" +requires-python = ">=3.9" +license = {file = "LICENSE"} +authors = [ + {name = "Jane Doe"}, +] +maintainers = [ + {name = "Jane Doe", email = "jane.doe@usa.com"}, +] +urls.Documentation = "https://todo.com" # TODO +urls.Source = "https://github.com/url/to/repo.git" +urls.Home-page = "https://github.com/url/to/repo.git" +dependencies = [ + "anndata", + "scanpy", +] + +[project.optional-dependencies] +dev = [ + "pre-commit", +] + +[tool.black] +line-length = 120 +include = '\.pyi?$|\.ipynb?$' +exclude = ''' +( + /( + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + )/ +) +''' + +[tool.isort] +profile = "black" +use_parentheses = true +known_num = "networkx,numpy,pandas,scipy,sklearn,statmodels" +known_plot = "matplotlib,mplscience,mpl_toolkits,seaborn" +known_bio = "anndata,scanpy" +sections = "FUTURE,STDLIB,THIRDPARTY,NUM,PLOT,BIO,FIRSTPARTY,LOCALFOLDER" +no_lines_before = "LOCALFOLDER" +balanced_wrapping = true +length_sort = "0" +indent = " " +float_to_top = true +order_by_type = false + +[tool.ruff] +src = ["."] +line-length = 119 +target-version = "py38" +select = [ + "F", # Errors detected by Pyflakes + "E", # Error detected by Pycodestyle + "W", # Warning detected by Pycodestyle + "D", # pydocstyle + "B", # flake8-bugbear + "TID", # flake8-tidy-imports + "C4", # flake8-comprehensions + "BLE", # flake8-blind-except + "UP", # pyupgrade + "RUF100", # Report unused noqa directives +] +ignore = [ + # line too long -> we accept long comment lines; black gets rid of long code lines + "E501", + # Do not assign a lambda expression, use a def -> lambda expression assignments are convenient + "E731", + # allow I, O, l as variable names -> I is the identity matrix + "E741", + # Missing docstring in public package + "D104", + # Missing docstring in public module + "D100", + # Missing docstring in __init__ + "D107", + # Errors from function calls in argument defaults. These are fine when the result is immutable. + "B008", + # __magic__ methods are are often self-explanatory, allow missing docstrings + "D105", + # first line should end with a period [Bug: doesn't work with single-line docstrings] + "D400", + # First line should be in imperative mood; try rephrasing + "D401", + ## Disable one in each pair of mutually incompatible rules + # We don’t want a blank line before a class docstring + "D203", + # We want docstrings to start immediately after the opening triple quote + "D213", + # Missing argument description in the docstring TODO: enable + "D417", + # Unable to detect undefined names + "F403", + # Underfined, or defined from star imports: module + "F405", + # Within an except clause, raise exceptions with `raise ... from err` + "B904", +] + +[tool.jupytext] +notebook_metadata_filter = "-all,-jupytext.text_representation" +cell_metadata_filter = "-all" + +[tool.jupytext.formats] +"notebooks/" = "ipynb" +"scripts/" = "py:percent" diff --git a/scripts/.gitkeep b/scripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/scripts/template.py b/scripts/template.py new file mode 100644 index 0000000..6264a10 --- /dev/null +++ b/scripts/template.py @@ -0,0 +1,41 @@ +# %% [markdown] +# # A descriptive title +# +# A short description of what this notebook is doing. + +# %% [markdown] +# ## Library imports + +# %% +import scanpy as sc + +from fancypackage import DATA_DIR, FIG_DIR + +# %% [markdown] +# ## General settings + +# %% +SAVE_FIGURES = False +if SAVE_FIGURES: + FIG_DIR.mkdir(parents=True, exist_ok=True) + +FIGURE_FORMATE = "pdf" + +# %% [markdown] +# ## Constants + +# %% [markdown] +# ## Function definitions + +# %% [markdown] +# ## Data loading + +# %% +adata = sc.read(DATA_DIR / "adata.h5ad") +adata + +# %% [markdown] +# ## Data preprocessing + +# %% [markdown] +# ## More advanced data analysis diff --git a/src/fancypackage/__init__.py b/src/fancypackage/__init__.py new file mode 100644 index 0000000..298947e --- /dev/null +++ b/src/fancypackage/__init__.py @@ -0,0 +1,3 @@ +from .core import DATA_DIR, FIG_DIR + +__all__ = ["DATA_DIR", "FIG_DIR"] diff --git a/src/fancypackage/core/__init__.py b/src/fancypackage/core/__init__.py new file mode 100644 index 0000000..54d77ea --- /dev/null +++ b/src/fancypackage/core/__init__.py @@ -0,0 +1,3 @@ +from ._constants import DATA_DIR, FIG_DIR + +__all__ = ["DATA_DIR", "FIG_DIR"] diff --git a/src/fancypackage/core/_constants.py b/src/fancypackage/core/_constants.py new file mode 100644 index 0000000..75df2eb --- /dev/null +++ b/src/fancypackage/core/_constants.py @@ -0,0 +1,7 @@ +from pathlib import Path + +ROOT = Path(__file__).parents[3].resolve() + + +DATA_DIR = ROOT / "data" +FIG_DIR = ROOT / "figures"