Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixup CI #10

Merged
merged 4 commits into from
Dec 16, 2024
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
6 changes: 6 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[flake8]
# Based directly on Black's recommendations:
# https://black.readthedocs.io/en/stable/the_black_code_style.html#line-length
max-line-length = 81
select = A,C,E,F,W,B,B950
ignore = E203, E501, W503
42 changes: 17 additions & 25 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,6 @@ on:
tags:
- '*'

env:
COMMIT_EMAIL: [email protected]
MAKE_TARGET: -C python
OWNER: tskit-dev
REPO: tskit
REQUIREMENTS: python/requirements/CI-docs/requirements.txt

jobs:
build-deploy-docs:
name: Docs
Expand All @@ -29,26 +22,25 @@ jobs:

- uses: actions/checkout@v4

- name: Setup Conda
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
activate-environment: tskit-docs-env

- name: Cache Conda env
uses: actions/cache@v4
- uses: actions/[email protected]
with:
path: ${{ env.CONDA }}/envs
key: conda-${{ runner.os }}--${{ runner.arch }}--${{ hashFiles(env.REQUIREMENTS) }}-${{ env.CACHE_NUMBER }}
env:
CACHE_NUMBER: 0
id: cache
python-version: "3.11"
cache: "pip"

- name: Update environment
- name: Create venv and install deps (one by one to avoid conflict errors)
run: |
mamba install -y python=3.12 doxygen pip
pip install -r ${{ env.REQUIREMENTS }}
if: steps.cache.outputs.cache-hit != 'true'
pip install --upgrade pip wheel
pip install -r requirements/CI-docs-pip/requirements.txt

- name: Build Docs
run: make -C docs
run: |
cd docs
make

- name: Trigger docs site rebuild
if: github.ref == 'refs/heads/main'
run: |
curl -X POST https://api.github.com/repos/tskit-dev/tskit-site/dispatches \
-H 'Accept: application/vnd.github.everest-preview+json' \
-u AdminBot-tskit:${{ secrets.ADMINBOT_TOKEN }} \
--data '{"event_type":"build-docs"}'
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python: [ 3.9, 3.12 ]
python: [ "3.10", 3.12 ]
os: [ macos-latest, ubuntu-24.04, windows-latest ]
defaults:
run:
Expand Down
29 changes: 29 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-merge-conflict
- id: debug-statements
- id: mixed-line-ending
- id: check-case-conflict
- id: check-yaml
- repo: https://github.com/asottile/reorder_python_imports
rev: v3.14.0
hooks:
- id: reorder-python-imports
- repo: https://github.com/asottile/pyupgrade
rev: v3.19.0
hooks:
- id: pyupgrade
args: [--py39-plus]
- repo: https://github.com/psf/black
rev: 24.10.0
hooks:
- id: black
language_version: python3
- repo: https://github.com/pycqa/flake8
rev: 7.1.1
hooks:
- id: flake8
args: [--config=.flake8]
additional_dependencies: ["flake8-bugbear==24.12.12", "flake8-builtins==2.5.0"]
1 change: 1 addition & 0 deletions requirements/CI-docs-pip/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ sphinx-issues==4.1.0
sphinx-argparse==0.4.0
svgwrite==1.4.3
tskit==0.6.0
tsinfer==0.3.3
scipy==1.14.1
msprime==1.3.2
sphinx-book-theme
Expand Down
55 changes: 35 additions & 20 deletions tests/test_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"""
Test tools for mapping between node sets of different tree sequences
"""

from collections import defaultdict
from itertools import combinations

Expand Down Expand Up @@ -99,10 +98,13 @@ def naive_compare(ts, other, transform=None):
Ineffiecient but transparent function to compute dissimilarity
and root-mean-square-error between two tree sequences.
"""

def f(t):
return np.log(1 + t)
if transform is not None:
f = transform

if transform is None:
transform = f

shared_spans = naive_shared_node_spans(ts, other).toarray()
max_span = np.max(shared_spans, axis=1)
assert len(max_span) == ts.num_nodes
Expand All @@ -115,7 +117,9 @@ def f(t):
else:
for j in range(other.num_nodes):
if shared_spans[i, j] == max_span[i]:
time_array[i, j] = np.abs(f(ts.nodes_time[i]) - f(other.nodes_time[j]))
time_array[i, j] = np.abs(
transform(ts.nodes_time[i]) - transform(other.nodes_time[j])
)
dissimilarity_matrix[i, j] = 1 / (1 + time_array[i, j])
best_match = np.argmax(dissimilarity_matrix, axis=1)
best_match_spans = np.zeros((ts.num_nodes,))
Expand Down Expand Up @@ -180,9 +184,7 @@ def test_node_spans(self, ts):
naive_ns = naive_node_span(ts)
assert np.allclose(eval_ns, naive_ns)

@pytest.mark.parametrize(
"pair", combinations([true_simpl, true_unary], 2)
)
@pytest.mark.parametrize("pair", combinations([true_simpl, true_unary], 2))
def test_shared_spans(self, pair):
"""
Check that efficient implementation returns same answer as naive
Expand All @@ -205,13 +207,16 @@ def test_match_self(self, ts):
assert np.allclose(time, ts.nodes_time)
assert np.array_equal(hit, np.arange(ts.num_nodes))


class TestDissimilarity:

def verify_compare(self, ts, other, transform=None):
match_span, ts_span, other_span, rmse = naive_compare(ts, other, transform=transform)
match_span, ts_span, other_span, rmse = naive_compare(
ts, other, transform=transform
)
dis = tscompare.compare(ts, other, transform=transform)
assert np.isclose(1.0 - match_span/ts_span, dis.arf)
assert np.isclose(match_span/other_span, dis.tpr)
assert np.isclose(1.0 - match_span / ts_span, dis.arf)
assert np.isclose(match_span / other_span, dis.tpr)
assert np.isclose(ts_span - match_span, dis.dissimilarity)
assert np.isclose(ts_span, dis.total_span[0])
assert np.isclose(other_span, dis.total_span[1])
Expand All @@ -235,15 +240,15 @@ def test_basic_comparison(self, pair):
def test_zero_dissimilarity(self, pair):
dis = tscompare.compare(pair[0], pair[1])
assert np.isclose(dis.dissimilarity, 0)
assert np.isclose(dis.arf, 0)
assert np.isclose(dis.arf, 0)
assert np.isclose(dis.rmse, 0)

def test_transform(self):
dis1 = tscompare.compare(true_simpl, true_simpl, transform=lambda t: t)
dis2 = tscompare.compare(true_simpl, true_simpl, transform=None)
assert dis1.dissimilarity == dis2.dissimilarity
assert dis1.rmse == dis2.rmse
self.verify_compare(true_simpl, true_ext, transform=lambda t: 1/(1 + t))
self.verify_compare(true_simpl, true_ext, transform=lambda t: 1 / (1 + t))

def get_simple_ts(self, samples=None, time=False, span=False, no_match=False):
# A simple tree sequence we can use to properly test various
Expand Down Expand Up @@ -397,12 +402,17 @@ def test_rmse(self):
true_total_span = 46
assert dis.total_span[0] == true_total_span
assert dis.total_span[1] == true_total_span

def f(t):
return np.log(1 + t)
true_rmse = np.sqrt((
2 * 6 * (f(500) - f(200))**2 # nodes 4, 5
+ 2 * 2 * (f(750) - f(600))**2 # nodes, 7, 8
) / true_total_span)

true_rmse = np.sqrt(
(
2 * 6 * (f(500) - f(200)) ** 2 # nodes 4, 5
+ 2 * 2 * (f(750) - f(600)) ** 2 # nodes, 7, 8
)
/ true_total_span
)
assert np.isclose(dis.arf, 0.0)
assert np.isclose(dis.tpr, 1.0)
assert np.isclose(dis.dissimilarity, 0.0)
Expand All @@ -414,12 +424,17 @@ def test_value_and_error(self):
dis = tscompare.compare(ts, other)
true_total_spans = (46, 47)
assert dis.total_span == true_total_spans

def f(t):
return np.log(1 + t)
true_rmse = np.sqrt((
2 * 6 * (f(500) - f(200))**2 # nodes 4, 5
+ 2 * 2 * (f(750) - f(600))**2 # nodes, 7, 8
) / true_total_spans[0])

true_rmse = np.sqrt(
(
2 * 6 * (f(500) - f(200)) ** 2 # nodes 4, 5
+ 2 * 2 * (f(750) - f(600)) ** 2 # nodes, 7, 8
)
/ true_total_spans[0]
)
assert np.isclose(dis.arf, 4 / true_total_spans[0])
assert np.isclose(dis.tpr, (true_total_spans[0] - 4) / true_total_spans[1])
assert np.isclose(dis.dissimilarity, 4)
Expand Down
9 changes: 7 additions & 2 deletions tscompare/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@
"""
Tools for comparing tree sequences
"""
from .methods import compare, node_spans, CladeMap, shared_node_spans, match_node_ages, ARFResult
from .provenance import __version__
from .methods import ARFResult # noqa F401
from .methods import CladeMap # noqa F401
from .methods import compare # noqa F401
from .methods import match_node_ages # noqa F401
from .methods import node_spans # noqa F401
from .methods import shared_node_spans # noqa F401
from .provenance import __version__ # noqa F401
Loading
Loading