Skip to content

SignalTrack

A Track backed by a BigWig file for per-base signal data. Provides signal_at() via mean signal over a range and raw_signal() for per-base values. Entry-level primitives (map_scores, scores, etc.) raise NotImplementedError — use bin_summarize() to convert to IntervalTrack first.

SignalTrack

SignalTrack(source: Any, bw: Any)

A Track backed by a BigWig file for per-base signal data.

Provides signal_at() via the mean signal over a range and raw_signal() for per-base values. regions() always yields nothing — signal tracks are continuous, not interval-based.

The pyBigWig backend is injected via the bw parameter, which must satisfy the pyBigWig file object interface (stats(), values()).

Parameters:

Name Type Description Default
source Any

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

required
bw Any

An open pyBigWig file object.

required

Examples:

>>> isinstance(SignalTrack(TrackLabel("t"), bw_handle), Track)
True
Source code in src/seqchain/track.py
def __init__(self, source: Any, bw: Any) -> None:
    if isinstance(source, str):
        raise TypeError(
            f"SignalTrack 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"SignalTrack source must have a .name attribute, "
            f"got {type(source).__name__}"
        )
    self._bw = bw

signal_at

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

Return mean signal over a genomic 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
float

Mean signal value, or 0.0 if the region has no data.

Examples:

>>> t.signal_at("chr1", 100, 200)
3.14
Source code in src/seqchain/track.py
def signal_at(self, chrom: str, start: int, end: int) -> float:
    """Return mean signal over a genomic window.

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

    Returns:
        Mean signal value, or ``0.0`` if the region has no data.

    Examples:
        >>> t.signal_at("chr1", 100, 200)  # doctest: +SKIP
        3.14
    """
    try:
        vals = self._bw.stats(chrom, start, end, type="mean")
    except (RuntimeError, KeyError):
        return 0.0
    if vals and vals[0] is not None:
        return float(vals[0])
    return 0.0

regions

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

Always yields nothing — SignalTrack has no interval data.

Parameters:

Name Type Description Default
chrom str

Chromosome name (unused).

required
start int

Window start (unused).

required
end int

Window end (unused).

required

Returns:

Type Description
Iterator[Region]

Empty iterator.

Source code in src/seqchain/track.py
def regions(self, chrom: str, start: int, end: int) -> Iterator[Region]:
    """Always yields nothing — SignalTrack has no interval data.

    Args:
        chrom: Chromosome name (unused).
        start: Window start (unused).
        end: Window end (unused).

    Returns:
        Empty iterator.
    """
    return iter([])

chrom_sizes

chrom_sizes() -> dict[str, int]

Return chromosome names and sizes from the BigWig header.

Returns:

Type Description
dict[str, int]

Dict mapping chromosome name to size in bp.

Examples:

>>> t.chrom_sizes()
{'chrI': 230218, 'chrII': 813184}
Source code in src/seqchain/track.py
def chrom_sizes(self) -> dict[str, int]:
    """Return chromosome names and sizes from the BigWig header.

    Returns:
        Dict mapping chromosome name to size in bp.

    Examples:
        >>> t.chrom_sizes()  # doctest: +SKIP
        {'chrI': 230218, 'chrII': 813184}
    """
    try:
        return dict(self._bw.chroms())
    except (RuntimeError, AttributeError):
        return {}

has_chrom

has_chrom(chrom: str) -> bool

Check whether the BigWig file contains data for a chromosome.

Parameters:

Name Type Description Default
chrom str

Chromosome name to check.

required

Returns:

Type Description
bool

True if the chromosome exists in the BigWig file.

Examples:

>>> t.has_chrom("chr1")
True
Source code in src/seqchain/track.py
def has_chrom(self, chrom: str) -> bool:
    """Check whether the BigWig file contains data for a chromosome.

    Args:
        chrom: Chromosome name to check.

    Returns:
        ``True`` if the chromosome exists in the BigWig file.

    Examples:
        >>> t.has_chrom("chr1")  # doctest: +SKIP
        True
    """
    return chrom in self.chrom_sizes()

raw_signal

raw_signal(chrom: str, start: int, end: int) -> list[float]

Return raw per-base signal values over a genomic range.

Parameters:

Name Type Description Default
chrom str

Chromosome name.

required
start int

Range start (inclusive).

required
end int

Range end (exclusive).

required

Returns:

Type Description
list[float]

List of per-base float values. Missing data is 0.0.

Examples:

>>> t.raw_signal("chr1", 100, 105)
[1.0, 2.0, 3.0, 4.0, 5.0]
Source code in src/seqchain/track.py
def raw_signal(self, chrom: str, start: int, end: int) -> list[float]:
    """Return raw per-base signal values over a genomic range.

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

    Returns:
        List of per-base float values. Missing data is ``0.0``.

    Examples:
        >>> t.raw_signal("chr1", 100, 105)  # doctest: +SKIP
        [1.0, 2.0, 3.0, 4.0, 5.0]
    """
    try:
        vals = self._bw.values(chrom, start, end)
    except (RuntimeError, KeyError):
        return [0.0] * (end - start)
    return [v if v is not None else 0.0 for v in vals]

map_scores

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

Not supported — SignalTrack stores no discrete scores.

Raises:

Type Description
NotImplementedError

Always.

Source code in src/seqchain/track.py
def map_scores(self, fn: Callable[[float], float]) -> "SignalTrack":
    """Not supported — SignalTrack stores no discrete scores.

    Raises:
        NotImplementedError: Always.
    """
    raise NotImplementedError(
        "SignalTrack is position-indexed, not entry-indexed. "
        "Use bin_summarize() to convert to IntervalTrack first."
    )

filter_entries

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

Not supported — SignalTrack stores no discrete entries.

Raises:

Type Description
NotImplementedError

Always.

Source code in src/seqchain/track.py
def filter_entries(self, fn: Callable[[float], bool]) -> "SignalTrack":
    """Not supported — SignalTrack stores no discrete entries.

    Raises:
        NotImplementedError: Always.
    """
    raise NotImplementedError(
        "SignalTrack is position-indexed, not entry-indexed. "
        "Use bin_summarize() to convert to IntervalTrack first."
    )

scores

scores() -> Iterator[float]

Not supported — SignalTrack stores no discrete scores.

Raises:

Type Description
NotImplementedError

Always.

Source code in src/seqchain/track.py
def scores(self) -> Iterator[float]:
    """Not supported — SignalTrack stores no discrete scores.

    Raises:
        NotImplementedError: Always.
    """
    raise NotImplementedError(
        "SignalTrack is position-indexed, not entry-indexed. "
        "Use bin_summarize() to convert to IntervalTrack first."
    )

with_scores

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

Not supported — SignalTrack stores no discrete scores.

Raises:

Type Description
NotImplementedError

Always.

Source code in src/seqchain/track.py
def with_scores(self, scores: Sequence[float]) -> "SignalTrack":
    """Not supported — SignalTrack stores no discrete scores.

    Raises:
        NotImplementedError: Always.
    """
    raise NotImplementedError(
        "SignalTrack is position-indexed, not entry-indexed. "
        "Use bin_summarize() to convert to IntervalTrack first."
    )