Skip to content

Commit

Permalink
doc: Document
Browse files Browse the repository at this point in the history
  • Loading branch information
msto committed Sep 24, 2024
1 parent 9d9ff5c commit 7ef6f0c
Showing 1 changed file with 65 additions and 14 deletions.
79 changes: 65 additions & 14 deletions prymer/offtarget/offtarget_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ class OffTargetResult:
"""Information obtained by running a single primer pair through the off-target detector.
Attributes:
primer_pair: the primer submitted
passes: True if the primer pair passes all checks, False otherwise
primer_pair: the primer pair submitted
passes: True if neither primer exceeds the specified maximum number of hits, and the primer
pair would generate an acceptable number of amplicons in the reference genome (i.e.
`min_primer_pair_hits <= num_amplicons <= max_primer_pair_hits`). False otherwise.
cached: True if this result is part of a cache, False otherwise. This is useful for testing
spans: the set of mappings of the primer pair to the genome or an empty list if mappings
were not retained
Expand All @@ -122,15 +124,28 @@ class OffTargetResult:


class OffTargetDetector:
"""A class for detecting off-target mappings of primers and primer pairs that uses a custom
version of "bwa aln".
"""
Detect off-target mappings of primers and primer pairs.
The off-target detection is faster and more sensitive than traditional isPCR and in addition can
correctly detect primers that are repetitive and contain many thousands or millions of mappings
to the genome.
`OffTargetDetector` uses a [custom, interactive
version](https://github.com/fulcrumgenomics/bwa-aln-interactive/) of `bwa aln` to perform
off-target detection. This approach is faster and more sensitive than traditional isPCR and in
addition can correctly detect primers that are repetitive and contain many thousands or millions
of mappings to the genome.
Note that while this class invokes BWA with multiple threads, it is not itself thread-safe.
Only one thread at a time should invoke methods on this class without external synchronization.
Off-target detection may be performed for individual primers or primer pairs.
To detect off-target hits for individual primers, use the `OffTargetDetector.filters()` method,
which will remove any primers that have more than the specified number of maximum hits against
the reference.
To detect off-target amplification of primer pairs, use the `OffTargetDetector.check_one()` or
`OffTargetDetector.check_all()` methods. These methods screen the individual primers in each
pair for off-target hits, and verify that the possible amplicons inferred by the primers'
alignments does not exceed the specified maximum number of primer pair hits.
"""

def __init__(
Expand Down Expand Up @@ -199,25 +214,61 @@ def __init__(
self._keep_primer_spans: bool = keep_primer_spans

def filter(self, primers: list[PrimerType]) -> list[PrimerType]:
"""Filters an iterable of Primers to return only those that have less than
`max_primer_hits` mappings to the genome."""
"""
Remove primers that have more than `max_primer_hits` mappings to the genome.
This method maps each primer to the specified reference with `bwa aln` to search for
off-target hits. Note that when the reference includes the sequence from which the primers
were design, the on-target hit will be included in the hit count. `max_primer_hits` should
be set to at least 1 in this case.
Args:
primers: A list of primers to filter.
Returns:
The input primers, filtered to remove any primers with more than `max_primer_hits`
mappings to the genome.
"""
results: dict[str, BwaResult] = self.mappings_of(primers)
return [
primer for primer in primers if results[primer.bases].hit_count <= self._max_primer_hits
]

def check_one(self, primer_pair: PrimerPair) -> OffTargetResult:
"""Checks a PrimerPair for off-target sites in the genome at which it might amplify."""
"""
Check an individual primer pair for off-target amplification.
See `OffTargetDetector.check_all()` for details.
Args:
primer_pair: The primer pair to check.
Returns:
The results of the off-target detection.
See `OffTargetResult` for details regarding the attributes included in the result.
"""
result: dict[PrimerPair, OffTargetResult] = self.check_all([primer_pair])
return result[primer_pair]

def check_all(self, primer_pairs: list[PrimerPair]) -> dict[PrimerPair, OffTargetResult]:
"""Checks a collection of primer pairs for off-target sites, returning a dictionary of
`PrimerPair`s to `OffTargetResult`.
"""
Check a collection of primer pairs for off-target amplification.
This method maps each primer to the specified reference with `bwa aln` to search for
off-target hits. Possible amplicons are identified from the pairwise combinations of these
alignments, up to the specified `max_amplicon_size`.
Primer pairs are marked as passing if both of the following are true:
1. Each primer has no more than `max_primer_hits` alignments to the genome.
2. The size of the set of possible amplicons does not exceed `max_primer_pair_hits`, and is
at least `min_primer_pair_hits`.
Args:
primer_pairs: The primer pairs to check.
Returns:
a Map containing all given primer pairs as keys with the values being the result of
off-target checking.
A dictionary mapping each checked primer pair to its off-target detection results.
See `OffTargetResult` for details regarding the attributes included in each result.
"""

primer_pair_results: dict[PrimerPair, OffTargetResult] = {}
Expand Down

0 comments on commit 7ef6f0c

Please sign in to comment.