# Copyright (C) 2016-2023 Deep Genomics Inc. All Rights Reserved.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np
from . import _cxx
from ._cxx_util import mock
from ._cxx_util import mock_result
from ._cxx_util import mock_unreachable
from ._cxx_util import strip_mock_bases
from .genome import Genome
from .interval import Interval
from .variant import Variant, VariantTable
#########################################################################
[docs]
@_cxx.register
class ReadAlignments(_cxx.ReadAlignments):
"""Access to read alignments.
"""
__slots__ = () # <--- NEW SLOTS OK
# def __new__(self): pass # <--- DO NOT OVERRIDE BASE CLASS IMPLEMENTATION
# def __del__(self): pass # <--- DO NOT IMPLEMENT
[docs]
@mock
def __init__(self, infile): # pragma: no cover
"""Open a .ralign file.
Parameters
----------
infile : :py:class:`str`
The .ralign file to open.
Raises
------
IOError
Occurs when `infile` refers to an incompatible ralign file for this version of ``genome_kit``.
"""
@mock
@property
def junctions(self): # pragma: no cover
"""Access to junctions inferred from read alignments
Returns
-------
:py:class:`~genome_kit.JunctionTable`
A table with optimized methods to query over all junctions by position.
"""
return mock_result(JunctionTable)
@mock
@property
def alignments(self): # pragma: no cover
"""Access to read alignments, i.e. a row in BAM file
Returns
-------
:py:class:`~genome_kit.AlignmentTable`
A table with optimized methods to query over all read alignments by position.
"""
return mock_result(AlignmentTable)
@mock
@property
def matches(self): # pragma: no cover
"""Access to aligned regions of read alignments
Returns
-------
:py:class:`~genome_kit.AlignmentMatchTable`
A table with optimized methods to query over all aligned regions by position.
"""
return mock_result(AlignmentMatchTable)
@mock
@property
def variants(self): # pragma: no cover
"""Access to variants observed by read alignments
Returns
-------
:py:class:`~genome_kit.VariantTable`
A table where each element (each row) is a variant that was observed
in at least one read alignment.
"""
return mock_result(VariantTable)
@mock
@property
def filename(self): # pragma: no cover
"""The path to the file from which read alignments are retrieved.
Returns
-------
:py:class:`str`
The path to the file, e.g. "/mnt/data/sample000132.ralign"
"""
return mock_result(str)
[docs]
@mock
def close(self): # pragma: no cover
"""Close the file handle.
Note that if you use a `with` statement the file handle is automatically closed::
# Open the file
with ReadAlignments('my_file.ralign') as raligns:
...
# <-- File is now closed
"""
mock_unreachable()
[docs]
@mock
@staticmethod
def ralign_version(): # pragma: no cover
"""The `ralign` file format version that this build supports.
Attempting to open an `ralign` file of a mismatched version will raise an :py:exc:`IOError`.
Returns
-------
:py:class:`int`
The version number.
"""
return mock_result(int)
[docs]
@mock
@staticmethod
def build_ralign(
outfile,
infiles,
reference_genome,
exclude=None,
allow=None,
include_duplicates=False,
library_format='U',
): # pragma: no cover
"""Build an `ralign` file from one or more `SAM` files.
If multiple input files are specified, their junctions and alignments will be pooled.
Once an `ralign` file is created, it can be opened by creating
a :py:class:`~genome_kit.ReadAlignments` object.
**Alignments on the reference genome.**
All junction, alignment, match, and variant intervals in the resulting file
are on the reference genome.
For example, an alignment starting at reference genome position 2
and with CIGAR string ``1M1D1M2N1M``
is matched to the reference genome as::
0 1 2 3 4 5 6 7 8 9 <-- reference genome coordinates
M D M - - M M <-- M = match, D = deletion
This results in one alignment (2:9), two matches (2:5, 7:9),
one junction (5:7), and one variant (3:4).
Similarly for insertions, with CIGAR string ``1M1I1M2N1M`` aligns as::
0 1 2 3 4 5 6 7 8 9
M M - - M M
^
I <-- I = insertion between
This results in one alignment (2:8), two matches (2:4, 6:8),
one junction (4:6), and one variant (3:3).
Parameters
----------
outfile : :py:class:`str`
The path to the destination `rdist` file.
infiles : :py:class:`list` of :py:class:`str` | :py:class:`file`
The paths to the source `SAM` files, or a reference to ``sys.stdin``.
Streaming lines from stdin is useful for reading directly from BAM
via ``samtools view -h``. Be sure to use ``-h`` so that
the reference genome can be inferred from the header lines.
reference_genome : :class:`~genome_kit.Genome`
The reference genome of the data in ``infiles``.
If the genome contains annotations, junction strands will be
inferred and validated against the introns annotations.
exclude : :py:class:`list` of :py:class:`~genome_kit.Interval`, optional
Junctions within these intervals will be excluded.
allow : :py:class:`list` of :py:class:`~genome_kit.Interval`, optional
Only junctions within these intervals will be included,
so long as they are not excluded.
include_duplicates : :py:class:`bool`, optional
Includes duplicates when `True`. Defaults to `False`. See
https://github.com/samtools/hts-specs/blob/master/SAMv1.pdf
subsection 1.4.2
library_format : :class:`str`, optional
Specifies to infer junction strands via the library format string.
"SF" implies the first read is the sense strand, whereas "SR"
implies the second read is the sense strand. (the default is 'U',
which represents unstranded [no strand inference]).
See https://salmon.readthedocs.io/en/stable/library_type.html.
"""
mock_unreachable()
PILEUP_A = 0
PILEUP_C = 1
PILEUP_G = 2
PILEUP_T = 3
PILEUP_DEL = 4
[docs]
def pileup(self, interval, dtype=np.int32): # pragma: no cover
"""
Returns the DNA sequence pileup for body reads in this `ReadAlignments`
as a 5-track. The pileup is variant-aware, so the track counts
the alternate sequences, instead of the reference, on any alignment
matches with variants.
Currently, only acgtACGT substitutions and deletions variants are
supported.
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
A positive interval to query over all the read alignments.
dtype : :py:class:`~numpy.dtype`, optional
The data type for the returned counts.
Returns
-------
:py:class:`~numpy.ndarray`
An array of ``shape`` (len(`interval`), 5) where the second
dimension is indexed via ``PILEUP_A``, ``PILEUP_C``, ``PILEUP_G``,
``PILEUP_T``, and ``PILEUP_DEL``.
"""
# "matches" refers to aligned regions: this includes mismatches.
# increment all the aligned regions and then fix-up for variant regions
counts = np.zeros((len(interval), 5), dtype)
ref_counts = np.zeros(len(interval), dtype)
for match in self.matches.find_overlapping(interval):
start = max(match.start, interval.start) - interval.start
end = min(match.end, interval.end) - interval.start
ref_counts[start:end] += 1
for variant in (x for x in match.variants if x.overlaps(interval.as_positive_strand())):
# ignore inserts for now
diff_len = len(variant.alt) - len(variant.ref)
if diff_len > 0:
continue
start = max(variant.start, interval.start)
end = min(variant.end, interval.end)
count_start = start - interval.start
count_end = end - interval.start
ref_counts[count_start:count_end] -= 1
position_indices = np.arange(count_start, count_end)
if diff_len == 0:
alt = variant.alt[start - variant.start:end - variant.start]
n_indices = [i for i, x in enumerate(alt) if x == 'N']
pileup_indices = np.delete(self._dna_as_pileup_index(alt), n_indices)
counts[np.delete(position_indices, n_indices), pileup_indices] += 1
elif diff_len < 0:
assert not variant.alt # normalized to only include deleted region (no padding)
counts[position_indices, self.PILEUP_DEL] += 1
assert (not ref_counts[ref_counts < 0].any())
dna_str = Genome(interval.reference_genome).dna(interval.as_positive_strand())
n_indices = [i for i, x in enumerate(dna_str) if x == 'N']
position_indices = np.delete(np.arange(len(interval)), n_indices)
pileup_indices = np.delete(self._dna_as_pileup_index(dna_str), n_indices)
ref_counts = np.delete(ref_counts, n_indices)
counts[position_indices, pileup_indices] += ref_counts
return counts
DNA_TO_INDEX = [b'\xFF'] * 256
DNA_TO_INDEX[ord('a')] = DNA_TO_INDEX[ord('A')] = b'\0'
DNA_TO_INDEX[ord('c')] = DNA_TO_INDEX[ord('C')] = b'\1'
DNA_TO_INDEX[ord('g')] = DNA_TO_INDEX[ord('G')] = b'\2'
DNA_TO_INDEX[ord('t')] = DNA_TO_INDEX[ord('T')] = b'\3'
DNA_TO_INDEX = b"".join(DNA_TO_INDEX)
@classmethod
def _dna_as_pileup_index(cls, dna_str):
"""
Convert a case-insensitive DNA string (ACGT) into an array of uint8 indices
in range {0,1,2,3}. Non-ACGT characters will be converted to index 255.
"""
indices = dna_str.encode('ascii').translate(cls.DNA_TO_INDEX)
return np.ndarray(shape=(len(indices), ), buffer=indices, dtype=np.uint8)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.close()
[docs]
def __repr__(self):
return '<ReadAlignments "{}">'.format(self.filename)
########################################################################
# Junction, JunctionTable
########################################################################
[docs]
@strip_mock_bases
@_cxx.register
class Junction(_cxx.Junction, Interval):
"""A Junction represents a gap in a read alignment when compared to the reference genome.
Bases: :py:class:`~genome_kit.Interval`
"""
__slots__ = () # <--- NEW SLOTS OK
# def __new__(self): pass # <--- DO NOT OVERRIDE BASE CLASS IMPLEMENTATION
# def __del__(self): pass # <--- DO NOT IMPLEMENT
# noinspection PyMissingConstructor
[docs]
@mock
def __init__(self): # pragma: no cover
pass # Stub to prevent Interval.__init__ from being accessible to docs
@mock
@property
def interval(self): # pragma: no cover
"""The interval spanned by this junction.
Note that :py:class:`~genome_kit.Junction` also inherits from :py:class:`~genome_kit.Interval`.
Returns
-------
:py:class:`~genome_kit.Interval`
The interval spanned by this junction.
"""
return mock_result(Interval)
@mock
@property
def _num_alignments(self): # pragma: no cover
"""
Returns
-------
:py:class:`int`
"""
return mock_result(int)
@mock
def _get_alignment(self, index): # pragma: no cover
"""
Parameters
----------
index : :py:class:`int`
Returns
-------
:py:class:`~genome_kit.Alignment`
"""
return mock_result(Alignment)
class _AlignmentsTupleAccessor(object):
__slots__ = '_junction'
def __init__(self, junction): # pragma: no cover
self._junction = junction
def __len__(self): # pragma: no cover
return self._junction._num_alignments
def __getitem__(self, item): # pragma: no cover
return self._junction._get_alignment(item)
@property
def alignments(self): # pragma: no cover
"""The read alignments across this junction.
Returns
-------
:py:class:`tuple` of :py:class:`~genome_kit.Alignment`
The read alignments across this junction.
"""
return self._AlignmentsTupleAccessor(self)
[docs]
def __repr__(self):
return '<Junction {}, len(alignments) = {}>'.format(self.interval, self._num_alignments)
[docs]
@_cxx.register
class JunctionTable(_cxx.JunctionTable):
__slots__ = () # <--- NEW SLOTS OK
# def __new__(self): pass # <--- DO NOT OVERRIDE BASE CLASS IMPLEMENTATION
# def __del__(self): pass # <--- DO NOT IMPLEMENT
[docs]
@mock
def find_5p_aligned(self, interval): # pragma: no cover
"""Returns all junctions that have 5' end aligned with 5' end of `interval`.
This function is a faster version of the brute-force filter::
[junc for junc in junctions if junc.end5 == interval.end5]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Junction`
All junctions that have 5' end aligned to the 5' end of `interval`.
"""
mock_unreachable()
return [Junction()]
[docs]
@mock
def find_3p_aligned(self, interval): # pragma: no cover
"""Returns all junctions that have 3' end aligned with 3' end of `interval`.
This function is a faster version of the brute-force filter::
[junc for junc in junctions if junc.end3 == interval.end3]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Junction`
All junctions that have 3' end aligned to the 3' end of `interval`.
"""
mock_unreachable()
return [Junction()]
[docs]
@mock
def find_5p_within(self, interval): # pragma: no cover
"""Returns all junctions that have 5'-most position within `interval`.
This function is a faster version of the brute-force filter::
[junc for junc in junctions if junc.end5.expand(0, 1) in interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Junction`
All junctions that have 5'-most position falling entirely within `interval`.
"""
mock_unreachable()
return [Junction()]
[docs]
@mock
def find_3p_within(self, interval): # pragma: no cover
"""Returns all junctions that have 3'-most position within `interval`.
This function is a faster version of the brute-force filter::
[junc for junc in junctions if junc.end3.expand(1, 0) in interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Junction`
All junctions that have 3'-most position falling entirely within `interval`.
"""
mock_unreachable()
return [Junction()]
[docs]
@mock
def find_within(self, interval): # pragma: no cover
"""Returns all junctions that fall entirely within `interval`.
This function is a faster version of the brute-force filter::
[junc for junc in junctions if junc in interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Junction`
All junction that fall entirely within `interval`.
"""
mock_unreachable()
return [Junction()]
[docs]
@mock
def find_overlapping(self, interval): # pragma: no cover
"""Returns all junctions that overlap `interval`.
This function is a faster version of the brute-force filter::
[junc for junc in junctions if junc.overlaps(interval)]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Junction`
All junctions that overlap `interval`.
"""
mock_unreachable()
return [Junction()]
[docs]
@mock
def find_exact(self, interval): # pragma: no cover
"""Returns all junctions that span exactly `interval`.
This function is a faster version of the brute-force filter::
[junc for junc in junctions if junc.interval == interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Junction`
All junctions that span exactly `interval`.
"""
mock_unreachable()
return [Junction()]
@mock
@property
def stranded(self): # pragma: no cover
"""If `True` then the strand is significant when calling the `find_x` methods.
Returns
-------
:py:class:`bool`
Whether this table can contain negative stranded intervals.
"""
return mock_result(bool)
[docs]
@mock
def __getitem__(self, index): # pragma: no cover
"""Lookup a junction by index
Allows iteration over all junctions::
for junc in junctions:
...
Parameters
----------
index : :py:class:`int`
The integer index of the requested junction.
Returns
-------
:py:class:`~genome_kit.Junction`
The junction object identified by the given index.
"""
return mock_result(Junction)
[docs]
def __repr__(self):
return "<JunctionTable, len = {}>".format(len(self))
########################################################################
# Alignment, AlignmentTable
########################################################################
[docs]
@strip_mock_bases
@_cxx.register
class Alignment(_cxx.Alignment, Interval):
"""A read alignment
Bases: :py:class:`~genome_kit.Interval`
"""
__slots__ = () # <--- NEW SLOTS OK
# def __new__(self): pass # <--- DO NOT OVERRIDE BASE CLASS IMPLEMENTATION
# def __del__(self): pass # <--- DO NOT IMPLEMENT
# noinspection PyMissingConstructor
[docs]
@mock
def __init__(self): # pragma: no cover
pass # Stub to prevent Interval.__init__ from being accessible to docs
@mock
@property
def interval(self): # pragma: no cover
"""The interval spanned by this read alignment.
Note that :py:class:`~genome_kit.Alignment` also inherits from :py:class:`~genome_kit.Interval`.
Returns
-------
:py:class:`~genome_kit.Interval`
The interval spanned by this read alignment.
"""
return mock_result(Interval)
@mock
@property
def matches(self): # pragma: no cover
"""The matching regions of this read alignment
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.AlignmentMatch`
A list of matching regions
"""
mock_unreachable()
return [AlignmentMatch()]
[docs]
def __repr__(self):
return '<Alignment {}, len(matches) = {}>'.format(self.interval, len(self.matches))
[docs]
@_cxx.register
class AlignmentTable(_cxx.AlignmentTable):
__slots__ = () # <--- NEW SLOTS OK
# def __new__(self): pass # <--- DO NOT OVERRIDE BASE CLASS IMPLEMENTATION
# def __del__(self): pass # <--- DO NOT IMPLEMENT
[docs]
@mock
def find_5p_aligned(self, interval): # pragma: no cover
"""Returns all read alignments that have 5' end aligned with 5' end of `interval`.
This function is a faster version of the brute-force filter::
[read for read in reads if read.end5 == interval.end5]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Alignment`
All read alignments that have 5' end aligned to the 5' end of `interval`.
"""
mock_unreachable()
return [Alignment()]
[docs]
@mock
def find_3p_aligned(self, interval): # pragma: no cover
"""Returns all read alignments that have 3' end aligned with 3' end of `interval`.
This function is a faster version of the brute-force filter::
[read for read in reads if read.end3 == interval.end3]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Alignment`
All read alignments that have 3' end aligned to the 3' end of `interval`.
"""
mock_unreachable()
return [Alignment()]
[docs]
@mock
def find_5p_within(self, interval): # pragma: no cover
"""Returns all read alignments that have 5'-most position within `interval`.
This function is a faster version of the brute-force filter::
[read for read in reads if read.end5.expand(0, 1) in interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Alignment`
All read alignments that have 5'-most position falling entirely within `interval`.
"""
mock_unreachable()
return [Alignment()]
[docs]
@mock
def find_3p_within(self, interval): # pragma: no cover
"""Returns all read alignments that have 3'-most position within `interval`.
This function is a faster version of the brute-force filter::
[read for read in reads if read.end3.expand(1, 0) in interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Alignment`
All read alignments that have 3'-most position falling entirely within `interval`.
"""
mock_unreachable()
return [Alignment()]
[docs]
@mock
def find_within(self, interval): # pragma: no cover
"""Returns all read alignments that fall entirely within `interval`.
This function is a faster version of the brute-force filter::
[read for read in reads if read in interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Alignment`
All read alignment that fall entirely within `interval`.
"""
mock_unreachable()
return [Alignment()]
[docs]
@mock
def find_overlapping(self, interval): # pragma: no cover
"""Returns all read alignments that overlap `interval`.
This function is a faster version of the brute-force filter::
[read for read in reads if read.overlaps(interval)]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Alignment`
All read alignments that overlap `interval`.
"""
mock_unreachable()
return [Alignment()]
[docs]
@mock
def find_exact(self, interval): # pragma: no cover
"""Returns all read alignments that span exactly `interval`.
This function is a faster version of the brute-force filter::
[read for read in reads if read.interval == interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.Alignment`
All read alignments that span exactly `interval`.
"""
mock_unreachable()
return [Alignment()]
@mock
@property
def stranded(self): # pragma: no cover
"""If `True` then the strand is significant when calling the `find_x` methods.
Returns
-------
:py:class:`bool`
Whether this table can contain negative stranded intervals.
"""
return mock_result(bool)
[docs]
@mock
def __getitem__(self, index): # pragma: no cover
"""Lookup a read alignment by index
Allows iteration over all read alignments::
for read in reads:
...
Parameters
----------
index : :py:class:`int`
The integer index of the requested read alignment.
Returns
-------
:py:class:`~genome_kit.Alignment`
The read alignment object identified by the given index.
"""
return mock_result(Alignment)
[docs]
def __repr__(self):
return "<AlignmentTable, len = {}>".format(len(self))
########################################################################
# AlignmentMatch, AlignmentMatchTable
########################################################################
[docs]
@strip_mock_bases
@_cxx.register
class AlignmentMatch(_cxx.AlignmentMatch, Interval):
"""A matching region a read alignment
Bases: :py:class:`~genome_kit.Interval`
"""
__slots__ = () # <--- NEW SLOTS OK
# def __new__(self): pass # <--- DO NOT OVERRIDE BASE CLASS IMPLEMENTATION
# def __del__(self): pass # <--- DO NOT IMPLEMENT
# noinspection PyMissingConstructor
[docs]
@mock
def __init__(self): # pragma: no cover
pass # Stub to prevent Interval.__init__ from being accessible to docs
@mock
@property
def interval(self): # pragma: no cover
"""The interval spanned by the matching region of a read alignment.
Note that :py:class:`~genome_kit.AlignmentMatch` also inherits from :py:class:`~genome_kit.Interval`.
Returns
-------
:py:class:`~genome_kit.Interval`
The interval spanned by this alignment match.
"""
return mock_result(Interval)
@mock
@property
def variants(self): # pragma: no cover
"""A list of variants observed in this matching region of an alignment.
Returns
-------
:py:class:`tuple` of :py:class:`~genome_kit.Variant`
A tuple of variants that this matching region of an alignment contains
"""
mock_unreachable()
return (Variant(), )
[docs]
def __repr__(self):
return '<AlignmentMatch {}, len(variants) = {}>'.format(self.interval, len(self.variants))
[docs]
@_cxx.register
class AlignmentMatchTable(_cxx.AlignmentMatchTable):
__slots__ = () # <--- NEW SLOTS OK
# def __new__(self): pass # <--- DO NOT OVERRIDE BASE CLASS IMPLEMENTATION
# def __del__(self): pass # <--- DO NOT IMPLEMENT
[docs]
@mock
def find_5p_aligned(self, interval): # pragma: no cover
"""Returns all alignment matches that have 5' end aligned with 5' end of `interval`.
This function is a faster version of the brute-force filter::
[match for match in matches if match.end5 == interval.end5]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.AlignmentMatch`
All alignment matches that have 5' end aligned to the 5' end of `interval`.
"""
mock_unreachable()
return [AlignmentMatch()]
[docs]
@mock
def find_3p_aligned(self, interval): # pragma: no cover
"""Returns all alignment matches that have 3' end aligned with 3' end of `interval`.
This function is a faster version of the brute-force filter::
[match for match in matches if match.end3 == interval.end3]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.AlignmentMatch`
All alignment matches that have 3' end aligned to the 3' end of `interval`.
"""
mock_unreachable()
return [AlignmentMatch()]
[docs]
@mock
def find_5p_within(self, interval): # pragma: no cover
"""Returns all alignment matches that have 5'-most position within `interval`.
This function is a faster version of the brute-force filter::
[match for match in matches if match.end5.expand(0, 1) in interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.AlignmentMatch`
All alignment matches that have 5'-most position falling entirely within `interval`.
"""
mock_unreachable()
return [AlignmentMatch()]
[docs]
@mock
def find_3p_within(self, interval): # pragma: no cover
"""Returns all alignment matches that have 3'-most position within `interval`.
This function is a faster version of the brute-force filter::
[match for match in matches if match.end3.expand(1, 0) in interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.AlignmentMatch`
All alignments matches that have 3'-most position falling entirely within `interval`.
"""
mock_unreachable()
return [AlignmentMatch()]
[docs]
@mock
def find_within(self, interval): # pragma: no cover
"""Returns all alignment matches that fall entirely within `interval`.
This function is a faster version of the brute-force filter::
[match for match in matches if match in interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.AlignmentMatch`
All alignment matches that fall entirely within `interval`.
"""
mock_unreachable()
return [AlignmentMatch()]
[docs]
@mock
def find_overlapping(self, interval): # pragma: no cover
"""Returns all alignment matches that overlap `interval`.
This function is a faster version of the brute-force filter::
[match for match in matches if match.overlaps(interval)]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.AlignmentMatch`
All alignment matches that overlap `interval`.
"""
mock_unreachable()
return [AlignmentMatch()]
[docs]
@mock
def find_exact(self, interval): # pragma: no cover
"""Returns all alignment matches that span exactly `interval`.
This function is a faster version of the brute-force filter::
[match for match in matches if match.interval == interval]
Parameters
----------
interval : :py:class:`~genome_kit.Interval`
The query interval.
Returns
-------
:py:class:`list` of :py:class:`~genome_kit.AlignmentMatch`
All alignment matches that span exactly `interval`.
"""
mock_unreachable()
return [AlignmentMatch()]
@mock
@property
def stranded(self): # pragma: no cover
"""If `True` then the strand is significant when calling the `find_x` methods.
Returns
-------
:py:class:`bool`
Whether this table can contain negative stranded intervals.
"""
return mock_result(bool)
[docs]
@mock
def __getitem__(self, index): # pragma: no cover
"""Lookup an alignment match by index
Allows iteration over all alignment matches::
for match in matches:
...
Parameters
----------
index : :py:class:`int`
The integer index of the requested alignment match.
Returns
-------
:py:class:`~genome_kit.AlignmentMatch`
The alignment match object identified by the given index.
"""
return mock_result(AlignmentMatch)
[docs]
def __repr__(self):
return "<AlignmentMatchTable, len = {}>".format(len(self))