root/trunk/DIST/DI_protdist.cxx

Revision 7811, 28.7 KB (checked in by westram, 10 months ago)

merge from dev [7748] [7749] [7750]

  • comments (C->C++ style)
  • fixed umlauts in TREEGEN
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : DI_protdist.cxx                                   //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "di_protdist.hxx"
12#include "di_matr.hxx"
13#include <aw_msg.hxx>
14#include <arb_progress.h>
15#include <cmath>
16
17#define di_assert(cond) arb_assert(cond)
18
19#define epsilon 0.000001        // a small number
20
21double di_protdist::pameigs[20] = {
22    -0.022091252, -0.019297602, 0.000004760, -0.017477817,
23    -0.016575549, -0.015504543, -0.002112213, -0.002685727,
24    -0.002976402, -0.013440755, -0.012926992, -0.004293227,
25    -0.005356688, -0.011064786, -0.010480731, -0.008760449,
26    -0.007142318, -0.007381851, -0.007806557, -0.008127024
27};
28
29double di_protdist::pamprobs[20][20] = {
30    {
31        -0.01522976, -0.00746819, -0.13934468, 0.11755315, -0.00212101,
32        0.01558456, -0.07408235, -0.00322387, 0.01375826, 0.00448826,
33        0.00154174, 0.02013313, -0.00159183, -0.00069275, -0.00399898,
34        0.08414055, -0.01188178, -0.00029870, 0.00220371, 0.00042546
35    },
36    {
37        -0.07765582, -0.00712634, -0.03683209, -0.08065755, -0.00462872,
38        -0.03791039, 0.10642147, -0.00912185, 0.01436308, -0.00133243,
39        0.00166346, 0.00624657, -0.00003363, -0.00128729, -0.00690319,
40        0.17442028, -0.05373336, -0.00078751, -0.00038151, 0.01382718
41    },
42    {
43        -0.08810973, -0.04081786, -0.04066004, -0.04736004, -0.03275406,
44        -0.03761164, -0.05047487, -0.09086213, -0.03269598, -0.03558015,
45        -0.08407966, -0.07970977, -0.01504743, -0.04011920, -0.05182232,
46        -0.07026991, -0.05846931, -0.01016998, -0.03047472, -0.06280511
47    },
48    {
49        0.02513756, -0.00578333, 0.09865453, 0.01322314, -0.00310665,
50        0.05880899, -0.09252443, -0.02986539, -0.03127460, 0.01007539,
51        -0.00360119, -0.01995024, 0.00094940, -0.00145868, -0.01388816,
52        0.11358341, -0.12127513, -0.00054696, -0.00055627, 0.00417284
53    },
54    {
55        0.16517316, -0.00254742, -0.03318745, -0.01984173, 0.00031890,
56        -0.02817810, 0.02661678, -0.01761215, 0.01665112, 0.10513343,
57        -0.00545026, 0.01827470, -0.00207616, -0.00763758, -0.01322808,
58        -0.02202576, -0.07434204, 0.00020593, 0.00119979, -0.10827873
59    },
60    {
61        0.16088826, 0.00056313, -0.02579303, -0.00319655, 0.00037228,
62        -0.03193150, 0.01655305, -0.03028640, 0.01367746, -0.11248153,
63        0.00778371, 0.02675579, 0.00243718, 0.00895470, -0.01729803,
64        -0.02686964, -0.08262584, 0.00011794, -0.00225134, 0.09415650
65    },
66    {
67        -0.01739295, 0.00572017, -0.00712592, -0.01100922, -0.00870113,
68        -0.00663461, -0.01153857, -0.02248432, -0.00382264, -0.00358612,
69        -0.00139345, -0.00971460, -0.00133312, 0.01927783, -0.01053838,
70        -0.00911362, -0.01010908, 0.09417598, 0.01763850, -0.00955454
71    },
72    {
73        0.01728888, 0.01344211, 0.01200836, 0.01857259, -0.17088517,
74        0.01457592, 0.01997839, 0.02844884, 0.00839403, 0.00196862,
75        0.01391984, 0.03270465, 0.00347173, -0.01940984, 0.01233979,
76        0.00542887, 0.01008836, 0.00126491, -0.02863042, 0.00449764
77    },
78    {
79        -0.02881366, -0.02184155, -0.01566086, -0.02593764, -0.04050907,
80        -0.01539603, -0.02576729, -0.05089606, -0.00597430, 0.02181643,
81        0.09835597, -0.04040940, 0.00873512, 0.12139434, -0.02427882,
82        -0.02945238, -0.01566867, -0.01606503, 0.09475319, 0.02238670
83    },
84    {
85        0.04080274, -0.02869626, -0.05191093, -0.08435843, 0.00021141,
86        0.13043842, 0.00871530, 0.00496058, -0.02797641, -0.00636933,
87        0.02243277, 0.03640362, -0.05735517, 0.00196918, -0.02218934,
88        -0.00608972, 0.02872922, 0.00047619, 0.00151285, 0.00883489
89    },
90    {
91        -0.02623824, 0.00331152, 0.03640692, 0.04260231, -0.00038223,
92        -0.07480340, -0.01022492, -0.00426473, 0.01448116, 0.01456847,
93        0.05786680, 0.03368691, -0.10126924, -0.00147454, 0.01275395,
94        0.00017574, -0.01585206, -0.00015767, -0.00231848, 0.02310137
95    },
96    {
97        -0.00846258, -0.01508106, -0.01967505, -0.02772004, 0.01248253,
98        -0.01331243, -0.02569382, -0.04461524, -0.02207075, 0.04663443,
99        0.19347923, -0.02745691, 0.02288515, -0.04883849, -0.01084597,
100        -0.01947187, -0.00081675, 0.00516540, -0.07815919, 0.08035585
101    },
102    {
103        -0.06553111, 0.09756831, 0.00524326, -0.00885098, 0.00756653,
104        0.02783099, -0.00427042, -0.16680359, 0.03951331, -0.00490540,
105        0.01719610, 0.15018204, 0.00882722, -0.00423197, -0.01919217,
106        -0.02963619, -0.01831342, -0.00524338, 0.00011379, -0.02566864
107    },
108    {
109        -0.07494341, -0.11348850, 0.00241343, -0.00803016, 0.00492438,
110        0.00711909, -0.00829147, 0.05793337, 0.02734209, 0.02059759,
111        -0.02770280, 0.14128338, 0.01532479, 0.00364307, 0.05968116,
112        -0.06497960, -0.08113941, 0.00319445, -0.00104222, 0.03553497
113    },
114    {
115        0.05948223, -0.08959930, 0.03269977, -0.03272374, -0.00365667,
116        -0.03423294, -0.06418925, -0.05902138, 0.05746317, -0.02580596,
117        0.01259572, 0.05848832, 0.00672666, 0.00233355, -0.05145149,
118        0.07348503, 0.11427955, 0.00142592, -0.01030651, -0.04862799
119    },
120    {
121        -0.01606880, 0.05200845, -0.01212967, -0.06824429, -0.00234304,
122        0.01094203, -0.07375538, 0.08808629, 0.12394822, 0.02231351,
123        -0.03608265, -0.06978045, -0.00618360, 0.00274747, -0.01921876,
124        -0.01541969, -0.02223856, -0.00107603, -0.01251777, 0.05412534
125    },
126    {
127        0.01688843, 0.05784728, -0.02256966, -0.07072251, -0.00422551,
128        -0.06261233, -0.08502830, 0.08925346, -0.08529597, 0.01519343,
129        -0.05008258, 0.10931873, 0.00521033, 0.02593305, -0.00717855,
130        0.02291527, 0.02527388, -0.00266188, -0.00871160, 0.02708135
131    },
132    {
133        -0.04233344, 0.00076379, 0.01571257, 0.04003092, 0.00901468,
134        0.00670577, 0.03459487, 0.12420216, -0.00067366, -0.01515094,
135        0.05306642, 0.04338407, 0.00511287, 0.01036639, -0.17867462,
136        -0.02289440, -0.03213205, 0.00017924, -0.01187362, -0.03933874
137    },
138    {
139        0.01284817, -0.01685622, 0.00724363, 0.01687952, -0.00882070,
140        -0.00555957, 0.01676246, -0.05560456, -0.00966893, 0.06197684,
141        -0.09058758, 0.00880607, 0.00108629, -0.08308956, -0.08056832,
142        -0.00413297, 0.02973107, 0.00092948, 0.07010111, 0.13007418
143    },
144    {
145        0.00700223, -0.01347574, 0.00691332, 0.03122905, 0.00310308,
146        0.00946862, 0.03455040, -0.06712536, -0.00304506, 0.04267941,
147        -0.10422292, -0.01127831, -0.00549798, 0.11680505, -0.03352701,
148        -0.00084536, 0.01631369, 0.00095063, -0.09570217, 0.06480321
149    }
150};
151
152void di_protdist::cats(di_cattype      wcat)
153{
154    // define categories of amino acids
155    aas             b;
156
157    // fundamental subgroups
158    cat[(long) cys - (long) ala] = 1;
159    cat[(long) met - (long) ala] = 2;
160    cat[(long) val - (long) ala] = 3;
161    cat[(long) leu - (long) ala] = 3;
162    cat[(long) ileu - (long) ala] = 3;
163    cat[(long) gly - (long) ala] = 4;
164    cat[0] = 4;
165    cat[(long) ser - (long) ala] = 4;
166    cat[(long) thr - (long) ala] = 4;
167    cat[(long) pro - (long) ala] = 5;
168    cat[(long) phe - (long) ala] = 6;
169    cat[(long) tyr - (long) ala] = 6;
170    cat[(long) trp - (long) ala] = 6;
171    cat[(long) glu - (long) ala] = 7;
172    cat[(long) gln - (long) ala] = 7;
173    cat[(long) asp - (long) ala] = 7;
174    cat[(long) asn - (long) ala] = 7;
175    cat[(long) lys - (long) ala] = 8;
176    cat[(long) arg - (long) ala] = 8;
177    cat[(long) his - (long) ala] = 8;
178    if (wcat == george) {
179        /* George, Hunt and Barker: sulfhydryl, small hydrophobic,
180         * small hydrophilic, aromatic, acid/acid-amide/hydrophilic,
181         * basic
182         */
183        for (b = ala; (long) b <= (long) val; b = (aas) ((long) b + 1)) {
184            if (cat[(long) b - (long) ala] == 3)
185                cat[(long) b - (long) ala] = 2;
186            if (cat[(long) b - (long) ala] == 5)
187                cat[(long) b - (long) ala] = 4;
188        }
189    }
190    if (wcat == chemical) {
191        /* Conn and Stumpf:  monoamino, aliphatic, heterocyclic,
192         * aromatic, dicarboxylic, basic
193         */
194        for (b = ala; (long) b <= (long) val; b = (aas) ((long) b + 1)) {
195            if (cat[(long) b - (long) ala] == 2)
196                cat[(long) b - (long) ala] = 1;
197            if (cat[(long) b - (long) ala] == 4)
198                cat[(long) b - (long) ala] = 3;
199        }
200    }
201    // Ben Hall's personal opinion
202    if (wcat != hall)
203        return;
204    for (b = ala; (long) b <= (long) val; b = (aas) ((long) b + 1)) {
205        if (cat[(long) b - (long) ala] == 3)
206            cat[(long) b - (long) ala] = 2;
207    }
208}
209
210
211void di_protdist::maketrans() {
212    // Make up transition probability matrix from code and category tables
213    long   i, j, k, m, n, s;
214    double x, sum = 0;
215    long   sub[3], newsub[3];
216    double f[4], g[4];
217    aas    b1, b2;
218    double TEMP, TEMP1, TEMP2, TEMP3;
219
220    for (i = 0; i <= 19; i++) {
221        pi[i] = 0.0;
222        for (j = 0; j <= 19; j++)
223            prob[i][j] = 0.0;
224    }
225    f[0] = freqt;
226    f[1] = freqc;
227    f[2] = freqa;
228    f[3] = freqg;
229    g[0] = freqc + freqt;
230    g[1] = freqc + freqt;
231    g[2] = freqa + freqg;
232    g[3] = freqa + freqg;
233    TEMP = f[0];
234    TEMP1 = f[1];
235    TEMP2 = f[2];
236    TEMP3 = f[3];
237    fracchange = xi * (2 * f[0] * f[1] / g[0] + 2 * f[2] * f[3] / g[2]) +
238        xv * (1 - TEMP * TEMP - TEMP1 * TEMP1 - TEMP2 * TEMP2 - TEMP3 * TEMP3);
239    for (i = 0; i <= 3; i++) {
240        for (j = 0; j <= 3; j++) {
241            for (k = 0; k <= 3; k++) {
242                if (trans[i][j][k] != stop)
243                    sum += f[i] * f[j] * f[k];
244            }
245        }
246    }
247    for (i = 0; i <= 3; i++) {
248        sub[0] = i + 1;
249        for (j = 0; j <= 3; j++) {
250            sub[1] = j + 1;
251            for (k = 0; k <= 3; k++) {
252                sub[2] = k + 1;
253                b1 = trans[i][j][k];
254                for (m = 0; m <= 2; m++) {
255                    s = sub[m];
256                    for (n = 1; n <= 4; n++) {
257                        memcpy(newsub, sub, sizeof(long) * 3L);
258                        newsub[m] = n;
259                        x = f[i] * f[j] * f[k] / (3.0 * sum);
260                        if (((s == 1 || s == 2) && (n == 3 || n == 4)) ||
261                            ((n == 1 || n == 2) && (s == 3 || s == 4)))
262                            x *= xv * f[n - 1];
263                        else
264                            x *= xi * f[n - 1] / g[n - 1] + xv * f[n - 1];
265                        b2 = trans[newsub[0] - 1][newsub[1] - 1][newsub[2] - 1];
266                        if (b1 != stop) {
267                            pi[b1] += x;
268                            if (b2 != stop) {
269                                if (cat[b1] != cat[b2]) {
270                                    prob[b1][b2] += x * ease;
271                                    prob[b1][b1] += x * (1.0 - ease);
272                                } else
273                                    prob[b1][b2] += x;
274                            } else
275                                prob[b1][b1] += x;
276                        }
277                    }
278                }
279            }
280        }
281    }
282    for (i = 0; i <= 19; i++)
283        prob[i][i] -= pi[i];
284    for (i = 0; i <= 19; i++) {
285        for (j = 0; j <= 19; j++)
286            prob[i][j] /= sqrt(pi[i] * pi[j]);
287    }
288    // computes pi^(1/2)*B*pi^(-1/2)
289}
290
291void di_protdist::code()
292{
293    // make up table of the code 0 = u, 1 = c, 2 = a, 3 = g
294
295    trans[0][0][0] = phe;
296    trans[0][0][1] = phe;
297    trans[0][0][2] = leu;
298    trans[0][0][3] = leu;
299    trans[0][1][0] = ser;
300    trans[0][1][1] = ser;
301    trans[0][1][2] = ser;
302    trans[0][1][3] = ser;
303    trans[0][2][0] = tyr;
304    trans[0][2][1] = tyr;
305    trans[0][2][2] = stop;
306    trans[0][2][3] = stop;
307    trans[0][3][0] = cys;
308    trans[0][3][1] = cys;
309    trans[0][3][2] = stop;
310    trans[0][3][3] = trp;
311    trans[1][0][0] = leu;
312    trans[1][0][1] = leu;
313    trans[1][0][2] = leu;
314    trans[1][0][3] = leu;
315    trans[1][1][0] = pro;
316    trans[1][1][1] = pro;
317    trans[1][1][2] = pro;
318    trans[1][1][3] = pro;
319    trans[1][2][0] = his;
320    trans[1][2][1] = his;
321    trans[1][2][2] = gln;
322    trans[1][2][3] = gln;
323    trans[1][3][0] = arg;
324    trans[1][3][1] = arg;
325    trans[1][3][2] = arg;
326    trans[1][3][3] = arg;
327    trans[2][0][0] = ileu;
328    trans[2][0][1] = ileu;
329    trans[2][0][2] = ileu;
330    trans[2][0][3] = met;
331    trans[2][1][0] = thr;
332    trans[2][1][1] = thr;
333    trans[2][1][2] = thr;
334    trans[2][1][3] = thr;
335    trans[2][2][0] = asn;
336    trans[2][2][1] = asn;
337    trans[2][2][2] = lys;
338    trans[2][2][3] = lys;
339    trans[2][3][0] = ser;
340    trans[2][3][1] = ser;
341    trans[2][3][2] = arg;
342    trans[2][3][3] = arg;
343    trans[3][0][0] = val;
344    trans[3][0][1] = val;
345    trans[3][0][2] = val;
346    trans[3][0][3] = val;
347    trans[3][1][0] = ala;
348    trans[3][1][1] = ala;
349    trans[3][1][2] = ala;
350    trans[3][1][3] = ala;
351    trans[3][2][0] = asp;
352    trans[3][2][1] = asp;
353    trans[3][2][2] = glu;
354    trans[3][2][3] = glu;
355    trans[3][3][0] = gly;
356    trans[3][3][1] = gly;
357    trans[3][3][2] = gly;
358    trans[3][3][3] = gly;
359    if (whichcode == mito)
360        trans[0][3][2] = trp;
361    if (whichcode == vertmito) {
362        trans[0][3][2] = trp;
363        trans[2][3][2] = stop;
364        trans[2][3][3] = stop;
365        trans[2][0][2] = met;
366    }
367    if (whichcode == flymito) {
368        trans[0][3][2] = trp;
369        trans[2][0][2] = met;
370        trans[2][3][2] = ser;
371    }
372    if (whichcode == yeastmito) {
373        trans[0][3][2] = trp;
374        trans[1][0][2] = thr;
375        trans[2][0][2] = met;
376    }
377}
378
379void di_protdist::transition()
380{
381    // calculations related to transition-transversion ratio
382    double          aa, bb, freqr, freqy, freqgr, freqty;
383
384    freqr = freqa + freqg;
385    freqy = freqc + freqt;
386    freqgr = freqg / freqr;
387    freqty = freqt / freqy;
388    aa = ttratio * freqr * freqy - freqa * freqg - freqc * freqt;
389    bb = freqa * freqgr + freqc * freqty;
390    xi = aa / (aa + bb);
391    xv = 1.0 - xi;
392    if (xi <= 0.0 && xi >= -epsilon)
393        xi = 0.0;
394    if (xi < 0.0) {
395        printf("THIS TRANSITION-TRANSVERSION RATIO IS IMPOSSIBLE WITH");
396        printf(" THESE BASE FREQUENCIES\n");
397        exit(-1);
398    }
399}
400
401void di_protdist::givens(di_aa_matrix a, long i, long j, long n, double ctheta, double stheta, bool left)
402{
403    // Givens transform at i,j for 1..n with angle theta
404    long            k;
405    double          d;
406
407    for (k = 0; k < n; k++) {
408        if (left) {
409            d = ctheta * a[i - 1][k] + stheta * a[j - 1][k];
410            a[j - 1][k] = ctheta * a[j - 1][k] - stheta * a[i - 1][k];
411            a[i - 1][k] = d;
412        }
413        else {
414            d = ctheta * a[k][i - 1] + stheta * a[k][j - 1];
415            a[k][j - 1] = ctheta * a[k][j - 1] - stheta * a[k][i - 1];
416            a[k][i - 1] = d;
417        }
418    }
419}
420
421void di_protdist::coeffs(double x, double y, double *c, double *s, double accuracy)
422{
423    // compute cosine and sine of theta
424    double          root;
425
426    root = sqrt(x * x + y * y);
427    if (root < accuracy) {
428        *c = 1.0;
429        *s = 0.0;
430    }
431    else {
432        *c = x / root;
433        *s = y / root;
434    }
435}
436
437void di_protdist::tridiag(di_aa_matrix a, long n, double accuracy)
438{
439    // Givens tridiagonalization
440    long            i, j;
441    double          s, c;
442
443    for (i = 2; i < n; i++) {
444        for (j = i + 1; j <= n; j++) {
445            coeffs(a[i - 2][i - 1], a[i - 2][j - 1], &c, &s, accuracy);
446            givens(a, i, j, n, c, s, true);
447            givens(a, i, j, n, c, s, false);
448            givens(eigvecs, i, j, n, c, s, true);
449        }
450    }
451}
452
453void di_protdist::shiftqr(di_aa_matrix a, long n, double accuracy)
454{
455    // QR eigenvalue-finder
456    long            i, j;
457    double          approx, s, c, d, TEMP, TEMP1;
458
459    for (i = n; i >= 2; i--) {
460        do {
461            TEMP = a[i - 2][i - 2] - a[i - 1][i - 1];
462            TEMP1 = a[i - 1][i - 2];
463            d = sqrt(TEMP * TEMP + TEMP1 * TEMP1);
464            approx = a[i - 2][i - 2] + a[i - 1][i - 1];
465            if (a[i - 1][i - 1] < a[i - 2][i - 2])
466                approx = (approx - d) / 2.0;
467            else
468                approx = (approx + d) / 2.0;
469            for (j = 0; j < i; j++)
470                a[j][j] -= approx;
471            for (j = 1; j < i; j++) {
472                coeffs(a[j - 1][j - 1], a[j][j - 1], &c, &s, accuracy);
473                givens(a, j, j + 1, i, c, s, true);
474                givens(a, j, j + 1, i, c, s, false);
475                givens(eigvecs, j, j + 1, n, c, s, true);
476            }
477            for (j = 0; j < i; j++)
478                a[j][j] += approx;
479        } while (fabs(a[i - 1][i - 2]) > accuracy);
480    }
481}
482
483
484void di_protdist::qreigen(di_aa_matrix proba, long n)
485{
486    // QR eigenvector/eigenvalue method for symmetric matrix
487    double          accuracy;
488    long            i, j;
489
490    accuracy = 1.0e-6;
491    for (i = 0; i < n; i++) {
492        for (j = 0; j < n; j++)
493            eigvecs[i][j] = 0.0;
494        eigvecs[i][i] = 1.0;
495    }
496    tridiag(proba, n, accuracy);
497    shiftqr(proba, n, accuracy);
498    for (i = 0; i < n; i++)
499        eig[i] = proba[i][i];
500    for (i = 0; i <= 19; i++) {
501        for (j = 0; j <= 19; j++)
502            proba[i][j] = sqrt(pi[j]) * eigvecs[i][j];
503    }
504    // proba[i][j] is the value of U' times pi^(1/2)
505}
506
507
508void di_protdist::pameigen()
509{
510    // eigenanalysis for PAM matrix, precomputed
511    memcpy(prob, pamprobs, sizeof(pamprobs));
512    memcpy(eig, pameigs, sizeof(pameigs));
513    fracchange = 0.01;
514}
515
516void di_protdist::build_exptteig(double tt) {
517    int m;
518    for (m = 0; m <= 19; m++) {
519        exptteig[m] = exp(tt * eig[m]);
520    }
521}
522
523void di_protdist::predict(double /* tt */, long nb1, long  nb2)
524{
525    // make contribution to prediction of this aa pair
526    long            m;
527    double          q;
528    double          TEMP;
529    for (m = 0; m <= 19; m++) {
530        q = prob[m][nb1] * prob[m][nb2] * exptteig[m];
531        p += q;
532        TEMP = eig[m];
533        dp += TEMP * q;
534        d2p += TEMP * TEMP * q;
535    }
536}
537
538void di_protdist::build_predikt_table(int pos) {
539    int             b1, b2;
540    double tt = pos_2_tt(pos);
541    build_exptteig(tt);
542    akt_slopes = slopes[pos] = (di_paa_matrix *) calloc(sizeof(di_paa_matrix), 1);
543    akt_curves = curves[pos] = (di_paa_matrix *) calloc(sizeof(di_paa_matrix), 1);
544    akt_infs = infs[pos] = (di_bool_matrix *) calloc(sizeof(di_bool_matrix), 1);
545
546    for (b1 = ala; b1 < di_max_paa; b1++) {
547        for (b2 = ala; b2 <= b1; b2++) {
548            if (b1 != stop && b1 != del && b1 != quest && b1 != unk &&
549                b2 != stop && b2 != del && b2 != quest && b2 != unk) {
550                p = 0.0;
551                dp = 0.0;
552                d2p = 0.0;
553                if (b1 != asx && b1 != glx && b2 != asx && b2 != glx) {
554                    predict(tt, b1, b2);
555                }
556                else {
557                    if (b1 == asx) {
558                        if (b2 == asx) {
559                            predict(tt, 2L, 2L);
560                            predict(tt, 2L, 3L);
561                            predict(tt, 3L, 2L);
562                            predict(tt, 3L, 3L);
563                        }
564                        else {
565                            if (b2 == glx) {
566                                predict(tt, 2L, 5L);
567                                predict(tt, 2L, 6L);
568                                predict(tt, 3L, 5L);
569                                predict(tt, 3L, 6L);
570                            }
571                            else {
572                                predict(tt, 2L, b2);
573                                predict(tt, 3L, b2);
574                            }
575                        }
576                    }
577                    else {
578                        if (b1 == glx) {
579                            if (b2 == asx) {
580                                predict(tt, 5L, 2L);
581                                predict(tt, 5L, 3L);
582                                predict(tt, 6L, 2L);
583                                predict(tt, 6L, 3L);
584                            }
585                            else {
586                                if (b2 == glx) {
587                                    predict(tt, 5L, 5L);
588                                    predict(tt, 5L, 6L);
589                                    predict(tt, 6L, 5L);
590                                    predict(tt, 6L, 6L);
591                                }
592                                else {
593                                    predict(tt, 5L, b2);
594                                    predict(tt, 6L, b2);
595                                }
596                            }
597                        }
598                        else {
599                            if (b2 == asx) {
600                                predict(tt, b1, 2L);
601                                predict(tt, b1, 3L);
602                                predict(tt, b1, 2L);
603                                predict(tt, b1, 3L);
604                            }
605                            else if (b2 == glx) {
606                                predict(tt, b1, 5L);
607                                predict(tt, b1, 6L);
608                                predict(tt, b1, 5L);
609                                predict(tt, b1, 6L);
610                            }
611                        }
612                    }
613                }
614                if (p > 0.0) {
615                    akt_slopes[0][b1][b2] = dp / p;
616                    akt_curves[0][b1][b2] = d2p / p - dp * dp / (p * p);
617                    akt_infs[0][b1][b2] = 0;
618                    akt_slopes[0][b2][b1] = akt_slopes[0][b1][b2];
619                    akt_curves[0][b2][b1] = akt_curves[0][b1][b2];
620                    akt_infs[0][b2][b1] = 0;
621                }
622                else {
623                    akt_infs[0][b1][b2] = 1;
624                    akt_infs[0][b2][b1] = 1;
625                }
626            }
627        }
628    }
629}
630
631int di_protdist::tt_2_pos(double tt) {
632    int pos = (int)(tt * fracchange * di_resolution);
633    if (pos >= di_resolution * di_max_dist)
634        pos = di_resolution * di_max_dist - 1;
635    if (pos < 0)
636        pos = 0;
637    return pos;
638}
639
640double di_protdist::pos_2_tt(int pos) {
641    double tt =  pos / (fracchange * di_resolution);
642    return tt+epsilon;
643}
644
645void di_protdist::build_akt_predikt(double tt)
646{
647    // take an actual slope from the hash table, else calculate a new one
648    int             pos = tt_2_pos(tt);
649    if (!slopes[pos]) {
650        build_predikt_table(pos);
651    }
652    akt_slopes = slopes[pos];
653    akt_curves = curves[pos];
654    akt_infs = infs[pos];
655    return;
656
657}
658
659GB_ERROR di_protdist::makedists(bool *aborted_flag) {
660    /* compute the distances.
661     * sets 'aborted_flag' to true, if it is non-NULL and user aborts the calculation
662     */
663    long   i, j, k, m, n, iterations;
664    double delta, slope, curv;
665    int    b1 = 0, b2=0;
666    double tt = 0;
667    int    pos;
668
669    arb_progress progress("Calculating distances", (spp*(spp+1))/2);
670    GB_ERROR     error = NULL;
671
672    for (i = 0; i < spp; i++) {
673        matrix->set(i, i, 0.0);
674        {
675            // move all unknown characters to del
676            ap_pro *seq1 = entries[i]->sequence_protein->get_sequence();
677            for (k = 0; k <chars;  k++) {
678                b1 = seq1[k];
679                if (b1 <= val) continue;
680                if (b1 == asx || b1 == glx) continue;
681                seq1[k] = del;
682            }
683        }
684
685        for (j = 0; j < i;  j++) {
686            if (whichcat > kimura) {
687                if (whichcat == pam)
688                    tt = 10.0;
689                else
690                    tt = 1.0;
691                delta = tt / 2.0;
692                iterations = 0;
693                do {
694                    slope = 0.0;
695                    curv = 0.0;
696                    pos = tt_2_pos(tt);
697                    tt = pos_2_tt(pos);
698                    build_akt_predikt(tt);
699                    const ap_pro *seq1 = entries[i]->sequence_protein->get_sequence();
700                    const ap_pro *seq2 = entries[j]->sequence_protein->get_sequence();
701                    for (k = chars; k >0; k--) {
702                        b1 = *(seq1++);
703                        b2 = *(seq2++);
704                        if (predict_infinity(b1, b2)) {
705                            break;
706                        }
707                        slope += predict_slope(b1, b2);
708                        curv += predict_curve(b1, b2);
709                    }
710                    iterations++;
711                    if (!predict_infinity(b1, b2)) {
712                        if (curv < 0.0) {
713                            tt -= slope / curv;
714                            if (tt > 10000.0) {
715                                aw_message(GB_export_errorf("INFINITE DISTANCE BETWEEN SPECIES %ld AND %ld; -1.0 WAS WRITTEN\n", i, j));
716                                tt = -1.0 / fracchange;
717                                break;
718                            }
719                            int npos = tt_2_pos(tt);
720                            int d = npos - pos; if (d<0) d=-d;
721                            if (d<=1) { // cannot optimize
722                                break;
723                            }
724
725                        }
726                        else {
727                            if ((slope > 0.0 && delta < 0.0) || (slope < 0.0 && delta > 0.0))
728                                delta /= -2;
729                            if (tt + delta < 0 && tt <= epsilon) {
730                                break;
731                            }
732                            tt += delta;
733                        }
734                    }
735                    else {
736                        delta /= -2;
737                        tt += delta;
738                        if (tt < 0) tt = 0;
739                    }
740                } while (iterations < 20);
741            }
742            else {                    // cat < kimura
743                m = 0;
744                n = 0;
745                const ap_pro *seq1 = entries[i]->sequence_protein->get_sequence();
746                const ap_pro *seq2 = entries[j]->sequence_protein->get_sequence();
747                for (k = chars; k >0; k--) {
748                    b1 = *(seq1++);
749                    b2 = *(seq2++);
750                    if (b1 <= val && b2 <= val) {
751                        if (b1 == b2)   m++;
752                        n++;
753                    }
754                }
755                if (n < 5) {            // no info
756                    tt = -1.0;
757                }
758                else {
759                    switch (whichcat) {
760                        case kimura:
761                            {
762                                double rel = 1 - (double) m / n;
763                                double drel = 1.0 - rel - 0.2 * rel * rel;
764                                if (drel < 0.0) {
765                                    aw_message(GB_export_errorf("DISTANCE BETWEEN SEQUENCES %3ld AND %3ld IS TOO LARGE FOR KIMURA FORMULA", i, j));
766                                    tt = -1.0;
767                                }
768                                else {
769                                    tt = -log(drel);
770                                }
771                            }
772                            break;
773                        case none:
774                            tt = (n-m)/(double)n;
775                            break;
776                        case similarity:
777                            tt = m/(double)n;
778                            break;
779                        default:
780                            di_assert(0);
781                            break;
782                    }
783                }
784            }
785            matrix->set(i, j, fracchange * tt);
786            progress.inc_and_check_user_abort(error);
787        }
788    }
789    if (aborted_flag && error) *aborted_flag = true;
790    return error;
791}
792
793
794void di_protdist::clean_slopes() {
795    for (int i=0; i<di_resolution*di_max_dist; i++) {
796        freenull(slopes[i]);
797        freenull(curves[i]);
798        freenull(infs[i]);
799    }
800    akt_slopes = 0;
801    akt_curves = 0;
802    akt_infs = 0;
803}
804
805di_protdist::~di_protdist() {
806    clean_slopes();
807}
808
809di_protdist::di_protdist(di_codetype codei, di_cattype cati, long nentries, DI_ENTRY     **entriesi, long seq_len, AP_smatrix *matrixi) {
810    memset((char *)this, 0, sizeof(di_protdist));
811    entries = entriesi;
812    matrix = matrixi;
813    freqa = .25;
814    freqc = .25;
815    freqg = .25;
816    freqt = .25;
817    ttratio = 2.0;
818    ease = 0.457;
819    spp = nentries;
820    chars = seq_len;
821    transition();
822    whichcode = codei;
823    whichcat = cati;
824    switch (cati) {
825        case none:
826        case similarity:
827        case kimura:
828            fracchange = 1.0;
829            break;
830        case pam:
831            code();
832            pameigen();
833            break;
834        default:
835            code();
836            maketrans();
837            qreigen(prob, 20L);
838            break;
839    }
840}
Note: See TracBrowser for help on using the browser.