Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: CI

on:
pull_request:
push:
branches:
- main

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
checks:
name: Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version:
- "3.12"
- "3.13"
- "3.14"

steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install uv and python
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
cache-dependency-glob: uv.lock

- name: Install the project
run: uv sync --locked --dev --extra analysis

- name: Check formatting
run: uv run ruff format --check

- name: Lint
run: uv run ruff check

- name: Type check
run: uv run pyrefly check

- name: Test
run: uv run pytest -v
74 changes: 74 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Publish to PyPI

on:
push:
tags:
- "v*"

concurrency:
group: pypi-publish
cancel-in-progress: false

jobs:
build:
name: Build distributions
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: false

- name: Verify tag matches package version
shell: bash
run: |
tag_version="${GITHUB_REF_NAME#v}"
project_version="$(uv version --short)"
if [[ "$tag_version" != "$project_version" ]]; then
echo "Tag version $tag_version does not match package version $project_version" >&2
exit 1
fi

- name: Build distributions
run: uv build

- name: Smoke test wheel
run: uv run --isolated --no-project --with dist/*.whl python -c "import routing_pyramids"

- name: Smoke test source distribution
run: uv run --isolated --no-project --with dist/*.tar.gz python -c "import routing_pyramids"

- name: Upload distributions
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: distributions
path: dist/
if-no-files-found: error

publish:
name: Publish distributions
needs: build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/routing-pyramids/
permissions:
id-token: write

steps:
- name: Download distributions
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: distributions
path: dist/

- name: Publish distributions to PyPI
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
16 changes: 16 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,19 @@ uv run pyrefly check
# test
uv run pytest
```

## Releasing

Publishing uses PyPI trusted publishing with GitHub Actions.
For each release, update and commit the version and lockfile:

```sh
uv version 0.2.0
git add pyproject.toml uv.lock
git commit -m "release 0.2.0"
```

Wait for CI to pass on the version commit,
then create and push the matching version tag.
The tag must be the package version prefixed with `v`.
Pushing it starts the publishing [workflow](.github/workflows/publish.yml).
6 changes: 3 additions & 3 deletions examples/visualize_bbbc013_latents.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
from dataclasses import dataclass
from pathlib import Path

import betterplots
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import torch
from betterplots.boxstripplot import boxstripplot
from cmap import Colormap as CmapColormap
from matplotlib.axes import Axes
from matplotlib.cm import ScalarMappable
Expand All @@ -24,6 +22,8 @@
from torch.utils.data import DataLoader
from umap import UMAP

from routing_pyramids._vendor.betterplots import set_style
from routing_pyramids._vendor.betterplots.boxstripplot import boxstripplot
from routing_pyramids.data.temporal_datamodule import BBBC013VideoDataModule
from routing_pyramids.pyramid_flow_system import (
PyramidFlowDecoder2d,
Expand Down Expand Up @@ -77,7 +77,7 @@

device = torch.device("cpu" if FORCE_CPU or not torch.cuda.is_available() else "cuda")
print(f"Using device: {device}")
betterplots.set_style(
set_style(
usetex=False,
serif=True,
font_size=8,
Expand Down
2 changes: 1 addition & 1 deletion examples/visualize_flow_aics_object_posterior.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import matplotlib.pyplot as plt
import numpy as np
import torch
from betterplots import set_style
from matplotlib.colors import hsv_to_rgb
from torch import Tensor
from torch.nn import functional as F

from routing_pyramids._vendor.betterplots import set_style
from routing_pyramids.data.temporal_video_dataset import OMEZarrVideoDataset
from routing_pyramids.data.transforms import get_normalization, get_transforms
from routing_pyramids.pyramid_flow_system import (
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ analysis = [
"seaborn>=0.13.2",
"scikit-learn>=1.9.0",
"umap-learn>=0.5.12",
"betterplots @ git+https://github.com/maweigert/betterplots@3a2c3bd7646290c5748e463553f33368ea8253bd",
]

[build-system]
Expand Down
1 change: 1 addition & 0 deletions src/routing_pyramids/_vendor/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Private vendored dependencies."""
76 changes: 76 additions & 0 deletions src/routing_pyramids/_vendor/betterplots/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Vendored from https://github.com/maweigert/betterplots
# 3a2c3bd7646290c5748e463553f33368ea8253bd.
# Copyright Martin Weigert (BSD-3-Clause).

from typing import Literal

from cycler import cycler

PALETTES = {
"mw": ["#4B6584", "#7A6FAF", "#B99B52", "#5F8F7A", "#A45A6A", "#5B8FA8"],
"tab10": [
"#1f77b4",
"#ff7f0e",
"#2ca02c",
"#d62728",
"#9467bd",
"#8c564b",
"#e377c2",
"#7f7f7f",
"#bcbd22",
"#17becf",
],
}


def set_style(
usetex=False,
serif=True,
font_size=12,
legend_font_size=10,
label_size=10,
tick_size=10,
colors: Literal["mw", "tab10"] | None = "tab10",
):
import matplotlib as mpl

mpl.rc("text", usetex=usetex)
# mpl.rc('font',family='serif')
# mpl.rc('font',serif=['Palatino'])
mpl.rcParams["font.family"] = "serif" if serif else "sans-serif"
mpl.rcParams["font.serif"] = ["Palatino"]
mpl.rcParams["font.sans-serif"] = [
"Inter 18pt",
"Myriad Pro",
"Neue Haas Grotesk Display Pro",
]
mpl.rc("font", size=font_size)
mpl.rc("legend", fontsize=legend_font_size)
mpl.rc("axes", labelsize=label_size)
mpl.rc("xtick", labelsize=tick_size)
mpl.rc("ytick", labelsize=tick_size)
mpl.rcParams["axes.titleweight"] = "semibold"

if colors is None:
colors = "tab10"
if colors not in PALETTES:
raise ValueError(
f"colors must be one of {list(PALETTES)} or None, got {colors!r}"
)
mpl.rcParams["axes.prop_cycle"] = cycler(color=PALETTES[colors])

if usetex:
mpl.rcParams["text.latex.preamble"] = r"\usepackage{mathtools,amssymb,bm}"
print(
"in case latex is not working, make sue that the following packages are installed:"
)
print(
"sudo apt-get install dvipng texlive-latex-extra texlive-fonts-recommended cm-super"
)

# xtick.major.size : 5
# xtick.minor.size : 3
# ytick.major.size : 5
# ytick.minor.size : 3
# axes.linewidth : 0.8
# legend.handlelength : 2.0
Loading