source: trunk/GDE/CLUSTALW/readmat.c

Last change on this file was 19480, checked in by westram, 15 months ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1#include <stdio.h>
2#include <math.h>
3#include <stdlib.h>
4#include <string.h>
5#include <ctype.h>
6#include "clustalw.h"
7#include "matrices.h"
8
9
10/*
11 *   Prototypes
12 */
13static Boolean commentline(char *line);
14
15
16/*
17 *   Global variables
18 */
19
20extern char     *amino_acid_codes;
21extern sint     gap_pos1, gap_pos2;
22extern sint     max_aa;
23extern short    def_dna_xref[],def_aa_xref[];
24extern sint     mat_avscore;
25extern sint     debug;
26extern Boolean  dnaflag;
27
28extern Boolean user_series;
29extern UserMatSeries matseries;
30extern short usermatseries[MAXMAT][NUMRES][NUMRES];
31extern short aa_xrefseries[MAXMAT][NUMRES+1];
32
33
34void init_matrix(void)
35{
36
37   char c1,c2;
38   short i, j, maxres;
39
40   max_aa = strlen(amino_acid_codes)-2;
41   gap_pos1 = NUMRES-2;          /* code for gaps inserted by clustalw */
42   gap_pos2 = NUMRES-1;           /* code for gaps already in alignment */
43
44/*
45   set up cross-reference for default matrices hard-coded in matrices.h
46*/
47   for (i=0;i<NUMRES;i++) def_aa_xref[i] = -1;
48   for (i=0;i<NUMRES;i++) def_dna_xref[i] = -1;
49
50   maxres = 0;
51   for (i=0;(c1=amino_acid_order[i]);i++)
52     {
53         for (j=0;(c2=amino_acid_codes[j]);j++)
54          {
55           if (c1 == c2)
56               {
57                  def_aa_xref[i] = j;
58                  maxres++;
59                  break;
60               }
61          }
62         if ((def_aa_xref[i] == -1) && (amino_acid_order[i] != '*'))
63            {
64                error("residue %c in matrices.h is not recognised",
65                                       amino_acid_order[i]);
66            }
67     }
68
69   maxres = 0;
70   for (i=0;(c1=nucleic_acid_order[i]);i++)
71     {
72         for (j=0;(c2=amino_acid_codes[j]);j++)
73          {
74           if (c1 == c2)
75               {
76                  def_dna_xref[i] = j;
77                  maxres++;
78                  break;
79               }
80          }
81         if ((def_dna_xref[i] == -1) && (nucleic_acid_order[i] != '*'))
82            {
83                error("nucleic acid %c in matrices.h is not recognised",
84                                       nucleic_acid_order[i]);
85            }
86     }
87}
88
89sint get_matrix(short *matptr, short *xref, sint matrix[NUMRES][NUMRES], Boolean neg_flag, sint scale)
90{
91   sint gg_score = 0;
92   sint gr_score = 0;
93   sint i, j, k, ix = 0;
94   sint ti, tj;
95   sint  maxres;
96   sint av1,av2,av3,min, max;
97/*
98   default - set all scores to 0
99*/
100   for (i=0;i<=max_aa;i++)
101      for (j=0;j<=max_aa;j++)
102          matrix[i][j] = 0;
103
104   ix = 0;
105   maxres = 0;
106   for (i=0;i<=max_aa;i++)
107    {
108      ti = xref[i];
109      for (j=0;j<=i;j++)
110       {
111          tj = xref[j]; 
112          if ((ti != -1) && (tj != -1))
113            {
114               k = matptr[ix];
115               if (ti==tj)
116                  {
117                     matrix[ti][ti] = k * scale;
118                     maxres++;
119                  }
120               else
121                  {
122                     matrix[ti][tj] = k * scale;
123                     matrix[tj][ti] = k * scale;
124                  }
125               ix++;
126            }
127       }
128    }
129
130   --maxres;
131
132   av1 = av2 = av3 = 0;
133   for (i=0;i<=max_aa;i++)
134    {
135      for (j=0;j<=i;j++)
136       {
137           av1 += matrix[i][j];
138           if (i==j)
139              {
140                 av2 += matrix[i][j];
141              }
142           else
143              {
144                 av3 += matrix[i][j];
145              }
146       }
147    }
148
149   av1 /= (maxres*maxres)/2;
150   av2 /= maxres;
151   av3 /= ((float)(maxres*maxres-maxres))/2;
152  mat_avscore = -av3;
153
154  min = max = matrix[0][0];
155  for (i=0;i<=max_aa;i++)
156    for (j=1;j<=i;j++)
157      {
158        if (matrix[i][j] < min) min = matrix[i][j];
159        if (matrix[i][j] > max) max = matrix[i][j];
160      }
161if (debug>1) fprintf(stdout,"maxres %d\n",(pint)max_aa);
162if (debug>1) fprintf(stdout,"average mismatch score %d\n",(pint)av3);
163if (debug>1) fprintf(stdout,"average match score %d\n",(pint)av2);
164if (debug>1) fprintf(stdout,"average score %d\n",(pint)av1);
165
166/*
167   if requested, make a positive matrix - add -(lowest score) to every entry
168*/
169  if (neg_flag == FALSE)
170   {
171
172if (debug>1) fprintf(stdout,"min %d max %d\n",(pint)min,(pint)max);
173      if (min < 0)
174        {
175           for (i=0;i<=max_aa;i++)
176            {
177              ti = xref[i];
178              if (ti != -1)
179                {
180                 for (j=0;j<=max_aa;j++)
181                   {
182                    tj = xref[j];
183/*
184                    if (tj != -1) matrix[ti][tj] -= (2*av3);
185*/
186                    if (tj != -1) matrix[ti][tj] -= min;
187                   }
188                }
189            }
190        }
191/*
192       gr_score = av3;
193       gg_score = -av3;
194*/
195
196   }
197
198
199
200  for (i=0;i<gap_pos1;i++)
201   {
202      matrix[i][gap_pos1] = gr_score;
203      matrix[gap_pos1][i] = gr_score;
204      matrix[i][gap_pos2] = gr_score;
205      matrix[gap_pos2][i] = gr_score;
206   }
207  matrix[gap_pos1][gap_pos1] = gg_score;
208  matrix[gap_pos2][gap_pos2] = gg_score;
209  matrix[gap_pos2][gap_pos1] = gg_score;
210  matrix[gap_pos1][gap_pos2] = gg_score;
211
212  maxres += 2;
213
214  return(maxres);
215}
216
217
218sint read_matrix_series(char *filename, short *usermat, short *xref)
219{
220   FILE *fd = NULL;
221   char mat_filename[FILENAMELEN];
222   char inline1[1024];
223   sint  maxres = 0;
224   sint nmat;
225   sint n,llimit,ulimit;
226
227   if (filename[0] == '\0')
228     {
229        error("comparison matrix not specified");
230        return((sint)0);
231     }
232   if ((fd=fopen(filename,"r"))==NULL) 
233     {
234        error("cannot open %s", filename);
235        return((sint)0);
236     }
237
238/* check the first line to see if it's a series or a single matrix */
239   while (fgets(inline1,1024,fd) != NULL)
240     {
241        if (commentline(inline1)) continue;
242        if(linetype(inline1,"CLUSTAL_SERIES"))
243                user_series=TRUE;
244        else
245                user_series=FALSE;
246        break;
247     }
248
249/* it's a single matrix */
250  if(user_series == FALSE)
251    {
252        fclose(fd);
253        maxres=read_user_matrix(filename,usermat,xref);
254        return(maxres);
255    }
256
257/* it's a series of matrices, find the next MATRIX line */
258   nmat=0;
259   matseries.nmat=0;
260   while (fgets(inline1,1024,fd) != NULL)
261     {
262        if (commentline(inline1)) continue;
263        if(linetype(inline1,"MATRIX"))
264        {
265                if(sscanf(inline1+6,"%d %d %s",&llimit,&ulimit,mat_filename)!=3)
266                {
267                        error("Bad format in file %s\n",filename);
268                        fclose(fd);
269                        return((sint)0);
270                }
271                if(llimit<0 || llimit > 100 || ulimit <0 || ulimit>100)
272                {
273                        error("Bad format in file %s\n",filename);
274                        fclose(fd);
275                        return((sint)0);
276                }
277                if(ulimit<=llimit)
278                {
279                        error("in file %s: lower limit is greater than upper (%d-%d)\n",filename,llimit,ulimit);
280                        fclose(fd);
281                        return((sint)0);
282                }
283                n=read_user_matrix(mat_filename,&usermatseries[nmat][0][0],&aa_xrefseries[nmat][0]);
284                if(n<=0)
285                {
286                        error("Bad format in matrix file %s\n",mat_filename);
287                        fclose(fd);
288                        return((sint)0);
289                }
290                matseries.mat[nmat].llimit=llimit;
291                matseries.mat[nmat].ulimit=ulimit;
292                matseries.mat[nmat].matptr=&usermatseries[nmat][0][0];
293                matseries.mat[nmat].aa_xref=&aa_xrefseries[nmat][0];
294                nmat++;
295        }
296    }
297   fclose(fd);
298   matseries.nmat=nmat;
299
300   maxres=n;
301   return(maxres);
302
303}
304
305sint read_user_matrix(char *filename, short *usermat, short *xref)
306{
307   double f;
308   FILE *fd;
309   sint  numargs,farg;
310   sint i, j, k = 0;
311   char codes[NUMRES];
312   char inline1[1024];
313   char *args[NUMRES+4];
314   char c1,c2;
315   sint ix1, ix = 0;
316   sint  maxres = 0;
317   float scale;
318
319   if (filename[0] == '\0')
320     {
321        error("comparison matrix not specified");
322        return((sint)0);
323     }
324
325   if ((fd=fopen(filename,"r"))==NULL) 
326   {
327        error("cannot open %s", filename);
328        return((sint)0);
329   }
330   maxres = 0;
331   while (fgets(inline1,1024,fd) != NULL)
332     {
333        if (commentline(inline1)) continue;
334        if(linetype(inline1,"CLUSTAL_SERIES"))
335        {
336                error("in %s - single matrix expected.", filename);
337                fclose(fd);
338                return((sint)0);
339        }
340/*
341   read residue characters.
342*/
343        k = 0;
344        {
345            int inline1Len = strlen(inline1);
346            for (j=0;j<inline1Len;j++)
347            {
348                if (isalpha((int)inline1[j])) codes[k++] = inline1[j];
349                if (k>NUMRES)
350                {
351                    error("too many entries in matrix %s",filename);
352                    fclose(fd);
353                    return((sint)0);
354                }
355            }
356        }
357        codes[k] = '\0';
358        break;
359    }
360
361   if (k == 0) 
362     {
363        error("wrong format in matrix %s",filename);
364        fclose(fd);
365        return((sint)0);
366     }
367
368/*
369   cross-reference the residues
370*/
371   for (i=0;i<NUMRES;i++) xref[i] = -1;
372
373   maxres = 0;
374   for (i=0;(c1=codes[i]);i++)
375     {
376         for (j=0;(c2=amino_acid_codes[j]);j++)
377           if (c1 == c2)
378               {
379                  xref[i] = j;
380                  maxres++;
381                  break;
382               }
383         if ((xref[i] == -1) && (codes[i] != '*'))
384            {
385                warning("residue %c in matrix %s not recognised",
386                                       codes[i],filename);
387            }
388     }
389
390
391/*
392   get the weights
393*/
394
395   ix = ix1 = 0;
396   while (fgets(inline1,1024,fd) != NULL)
397     {
398        if (inline1[0] == '\n') continue;
399        if (inline1[0] == '#' ||
400            inline1[0] == '!') break;
401        numargs = getargs(inline1, args, (int)(k+1));
402        if (numargs < maxres)
403          {
404             error("wrong format in matrix %s",filename);
405             fclose(fd);
406             return((sint)0);
407          }
408        if (isalpha(args[0][0])) farg=1;
409        else farg=0;
410
411/* decide whether the matrix values are float or decimal */
412        scale=1.0;
413        {
414            int argsFargLen = strlen(args[farg]);
415            for(i=0;i<argsFargLen;i++)
416                if(args[farg][i]=='.')
417                {
418/* we've found a float value */
419                    scale=10.0;
420                    break;
421                }
422        }
423
424        for (i=0;i<=ix;i++)
425          {
426             if (xref[i] != -1)
427               {
428                  f = atof(args[i+farg]);
429                  usermat[ix1++] = (short)(f*scale);
430               }
431          }
432        ix++;
433     }
434   if (ix != k+1)
435     {
436        error("wrong format in matrix %s",filename);
437        fclose(fd);
438        return((sint)0);
439     }
440
441
442  maxres += 2;
443  fclose(fd);
444
445  return(maxres);
446}
447
448int getargs(char *inline1,char *args[],int max)
449{
450
451        char    *inptr;
452/*
453#ifndef MAC
454        char    *strtok(char *s1, const char *s2);
455#endif
456*/
457        int     i;
458
459        inptr=inline1;
460        for (i=0;i<=max;i++)
461        {
462                if ((args[i]=strtok(inptr," \t\n"))==NULL)
463                        break;
464                inptr=NULL;
465        }
466
467        return(i);
468}
469
470
471static Boolean commentline(char *line)
472{
473        int i;
474 
475        if(line[0] == '#') return TRUE;
476        for(i=0;line[i]!='\n' && line[i]!=EOS;i++) {
477                if(!isspace(line[i]))
478                        return FALSE;
479        }
480        return TRUE;
481}
482
Note: See TracBrowser for help on using the repository browser.