Skip to content

Commit

Permalink
feat: use OffTargetDetector and ExecutableRunner as ContextManagers
Browse files Browse the repository at this point in the history
  • Loading branch information
clintval committed Oct 4, 2024
1 parent c434b1d commit 894498e
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 27 deletions.
4 changes: 3 additions & 1 deletion prymer/offtarget/offtarget_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
""" # noqa: E501

import itertools
from contextlib import AbstractContextManager
from dataclasses import dataclass
from dataclasses import field
from dataclasses import replace
Expand Down Expand Up @@ -124,7 +125,7 @@ class OffTargetResult:
right_primer_spans: list[Span] = field(default_factory=list)


class OffTargetDetector:
class OffTargetDetector(AbstractContextManager):
"""
Detect off-target mappings of primers and primer pairs.
Expand Down Expand Up @@ -442,4 +443,5 @@ def __exit__(
traceback: Optional[TracebackType],
) -> None:
"""Gracefully terminates any running subprocesses."""
super().__exit__(exc_type, exc_value, traceback)
self.close()
4 changes: 3 additions & 1 deletion prymer/util/executable_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
import os
import shutil
import subprocess
from contextlib import AbstractContextManager
from pathlib import Path
from types import TracebackType
from typing import Optional
from typing import Self


class ExecutableRunner:
class ExecutableRunner(AbstractContextManager):
"""
Base class for interaction with subprocess for all command-line tools. The base class supports
use of the context management protocol and performs basic validation of executable paths.
Expand Down Expand Up @@ -67,6 +68,7 @@ def __exit__(
traceback: Optional[TracebackType],
) -> None:
"""Gracefully terminates any running subprocesses."""
super().__exit__(exc_type, exc_value, traceback)
self.close()

@classmethod
Expand Down
48 changes: 23 additions & 25 deletions tests/api/test_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,31 +573,29 @@ def _pick_top_primer_pairs(
max_primer_pair_hits: int,
min_difference: int = 1,
) -> list[PrimerPair]:
offtarget_detector = OffTargetDetector(
ref=picking_ref,
max_primer_hits=max_primer_hits,
max_primer_pair_hits=max_primer_pair_hits,
three_prime_region_length=5,
max_mismatches_in_three_prime_region=0,
max_mismatches=0,
max_amplicon_size=params.amplicon_sizes.max,
)
dimer_checker = NtThermoAlign()

picked = pick_top_primer_pairs(
primer_pairs=primer_pairs,
num_primers=len(primer_pairs),
min_difference=min_difference,
params=params,
offtarget_detector=offtarget_detector,
is_dimer_tm_ok=lambda s1, s2: (
dimer_checker.duplex_tm(s1=s1, s2=s2) <= params.max_dimer_tm
),
)
offtarget_detector.close()
dimer_checker.close()

return picked
with (
NtThermoAlign() as dimer_checker,
OffTargetDetector(
ref=picking_ref,
max_primer_hits=max_primer_hits,
max_primer_pair_hits=max_primer_pair_hits,
three_prime_region_length=5,
max_mismatches_in_three_prime_region=0,
max_mismatches=0,
max_amplicon_size=params.amplicon_sizes.max,
) as offtarget_detector
):
picked: list[PrimerPair] = pick_top_primer_pairs(
primer_pairs=primer_pairs,
num_primers=len(primer_pairs),
min_difference=min_difference,
params=params,
offtarget_detector=offtarget_detector,
is_dimer_tm_ok=lambda s1, s2: (
dimer_checker.duplex_tm(s1=s1, s2=s2) <= params.max_dimer_tm
),
)
return picked


_PARAMS: FilteringParams = _zero_score_filtering_params(_score_input())
Expand Down

0 comments on commit 894498e

Please sign in to comment.