Skip to content

Commit

Permalink
feat: remove cgranges for superintervals
Browse files Browse the repository at this point in the history
  • Loading branch information
clintval committed Dec 2, 2024
1 parent 352a3e8 commit 8c1c6d3
Show file tree
Hide file tree
Showing 12 changed files with 284 additions and 247 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/publish_bedspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true

- uses: rickstaa/action-contains-tag@v1
id: contains_tag
Expand Down Expand Up @@ -102,7 +101,6 @@ jobs:
with:
fetch-depth: 0
ref: ${{ github.ref_name }}
submodules: true

- name: Generate a Changelog
uses: orhun/git-cliff-action@v3
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ jobs:
PYTHON_VERSION: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
with:
submodules: "true"

- name: Set up Python ${{ matrix.PYTHON_VERSION }}
uses: actions/setup-python@v5
Expand Down
51 changes: 11 additions & 40 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,55 +7,26 @@ on:

jobs:
build-wheels:
name: Build wheels for ${{ matrix.python }}-${{ matrix.platform.target }}_${{ matrix.platform.arch }} on ${{ matrix.platform.os }}
runs-on: ${{ matrix.platform.os }}
name: Build wheels for ${{ matrix.PYTHON_VERSION }}
runs-on: ubuntu-latest
strategy:
matrix:
python: [cp312]
platform:
- os: ubuntu-latest
target: manylinux
arch: x86_64
- os: ubuntu-latest
target: musllinux
arch: x86_64
# These don't work right now - they just hang while pulling the build image from quay.
# If this doesn't resolve itself, we could try to configure different images:
# https://cibuildwheel.readthedocs.io/en/stable/options/.
# - os: ubuntu-latest
# target: manylinux
# arch: aarch64
# - os: ubuntu-latest
# target: musllinux
# arch: aarch64
- os: macos-latest
target: macosx
arch: x86_64
- os: macos-latest
target: macosx
arch: arm64
PYTHON_VERSION: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
with:
submodules: "true"

- uses: actions/setup-python@v5
- name: Set up Python ${{ matrix.PYTHON_VERSION }}
uses: actions/setup-python@v5
with:
python-version: 3.12

- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.17.0
python-version: ${{ matrix.PYTHON_VERSION }}

- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_ARCHS: ${{ matrix.platform.arch }}
CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform.target }}_${{ matrix.platform.arch }}
CIBW_BUILD_VERBOSITY: 1
run: pip wheel --no-deps -w wheelhouse .

- uses: actions/upload-artifact@v4
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
name: bedspec-wheels-${{ matrix.python }}-${{ matrix.platform.target }}_${{ matrix.platform.arch }}
path: ./wheelhouse/*.whl
name: bedspec-wheels-${{ matrix.PYTHON_VERSION }}
path: ./wheelhouse/bedspec*.whl
if-no-files-found: error
5 changes: 0 additions & 5 deletions .gitmodules

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ For example, to create a custom BED3+1 class:
>>>
>>> from bedspec import SimpleBed
>>>
>>> @dataclass(eq=True)
>>> @dataclass
... class Bed3Plus1(SimpleBed):
... refname: str
... start: int
Expand Down
18 changes: 9 additions & 9 deletions bedspec/_bedspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def territory(self) -> Iterator[ReferenceSpan]:
yield self.bed2


@dataclass(eq=True, slots=True)
@dataclass(slots=True, unsafe_hash=True)
class BedColor:
"""The color of a BED record in red, green, and blue color values."""

Expand Down Expand Up @@ -209,15 +209,15 @@ def __str__(self) -> str:
return f"{self.r},{self.g},{self.b}"


@dataclass(eq=True, slots=True)
@dataclass(slots=True, unsafe_hash=True)
class Bed2(PointBed):
"""A BED2 record that describes a single 0-based 1-length point."""

refname: str
start: int


@dataclass(eq=True, slots=True)
@dataclass(slots=True, unsafe_hash=True)
class Bed3(SimpleBed):
"""A BED3 record that describes a contiguous linear interval."""

Expand All @@ -226,7 +226,7 @@ class Bed3(SimpleBed):
end: int = field(kw_only=True)


@dataclass(eq=True, slots=True)
@dataclass(slots=True, unsafe_hash=True)
class Bed4(SimpleBed):
"""A BED4 record that describes a contiguous linear interval."""

Expand All @@ -236,7 +236,7 @@ class Bed4(SimpleBed):
name: str | None = field(kw_only=True)


@dataclass(eq=True, slots=True)
@dataclass(slots=True, unsafe_hash=True)
class Bed5(SimpleBed, Named):
"""A BED5 record that describes a contiguous linear interval."""

Expand All @@ -247,7 +247,7 @@ class Bed5(SimpleBed, Named):
score: int | None = field(kw_only=True)


@dataclass(eq=True, slots=True)
@dataclass(slots=True, unsafe_hash=True)
class Bed6(SimpleBed, Named, Stranded):
"""A BED6 record that describes a contiguous linear interval."""

Expand All @@ -259,7 +259,7 @@ class Bed6(SimpleBed, Named, Stranded):
strand: BedStrand | None = field(kw_only=True)


@dataclass(eq=True, slots=True)
@dataclass(slots=True, unsafe_hash=True)
class Bed12(SimpleBed, Named, Stranded):
"""A BED12 record that describes a contiguous linear interval."""

Expand Down Expand Up @@ -301,7 +301,7 @@ def __post_init__(self) -> None:
raise ValueError("The last defined block's end must be equal to the BED end!")


@dataclass(eq=True, slots=True)
@dataclass(slots=True, unsafe_hash=True)
class BedGraph(SimpleBed):
"""A bedGraph feature for continuous-valued data."""

Expand All @@ -311,7 +311,7 @@ class BedGraph(SimpleBed):
value: float = field(kw_only=True)


@dataclass(eq=True, slots=True)
@dataclass(slots=True, unsafe_hash=True)
class BedPE(PairBed, Named):
"""A BED record that describes a pair of BED records as per the bedtools spec."""

Expand Down
16 changes: 9 additions & 7 deletions bedspec/overlap/_overlap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
from typing import TypeAlias
from typing import TypeVar

from superintervals import ( # type: ignore[import-untyped] # pyright: ignore[reportMissingTypeStubs]
IntervalSet, # pyright: ignore[reportUnknownVariableType]
)
from typing_extensions import override

import cgranges as cr
from bedspec._bedspec import ReferenceSpan

ReferenceSpanType = TypeVar("ReferenceSpanType", bound=ReferenceSpan)
Expand All @@ -33,7 +35,7 @@ class OverlapDetector(Iterable[ReferenceSpanType], Generic[ReferenceSpanType]):

def __init__(self, features: Iterable[ReferenceSpanType] | None = None) -> None:
self._refname_to_features: dict[Refname, list[ReferenceSpanType]] = defaultdict(list)
self._refname_to_tree: dict[Refname, cr.cgranges] = defaultdict(cr.cgranges) # type: ignore[attr-defined,name-defined] # pyright: ignore[reportUnknownArgumentType, reportUnknownMemberType]
self._refname_to_tree: dict[Refname, IntervalSet] = defaultdict(IntervalSet) # pyright: ignore[reportUnknownArgumentType]
self._refname_to_is_indexed: dict[Refname, bool] = defaultdict(lambda: False)
if features is not None:
self.add(*features)
Expand All @@ -47,10 +49,10 @@ def add(self, *features: ReferenceSpanType) -> None:
"""Add a feature to this overlap detector."""
for feature in features:
refname: Refname = feature.refname
feature_idx: int = len(self._refname_to_features[refname])
feature_index: int = len(self._refname_to_features[refname])

self._refname_to_features[refname].append(feature)
self._refname_to_tree[refname].add(refname, feature.start, feature.end, feature_idx) # pyright: ignore[reportUnknownMemberType]
self._refname_to_tree[refname].add(feature.start, feature.end - 1, feature_index) # pyright: ignore[reportUnknownMemberType]
self._refname_to_is_indexed[refname] = False # mark that this tree needs re-indexing

def overlapping(self, feature: ReferenceSpan) -> Iterator[ReferenceSpanType]:
Expand All @@ -60,9 +62,9 @@ def overlapping(self, feature: ReferenceSpan) -> Iterator[ReferenceSpanType]:
if refname in self._refname_to_tree.keys() and not self._refname_to_is_indexed[refname]: # pyright: ignore[reportUnknownMemberType]
self._refname_to_tree[refname].index() # pyright: ignore[reportUnknownMemberType]

idx: int
for *_, idx in self._refname_to_tree[refname].overlap(refname, feature.start, feature.end): # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
yield self._refname_to_features[refname][idx]
index: int
for index in self._refname_to_tree[refname].find_overlaps(feature.start, feature.end - 1): # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
yield self._refname_to_features[refname][index]

def overlaps(self, feature: ReferenceSpan) -> bool:
"""Determine if a query feature overlaps any other features."""
Expand Down
23 changes: 0 additions & 23 deletions build.py

This file was deleted.

1 change: 0 additions & 1 deletion cgranges
Submodule cgranges deleted from 2fb5a2
Loading

0 comments on commit 8c1c6d3

Please sign in to comment.