# [Bioperl-l] Bio::SeqFeature::Primer Calculating the Primer TM

Barry Moore barry.moore at genetics.utah.edu
Tue Feb 17 19:23:01 EST 2004

```John, Rob and others,

Well I certainly am not a Tm guru, but I'll reply none the less.  I have
written a Tm calculator that uses thermodynamic parameters rather than
"rule of thumb" calculations.  Mine follows the formula (and
modifications) described by Integrated DNA Technologies on their web
site
(http://www.idtdna.com/program/techbulletins/Calculating_Tm_(melting_temperature).asp
<http://www.idtdna.com/program/techbulletins/Calculating_Tm_%28melting_temperature%29.asp>).
This code uses the equation: Tm = (dH / (dS +R * ln(C)) - 273.15  found
in Breslauer (1986) and apparently used by GCG and the Python guys where
R is the molar gas constant, and C is the molar concentration of the
oligo.  It adds to that an adjustment of Na+ concentration as per Santa
Lucia (1996) with some additional tweaking as described on the IDT web
page above to give: Tm = (dH / (dS +R * ln(C)) - 273.15 + 12.0 *
log[Na+] .  It uses the nearest-neighbor thermodynamic parameter set of
Allawi and SantaLucia (1997), but it looks like maybe it should be
updated to the SantaLucia (1998) parameter set.

I haven't read all the papers discussed in the various posts today, only
the couple that my code is based on (and had plenty of trouble
understanding all that was in those!), so I don't want to imply that the
equations that I use are based on a thorough review of oligo
thermodynamics literature, but the code seems to work, and it gives good
Tm values. Theoretically I should get the exact same values as IDT's web
calculator, but I don't.  My values are always very close, but off by a
fraction to a couple degrees.  It may be due to a difference in
parameter sets, although I'm using the same one that IDT references on
their site.

Rob, I morphed my code into your Primer Tm method, and tried it out.  It
seems to work fine.  It requires one extra parameter (oligo
concentration) that I just defaulted.  If you want to use the code as is
(or as a starting point) it is yours to do with as you see fit.  I can
update the "thermodynamic parameters" hash to the SantaLucia (1998)
values if this code looks promising and there is general agreement those
values are the better.  I don't have CVS access, so I'll just post the
modified method code at the very end of this message.

I did a quick and dirty test to see how Tm values differ between your
Primer Tm method, my code, and IDT's web calculator.  They tend towards
Tm(Rob) > Tm(IDT) > Tm(Barry).  Here's the result:

Oligo 	Primer.pm (Rob) 	Primer.pm (Barry) 	IDT
ACCGATACCG 	34.49709793 	29.41129054 	31.3
ACCCGATCTAGTAGA 	49.03043126 	41.9210458 	43.3
CATGGAGAGGGTGCAAATCC 	62.44709793 	55.72210633 	56.8
AAAGTAACCGAGAGAATCTGGAACA 	62.29709793 	56.7940798 	57.7
GGCTTTTGAAGTGGCAGAAAGACTGGGGGT 	71.76376459 	67.19994018 	68
CACTCGCCTGCTGGATGCAGAAGATGTGGATGTGC 	76.18281221 	70.5586708 	71.2
CTCTCCAGATGAAAAGTCTGTAATCACTTATGTGTCTTCG 	71.29709793 	63.54486627 	64.1
ATTTATGATGCCTTCCCTAAAGTTCCTGAGGGTGGAGAAGGGATC 	75.69709793 	69.5961597
70.1
AGTGCTACGGAAGTGGACTCCAGGTGGCAAGAATACCAAAGCCGAGTGGA 	80.03709793
75.41693338 	75.9

Here are the papers I've referenced:

* Breslauer, K.J., Frank, R., Blocker, H., Marky, L.A. (1986)
"Predicting DNA duplex stability from the base sequence."
Proc.Natl. Acad. Sci. USA 83:3746-3750
* SantaLucia, Jr., J.S, Allawi, H.T., Seneviratne, P.A. (1996)
"Improved nearest-neighbor parameters for predicting DNA duplex
stability" Biochemistry 35:3555-3562.
* Allawi, H.T., SantaLucia, J. Jr. (1997) "Thermodynamics and NMR of
internal G.T mismatches in DNA." Biochemistry 36: 10581-10594
* SantaLucia J. Jr. (1998) "A unified view of polymer, dumbbell, and
oligonucleotide DNA nearest-neighbor thermodynamics" PNAS 95:
1460-1465.

Here is the new Tm method code:

=head2 Tm()

Title   : Tm()
Usage   : \$tm = \$primer->Tm(-salt=>'0.05')
Function: Calculates and returns the Tm (melting temperature) of the primer
Returns : A scalar containing the Tm.
Args    : -salt set the Na+ concentration on which to base the calculation.
(A parameter should be added to allow the oligo concentration
to be set.)
Notes   : Calculation of Tm as per Allawi et. al Biochemistry 1997
36:10581-10594.  Also see
documentation at http://biotools.idtdna.com/analyzer/ as they
use this formula and
have a couple nice help pages.  These Tm values will be about
are about 0.5-3 degrees
off from those of the idtdna web tool.  I don't know why.
=cut

sub Tm  {
my (\$self, %args) = @_;
my \$salt_conc = 0.05; #salt concentration (molar units)
my \$oligo_conc = 0.00000025; #oligo concentration (molar units)
if (\$args{'-salt'}) {\$salt_conc = \$args{'-salt'}} #accept object
defined salt concentration
#if (\$args{'-oligo'}) {\$oligo_conc = \$args{'-oligo'}} #accept object
defined oligo concentration
my \$seqobj = \$self->seq();
my \$length = \$seqobj->length();
my \$sequence = uc \$seqobj->seq();
my @dinucleotides;
my \$enthalpy;
my \$entropy;
#Break sequence string into an array of all possible dinucleotides
while (\$sequence =~ /(.)(?=(.))/g) {
push @dinucleotides, \$1.\$2;
}
#Build a hash with the thermodynamic values
my %thermo_values = ('AA' => {'enthalpy' => -7.9,
'entropy'  => -22.2},
'AC' => {'enthalpy' => -8.4,
'entropy'  => -22.4},
'AG' => {'enthalpy' => -7.8,
'entropy'  => -21},
'AT' => {'enthalpy' => -7.2,
'entropy'  => -20.4},
'CA' => {'enthalpy' => -8.5,
'entropy'  => -22.7},
'CC' => {'enthalpy' => -8,
'entropy'  => -19.9},
'CG' => {'enthalpy' => -10.6,
'entropy'  => -27.2},
'CT' => {'enthalpy' => -7.8,
'entropy'  => -21},
'GA' => {'enthalpy' => -8.2,
'entropy'  => -22.2},
'GC' => {'enthalpy' => -9.8,
'entropy'  => -24.4},
'GG' => {'enthalpy' => -8,
'entropy'  => -19.9},
'GT' => {'enthalpy' => -8.4,
'entropy'  => -22.4},
'TA' => {'enthalpy' => -7.2,
'entropy'  => -21.3},
'TC' => {'enthalpy' => -8.2,
'entropy'  => -22.2},
'TG' => {'enthalpy' => -8.5,
'entropy'  => -22.7},
'TT' => {'enthalpy' => -7.9,
'entropy'  => -22.2},
'A' =>  {'enthalpy' => 2.3,
'entropy'  => 4.1},
'C' =>  {'enthalpy' => 0.1,
'entropy'  => -2.8},
'G' =>  {'enthalpy' => 0.1,
'entropy'  => -2.8},
'T' =>  {'enthalpy' => 2.3,
'entropy'  => 4.1}
);
#Loop through dinucleotides and calculate cumulative enthalpy and
entropy values
for (@dinucleotides) {
\$enthalpy += \$thermo_values{\$_}{enthalpy};
\$entropy += \$thermo_values{\$_}{entropy};
}
#Account for initiation parameters
\$enthalpy += \$thermo_values{substr(\$sequence, 0, 1)}{enthalpy};
\$entropy += \$thermo_values{substr(\$sequence, 0, 1)}{entropy};
\$enthalpy += \$thermo_values{substr(\$sequence, -1, 1)}{enthalpy};
\$entropy += \$thermo_values{substr(\$sequence, -1, 1)}{entropy};
#Symmetry correction
\$entropy -= 1.4;
my \$r = 1.987; #molar gas constant
my \$tm = (\$enthalpy * 1000 / (\$entropy + (\$r * log(\$oligo_conc))) -
273.15 + (12* (log(\$salt_conc)/log(10))));
\$self->{'Tm'}=\$tm;
return \$tm;
}

```

More information about the Bioperl-l mailing list