2
Copyright (c) 1996,1997,1998,1999,2000,2001,2004,2006
3
Whitehead Institute for Biomedical Research, Steve Rozen
4
(http://jura.wi.mit.edu/rozen), and Helen Skaletsky
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
11
* Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
* Redistributions in binary form must reproduce the above
14
copyright notice, this list of conditions and the following disclaimer
15
in the documentation and/or other materials provided with the
17
* Neither the names of the copyright holders nor contributors may
18
be used to endorse or promote products derived from this software
19
without specific prior written permission.
21
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
OWNERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
#include "primer3_release.h"
41
* Tables of nearest-neighbor thermodynamics for DNA bases.
42
* See Breslauer, Frank, Blocker, and Markey,
43
* "Predicting DNA duplex stability from the base sequence."
44
* Proc. Natl. Acad. Sci. USA, vol 83, page 3746 (1986).
46
* http://www.pubmedcentral.nih.gov/picrender.fcgi?artid=323600&blobtype=pdf
110
/* Delta G's of disruption * 1000. */
147
#define CATID5(A,B,C,D,E) A##B##C##D##E
148
#define CATID2(A,B) A##B
149
#define DO_PAIR(LAST,THIS) \
150
if (CATID2(THIS,_CHAR) == c) { \
151
dh += CATID5(H,_,LAST,_,THIS); \
152
ds += CATID5(S,_,LAST,_,THIS); \
153
goto CATID2(THIS,_STATE); \
156
#define STATE(LAST) \
157
CATID2(LAST,_STATE): \
160
else DO_PAIR(LAST,T) \
161
else DO_PAIR(LAST,G) \
162
else DO_PAIR(LAST,C) \
163
else DO_PAIR(LAST,N) \
164
else if ('\0' == c) \
169
oligotm(s, DNA_nM, K_mM)
174
register int dh = 0, ds = 108;
176
double delta_H, delta_S;
178
/* Use a finite-state machine (DFA) to calucluate dh and ds for s. */
180
if (c == 'A') goto A_STATE;
181
else if (c == 'G') goto G_STATE;
182
else if (c == 'T') goto T_STATE;
183
else if (c == 'C') goto C_STATE;
184
else if (c == 'N') goto N_STATE;
192
DONE: /* dh and ds are now computed for the given sequence. */
193
delta_H = dh * -100.0; /*
194
* Nearest-neighbor thermodynamic values for dh
195
* are given in 100 cal/mol of interaction.
197
delta_S = ds * -0.1; /*
198
* Nearest-neighbor thermodynamic values for ds
199
* are in in .1 cal/K per mol of interaction.
203
* See Rychlik, Spencer, Rhoads,
204
* "Optimization of the annealing temperature for
205
* DNA amplification in vitro."
206
* Nucleic Acids Research, vol 18, no 21, page 6409 (1990).
208
* http://www.pubmedcentral.nih.gov/articlerender.fcgi?tool=pubmed&pubmedid=2243783
211
return delta_H / (delta_S + 1.987 * log(DNA_nM/4000000000.0))
212
- 273.15 + 16.6 * log10(K_mM/1000.0);
215
* length of s was less than 2 or there was an illegal character in
218
return OLIGOTM_ERROR;
222
#define DO_PAIR(LAST,THIS) \
223
if (CATID2(THIS,_CHAR) == c) { \
224
dg += CATID5(G,_,LAST,_,THIS); \
225
goto CATID2(THIS,_STATE); \
230
const char *s; /* The sequence. */
235
/* Use a finite-state machine (DFA) to calucluate dg s. */
237
if (c == 'A') goto A_STATE;
238
else if (c == 'G') goto G_STATE;
239
else if (c == 'T') goto T_STATE;
240
else if (c == 'C') goto C_STATE;
241
else if (c == 'N') goto N_STATE;
249
DONE: /* dg is now computed for the given sequence. */
253
* length of s was less than 2 or there was an illegal character in
256
return OLIGOTM_ERROR;
259
double end_oligodg(s, len)
261
int len; /* The number of characters to return. */
264
return x < len ? oligodg(s) : oligodg(s + (x - len));
267
double seqtm(seq, dna_conc, salt_conc, nn_max_len)
273
int len = strlen(seq);
274
return (len > nn_max_len)
275
? long_seq_tm(seq, 0, len, salt_conc) : oligotm(seq, dna_conc, salt_conc);
278
/* See oligotm.h for documentation on this function and the formula it
281
long_seq_tm(s, start, len, salt_conc)
289
if(start + len > strlen(s) || start < 0 || len <= 0) return OLIGOTM_ERROR;
290
end = &s[start + len];
291
/* Length <= 0 is nonsensical. */
292
for (p = &s[start]; p < end; p++) {
293
if ('G' == *p || 'g' == *p || 'C' == *p || 'c' == *p)
299
+ (16.6 * log10(salt_conc / 1000.0))
300
+ (41.0 * (((double) GC_count) / len))