Utility Classes and Methods for NtThermoAlign
This module contains the NtThermoAlign class for
submitting multiple queries to ntthal, a command line tool included with primer3. Methods
include functions to open and use subprocesses, check and
manipulate status, and calculate melting temperature of valid oligo sequences.
The class can be optionally used as a context manager.
Examples of Calculating Melting Temperature
>>> from prymer import ntthal
>>> t = ntthal.NtThermoAlign()
>>> print(t.duplex_tm(s1="ATGC", s2="GCAT"))
-54.75042
>>> from prymer import ntthal
>>> with ntthal.NtThermoAlign() as t:
... print(t.duplex_tm(s1="ATGC", s2="GCAT"))
-54.75042
Attributes
DIVALENT_MILLIMOLAR
module-attribute
DIVALENT_MILLIMOLAR: float = 0.0
The default concentration of divalent cations in mM
DNA_NANOMOLAR
module-attribute
DNA_NANOMOLAR: float = 50.0
The concentration of DNA strands in nM
DNTP_MILLIMOLAR
module-attribute
DNTP_MILLIMOLAR: float = 0.0
The default concentration of deoxynycleotide triphosphate in mM
MONOVALENT_MILLIMOLAR
module-attribute
MONOVALENT_MILLIMOLAR: float = 50.0
The default concentration of monovalent cations in mM
TEMPERATURE
module-attribute
TEMPERATURE: float = 37.0
The default temperature at which duplex is calculated (Celsius)
Classes
NtThermoAlign
Bases: ExecutableRunner
Uses the ntthal command line tool to calculate the melting temperature of user-provided
oligo sequences.
Source code in prymer/ntthal/__init__.py
| class NtThermoAlign(ExecutableRunner):
"""
Uses the `ntthal` command line tool to calculate the melting temperature of user-provided
oligo sequences.
"""
def __init__(
self,
executable: str | Path = "ntthal",
monovalent_millimolar: float = MONOVALENT_MILLIMOLAR,
divalent_millimolar: float = DIVALENT_MILLIMOLAR,
dntp_millimolar: float = DNTP_MILLIMOLAR,
dna_nanomolar: float = DNA_NANOMOLAR,
temperature: float = TEMPERATURE,
):
"""
Args:
executable: string or Path representation of ntthal executable path
monovalent_millimolar: concentration of monovalent cations in mM
divalent_millimolar: concentration of divalent cations in mM
dntp_millimolar: concentration of deoxynycleotide triphosphate in mM
dna_nanomolar: concentration of DNA strands in nM
temperature: temperature at which duplex is calculated (Celsius)
"""
executable_path = ExecutableRunner.validate_executable_path(executable=executable)
command: list[str] = [f"{executable_path}", "-r", "-i"]
if monovalent_millimolar < 0:
raise ValueError(f"monovalent_millimolar must be >=0, received {monovalent_millimolar}")
if divalent_millimolar < 0:
raise ValueError(f"divalent_millimolar must be >=0, received {divalent_millimolar}")
if dntp_millimolar < 0:
raise ValueError(f"dntp_millimolar must be >=0, received {dntp_millimolar}")
if dna_nanomolar < 0:
raise ValueError(f"dna_nanomolar must be >=0, received {dna_nanomolar}")
if temperature < 0:
raise ValueError(f"temperature must be >=0, received {temperature}")
command.extend(["-mv", f"{monovalent_millimolar}"])
command.extend(["-dv", f"{divalent_millimolar}"])
command.extend(["-n", f"{dntp_millimolar}"])
command.extend(["-d", f"{dna_nanomolar}"])
command.extend(["-t", f"{temperature}"])
super().__init__(command=command)
def duplex_tm(self, s1: str, s2: str) -> float:
"""
Calculates the melting temperature (Tm) of two provided oligos.
Args:
s1: the sequence of oligo 1 (5'->3' orientation)
s2: the sequence of oligo 2 (5'->3' orientation)
Example:
>>> t = NtThermoAlign()
>>> t.duplex_tm(s1 = "ACGT", s2 = "ACGT")
-46.542706
Returns:
result: ntthal-calculated melting temperature
Raises:
ValueError: if ntthal result cannot be cast to a float
RuntimeError: if underlying subprocess has already been terminated
"""
if not self.is_alive:
raise RuntimeError(
"Error, trying to use a subprocess that has already been "
f"terminated, return code {self._subprocess.returncode}"
)
if not s1.isalpha() or not s2.isalpha():
raise ValueError(
"Both input strings must be all alphabetic and non-empty, "
f"received {s1} and {s2}"
)
self._subprocess.stdin.write(f"{s1},{s2}\n")
self._subprocess.stdin.flush() # forces the input to be sent to the underlying process.
raw_result = self._subprocess.stdout.readline().rstrip("\r\n")
try:
result = float(raw_result)
except ValueError as e:
raise ValueError(f"Error: {e}, {raw_result} cannot be cast to float") from e
return result
|
Functions
__init__
__init__(
executable: str | Path = "ntthal",
monovalent_millimolar: float = MONOVALENT_MILLIMOLAR,
divalent_millimolar: float = DIVALENT_MILLIMOLAR,
dntp_millimolar: float = DNTP_MILLIMOLAR,
dna_nanomolar: float = DNA_NANOMOLAR,
temperature: float = TEMPERATURE,
)
Parameters:
| Name |
Type |
Description |
Default |
executable |
str | Path
|
string or Path representation of ntthal executable path
|
'ntthal'
|
monovalent_millimolar |
float
|
concentration of monovalent cations in mM
|
MONOVALENT_MILLIMOLAR
|
divalent_millimolar |
float
|
concentration of divalent cations in mM
|
DIVALENT_MILLIMOLAR
|
dntp_millimolar |
float
|
concentration of deoxynycleotide triphosphate in mM
|
DNTP_MILLIMOLAR
|
dna_nanomolar |
float
|
concentration of DNA strands in nM
|
DNA_NANOMOLAR
|
temperature |
float
|
temperature at which duplex is calculated (Celsius)
|
TEMPERATURE
|
Source code in prymer/ntthal/__init__.py
| def __init__(
self,
executable: str | Path = "ntthal",
monovalent_millimolar: float = MONOVALENT_MILLIMOLAR,
divalent_millimolar: float = DIVALENT_MILLIMOLAR,
dntp_millimolar: float = DNTP_MILLIMOLAR,
dna_nanomolar: float = DNA_NANOMOLAR,
temperature: float = TEMPERATURE,
):
"""
Args:
executable: string or Path representation of ntthal executable path
monovalent_millimolar: concentration of monovalent cations in mM
divalent_millimolar: concentration of divalent cations in mM
dntp_millimolar: concentration of deoxynycleotide triphosphate in mM
dna_nanomolar: concentration of DNA strands in nM
temperature: temperature at which duplex is calculated (Celsius)
"""
executable_path = ExecutableRunner.validate_executable_path(executable=executable)
command: list[str] = [f"{executable_path}", "-r", "-i"]
if monovalent_millimolar < 0:
raise ValueError(f"monovalent_millimolar must be >=0, received {monovalent_millimolar}")
if divalent_millimolar < 0:
raise ValueError(f"divalent_millimolar must be >=0, received {divalent_millimolar}")
if dntp_millimolar < 0:
raise ValueError(f"dntp_millimolar must be >=0, received {dntp_millimolar}")
if dna_nanomolar < 0:
raise ValueError(f"dna_nanomolar must be >=0, received {dna_nanomolar}")
if temperature < 0:
raise ValueError(f"temperature must be >=0, received {temperature}")
command.extend(["-mv", f"{monovalent_millimolar}"])
command.extend(["-dv", f"{divalent_millimolar}"])
command.extend(["-n", f"{dntp_millimolar}"])
command.extend(["-d", f"{dna_nanomolar}"])
command.extend(["-t", f"{temperature}"])
super().__init__(command=command)
|
duplex_tm
duplex_tm(s1: str, s2: str) -> float
Calculates the melting temperature (Tm) of two provided oligos.
Parameters:
| Name |
Type |
Description |
Default |
s1 |
str
|
the sequence of oligo 1 (5'->3' orientation)
|
required
|
s2 |
str
|
the sequence of oligo 2 (5'->3' orientation)
|
required
|
Example
t = NtThermoAlign()
t.duplex_tm(s1 = "ACGT", s2 = "ACGT")
-46.542706
Returns:
| Name | Type |
Description |
result |
float
|
ntthal-calculated melting temperature
|
Raises:
| Type |
Description |
ValueError
|
if ntthal result cannot be cast to a float
|
RuntimeError
|
if underlying subprocess has already been terminated
|
Source code in prymer/ntthal/__init__.py
| def duplex_tm(self, s1: str, s2: str) -> float:
"""
Calculates the melting temperature (Tm) of two provided oligos.
Args:
s1: the sequence of oligo 1 (5'->3' orientation)
s2: the sequence of oligo 2 (5'->3' orientation)
Example:
>>> t = NtThermoAlign()
>>> t.duplex_tm(s1 = "ACGT", s2 = "ACGT")
-46.542706
Returns:
result: ntthal-calculated melting temperature
Raises:
ValueError: if ntthal result cannot be cast to a float
RuntimeError: if underlying subprocess has already been terminated
"""
if not self.is_alive:
raise RuntimeError(
"Error, trying to use a subprocess that has already been "
f"terminated, return code {self._subprocess.returncode}"
)
if not s1.isalpha() or not s2.isalpha():
raise ValueError(
"Both input strings must be all alphabetic and non-empty, "
f"received {s1} and {s2}"
)
self._subprocess.stdin.write(f"{s1},{s2}\n")
self._subprocess.stdin.flush() # forces the input to be sent to the underlying process.
raw_result = self._subprocess.stdout.readline().rstrip("\r\n")
try:
result = float(raw_result)
except ValueError as e:
raise ValueError(f"Error: {e}, {raw_result} cannot be cast to float") from e
return result
|