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

john herbert john.herbert at clinical-pharmacology.oxford.ac.uk
Wed Feb 18 08:48:34 EST 2004


Hello All.
Thanks for all you suggestions and code. I did have a go myself but it
was not until Barry supplied this code that I actually got it.
Kind regards,
John.

>>> Barry Moore <barry.moore at genetics.utah.edu> 18/02/2004 00:23:01
>>>
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