Skip to content

IntervalTrack

A Track backed by a sorted-list interval index. Stores Region objects and supports fast overlap queries. signal_at() returns an overlap-weighted average of region scores within the query window.

IntervalTrack

IntervalTrack(source: Any, regions: Iterable[Region])

A Track backed by a sorted-list interval index.

Stores a collection of Region objects and supports fast overlap queries via IntervalIndex.

signal_at() returns an overlap-weighted average of region scores within the query window. regions() yields all overlapping regions.

Parameters:

Name Type Description Default
source Any

Named source with a .name attribute (preset, config, TrackLabel).

required
regions Iterable[Region]

Iterable of Region objects to index.

required

Examples:

>>> t = IntervalTrack(TrackLabel("peaks"), [Region("chr1", 100, 200, score=5.0)])
>>> list(t.regions("chr1", 150, 160))
[Region(chrom='chr1', start=100, end=200, strand='.', score=5.0, name='', tags={})]
Source code in src/seqchain/track.py
def __init__(self, source: Any, regions: Iterable[Region]) -> None:
    from seqchain.primitives.intervals import IntervalIndex

    if isinstance(source, str):
        raise TypeError(
            f"IntervalTrack requires a named source (preset, config, "
            f"TrackLabel), not a bare string. Use TrackLabel({source!r}) "
            f"for engine-internal names."
        )
    try:
        self.name: str = source.name
    except AttributeError:
        raise TypeError(
            f"IntervalTrack source must have a .name attribute, "
            f"got {type(source).__name__}"
        )
    self._regions = list(regions)
    self._index = IntervalIndex.build(self._regions)

signal_at

signal_at(chrom: str, start: int, end: int) -> float

Overlap-weighted average score of regions in the query window.

For each overlapping region, computes the number of overlapping base pairs with the query and weights by the region's score. Returns the weighted average, or 0.0 if there are no overlaps.

Parameters:

Name Type Description Default
chrom str

Chromosome name.

required
start int

Window start (inclusive).

required
end int

Window end (exclusive).

required

Returns:

Type Description
float

Weighted average score, or 0.0.

Examples:

>>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 100, 200, score=10.0)])
>>> t.signal_at("chr1", 150, 250)
10.0
Source code in src/seqchain/track.py
def signal_at(self, chrom: str, start: int, end: int) -> float:
    """Overlap-weighted average score of regions in the query window.

    For each overlapping region, computes the number of overlapping
    base pairs with the query and weights by the region's score.
    Returns the weighted average, or ``0.0`` if there are no overlaps.

    Args:
        chrom: Chromosome name.
        start: Window start (inclusive).
        end: Window end (exclusive).

    Returns:
        Weighted average score, or ``0.0``.

    Examples:
        >>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 100, 200, score=10.0)])
        >>> t.signal_at("chr1", 150, 250)
        10.0
    """
    hits = self._index.overlapping(chrom, start, end)
    if not hits:
        return 0.0

    total_weight = 0.0
    total_bp = 0
    for r in hits:
        overlap_start = max(r.start, start)
        overlap_end = min(r.end, end)
        bp = overlap_end - overlap_start
        total_weight += bp * r.score
        total_bp += bp

    if total_bp == 0:
        return 0.0
    return total_weight / total_bp

regions

regions(chrom: str, start: int, end: int) -> Iterator[Region]

Yield all regions overlapping the query window.

Parameters:

Name Type Description Default
chrom str

Chromosome name.

required
start int

Window start (inclusive).

required
end int

Window end (exclusive).

required

Returns:

Type Description
Iterator[Region]

Iterator of overlapping Region objects.

Examples:

>>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 10, 20)])
>>> len(list(t.regions("chr1", 15, 25)))
1
Source code in src/seqchain/track.py
def regions(self, chrom: str, start: int, end: int) -> Iterator[Region]:
    """Yield all regions overlapping the query window.

    Args:
        chrom: Chromosome name.
        start: Window start (inclusive).
        end: Window end (exclusive).

    Returns:
        Iterator of overlapping `Region` objects.

    Examples:
        >>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 10, 20)])
        >>> len(list(t.regions("chr1", 15, 25)))
        1
    """
    yield from self._index.overlapping(chrom, start, end)

__iter__

__iter__() -> Iterator[Region]

Iterate over all regions in entry order.

Returns:

Type Description
Iterator[Region]

Iterator of Region objects.

Examples:

>>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10)])
>>> [r.chrom for r in t]
['chr1']
Source code in src/seqchain/track.py
def __iter__(self) -> Iterator[Region]:
    """Iterate over all regions in entry order.

    Returns:
        Iterator of `Region` objects.

    Examples:
        >>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10)])
        >>> [r.chrom for r in t]
        ['chr1']
    """
    return iter(self._regions)

__getitem__

__getitem__(index: int | slice) -> Region | list[Region]

Access regions by index or slice.

Parameters:

Name Type Description Default
index int | slice

Integer index or slice.

required

Returns:

Type Description
Region | list[Region]

A single Region for integer index, or a list of

Region | list[Region]

Regions for a slice.

Examples:

>>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=1.0)])
>>> t[0].score
1.0
Source code in src/seqchain/track.py
def __getitem__(self, index: int | slice) -> Region | list[Region]:
    """Access regions by index or slice.

    Args:
        index: Integer index or slice.

    Returns:
        A single `Region` for integer index, or a list of
        Regions for a slice.

    Examples:
        >>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=1.0)])
        >>> t[0].score
        1.0
    """
    return self._regions[index]

__len__

__len__() -> int

Total number of indexed regions.

Returns:

Type Description
int

Region count.

Source code in src/seqchain/track.py
def __len__(self) -> int:
    """Total number of indexed regions.

    Returns:
        Region count.
    """
    return len(self._index)

map_scores

map_scores(fn: Callable[[float], float]) -> 'IntervalTrack'

Return a new IntervalTrack with fn applied to every region score.

Parameters:

Name Type Description Default
fn Callable[[float], float]

A function that maps a float score to a new float score.

required

Returns:

Type Description
'IntervalTrack'

A new IntervalTrack with transformed scores.

Examples:

>>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=2.0)])
>>> t2 = t.map_scores(lambda s: s * 3)
>>> t2[0].score
6.0
Source code in src/seqchain/track.py
def map_scores(self, fn: Callable[[float], float]) -> "IntervalTrack":
    """Return a new IntervalTrack with *fn* applied to every region score.

    Args:
        fn: A function that maps a float score to a new float score.

    Returns:
        A new IntervalTrack with transformed scores.

    Examples:
        >>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=2.0)])
        >>> t2 = t.map_scores(lambda s: s * 3)
        >>> t2[0].score
        6.0
    """
    return IntervalTrack(
        self,
        [replace(r, score=fn(r.score)) for r in self._regions],
    )

filter_entries

filter_entries(fn: Callable[[float], bool]) -> 'IntervalTrack'

Return a new IntervalTrack keeping only regions where fn(score) is true.

Parameters:

Name Type Description Default
fn Callable[[float], bool]

Predicate on the score.

required

Returns:

Type Description
'IntervalTrack'

A new IntervalTrack with only matching regions.

Examples:

>>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=5.0)])
>>> t2 = t.filter_entries(lambda s: s > 3.0)
>>> len(t2)
1
Source code in src/seqchain/track.py
def filter_entries(self, fn: Callable[[float], bool]) -> "IntervalTrack":
    """Return a new IntervalTrack keeping only regions where *fn(score)* is true.

    Args:
        fn: Predicate on the score.

    Returns:
        A new IntervalTrack with only matching regions.

    Examples:
        >>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=5.0)])
        >>> t2 = t.filter_entries(lambda s: s > 3.0)
        >>> len(t2)
        1
    """
    return IntervalTrack(
        self,
        [r for r in self._regions if fn(r.score)],
    )

scores

scores() -> Iterator[float]

Iterate over all region scores in entry order.

Returns:

Type Description
Iterator[float]

Iterator of float scores.

Examples:

>>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=1.0)])
>>> list(t.scores())
[1.0]
Source code in src/seqchain/track.py
def scores(self) -> Iterator[float]:
    """Iterate over all region scores in entry order.

    Returns:
        Iterator of float scores.

    Examples:
        >>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=1.0)])
        >>> list(t.scores())
        [1.0]
    """
    return (r.score for r in self._regions)

with_scores

with_scores(scores: Sequence[float]) -> 'IntervalTrack'

Rebuild the IntervalTrack with new scores in entry order.

Parameters:

Name Type Description Default
scores Sequence[float]

New score values, one per region.

required

Returns:

Type Description
'IntervalTrack'

A new IntervalTrack with replaced scores.

Raises:

Type Description
ValueError

If length does not match.

Examples:

>>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=1.0)])
>>> t2 = t.with_scores([99.0])
>>> t2[0].score
99.0
Source code in src/seqchain/track.py
def with_scores(self, scores: Sequence[float]) -> "IntervalTrack":
    """Rebuild the IntervalTrack with new scores in entry order.

    Args:
        scores: New score values, one per region.

    Returns:
        A new IntervalTrack with replaced scores.

    Raises:
        ValueError: If length does not match.

    Examples:
        >>> t = IntervalTrack(TrackLabel("t"), [Region("chr1", 0, 10, score=1.0)])
        >>> t2 = t.with_scores([99.0])
        >>> t2[0].score
        99.0
    """
    scores = list(scores)
    if len(scores) != len(self._regions):
        raise ValueError(
            f"Expected {len(self._regions)} scores, got {len(scores)}"
        )
    return IntervalTrack(
        self,
        [replace(r, score=s) for r, s in zip(self._regions, scores)],
    )